From af85ddece6971380f7bd6452740c1b194764a845 Mon Sep 17 00:00:00 2001 From: Uladzimir Karpenka Date: Thu, 4 Jun 2026 20:40:40 +0300 Subject: [PATCH] Fix TX following active RX VFO instead of the TX selector The TX VFO is chosen independently of the RX VFO via the TX-A/TX-B buttons (FSplitTxB: False=A, True=B); UI highlights TX-A when not split. But the TX frequency and TX overlay used FActiveVfo in the non-split branch, coupling TX to the active RX VFO. Result: with RX on B and TX-A selected, the radio still transmitted on B (TX overlay also drew on B). Make the TX VFO depend solely on FSplitTxB in all three spots: ActiveTXFreqHz and both TXVfoIndex assignments (live update + ApplyMOX). Now RX=B / TX=A works as the UI indicates. Pre-existing bug, not a refactor regression. Builds clean, links. Co-Authored-By: Claude Opus 4.8 --- MainForm.pas | 8 +++++--- RadioController.pas | 6 ++++-- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/MainForm.pas b/MainForm.pas index 5d8f0c9..a844dc2 100644 --- a/MainForm.pas +++ b/MainForm.pas @@ -3017,9 +3017,10 @@ begin // TX overlay следует за активной TX-частотой (учитывает split). При CTUN // спектр TX будет отрисован на VFO, а не в центре дисплея. FSpecView.TXFreq := ActiveTXFreqHz; - // Какой VFO привязан к TX (для split-полос фильтра): 1=B при FController.FSplitTxB, иначе FController.FActiveVfo. + // Какой VFO привязан к TX (для split-полос фильтра): задаётся селектором + // FSplitTxB (TX-A/TX-B), независимо от активного RX-VFO. if FController.FSplitTxB then FSpecView.TXVfoIndex := 1 - else FSpecView.TXVfoIndex := FController.FActiveVfo; + else FSpecView.TXVfoIndex := 0; if UpdateWidebandFrequencyView and FShowWideband and (PbWideband <> nil) then PbWideband.Invalidate; end; @@ -5559,8 +5560,9 @@ begin StyleButton(BtnMOX, False); // TX-overlay в SpectrumView: фиксируем актуальную TX-частоту/VFO-индекс и режим FSpecView.TXFreq := ActiveTXFreqHz; + // TX-VFO задаётся селектором FSplitTxB, независимо от активного RX-VFO. if FController.FSplitTxB then FSpecView.TXVfoIndex := 1 - else FSpecView.TXVfoIndex := FController.FActiveVfo; + else FSpecView.TXVfoIndex := 0; // DUP: данные остаются от RX-анализатора (TXMode=False), но TX-полоса // фильтра рисуется поверх через TXOverlay. Без DUP при TX оба флага True. FSpecView.TXMode := FController.FTransmitting and not FController.FDisplayDuplex; diff --git a/RadioController.pas b/RadioController.pas index 0474698..81bbda7 100644 --- a/RadioController.pas +++ b/RadioController.pas @@ -392,9 +392,11 @@ end; function TRadioController.ActiveTXFreqHz: Double; begin + // TX-VFO задаётся ТОЛЬКО селектором FSplitTxB (UI: кнопки TX-A/TX-B), + // независимо от активного RX-VFO. Раньше при не-split TX ошибочно следовал + // за активным RX (TX-A горит, но передача шла на B при активном B). if FSplitTxB then Result := FVfoB - else if FActiveVfo = 0 then Result := FVfoA - else Result := FVfoB; + else Result := FVfoA; if FMode = MODE_FM then case FFMRptDir of RPT_MINUS: Result := Result - FFMRptOffsetHz;