Phase 5 (batch 28): move display state into the controller

Move the 14 persisted display-state fields (FShow*/FSpec*/FWf*/FTXSpec*/
FWidebandFill/FSpectrumFill) from MainForm into TRadioController so a
headless device load (DoConnectDevice) can apply them without the UI. Pure
field relocation: every reader/writer now addresses FController.F*, render
still happens in MainForm against FSpecView/FWidebandView. Compiler-verified
complete; behavior preserved.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Uladzimir Karpenka
2026-06-08 11:15:58 +03:00
co-authored by Claude Opus 4.8
parent 9fdfc67f65
commit 1fdbe27b96
2 changed files with 125 additions and 124 deletions
+109 -124
View File
@@ -153,27 +153,12 @@ type
FSpectrumWidth: Integer; // актуальная ширина для FDSPEngine и resize-детектора FSpectrumWidth: Integer; // актуальная ширина для FDSPEngine и resize-детектора
FSpectrumHeight: Integer; FSpectrumHeight: Integer;
FWaterfallHeight:Integer; FWaterfallHeight:Integer;
FShowSpectrum: Boolean;
FShowWaterfall: Boolean;
FShowWideband: Boolean;
FWidebandFill: Boolean;
FSpectrumFill: Boolean;
FDisplayFPS: Integer; FDisplayFPS: Integer;
FWaterfallDirty: Boolean; FWaterfallDirty: Boolean;
FWidebandDirty: Boolean; FWidebandDirty: Boolean;
FPreChannelPower: Integer; // мощность до применения канала (-1 = не сохранена) FPreChannelPower: Integer; // мощность до применения канала (-1 = не сохранена)
FWfManualHigh: Double; // Display state (FShow*/FSpec*/FWf*/FTXSpec*/FController.FWidebandFill/FController.FSpectrumFill)
FWfManualLow: Double; // переехало в TRadioController (нужно headless-load в DoConnectDevice).
FWfAGCOffset: Double;
// Spectrum display settings (for settings save/load)
FSpecRefLevel: Double;
FSpecRange: Double;
FSpecGridStep: Double;
// TX-specific grid (Thetis-style: при TX рисуем спектр в своих границах).
// Применяются к FSpecView когда FTransmitting=True; иначе используются RX-значения.
FTXSpecRefLevel: Double;
FTXSpecRange: Double;
FTXSpecGridStep: Double;
// DSP data buffers (copy of last DSP output, for WebServer.PushSpectrum) // DSP data buffers (copy of last DSP output, for WebServer.PushSpectrum)
FSpectrumBuf: array[0..1023] of Single; FSpectrumBuf: array[0..1023] of Single;
FWaterfallBuf: array[0..1023] of Single; FWaterfallBuf: array[0..1023] of Single;
@@ -803,18 +788,18 @@ begin
Result.WfAvgMode := 3; Result.WfAvgMode := 3;
Result.WfAvgTimeMS := 120.0; Result.WfAvgTimeMS := 120.0;
end; end;
Result.WfManualHigh := FWfManualHigh; Result.WfManualHigh := FController.FWfManualHigh;
Result.WfManualLow := FWfManualLow; Result.WfManualLow := FController.FWfManualLow;
Result.WfAGCOffset := FWfAGCOffset; Result.WfAGCOffset := FController.FWfAGCOffset;
Result.SpecRefLevel := FSpecRefLevel; Result.SpecRefLevel := FController.FSpecRefLevel;
Result.SpecRange := FSpecRange; Result.SpecRange := FController.FSpecRange;
Result.SpecGridStep := FSpecGridStep; Result.SpecGridStep := FController.FSpecGridStep;
Result.AudioSampleRate := FController.FAudioOut.SampleRate; Result.AudioSampleRate := FController.FAudioOut.SampleRate;
Result.ShowSpectrum := FShowSpectrum; Result.ShowSpectrum := FController.FShowSpectrum;
Result.ShowWaterfall := FShowWaterfall; Result.ShowWaterfall := FController.FShowWaterfall;
Result.ShowWideband := FShowWideband; Result.ShowWideband := FController.FShowWideband;
Result.WidebandFill := FWidebandFill; Result.WidebandFill := FController.FWidebandFill;
Result.SpectrumFill := FSpectrumFill; Result.SpectrumFill := FController.FSpectrumFill;
Result.DisplayDuplex := FController.FDisplayDuplex; Result.DisplayDuplex := FController.FDisplayDuplex;
Result.DisplayFPS := FDisplayFPS; Result.DisplayFPS := FDisplayFPS;
Result.LightTheme := FLightTheme; Result.LightTheme := FLightTheme;
@@ -917,9 +902,9 @@ begin
FController.FSampleRate := 192000; FController.FSampleRate := 192000;
FController.FCurrentBand := 5; // 20m по умолчанию FController.FCurrentBand := 5; // 20m по умолчанию
// Waterfall normalization // Waterfall normalization
FWfManualHigh := -80.0; FController.FWfManualHigh := -80.0;
FWfManualLow := -130.0; FController.FWfManualLow := -130.0;
FWfAGCOffset := 0.0; FController.FWfAGCOffset := 0.0;
FController.FWfAGCEnabled := True; FController.FWfAGCEnabled := True;
FController.FWfNFEnabled := False; FController.FWfNFEnabled := False;
FController.FDitherEnabled := True; FController.FDitherEnabled := True;
@@ -942,13 +927,13 @@ begin
FWaterfallFrameCounter := 0; FWaterfallFrameCounter := 0;
FController.FDevConnected := False; FController.FDevConnected := False;
// Spectrum grid settings defaults // Spectrum grid settings defaults
FSpecRefLevel := -20.0; FController.FSpecRefLevel := -20.0;
FSpecRange := 110.0; FController.FSpecRange := 110.0;
FSpecGridStep := 10.0; FController.FSpecGridStep := 10.0;
// TX grid defaults (синхронно с TSettingsManager.DefaultTX) // TX grid defaults (синхронно с TSettingsManager.DefaultTX)
FTXSpecRefLevel := 0.0; FController.FTXSpecRefLevel := 0.0;
FTXSpecRange := 80.0; FController.FTXSpecRange := 80.0;
FTXSpecGridStep := 10.0; FController.FTXSpecGridStep := 10.0;
FSettingsForm := nil; FSettingsForm := nil;
FChannelsForm := nil; FChannelsForm := nil;
FActiveChannelIdx := -1; FActiveChannelIdx := -1;
@@ -1068,11 +1053,11 @@ begin
FVfoOverlay.OnInvalidate := OnVfoOverlayInvalidate; FVfoOverlay.OnInvalidate := OnVfoOverlayInvalidate;
FVfoOverlay.Visible := False; FVfoOverlay.Visible := False;
FPanelHidden := False; FPanelHidden := False;
FShowSpectrum := True; FController.FShowSpectrum := True;
FShowWaterfall := True; FController.FShowWaterfall := True;
FShowWideband := False; FController.FShowWideband := False;
FWidebandFill := False; FController.FWidebandFill := False;
FSpectrumFill := True; FController.FSpectrumFill := True;
FDisplayFPS := 60; FDisplayFPS := 60;
FFreqMhzDigits := 3; FFreqMhzDigits := 3;
FSplitterRatio := 0.40; FSplitterRatio := 0.40;
@@ -1112,12 +1097,12 @@ begin
FSpecView.AGCTop := FController.FAGCTop; FSpecView.AGCTop := FController.FAGCTop;
FSpecView.WfAGCEnabled := FController.FWfAGCEnabled; FSpecView.WfAGCEnabled := FController.FWfAGCEnabled;
FSpecView.WfNFEnabled := FController.FWfNFEnabled; FSpecView.WfNFEnabled := FController.FWfNFEnabled;
FSpecView.WfManualHigh := FWfManualHigh; FSpecView.WfManualHigh := FController.FWfManualHigh;
FSpecView.WfManualLow := FWfManualLow; FSpecView.WfManualLow := FController.FWfManualLow;
FSpecView.WfAGCOffset := FWfAGCOffset; FSpecView.WfAGCOffset := FController.FWfAGCOffset;
FSpecView.SpecRefLevel := FSpecRefLevel; FSpecView.SpecRefLevel := FController.FSpecRefLevel;
FSpecView.SpecRange := FSpecRange; FSpecView.SpecRange := FController.FSpecRange;
FSpecView.SpecGridStep := FSpecGridStep; FSpecView.SpecGridStep := FController.FSpecGridStep;
// TX overlay: ширина окна = TX_SAMPLE_RATE из движка (фикс 192k) // TX overlay: ширина окна = TX_SAMPLE_RATE из движка (фикс 192k)
FSpecView.TXSpanHz := WDSPEngine.TX_SAMPLE_RATE; FSpecView.TXSpanHz := WDSPEngine.TX_SAMPLE_RATE;
FSpecView.WfFrameInterval := FWaterfallFrameInterval; FSpecView.WfFrameInterval := FWaterfallFrameInterval;
@@ -2425,7 +2410,7 @@ begin
UpdateWidebandFrequencyView; UpdateWidebandFrequencyView;
WideH := 0; WideH := 0;
WideSpecH := 0; WideSpecH := 0;
if FShowWideband then if FController.FShowWideband then
WideH := Min(MulDiv(WB_H, Screen.PixelsPerInch, 96), Max(40, RH div 2)); WideH := Min(MulDiv(WB_H, Screen.PixelsPerInch, 96), Max(40, RH div 2));
if WideH > 0 then if WideH > 0 then
WideSpecH := Max(1, WideH - RULER_H); WideSpecH := Max(1, WideH - RULER_H);
@@ -2433,8 +2418,8 @@ begin
if PbWideband <> nil then if PbWideband <> nil then
begin begin
PbWideband.SetBounds(0, 0, RW, WideSpecH); PbWideband.SetBounds(0, 0, RW, WideSpecH);
PbWideband.Visible := FShowWideband and (WideSpecH > 0); PbWideband.Visible := FController.FShowWideband and (WideSpecH > 0);
if FShowWideband and (RW > 0) and (WideSpecH > 0) then if FController.FShowWideband and (RW > 0) and (WideSpecH > 0) then
begin begin
FWidebandView.SetBitmapSize(RW, WideSpecH); FWidebandView.SetBitmapSize(RW, WideSpecH);
PbWideband.Invalidate; PbWideband.Invalidate;
@@ -2442,9 +2427,9 @@ begin
end; end;
if PbWidebandRuler <> nil then if PbWidebandRuler <> nil then
begin begin
PbWidebandRuler.SetBounds(0, WideSpecH, RW, IfThen(FShowWideband and (WideH > 0), RULER_H, 0)); PbWidebandRuler.SetBounds(0, WideSpecH, RW, IfThen(FController.FShowWideband and (WideH > 0), RULER_H, 0));
PbWidebandRuler.Visible := FShowWideband and (WideH > 0); PbWidebandRuler.Visible := FController.FShowWideband and (WideH > 0);
if FShowWideband and (RW > 0) and (WideH > 0) then if FController.FShowWideband and (RW > 0) and (WideH > 0) then
begin begin
FWidebandView.SetRulerSize(RW, RULER_H); FWidebandView.SetRulerSize(RW, RULER_H);
PbWidebandRuler.Invalidate; PbWidebandRuler.Invalidate;
@@ -2454,7 +2439,7 @@ begin
ResizeSMeter; ResizeSMeter;
// ---- Оба скрыты ---- // ---- Оба скрыты ----
if (not FShowSpectrum) and (not FShowWaterfall) then if (not FController.FShowSpectrum) and (not FController.FShowWaterfall) then
begin begin
PbSpectrum.Visible := False; PbSpectrum.Visible := False;
PbRuler.Visible := False; PbRuler.Visible := False;
@@ -2468,7 +2453,7 @@ begin
end; end;
// ---- Только спектр (водопад скрыт) ---- // ---- Только спектр (водопад скрыт) ----
if FShowSpectrum and (not FShowWaterfall) then if FController.FShowSpectrum and (not FController.FShowWaterfall) then
begin begin
AvailH := RH - TopOff - RULER_H; AvailH := RH - TopOff - RULER_H;
if AvailH < MIN_SH then AvailH := MIN_SH; if AvailH < MIN_SH then AvailH := MIN_SH;
@@ -2497,7 +2482,7 @@ begin
end; end;
// ---- Только водопад (спектр скрыт): линейка под водопадом ---- // ---- Только водопад (спектр скрыт): линейка под водопадом ----
if (not FShowSpectrum) and FShowWaterfall then if (not FController.FShowSpectrum) and FController.FShowWaterfall then
begin begin
AvailH := RH - TopOff - RULER_H; AvailH := RH - TopOff - RULER_H;
if AvailH < MIN_WH then AvailH := MIN_WH; if AvailH < MIN_WH then AvailH := MIN_WH;
@@ -2944,7 +2929,7 @@ begin
// FSplitTxB (TX-A/TX-B), независимо от активного RX-VFO. // FSplitTxB (TX-A/TX-B), независимо от активного RX-VFO.
if FController.FSplitTxB then FSpecView.TXVfoIndex := 1 if FController.FSplitTxB then FSpecView.TXVfoIndex := 1
else FSpecView.TXVfoIndex := 0; else FSpecView.TXVfoIndex := 0;
if UpdateWidebandFrequencyView and FShowWideband and (PbWideband <> nil) then if UpdateWidebandFrequencyView and FController.FShowWideband and (PbWideband <> nil) then
PbWideband.Invalidate; PbWideband.Invalidate;
end; end;
@@ -3030,10 +3015,10 @@ begin
// PbSpectrum.Height может быть ненулевым при FSpectrumHeight=0, // PbSpectrum.Height может быть ненулевым при FSpectrumHeight=0,
// что вызвало бы сброс буфера водопада на каждом тике. // что вызвало бы сброс буфера водопада на каждом тике.
if (FSpectrumWidth = 0) or if (FSpectrumWidth = 0) or
(FShowWideband and (PbWideband.Width <> FSpectrumWidth)) or (FController.FShowWideband and (PbWideband.Width <> FSpectrumWidth)) or
(FShowSpectrum and ((PbSpectrum.Width <> FSpectrumWidth) or (FController.FShowSpectrum and ((PbSpectrum.Width <> FSpectrumWidth) or
(PbSpectrum.Height <> FSpectrumHeight))) or (PbSpectrum.Height <> FSpectrumHeight))) or
(FShowWaterfall and not FShowSpectrum and (FController.FShowWaterfall and not FController.FShowSpectrum and
((PbWaterfall.Width <> FSpectrumWidth) or ((PbWaterfall.Width <> FSpectrumWidth) or
(PbWaterfall.Height <> FWaterfallHeight))) then (PbWaterfall.Height <> FWaterfallHeight))) then
ResizeSpectrumPanels; ResizeSpectrumPanels;
@@ -3117,7 +3102,7 @@ begin
PbWaterfall.Invalidate; PbWaterfall.Invalidate;
FWaterfallDirty := False; FWaterfallDirty := False;
end; end;
if FWidebandDirty and FShowWideband then if FWidebandDirty and FController.FShowWideband then
begin begin
PbWideband.Invalidate; PbWideband.Invalidate;
FWidebandDirty := False; FWidebandDirty := False;
@@ -3325,7 +3310,7 @@ end;
procedure TMainForm.OnWidebandCB(ADCIndex: Integer; procedure TMainForm.OnWidebandCB(ADCIndex: Integer;
const Samples: array of SmallInt; Count: Integer); const Samples: array of SmallInt; Count: Integer);
begin begin
if (not FShowWideband) or (FWidebandView = nil) then Exit; if (not FController.FShowWideband) or (FWidebandView = nil) then Exit;
FWidebandView.SetSamples(Samples, Count); FWidebandView.SetSamples(Samples, Count);
FWidebandDirty := True; FWidebandDirty := True;
end; end;
@@ -3806,10 +3791,10 @@ begin
RebuildXvtrButtons; RebuildXvtrButtons;
ApplyXvtrToNetwork; ApplyXvtrToNetwork;
PushXvtrToWeb; PushXvtrToWeb;
FTXSpecRefLevel := FController.FTXSettings.TXSpecRefLevel; FController.FTXSpecRefLevel := FController.FTXSettings.TXSpecRefLevel;
FTXSpecRange := FController.FTXSettings.TXSpecRange; FController.FTXSpecRange := FController.FTXSettings.TXSpecRange;
if FController.FTXSettings.TXSpecGridStep > 0 then if FController.FTXSettings.TXSpecGridStep > 0 then
FTXSpecGridStep := FController.FTXSettings.TXSpecGridStep; FController.FTXSpecGridStep := FController.FTXSettings.TXSpecGridStep;
FController.FVolume := G_Settings.Volume; FController.FVolume := G_Settings.Volume;
FController.FActiveVfo := G_Settings.ActiveVfo; FController.FActiveVfo := G_Settings.ActiveVfo;
// PA settings // PA settings
@@ -3839,23 +3824,23 @@ begin
FController.FDitherEnabled := G_Settings.DitherEnabled; FController.FDitherEnabled := G_Settings.DitherEnabled;
FController.FRandomEnabled := G_Settings.RandomEnabled; FController.FRandomEnabled := G_Settings.RandomEnabled;
FController.FSendAudioToRadio := G_Settings.SendAudioToRadio; FController.FSendAudioToRadio := G_Settings.SendAudioToRadio;
FWfManualHigh := G_Settings.WfManualHigh; FController.FWfManualHigh := G_Settings.WfManualHigh;
FWfManualLow := G_Settings.WfManualLow; FController.FWfManualLow := G_Settings.WfManualLow;
FWfAGCOffset := G_Settings.WfAGCOffset; FController.FWfAGCOffset := G_Settings.WfAGCOffset;
FSpecView.WfAGCEnabled := FController.FWfAGCEnabled; FSpecView.WfAGCEnabled := FController.FWfAGCEnabled;
FSpecView.WfNFEnabled := FController.FWfNFEnabled; FSpecView.WfNFEnabled := FController.FWfNFEnabled;
FSpecView.WfManualHigh := FWfManualHigh; FSpecView.WfManualHigh := FController.FWfManualHigh;
FSpecView.WfManualLow := FWfManualLow; FSpecView.WfManualLow := FController.FWfManualLow;
FSpecView.WfAGCOffset := FWfAGCOffset; FSpecView.WfAGCOffset := FController.FWfAGCOffset;
FSpecView.ResetWfAvgBuf; FSpecView.ResetWfAvgBuf;
FShowSpectrum := G_Settings.ShowSpectrum; FController.FShowSpectrum := G_Settings.ShowSpectrum;
FShowWaterfall := G_Settings.ShowWaterfall; FController.FShowWaterfall := G_Settings.ShowWaterfall;
FShowWideband := G_Settings.ShowWideband; FController.FShowWideband := G_Settings.ShowWideband;
FWidebandFill := G_Settings.WidebandFill; FController.FWidebandFill := G_Settings.WidebandFill;
if Assigned(FWidebandView) then if Assigned(FWidebandView) then
FWidebandView.SetFillSpectrum(FWidebandFill); FWidebandView.SetFillSpectrum(FController.FWidebandFill);
FSpectrumFill := G_Settings.SpectrumFill; FController.FSpectrumFill := G_Settings.SpectrumFill;
FSpecView.FillSpectrum := FSpectrumFill; FSpecView.FillSpectrum := FController.FSpectrumFill;
FController.FDisplayDuplex := G_Settings.DisplayDuplex; FController.FDisplayDuplex := G_Settings.DisplayDuplex;
if BtnDUP <> nil then StyleButton(BtnDUP, FController.FDisplayDuplex); if BtnDUP <> nil then StyleButton(BtnDUP, FController.FDisplayDuplex);
if G_Settings.DisplayFPS > 0 then if G_Settings.DisplayFPS > 0 then
@@ -3864,12 +3849,12 @@ begin
// Настройки дисплея и сетки // Настройки дисплея и сетки
if G_Settings.FFTSize > 0 then if G_Settings.FFTSize > 0 then
begin begin
FSpecRefLevel := G_Settings.SpecRefLevel; FController.FSpecRefLevel := G_Settings.SpecRefLevel;
FSpecRange := G_Settings.SpecRange; FController.FSpecRange := G_Settings.SpecRange;
if G_Settings.SpecGridStep > 0 then FSpecGridStep := G_Settings.SpecGridStep; if G_Settings.SpecGridStep > 0 then FController.FSpecGridStep := G_Settings.SpecGridStep;
FSpecView.SpecRefLevel := FSpecRefLevel; FSpecView.SpecRefLevel := FController.FSpecRefLevel;
FSpecView.SpecRange := FSpecRange; FSpecView.SpecRange := FController.FSpecRange;
FSpecView.SpecGridStep := FSpecGridStep; FSpecView.SpecGridStep := FController.FSpecGridStep;
InvalidateGridCache; InvalidateGridCache;
if FController.FWDSPReady then if FController.FWDSPReady then
begin begin
@@ -3938,7 +3923,7 @@ begin
GenPkt.PAConfig := $01; GenPkt.PAConfig := $01;
GenPkt.WBPort[0] := (PORT_WIDEBAND_ADC0 shr 8) and $FF; GenPkt.WBPort[0] := (PORT_WIDEBAND_ADC0 shr 8) and $FF;
GenPkt.WBPort[1] := PORT_WIDEBAND_ADC0 and $FF; GenPkt.WBPort[1] := PORT_WIDEBAND_ADC0 and $FF;
GenPkt.WBEnable := IfThen(FShowWideband, 1, 0); GenPkt.WBEnable := IfThen(FController.FShowWideband, 1, 0);
GenPkt.WBSamplesPerPkt[0] := 512 shr 8; GenPkt.WBSamplesPerPkt[0] := 512 shr 8;
GenPkt.WBSamplesPerPkt[1] := 512 and $FF; GenPkt.WBSamplesPerPkt[1] := 512 and $FF;
GenPkt.WBSampleSize := 16; GenPkt.WBSampleSize := 16;
@@ -3949,7 +3934,7 @@ begin
else else
GenPkt.AlexEnable := $01; GenPkt.AlexEnable := $01;
FController.FNetwork.SendGeneralPacket(GenPkt); FController.FNetwork.SendGeneralPacket(GenPkt);
FController.FNetwork.ConfigureWideband(0, FShowWideband, 512, 16, 70, 32); FController.FNetwork.ConfigureWideband(0, FController.FShowWideband, 512, 16, 70, 32);
if FController.FNetwork.Device.BoardType in [3, 4, 5] then if FController.FNetwork.Device.BoardType in [3, 4, 5] then
FController.FActiveDDC := 2 FController.FActiveDDC := 2
@@ -5798,16 +5783,16 @@ begin
OldAtt := FController.FTXSettings.AttOnTX; OldAtt := FController.FTXSettings.AttOnTX;
OldTUNLevel := FController.FTXSettings.TUNLevel; OldTUNLevel := FController.FTXSettings.TUNLevel;
OldTUNFreq := FController.FTXSettings.TUNFreq; OldTUNFreq := FController.FTXSettings.TUNFreq;
GridChanged := (FTXSpecRefLevel <> T.TXSpecRefLevel) GridChanged := (FController.FTXSpecRefLevel <> T.TXSpecRefLevel)
or (FTXSpecRange <> T.TXSpecRange) or (FController.FTXSpecRange <> T.TXSpecRange)
or (FTXSpecGridStep <> T.TXSpecGridStep); or (FController.FTXSpecGridStep <> T.TXSpecGridStep);
FController.FTXSettings := T; FController.FTXSettings := T;
NewMicByte := BuildMicLineSelectByte; NewMicByte := BuildMicLineSelectByte;
// TX-grid в момент правки — обновляем рабочие поля и (если на передаче) пушим в FSpecView // TX-grid в момент правки — обновляем рабочие поля и (если на передаче) пушим в FSpecView
FTXSpecRefLevel := FController.FTXSettings.TXSpecRefLevel; FController.FTXSpecRefLevel := FController.FTXSettings.TXSpecRefLevel;
FTXSpecRange := FController.FTXSettings.TXSpecRange; FController.FTXSpecRange := FController.FTXSettings.TXSpecRange;
if FController.FTXSettings.TXSpecGridStep > 0 then if FController.FTXSettings.TXSpecGridStep > 0 then
FTXSpecGridStep := FController.FTXSettings.TXSpecGridStep; FController.FTXSpecGridStep := FController.FTXSettings.TXSpecGridStep;
if GridChanged and FController.FTransmitting then if GridChanged and FController.FTransmitting then
ApplySpecViewGridFromState; ApplySpecViewGridFromState;
ApplyTXSettingsToDSP; ApplyTXSettingsToDSP;
@@ -6227,21 +6212,21 @@ procedure TMainForm.ApplyWaterfallParams(WfDet, WfAvgMode: Integer;
begin begin
if FController.FWDSPReady then if FController.FWDSPReady then
FController.FDSPEngine.SetWaterfallDisplay(WfDet, WfAvgMode, WfAvgTimeMS); FController.FDSPEngine.SetWaterfallDisplay(WfDet, WfAvgMode, WfAvgTimeMS);
FWfManualHigh := WfHigh; FController.FWfManualHigh := WfHigh;
FWfManualLow := WfLow; FController.FWfManualLow := WfLow;
FWfAGCOffset := WfAGCOffset; FController.FWfAGCOffset := WfAGCOffset;
FSpecView.WfManualHigh := FWfManualHigh; FSpecView.WfManualHigh := FController.FWfManualHigh;
FSpecView.WfManualLow := FWfManualLow; FSpecView.WfManualLow := FController.FWfManualLow;
FSpecView.WfAGCOffset := FWfAGCOffset; FSpecView.WfAGCOffset := FController.FWfAGCOffset;
FSpecView.ResetWfAvgBuf; FSpecView.ResetWfAvgBuf;
FSpectrumDirty := True; FSpectrumDirty := True;
end; end;
procedure TMainForm.ApplyGridParams(RefLevel, Range, GridStep: Double); procedure TMainForm.ApplyGridParams(RefLevel, Range, GridStep: Double);
begin begin
FSpecRefLevel := RefLevel; FController.FSpecRefLevel := RefLevel;
FSpecRange := Range; FController.FSpecRange := Range;
if GridStep > 0 then FSpecGridStep := GridStep; if GridStep > 0 then FController.FSpecGridStep := GridStep;
// На передаче FSpecView показывает TX-сетку — RX-правка не должна её перетирать. // На передаче FSpecView показывает TX-сетку — RX-правка не должна её перетирать.
if not FController.FTransmitting then ApplySpecViewGridFromState; if not FController.FTransmitting then ApplySpecViewGridFromState;
end; end;
@@ -6251,14 +6236,14 @@ begin
// При DUP во время TX данные приходят от RX-анализатора → используем RX-сетку. // При DUP во время TX данные приходят от RX-анализатора → используем RX-сетку.
if FController.FTransmitting and not FController.FDisplayDuplex then if FController.FTransmitting and not FController.FDisplayDuplex then
begin begin
FSpecView.SpecRefLevel := FTXSpecRefLevel; FSpecView.SpecRefLevel := FController.FTXSpecRefLevel;
FSpecView.SpecRange := FTXSpecRange; FSpecView.SpecRange := FController.FTXSpecRange;
FSpecView.SpecGridStep := FTXSpecGridStep; FSpecView.SpecGridStep := FController.FTXSpecGridStep;
end else end else
begin begin
FSpecView.SpecRefLevel := FSpecRefLevel; FSpecView.SpecRefLevel := FController.FSpecRefLevel;
FSpecView.SpecRange := FSpecRange; FSpecView.SpecRange := FController.FSpecRange;
FSpecView.SpecGridStep := FSpecGridStep; FSpecView.SpecGridStep := FController.FSpecGridStep;
end; end;
InvalidateGridCache; InvalidateGridCache;
FSpectrumDirty := True; FSpectrumDirty := True;
@@ -6327,16 +6312,16 @@ end;
procedure TMainForm.ApplyVisibility(ShowSpectrum, ShowWaterfall, procedure TMainForm.ApplyVisibility(ShowSpectrum, ShowWaterfall,
ShowWideband, WidebandFill, SpectrumFill: Boolean); ShowWideband, WidebandFill, SpectrumFill: Boolean);
begin begin
FShowSpectrum := ShowSpectrum; FController.FShowSpectrum := ShowSpectrum;
FShowWaterfall := ShowWaterfall; FController.FShowWaterfall := ShowWaterfall;
FShowWideband := ShowWideband; FController.FShowWideband := ShowWideband;
FWidebandFill := WidebandFill; FController.FWidebandFill := WidebandFill;
FSpectrumFill := SpectrumFill; FController.FSpectrumFill := SpectrumFill;
if Assigned(FWidebandView) then if Assigned(FWidebandView) then
FWidebandView.SetFillSpectrum(FWidebandFill); FWidebandView.SetFillSpectrum(FController.FWidebandFill);
FSpecView.FillSpectrum := FSpectrumFill; FSpecView.FillSpectrum := FController.FSpectrumFill;
if Assigned(FController.FNetwork) and FController.FNetwork.Connected then if Assigned(FController.FNetwork) and FController.FNetwork.Connected then
FController.FNetwork.ConfigureWideband(0, FShowWideband, 512, 16, 70, 32); FController.FNetwork.ConfigureWideband(0, FController.FShowWideband, 512, 16, 70, 32);
ResizeSpectrumPanels; ResizeSpectrumPanels;
end; end;
@@ -6422,8 +6407,8 @@ begin
FCATLastGlobal.CATTcpPort); FCATLastGlobal.CATTcpPort);
// Перечисляем PA устройства // Перечисляем PA устройства
SF.RefreshAudioDevices(FController.FAudioOut, FController.FAudioIn); SF.RefreshAudioDevices(FController.FAudioOut, FController.FAudioIn);
SF.LoadVisibility(FShowSpectrum, FShowWaterfall, FShowWideband, FWidebandFill, SF.LoadVisibility(FController.FShowSpectrum, FController.FShowWaterfall, FController.FShowWideband, FController.FWidebandFill,
FSpectrumFill); FController.FSpectrumFill);
SF.LoadWfAGCNF(FController.FWfAGCEnabled, FController.FWfNFEnabled); SF.LoadWfAGCNF(FController.FWfAGCEnabled, FController.FWfNFEnabled);
SF.LoadADCSettings(FController.FDitherEnabled, FController.FRandomEnabled); SF.LoadADCSettings(FController.FDitherEnabled, FController.FRandomEnabled);
SF.LoadWebSettings(FWebEnabled, FWebPort, FWebBindAddr, FWebUser, FWebPass); SF.LoadWebSettings(FWebEnabled, FWebPort, FWebBindAddr, FWebUser, FWebPass);
@@ -6443,16 +6428,16 @@ begin
FController.FDSPEngine.WfDetector, FController.FDSPEngine.WfDetector,
FController.FDSPEngine.WfAvgMode, FController.FDSPEngine.WfAvgMode,
FController.FDSPEngine.WfAvgTimeMS, FController.FDSPEngine.WfAvgTimeMS,
FWfManualHigh, FController.FWfManualHigh,
FWfManualLow, FController.FWfManualLow,
FWfAGCOffset, FController.FWfAGCOffset,
FSpecRefLevel, FSpecRange, FSpecGridStep, FController.FSpecRefLevel, FController.FSpecRange, FController.FSpecGridStep,
FController.FAudioOutDevName, FController.FAudioInDevName) FController.FAudioOutDevName, FController.FAudioInDevName)
else else
SF.LoadValues( SF.LoadValues(
131072, 2, 0, 3, 30.0, 131072, 2, 0, 3, 30.0,
0, 3, 120.0, FWfManualHigh, FWfManualLow, FWfAGCOffset, 0, 3, 120.0, FController.FWfManualHigh, FController.FWfManualLow, FController.FWfAGCOffset,
FSpecRefLevel, FSpecRange, FSpecGridStep, FController.FSpecRefLevel, FController.FSpecRange, FController.FSpecGridStep,
FController.FAudioOutDevName, FController.FAudioInDevName); FController.FAudioOutDevName, FController.FAudioInDevName);
SF.Show; SF.Show;
end; end;
+16
View File
@@ -175,6 +175,22 @@ type
FDitherEnabled: Boolean; FDitherEnabled: Boolean;
FRandomEnabled: Boolean; FRandomEnabled: Boolean;
// ---- Display state (persist в TGlobalSettings; рендерится FSpecView/Wideband) ----
FShowSpectrum: Boolean;
FShowWaterfall: Boolean;
FShowWideband: Boolean;
FWidebandFill: Boolean;
FSpectrumFill: Boolean;
FWfManualHigh: Double;
FWfManualLow: Double;
FWfAGCOffset: Double;
FSpecRefLevel: Double;
FSpecRange: Double;
FSpecGridStep: Double;
FTXSpecRefLevel: Double; // TX-сетка (Thetis-style): применяется при FTransmitting
FTXSpecRange: Double;
FTXSpecGridStep: Double;
// ---- FM ---- // ---- FM ----
FFMDeviation: Double; FFMDeviation: Double;
FFMCTCSSOn: Boolean; FFMCTCSSOn: Boolean;