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