From 22e01a6e3f50562f2a8e570dac2078a63a5e7248 Mon Sep 17 00:00:00 2001 From: Uladzimir Karpenka Date: Sat, 9 May 2026 16:15:34 +0300 Subject: [PATCH] fix web TX spectrum position in CTUN mode Add 'dup' field to state JSON (FDisplayDuplex). In CTUN+non-DUP TX, use vfo_a_hz as spectrum center so the TX signal renders at the VFO position instead of the display center. In CTUN+DUP TX, keep center_hz so the RX spectrum stays correctly positioned at the filter. Co-Authored-By: Claude Sonnet 4.6 --- MainForm.pas | 2 +- WebPageHtml.pas | 4 +++- WebServer.pas | 11 +++++++---- 3 files changed, 11 insertions(+), 6 deletions(-) diff --git a/MainForm.pas b/MainForm.pas index 48d0c5f..57eb75e 100644 --- a/MainForm.pas +++ b/MainForm.pas @@ -2776,7 +2776,7 @@ begin FCenterFreq, FFilter, FVfoB, FActiveVfo, FTransmitting, TrkDrive.Position, - FAtten, FTuning); + FAtten, FTuning, FDisplayDuplex); end; // =========================================================================== diff --git a/WebPageHtml.pas b/WebPageHtml.pas index 1b245f8..6eaaecb 100644 --- a/WebPageHtml.pas +++ b/WebPageHtml.pas @@ -410,7 +410,9 @@ begin 'Object.keys(msg).forEach(function(k){var pk=PEND_MAP[k];if(!pk||!isPending(pk))cur[k]=msg[k];});' + // Обновляем localCenter/localSpan из сервера только когда пользователь не тянет 'if(!dragging&&Date.now()-wheelActiveTs>300){' + - 'if(msg.center_hz!=null)localCenter=msg.center_hz;' + + // В CTUN без DUP: TX-спектр WDSP центрирован по vfo_a_hz, а не по DDC LO. + // В CTUN с DUP: показываем RX-спектр → center_hz остаётся. + 'if(msg.center_hz!=null)localCenter=(cur.transmitting&&cur.ctun&&!cur.dup)?cur.vfo_a_hz:msg.center_hz;' + 'if(msg.span_hz!=null)localSpan=msg.span_hz||192000;' + '}' + 'if(!isPending("freq")){vfoA=cur.vfo_a_hz||vfoA;}' + diff --git a/WebServer.pas b/WebServer.pas index da60032..782ecef 100644 --- a/WebServer.pas +++ b/WebServer.pas @@ -218,6 +218,7 @@ type FAttnIdx: Integer; FOnTun: TWebCmdTun; FTuning: Boolean; + FDuplex: Boolean; FWebClientActive: Boolean; @@ -262,7 +263,7 @@ type CenterHz: Double; FilterIdx: Integer; VfoB: Double; ActiveVfo: Integer; Transmitting: Boolean; DriveLevel: Integer; - AttnIdx: Integer; Tuning: Boolean); + AttnIdx: Integer; Tuning: Boolean; Duplex: Boolean); property WebClientActive: Boolean read FWebClientActive; @@ -1133,7 +1134,7 @@ begin '"wf_agc":%s,"wf_nf":%s,"band_idx":%d,"smeter_dbm":%.1f,' + '"running":%s,"mute":%s,"ctun":%s,' + '"nr_mode":%d,"nr":%s,"nb_mode":%d,"nb":%s,"snb":%s,"anf":%s,"connected":%s,' + - '"transmitting":%s,"drive":%d,"attn_idx":%d,"tuning":%s}', + '"transmitting":%s,"drive":%d,"attn_idx":%d,"tuning":%s,"dup":%s}', [FFreq, FVfoB, FActiveVfo, FMode, MODE_N[FMode mod 8], FFilterIdx, FFilterBW, @@ -1155,7 +1156,8 @@ begin BoolToStr(FTransmitting, 'true', 'false'), FDriveLevel, FAttnIdx, - BoolToStr(FTuning, 'true', 'false') + BoolToStr(FTuning, 'true', 'false'), + BoolToStr(FDuplex, 'true', 'false') ]); finally FStateLock.Leave; @@ -1222,7 +1224,7 @@ procedure TWebServer.PushSpectrum( CenterHz: Double; FilterIdx: Integer; VfoB: Double; ActiveVfo: Integer; Transmitting: Boolean; DriveLevel: Integer; - AttnIdx: Integer; Tuning: Boolean); + AttnIdx: Integer; Tuning: Boolean; Duplex: Boolean); var N, i: Integer; begin if not FRunning then Exit; @@ -1258,6 +1260,7 @@ begin FDriveLevel := DriveLevel; FAttnIdx := AttnIdx; FTuning := Tuning; + FDuplex := Duplex; finally FStateLock.Leave; end;