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