mirror of
https://git.vladimir.cc/vladimir/ewsdr.git
synced 2026-08-25 20:37:33 +00:00
Phase 5 (batch 22): move engine lifecycle into the controller
TRadioController now owns its engines: CreateEngines(ASampleRate) builds FNetwork/FDSPEngine/FAudioOut/FAudioIn (and the constructor now owns FSettings), FreeEngines closes and frees them, and Destroy calls FreeEngines + frees FSettings. FormCreate replaces the four inline T...Create calls with a single FController.CreateEngines (after the startup sample rate is loaded, so FDSPEngine is still born at the right rate) and keeps wiring the MainForm callbacks. FormDestroy keeps the graceful Run=0 stop + Disconnect but drops the per-engine Close/Free and FSettings.Free, which now happen in the controller's destructor. This is a behaviour-preserving ownership move toward headless/daemon operation. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
33c433ce5e
commit
8be98b72e1
+10
-25
@@ -989,8 +989,7 @@ begin
|
||||
TSettingsManager.DefaultBand(bi_, FController.FBandCache[bi_]);
|
||||
FController.FCurrentBand := 5;
|
||||
|
||||
// Загружаем JSON настройки
|
||||
FController.FSettings := TSettingsManager.Create;
|
||||
// Загружаем JSON настройки (FSettings создаётся в TRadioController.Create)
|
||||
FController.FSettings.Load;
|
||||
|
||||
// Загружаем список каналов
|
||||
@@ -1152,7 +1151,10 @@ begin
|
||||
FSpecView.PAMaxPower := FController.FPAMaxPower;
|
||||
FWidebandView := TWidebandView.Create;
|
||||
|
||||
FController.FNetwork := THPSDRNetwork.Create;
|
||||
// Движки создаёт контроллер (владелец lifecycle — нужно для демона); здесь
|
||||
// лишь навешиваем колбэки на методы MainForm. FSampleRate уже загружен из
|
||||
// startup-preview выше, поэтому FDSPEngine рождается с нужной частотой.
|
||||
FController.CreateEngines(FController.FSampleRate);
|
||||
FController.FNetwork.OnDeviceFound := OnDeviceFound;
|
||||
FController.FNetwork.OnHPStatus := OnHPStatusCB;
|
||||
FController.FNetwork.OnDDCIQ := OnDDCIQCB;
|
||||
@@ -1170,13 +1172,8 @@ begin
|
||||
UpdateVfoDisplay;
|
||||
UpdateFilterButtons;
|
||||
|
||||
// DSP Engine — создаём объект, Open вызовется при нажатии START
|
||||
// (FController.FDSPEngine.Open загружает libwdsp и занимает ~1-2 сек)
|
||||
// DSP Engine.Open (загрузка libwdsp, ~1-2 сек) вызывается при нажатии START.
|
||||
FController.FWDSPReady := False;
|
||||
// BufSize=512: FBufSize=2048 @ 192kHz, FAudioBufSize=512 @ 48kHz.
|
||||
// Уменьшение с 1024 вдвое сокращает время построения downsampler в OpenChannel RXA
|
||||
// (~1300ms → ~650ms). Латентность: 512/48000 ≈ 10.7ms — допустимо для SDR.
|
||||
FController.FDSPEngine := TWDSPEngine.Create(FController.FSampleRate, 48000, 512);
|
||||
FController.FDSPEngine.OnAudio := OnAudioReady;
|
||||
FController.FDSPEngine.OnSpectrum := OnSpectrumReady;
|
||||
FController.FDSPEngine.OnWaterfall := OnWaterfallReady;
|
||||
@@ -1185,12 +1182,6 @@ begin
|
||||
// тиком, если выбран источник SoundCard. Для Radio колбэк не вызывается.
|
||||
FController.FDSPEngine.OnPullMicSamples := PullSoundCardMic;
|
||||
|
||||
// Audio output/input — создаём объекты сейчас, открываем после показа формы
|
||||
// (Pa_Initialize на Linux пишет в stderr до перехвата сигналов FPC)
|
||||
FController.FAudioOut := TAudioOutput.Create(48000);
|
||||
FController.FAudioOut.OutputBufferSize := FController.FSettings.LoadAudioBufferSize;
|
||||
FController.FAudioIn := TAudioInput.Create(48000);
|
||||
|
||||
FMeterTimer := TTimer.Create(Self);
|
||||
FMeterTimer.Interval := 100;
|
||||
FMeterTimer.OnTimer := MeterTimerTick;
|
||||
@@ -1221,16 +1212,11 @@ procedure TMainForm.FormDestroy(Sender: TObject);
|
||||
begin
|
||||
FMeterTimer.Enabled := False;
|
||||
FSpectrumTimer.Enabled := False;
|
||||
// Грациозный стоп радио (Run=0) до освобождения; сами движки закрывает и
|
||||
// освобождает TRadioController.Destroy (FreeEngines) ниже.
|
||||
if FController.FNetwork.Running then
|
||||
FController.FNetwork.SetRunAndFreq(False, XvtrTranslate(FController.FCenterFreq), XvtrTranslate(FController.FCenterFreq), 0);
|
||||
FController.FNetwork.Disconnect;
|
||||
FController.FNetwork.Free;
|
||||
FController.FAudioOut.Close;
|
||||
FController.FAudioOut.Free;
|
||||
FController.FAudioIn.Close;
|
||||
FController.FAudioIn.Free;
|
||||
FController.FDSPEngine.Close;
|
||||
FController.FDSPEngine.Free;
|
||||
FreeAndNil(FSpecView);
|
||||
FreeAndNil(FWidebandView);
|
||||
|
||||
@@ -1245,15 +1231,14 @@ begin
|
||||
// Размер окна сохраняем всегда (не зависит от подключения)
|
||||
FController.FSettings.SaveStartupPreview(FController.FVfoA, FController.FVfoB, FController.FSampleRate);
|
||||
FController.FSettings.Save;
|
||||
FController.FSettings.Free;
|
||||
FreeAndNil(FController.FChannelStore);
|
||||
FWebServer.Stop;
|
||||
FWebServer.Free;
|
||||
if Assigned(FCATTcp) then begin FCATTcp.Stop; FreeAndNil(FCATTcp); end;
|
||||
if Assigned(FCATSerial) then begin FCATSerial.StopAll; FreeAndNil(FCATSerial); end;
|
||||
FreeAndNil(FCATEngine);
|
||||
// Движки (поля FController) уже освобождены выше.
|
||||
// Освобождаем само ядро последним.
|
||||
// Ядро освобождаем последним — его Destroy закрывает и освобождает движки
|
||||
// (FreeEngines) и FSettings.
|
||||
FreeAndNil(FController);
|
||||
end;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user