mirror of
https://git.vladimir.cc/vladimir/ewsdr.git
synced 2026-08-25 20:37:33 +00:00
refactoring SettingsForm
This commit is contained in:
+42
-6
@@ -15,6 +15,7 @@ unit AudioInput;
|
|||||||
|
|
||||||
{$IFDEF FPC}
|
{$IFDEF FPC}
|
||||||
{$MODE Delphi}
|
{$MODE Delphi}
|
||||||
|
{$PACKRECORDS C}
|
||||||
{$ENDIF}
|
{$ENDIF}
|
||||||
|
|
||||||
interface
|
interface
|
||||||
@@ -156,9 +157,13 @@ const
|
|||||||
'libportaudio.so.0'
|
'libportaudio.so.0'
|
||||||
);
|
);
|
||||||
{$ELSE}
|
{$ELSE}
|
||||||
PA_IN_LIBS: array[0..1] of AnsiString = (
|
PA_IN_LIBS: array[0..5] of AnsiString = (
|
||||||
'portaudio_x64.dll',
|
'portaudio_x64.dll',
|
||||||
'portaudio.dll'
|
'portaudio_x86.dll',
|
||||||
|
'portaudio.dll',
|
||||||
|
'libportaudio-2.dll',
|
||||||
|
'libportaudio.dll',
|
||||||
|
'libportaudio64.dll'
|
||||||
);
|
);
|
||||||
{$ENDIF}
|
{$ENDIF}
|
||||||
PA_NO_ERROR = 0;
|
PA_NO_ERROR = 0;
|
||||||
@@ -265,7 +270,11 @@ begin
|
|||||||
|
|
||||||
if FLibHandle = NilHandle then
|
if FLibHandle = NilHandle then
|
||||||
begin
|
begin
|
||||||
|
{$IFDEF WINDOWS}
|
||||||
|
FLastError := 'PortAudio DLL not found. Put portaudio_x64.dll, portaudio.dll, or libportaudio-2.dll next to ewsdr.exe';
|
||||||
|
{$ELSE}
|
||||||
FLastError := 'libportaudio not found';
|
FLastError := 'libportaudio not found';
|
||||||
|
{$ENDIF}
|
||||||
Exit;
|
Exit;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@@ -279,7 +288,15 @@ begin
|
|||||||
FPa_CloseStream := TPaMic_CloseStream (GetProcAddress(FLibHandle, 'Pa_CloseStream'));
|
FPa_CloseStream := TPaMic_CloseStream (GetProcAddress(FLibHandle, 'Pa_CloseStream'));
|
||||||
FPa_GetErrorText := TPaMic_GetErrorText(GetProcAddress(FLibHandle, 'Pa_GetErrorText'));
|
FPa_GetErrorText := TPaMic_GetErrorText(GetProcAddress(FLibHandle, 'Pa_GetErrorText'));
|
||||||
|
|
||||||
if not Assigned(FPa_Initialize) or not Assigned(FPa_OpenStream) then
|
if not Assigned(FPa_Initialize) or
|
||||||
|
not Assigned(FPa_Terminate) or
|
||||||
|
not Assigned(FPa_GetDeviceCount) or
|
||||||
|
not Assigned(FPa_GetDeviceInfo) or
|
||||||
|
not Assigned(FPa_OpenStream) or
|
||||||
|
not Assigned(FPa_StartStream) or
|
||||||
|
not Assigned(FPa_StopStream) or
|
||||||
|
not Assigned(FPa_CloseStream) or
|
||||||
|
not Assigned(FPa_GetErrorText) then
|
||||||
begin
|
begin
|
||||||
FLastError := 'libportaudio: symbols not found';
|
FLastError := 'libportaudio: symbols not found';
|
||||||
FreeLibrary(FLibHandle);
|
FreeLibrary(FLibHandle);
|
||||||
@@ -329,10 +346,27 @@ begin
|
|||||||
Count := 0;
|
Count := 0;
|
||||||
Result := False;
|
Result := False;
|
||||||
if not Initialize then Exit;
|
if not Initialize then Exit;
|
||||||
if not Assigned(FPa_GetDeviceCount) or not Assigned(FPa_GetDeviceInfo) then Exit;
|
if not Assigned(FPa_GetDeviceCount) or not Assigned(FPa_GetDeviceInfo) then
|
||||||
|
begin
|
||||||
|
FLastError := 'PortAudio device enumeration is not available';
|
||||||
|
Exit;
|
||||||
|
end;
|
||||||
|
|
||||||
N := FPa_GetDeviceCount();
|
N := FPa_GetDeviceCount();
|
||||||
if N <= 0 then Exit;
|
if N < 0 then
|
||||||
|
begin
|
||||||
|
FLastError := 'Pa_GetDeviceCount: ';
|
||||||
|
if Assigned(FPa_GetErrorText) then
|
||||||
|
FLastError := FLastError + string(FPa_GetErrorText(N))
|
||||||
|
else
|
||||||
|
FLastError := FLastError + IntToStr(N);
|
||||||
|
Exit;
|
||||||
|
end;
|
||||||
|
if N = 0 then
|
||||||
|
begin
|
||||||
|
FLastError := 'No PortAudio devices found';
|
||||||
|
Exit;
|
||||||
|
end;
|
||||||
|
|
||||||
for I := 0 to N - 1 do
|
for I := 0 to N - 1 do
|
||||||
begin
|
begin
|
||||||
@@ -410,8 +444,10 @@ begin
|
|||||||
InParam.device := FDeviceIndex;
|
InParam.device := FDeviceIndex;
|
||||||
InParam.sampleFormat := PA_FLOAT32;
|
InParam.sampleFormat := PA_FLOAT32;
|
||||||
|
|
||||||
// suggestedLatency = defaultLowInputLatency устройства (как в piHPSDR)
|
|
||||||
Info := FPa_GetDeviceInfo(FDeviceIndex);
|
Info := FPa_GetDeviceInfo(FDeviceIndex);
|
||||||
|
{$IFDEF WINDOWS}
|
||||||
|
// На Windows latency=0 часто ломает WASAPI/MME; берём значение от устройства.
|
||||||
|
{$ENDIF}
|
||||||
if Info <> nil then
|
if Info <> nil then
|
||||||
InParam.suggestedLatency := Info^.defaultLowInputLatency
|
InParam.suggestedLatency := Info^.defaultLowInputLatency
|
||||||
else
|
else
|
||||||
|
|||||||
+47
-7
@@ -15,6 +15,7 @@ unit AudioOutput;
|
|||||||
|
|
||||||
{$IFDEF FPC}
|
{$IFDEF FPC}
|
||||||
{$MODE Delphi}
|
{$MODE Delphi}
|
||||||
|
{$PACKRECORDS C}
|
||||||
{$ENDIF}
|
{$ENDIF}
|
||||||
|
|
||||||
interface
|
interface
|
||||||
@@ -166,9 +167,13 @@ const
|
|||||||
'libportaudio.so.0'
|
'libportaudio.so.0'
|
||||||
);
|
);
|
||||||
{$ELSE}
|
{$ELSE}
|
||||||
PA_LIBS: array[0..1] of AnsiString = (
|
PA_LIBS: array[0..5] of AnsiString = (
|
||||||
'portaudio_x64.dll',
|
'portaudio_x64.dll',
|
||||||
'portaudio.dll'
|
'portaudio_x86.dll',
|
||||||
|
'portaudio.dll',
|
||||||
|
'libportaudio-2.dll',
|
||||||
|
'libportaudio.dll',
|
||||||
|
'libportaudio64.dll'
|
||||||
);
|
);
|
||||||
{$ENDIF}
|
{$ENDIF}
|
||||||
PA_NO_ERROR = 0;
|
PA_NO_ERROR = 0;
|
||||||
@@ -282,7 +287,11 @@ begin
|
|||||||
|
|
||||||
if FLibHandle = NilHandle then
|
if FLibHandle = NilHandle then
|
||||||
begin
|
begin
|
||||||
|
{$IFDEF WINDOWS}
|
||||||
|
FLastError := 'PortAudio DLL not found. Put portaudio_x64.dll, portaudio.dll, or libportaudio-2.dll next to ewsdr.exe';
|
||||||
|
{$ELSE}
|
||||||
FLastError := 'libportaudio not found. sudo apt install libportaudio2';
|
FLastError := 'libportaudio not found. sudo apt install libportaudio2';
|
||||||
|
{$ENDIF}
|
||||||
Exit;
|
Exit;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@@ -297,7 +306,16 @@ begin
|
|||||||
FPa_CloseStream := TPa_CloseStream(GetProcAddress(FLibHandle, 'Pa_CloseStream'));
|
FPa_CloseStream := TPa_CloseStream(GetProcAddress(FLibHandle, 'Pa_CloseStream'));
|
||||||
FPa_GetErrorText := TPa_GetErrorText(GetProcAddress(FLibHandle, 'Pa_GetErrorText'));
|
FPa_GetErrorText := TPa_GetErrorText(GetProcAddress(FLibHandle, 'Pa_GetErrorText'));
|
||||||
|
|
||||||
if not Assigned(FPa_Initialize) or not Assigned(FPa_OpenStream) then
|
if not Assigned(FPa_Initialize) or
|
||||||
|
not Assigned(FPa_Terminate) or
|
||||||
|
not Assigned(FPa_GetDefaultOutputDevice) or
|
||||||
|
not Assigned(FPa_GetDeviceCount) or
|
||||||
|
not Assigned(FPa_GetDeviceInfo) or
|
||||||
|
not Assigned(FPa_OpenStream) or
|
||||||
|
not Assigned(FPa_StartStream) or
|
||||||
|
not Assigned(FPa_StopStream) or
|
||||||
|
not Assigned(FPa_CloseStream) or
|
||||||
|
not Assigned(FPa_GetErrorText) then
|
||||||
begin
|
begin
|
||||||
FLastError := 'libportaudio: symbols not found';
|
FLastError := 'libportaudio: symbols not found';
|
||||||
FreeLibrary(FLibHandle);
|
FreeLibrary(FLibHandle);
|
||||||
@@ -350,10 +368,27 @@ begin
|
|||||||
Count := 0;
|
Count := 0;
|
||||||
Result := False;
|
Result := False;
|
||||||
if not Initialize then Exit;
|
if not Initialize then Exit;
|
||||||
if not Assigned(FPa_GetDeviceCount) or not Assigned(FPa_GetDeviceInfo) then Exit;
|
if not Assigned(FPa_GetDeviceCount) or not Assigned(FPa_GetDeviceInfo) then
|
||||||
|
begin
|
||||||
|
FLastError := 'PortAudio device enumeration is not available';
|
||||||
|
Exit;
|
||||||
|
end;
|
||||||
|
|
||||||
N := FPa_GetDeviceCount();
|
N := FPa_GetDeviceCount();
|
||||||
if N <= 0 then Exit;
|
if N < 0 then
|
||||||
|
begin
|
||||||
|
FLastError := 'Pa_GetDeviceCount: ';
|
||||||
|
if Assigned(FPa_GetErrorText) then
|
||||||
|
FLastError := FLastError + string(FPa_GetErrorText(N))
|
||||||
|
else
|
||||||
|
FLastError := FLastError + IntToStr(N);
|
||||||
|
Exit;
|
||||||
|
end;
|
||||||
|
if N = 0 then
|
||||||
|
begin
|
||||||
|
FLastError := 'No PortAudio devices found';
|
||||||
|
Exit;
|
||||||
|
end;
|
||||||
|
|
||||||
for I := 0 to N - 1 do
|
for I := 0 to N - 1 do
|
||||||
begin
|
begin
|
||||||
@@ -416,6 +451,7 @@ var
|
|||||||
OutParam: TPaStreamParameters;
|
OutParam: TPaStreamParameters;
|
||||||
Err: TPaError;
|
Err: TPaError;
|
||||||
Dev: TPaDeviceIndex;
|
Dev: TPaDeviceIndex;
|
||||||
|
Info: PPaDeviceInfo;
|
||||||
begin
|
begin
|
||||||
Result := False;
|
Result := False;
|
||||||
if FOpen then begin Result := True; Exit; end;
|
if FOpen then begin Result := True; Exit; end;
|
||||||
@@ -441,8 +477,12 @@ begin
|
|||||||
OutParam.hostApiSpecificStreamInfo := nil;
|
OutParam.hostApiSpecificStreamInfo := nil;
|
||||||
OutParam.sampleFormat := PA_FLOAT32;
|
OutParam.sampleFormat := PA_FLOAT32;
|
||||||
{$IFDEF WINDOWS}
|
{$IFDEF WINDOWS}
|
||||||
// На Windows latency=0 вызывает фризы — используем разумный минимум
|
// На Windows latency=0 часто ломает WASAPI/MME; берём значение от устройства.
|
||||||
OutParam.suggestedLatency := 0.050; // 50ms — стабильно на Windows WASAPI/MME
|
Info := FPa_GetDeviceInfo(Dev);
|
||||||
|
if (Info <> nil) and (Info^.defaultLowOutputLatency > 0.0) then
|
||||||
|
OutParam.suggestedLatency := Info^.defaultLowOutputLatency
|
||||||
|
else
|
||||||
|
OutParam.suggestedLatency := 0.050;
|
||||||
{$ELSE}
|
{$ELSE}
|
||||||
OutParam.suggestedLatency := 0.0; // на Linux ALSA справляется с минимумом
|
OutParam.suggestedLatency := 0.0; // на Linux ALSA справляется с минимумом
|
||||||
{$ENDIF}
|
{$ENDIF}
|
||||||
|
|||||||
+3
-3
@@ -952,7 +952,7 @@ begin
|
|||||||
end
|
end
|
||||||
else
|
else
|
||||||
begin
|
begin
|
||||||
Result.FFTSize := 4096;
|
Result.FFTSize := 131072;
|
||||||
Result.WindowType := 2;
|
Result.WindowType := 2;
|
||||||
Result.SpecDetector := 0;
|
Result.SpecDetector := 0;
|
||||||
Result.SpecAvgMode := 3;
|
Result.SpecAvgMode := 3;
|
||||||
@@ -1177,7 +1177,7 @@ begin
|
|||||||
FPanelHidden := False;
|
FPanelHidden := False;
|
||||||
FShowSpectrum := True;
|
FShowSpectrum := True;
|
||||||
FShowWaterfall := True;
|
FShowWaterfall := True;
|
||||||
FDisplayFPS := 20;
|
FDisplayFPS := 60;
|
||||||
FWaterfallDirty := True;
|
FWaterfallDirty := True;
|
||||||
FSplitterRatio := 0.40; // 40% спектр, 60% водопад по умолчанию
|
FSplitterRatio := 0.40; // 40% спектр, 60% водопад по умолчанию
|
||||||
FSplitterDrag := False;
|
FSplitterDrag := False;
|
||||||
@@ -5815,7 +5815,7 @@ begin
|
|||||||
FAudioOutDevName, FAudioInDevName)
|
FAudioOutDevName, FAudioInDevName)
|
||||||
else
|
else
|
||||||
SF.LoadValues(
|
SF.LoadValues(
|
||||||
4096, 2, 0, 3, 30.0,
|
131072, 2, 0, 3, 30.0,
|
||||||
0, 3, 120.0, FWfManualHigh, FWfManualLow, FWfAGCOffset,
|
0, 3, 120.0, FWfManualHigh, FWfManualLow, FWfAGCOffset,
|
||||||
FSpecRefLevel, FSpecRange, FSpecGridStep,
|
FSpecRefLevel, FSpecRange, FSpecGridStep,
|
||||||
FAudioOutDevName, FAudioInDevName);
|
FAudioOutDevName, FAudioInDevName);
|
||||||
|
|||||||
+25
-15
@@ -49,7 +49,7 @@ type
|
|||||||
WindowWidth: Integer;
|
WindowWidth: Integer;
|
||||||
WindowHeight: Integer;
|
WindowHeight: Integer;
|
||||||
// --- Display settings ---
|
// --- Display settings ---
|
||||||
FFTSize: Integer; // 1024,2048,4096,8192,16384
|
FFTSize: Integer; // 4096..262144
|
||||||
WindowType: Integer; // 0=Rect,1=BH4,2=Hann,3=FlatTop,4=Hamming,5=Kaiser,6=BH7
|
WindowType: Integer; // 0=Rect,1=BH4,2=Hann,3=FlatTop,4=Hamming,5=Kaiser,6=BH7
|
||||||
SpecDetector: Integer; // 0=Peak,1=Rosenfell,2=Average,3=Sample,4=RMS
|
SpecDetector: Integer; // 0=Peak,1=Rosenfell,2=Average,3=Sample,4=RMS
|
||||||
SpecAvgMode: Integer; // 0=None,1=Recursive,2=TimeWindow,3=LogRecursive
|
SpecAvgMode: Integer; // 0=None,1=Recursive,2=TimeWindow,3=LogRecursive
|
||||||
@@ -171,7 +171,7 @@ begin
|
|||||||
G.PAMaxPower := 100.0;
|
G.PAMaxPower := 100.0;
|
||||||
for i := 0 to CFG_BAND_COUNT-1 do G.PABandCal[i] := 100.0;
|
for i := 0 to CFG_BAND_COUNT-1 do G.PABandCal[i] := 100.0;
|
||||||
// Display defaults
|
// Display defaults
|
||||||
G.FFTSize := 4096;
|
G.FFTSize := 131072;
|
||||||
G.WindowType := 2; // Hann
|
G.WindowType := 2; // Hann
|
||||||
G.SpecDetector := 0; // Peak
|
G.SpecDetector := 0; // Peak
|
||||||
G.SpecAvgMode := 3; // Log Recursive
|
G.SpecAvgMode := 3; // Log Recursive
|
||||||
@@ -190,7 +190,7 @@ begin
|
|||||||
G.AudioInDevice := '';
|
G.AudioInDevice := '';
|
||||||
G.ShowSpectrum := True;
|
G.ShowSpectrum := True;
|
||||||
G.ShowWaterfall := True;
|
G.ShowWaterfall := True;
|
||||||
G.DisplayFPS := 20;
|
G.DisplayFPS := 60;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
constructor TSettingsManager.Create(const FilePath: string);
|
constructor TSettingsManager.Create(const FilePath: string);
|
||||||
@@ -336,30 +336,40 @@ begin
|
|||||||
G.LastBand := JI(GObj,'last_band',5);
|
G.LastBand := JI(GObj,'last_band',5);
|
||||||
G.SampleRate := JI(GObj,'sample_rate',192000);
|
G.SampleRate := JI(GObj,'sample_rate',192000);
|
||||||
// Display settings
|
// Display settings
|
||||||
G.FFTSize := JI(GObj,'fft_size',4096);
|
G.FFTSize := JI(GObj,'fft_size',131072);
|
||||||
G.WindowType := JI(GObj,'win_type',5);
|
G.WindowType := JI(GObj,'win_type',2);
|
||||||
G.SpecDetector := JI(GObj,'spec_detector',0);
|
G.SpecDetector := JI(GObj,'spec_detector',0);
|
||||||
G.SpecAvgMode := JI(GObj,'spec_avg_mode',0);
|
G.SpecAvgMode := JI(GObj,'spec_avg_mode',3);
|
||||||
if GObj.Find('spec_avg_time_ms') <> nil then
|
if GObj.Find('spec_avg_time_ms') <> nil then
|
||||||
G.SpecAvgTimeMS := JD(GObj,'spec_avg_time_ms',120.0)
|
G.SpecAvgTimeMS := JD(GObj,'spec_avg_time_ms',30.0)
|
||||||
else
|
else if (GObj.Find('spec_avg_count') <> nil) or
|
||||||
|
(GObj.Find('spec_backmult') <> nil) then
|
||||||
|
begin
|
||||||
G.SpecAvgTimeMS := LegacyAverageTimeMS(
|
G.SpecAvgTimeMS := LegacyAverageTimeMS(
|
||||||
JI(GObj,'display_fps',20),
|
JI(GObj,'display_fps',60),
|
||||||
G.SpecAvgMode,
|
G.SpecAvgMode,
|
||||||
JI(GObj,'spec_avg_count',1),
|
JI(GObj,'spec_avg_count',1),
|
||||||
JD(GObj,'spec_backmult',0.0),
|
JD(GObj,'spec_backmult',0.0),
|
||||||
120.0);
|
30.0);
|
||||||
G.WfDetector := JI(GObj,'wf_detector',2);
|
end
|
||||||
G.WfAvgMode := JI(GObj,'wf_avg_mode',1);
|
else
|
||||||
|
G.SpecAvgTimeMS := 30.0;
|
||||||
|
G.WfDetector := JI(GObj,'wf_detector',0);
|
||||||
|
G.WfAvgMode := JI(GObj,'wf_avg_mode',3);
|
||||||
if GObj.Find('wf_avg_time_ms') <> nil then
|
if GObj.Find('wf_avg_time_ms') <> nil then
|
||||||
G.WfAvgTimeMS := JD(GObj,'wf_avg_time_ms',120.0)
|
G.WfAvgTimeMS := JD(GObj,'wf_avg_time_ms',120.0)
|
||||||
else
|
else if (GObj.Find('wf_avg_count') <> nil) or
|
||||||
|
(GObj.Find('wf_backmult') <> nil) then
|
||||||
|
begin
|
||||||
G.WfAvgTimeMS := LegacyAverageTimeMS(
|
G.WfAvgTimeMS := LegacyAverageTimeMS(
|
||||||
JI(GObj,'display_fps',20),
|
JI(GObj,'display_fps',60),
|
||||||
G.WfAvgMode,
|
G.WfAvgMode,
|
||||||
JI(GObj,'wf_avg_count',2),
|
JI(GObj,'wf_avg_count',2),
|
||||||
JD(GObj,'wf_backmult',0.25),
|
JD(GObj,'wf_backmult',0.25),
|
||||||
120.0);
|
120.0);
|
||||||
|
end
|
||||||
|
else
|
||||||
|
G.WfAvgTimeMS := 120.0;
|
||||||
G.WfManualHigh := JD(GObj,'wf_manual_high',-80.0);
|
G.WfManualHigh := JD(GObj,'wf_manual_high',-80.0);
|
||||||
G.WfManualLow := JD(GObj,'wf_manual_low',-130.0);
|
G.WfManualLow := JD(GObj,'wf_manual_low',-130.0);
|
||||||
G.WfAGCOffset := JD(GObj,'wf_agc_offset',0.0);
|
G.WfAGCOffset := JD(GObj,'wf_agc_offset',0.0);
|
||||||
@@ -373,7 +383,7 @@ begin
|
|||||||
// Visibility settings
|
// Visibility settings
|
||||||
G.ShowSpectrum := JB(GObj,'show_spectrum',True);
|
G.ShowSpectrum := JB(GObj,'show_spectrum',True);
|
||||||
G.ShowWaterfall := JB(GObj,'show_waterfall',True);
|
G.ShowWaterfall := JB(GObj,'show_waterfall',True);
|
||||||
G.DisplayFPS := JI(GObj,'display_fps',20);
|
G.DisplayFPS := JI(GObj,'display_fps',60);
|
||||||
// PA settings
|
// PA settings
|
||||||
G.PAMaxPower := JD(GObj,'pa_max_power',100.0);
|
G.PAMaxPower := JD(GObj,'pa_max_power',100.0);
|
||||||
for i := 0 to CFG_BAND_COUNT-1 do
|
for i := 0 to CFG_BAND_COUNT-1 do
|
||||||
|
|||||||
+590
-478
File diff suppressed because it is too large
Load Diff
+3
-3
@@ -551,10 +551,10 @@ begin
|
|||||||
FANFEnabled := False;
|
FANFEnabled := False;
|
||||||
FRXAccPos := 0;
|
FRXAccPos := 0;
|
||||||
// Analyzer defaults
|
// Analyzer defaults
|
||||||
FFFTSize := 4096;
|
FFFTSize := 131072;
|
||||||
FWindowType := 2; // Hann
|
FWindowType := 2; // Hann
|
||||||
FDisplayFPS := 20;
|
FDisplayFPS := 60;
|
||||||
FEffectiveDisplayFPS := 20.0;
|
FEffectiveDisplayFPS := 60.0;
|
||||||
FDisplayPixelCount := SPECTRUM_PIXELS;
|
FDisplayPixelCount := SPECTRUM_PIXELS;
|
||||||
FSpecDetector := 0; // Peak
|
FSpecDetector := 0; // Peak
|
||||||
FSpecAvgMode := 3; // Log Recursive
|
FSpecAvgMode := 3; // Log Recursive
|
||||||
|
|||||||
Reference in New Issue
Block a user