From 4f281ce40014c03110c8e63103861b625ba96544 Mon Sep 17 00:00:00 2001 From: Uladzimir Karpenka Date: Wed, 27 May 2026 15:52:54 +0300 Subject: [PATCH] Channel memory: apply and restore TX power, fix auto-clear after band switch - ApplyChannel now sets TrkDrive from Ch.Power; saves pre-channel level in FPreChannelPower (works around TrkDriveChange clearing the field on assignment) - Power is restored when tuning away from channel (CheckChannelActive) or on first VFO movement after returning to band with no active channel (ApplyVfoA) - Manual drive slider move clears FPreChannelPower so restore is skipped Co-Authored-By: Claude Sonnet 4.6 --- MainForm.pas | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/MainForm.pas b/MainForm.pas index cd955b4..27a0231 100644 --- a/MainForm.pas +++ b/MainForm.pas @@ -260,6 +260,7 @@ type FFMRptOffsetHz: Double; FFMRptAutoActive: Boolean; // True = RPT включён автоматически (авто или из канала) FFMCTCSSAutoActive: Boolean; // True = CTCSS включён из канала (не вручную) + FPreChannelPower: Integer; // мощность до применения канала (-1 = не сохранена) FWfManualHigh: Double; FWfManualLow: Double; FWfAGCOffset: Double; @@ -1159,6 +1160,7 @@ begin FFMRptOffsetHz := RPT_DEFAULT_2M; FFMRptAutoActive := False; FFMCTCSSAutoActive := False; + FPreChannelPower := -1; FSpectrumBufCount := 1024; FWaterfallBufCount := 1024; FWaterfallFrameInterval := 2; @@ -4652,6 +4654,14 @@ begin if BtnFMRptMinus <> nil then StyleButton(BtnFMRptMinus, False); if BtnFMRptPlus <> nil then StyleButton(BtnFMRptPlus, False); end; + if FPreChannelPower >= 0 then + begin + TrkDrive.Position := FPreChannelPower; + FPreChannelPower := -1; + FDriveLevel := CalcDriveByte; + if FWDSPReady then + FDSPEngine.SetDriveLevel(TrkDrive.Position / 100.0); + end; end; // Auto-enable repeater minus for 2 m repeater input segment @@ -5544,6 +5554,17 @@ begin if EdFMRptOffset <> nil then EdFMRptOffset.Text := RptFormatOffset(FFMRptOffsetHz); end; + // Мощность из канала. + // TrkDrive.Position := ... синхронно вызывает TrkDriveChange → FPreChannelPower := -1, + // поэтому сохраняем оригинал в локальную переменную и восстанавливаем после. + if Ch.Power >= 0 then + begin + i := TrkDrive.Position; // запомнить до срабатывания OnChange + TrkDrive.Position := EnsureRange(Ch.Power, 0, 100); // TrkDriveChange обновит FDriveLevel и WDSP + if FPreChannelPower < 0 then + FPreChannelPower := i; // установить после (TrkDriveChange уже сбросил в -1) + end; + // Частота VFO A ApplyVfoA(Round(Ch.RXFreq)); @@ -5595,6 +5616,16 @@ begin if BtnFMRptPlus <> nil then StyleButton(BtnFMRptPlus, False); UpdateRptAutoState; end; + + // Восстанавливаем мощность которая была до применения канала + if FPreChannelPower >= 0 then + begin + TrkDrive.Position := FPreChannelPower; + FPreChannelPower := -1; + FDriveLevel := CalcDriveByte; + if FWDSPReady then + FDSPEngine.SetDriveLevel(TrkDrive.Position / 100.0); + end; end; end; @@ -6687,6 +6718,7 @@ end; procedure TMainForm.TrkDriveChange(Sender: TObject); begin + FPreChannelPower := -1; // ручное изменение снимает сохранённую мощность канала FDriveLevel := CalcDriveByte; if FWDSPReady then FDSPEngine.SetDriveLevel(TrkDrive.Position / 100.0);