From 492b29bea1b81329bc6b683160b92f90cb7ee00b Mon Sep 17 00:00:00 2001 From: Uladzimir Karpenka Date: Fri, 5 Jun 2026 16:40:01 +0300 Subject: [PATCH] Phase 3 (batch 19): move TUN (tune tone) into the controller SetTune now carries the TUN engine logic: the DoNotTx/RXOnly safety gates, enabling the WDSP PostGen tone before TX, the TUN-level drive (CalcDriveByte sees FTuning), driving TX on/off via SetMOX, and the network re-push on exit. MainForm.ApplyTUN becomes a thin wrapper (mirrors FWebClientActive, calls SetTune); the BtnTUN style render moves to OnControllerState(rfTuning). BtnMOXClick still exits tune via ApplyTUN(False). Co-Authored-By: Claude Opus 4.8 --- MainForm.pas | 46 ++++++--------------------------------------- RadioController.pas | 38 ++++++++++++++++++++++++++++++++++++- 2 files changed, 43 insertions(+), 41 deletions(-) diff --git a/MainForm.pas b/MainForm.pas index fb06d91..f5f34f4 100644 --- a/MainForm.pas +++ b/MainForm.pas @@ -1347,6 +1347,8 @@ begin ApplySpecViewGridFromState; // сетка спектра под активный тракт FDUCPendingCount := 0; end; + rfTuning: + StyleButton(BtnTUN, FController.FTuning); rfBand: // В XVTR-режиме HF-кнопки гасим (активна XVTR-кнопка, см. rfXvtr). for i := 0 to BAND_COUNT - 1 do @@ -4588,46 +4590,10 @@ end; // --------------------------------------------------------------------------- procedure TMainForm.ApplyTUN(Active: Boolean); begin - if Active = FController.FTuning then Exit; - // Safety: те же блокировки что в ApplyMOX. TUN — это TX через WDSP PostGen, - // он тоже должен молчать на бэндах с DoNotTx или на RX-only XVTR. - if Active and FController.FDevConnected and (FController.FCurrentXvtr < 0) - and FController.FAlexSettings.DoNotTx[EnsureRange(FController.FCurrentBand, 0, 10)] then - Exit; - if Active and (FController.FCurrentXvtr >= 0) and (FController.FCurrentXvtr < CFG_XVTR_COUNT) - and FController.FXvtrSettings.Entries[FController.FCurrentXvtr].RXOnly then - Exit; - if Active then - begin - // Включаем тон ДО запуска TX-аудио, чтобы первые сэмплы уже шли с тоном - if FController.FWDSPReady then - FController.FDSPEngine.SetTXTone(True, FController.FTXSettings.TUNFreq, 1.0); - FController.FTuning := True; - StyleButton(BtnTUN, True); - // Drive байт пересчитываем (CalcDriveByte увидит FController.FTuning=True) - FController.FDriveLevel := CalcDriveByte; - if FController.FWDSPReady then - FController.FDSPEngine.SetDriveLevel(FController.FTXSettings.TUNLevel / 100.0); - // Активируем TX (то же что MOX — PTT, run TXA-канал) - if not FController.FTransmitting then ApplyMOX(True); - end else - begin - // Выключаем TX, потом тон, потом восстанавливаем drive - if FController.FTransmitting then ApplyMOX(False); - if FController.FWDSPReady then - FController.FDSPEngine.SetTXTone(False, 0, 0); - FController.FTuning := False; - StyleButton(BtnTUN, False); - FController.FDriveLevel := CalcDriveByte; - if FController.FWDSPReady then - FController.FDSPEngine.SetDriveLevel(FController.FDrivePercent / 100.0); - if FController.FNetwork.Connected and FController.FNetwork.Running then - begin - FController.FNetwork.UpdateState(XvtrTranslate(FController.FCenterFreq), XvtrTranslate(ActiveTXFreqHz), FController.FDriveLevel, - FController.FTransmitting, True, True); - FController.FNetwork.SendFullHP; - end; - end; + // Web-слой пока не владеет своим флагом — зеркалим состояние клиента в + // контроллер перед командой (SetTune зовёт SetMOX, который читает его). + FController.FWebClientActive := Assigned(FWebServer) and FWebServer.WebClientActive; + FController.SetTune(Active); // ядро TUN (safety/тон/drive/MOX) + рендер через rfTuning end; procedure TMainForm.BtnTUNClick(Sender: TObject); diff --git a/RadioController.pas b/RadioController.pas index 6c51e2a..c35c081 100644 --- a/RadioController.pas +++ b/RadioController.pas @@ -1341,7 +1341,43 @@ begin end; procedure TRadioController.SetTune(On_: Boolean); -begin FTuning := On_; Changed(rfTuning); { TODO wiring: ApplyTUN } end; +begin + if On_ = FTuning then Exit; + // Safety: те же блокировки, что и в SetMOX — TUN это TX через WDSP PostGen-тон, + // он тоже должен молчать на бэндах с DoNotTx и на RX-only XVTR. + if On_ and FDevConnected and (FCurrentXvtr < 0) + and FAlexSettings.DoNotTx[EnsureRange(FCurrentBand, 0, 10)] then Exit; + if On_ and (FCurrentXvtr >= 0) and (FCurrentXvtr < CFG_XVTR_COUNT) + and FXvtrSettings.Entries[FCurrentXvtr].RXOnly then Exit; + if On_ then + begin + // Тон включаем ДО запуска TX-аудио, чтобы первые сэмплы уже шли с тоном. + if FWDSPReady and Assigned(FDSPEngine) then + FDSPEngine.SetTXTone(True, FTXSettings.TUNFreq, 1.0); + FTuning := True; + FDriveLevel := CalcDriveByte; // CalcDriveByte увидит FTuning=True (TUN-уровень) + if FWDSPReady and Assigned(FDSPEngine) then + FDSPEngine.SetDriveLevel(FTXSettings.TUNLevel / 100.0); + if not FTransmitting then SetMOX(True); // PTT + run TXA-канал + end + else + begin + if FTransmitting then SetMOX(False); + if FWDSPReady and Assigned(FDSPEngine) then + FDSPEngine.SetTXTone(False, 0, 0); + FTuning := False; + FDriveLevel := CalcDriveByte; // вернуть обычный drive% + if FWDSPReady and Assigned(FDSPEngine) then + FDSPEngine.SetDriveLevel(FDrivePercent / 100.0); + if Assigned(FNetwork) and FNetwork.Connected and FNetwork.Running then + begin + FNetwork.UpdateState(XvtrTranslate(FCenterFreq), XvtrTranslate(ActiveTXFreqHz), + FDriveLevel, FTransmitting, True, True); + FNetwork.SendFullHP; + end; + end; + Changed(rfTuning); +end; procedure TRadioController.SetFMStep(Idx: Integer); begin