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 <noreply@anthropic.com>
This commit is contained in:
2026-05-09 16:15:34 +03:00
co-authored by Claude Sonnet 4.6
parent 9ae77ddeb4
commit 22e01a6e3f
3 changed files with 11 additions and 6 deletions
+1 -1
View File
@@ -2776,7 +2776,7 @@ begin
FCenterFreq, FFilter, FCenterFreq, FFilter,
FVfoB, FActiveVfo, FVfoB, FActiveVfo,
FTransmitting, TrkDrive.Position, FTransmitting, TrkDrive.Position,
FAtten, FTuning); FAtten, FTuning, FDisplayDuplex);
end; end;
// =========================================================================== // ===========================================================================
+3 -1
View File
@@ -410,7 +410,9 @@ begin
'Object.keys(msg).forEach(function(k){var pk=PEND_MAP[k];if(!pk||!isPending(pk))cur[k]=msg[k];});' + 'Object.keys(msg).forEach(function(k){var pk=PEND_MAP[k];if(!pk||!isPending(pk))cur[k]=msg[k];});' +
// Обновляем localCenter/localSpan из сервера только когда пользователь не тянет // Обновляем localCenter/localSpan из сервера только когда пользователь не тянет
'if(!dragging&&Date.now()-wheelActiveTs>300){' + '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(msg.span_hz!=null)localSpan=msg.span_hz||192000;' +
'}' + '}' +
'if(!isPending("freq")){vfoA=cur.vfo_a_hz||vfoA;}' + 'if(!isPending("freq")){vfoA=cur.vfo_a_hz||vfoA;}' +
+7 -4
View File
@@ -218,6 +218,7 @@ type
FAttnIdx: Integer; FAttnIdx: Integer;
FOnTun: TWebCmdTun; FOnTun: TWebCmdTun;
FTuning: Boolean; FTuning: Boolean;
FDuplex: Boolean;
FWebClientActive: Boolean; FWebClientActive: Boolean;
@@ -262,7 +263,7 @@ type
CenterHz: Double; FilterIdx: Integer; CenterHz: Double; FilterIdx: Integer;
VfoB: Double; ActiveVfo: Integer; VfoB: Double; ActiveVfo: Integer;
Transmitting: Boolean; DriveLevel: Integer; Transmitting: Boolean; DriveLevel: Integer;
AttnIdx: Integer; Tuning: Boolean); AttnIdx: Integer; Tuning: Boolean; Duplex: Boolean);
property WebClientActive: Boolean read FWebClientActive; property WebClientActive: Boolean read FWebClientActive;
@@ -1133,7 +1134,7 @@ begin
'"wf_agc":%s,"wf_nf":%s,"band_idx":%d,"smeter_dbm":%.1f,' + '"wf_agc":%s,"wf_nf":%s,"band_idx":%d,"smeter_dbm":%.1f,' +
'"running":%s,"mute":%s,"ctun":%s,' + '"running":%s,"mute":%s,"ctun":%s,' +
'"nr_mode":%d,"nr":%s,"nb_mode":%d,"nb":%s,"snb":%s,"anf":%s,"connected":%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, [FFreq, FVfoB, FActiveVfo,
FMode, MODE_N[FMode mod 8], FMode, MODE_N[FMode mod 8],
FFilterIdx, FFilterBW, FFilterIdx, FFilterBW,
@@ -1155,7 +1156,8 @@ begin
BoolToStr(FTransmitting, 'true', 'false'), BoolToStr(FTransmitting, 'true', 'false'),
FDriveLevel, FDriveLevel,
FAttnIdx, FAttnIdx,
BoolToStr(FTuning, 'true', 'false') BoolToStr(FTuning, 'true', 'false'),
BoolToStr(FDuplex, 'true', 'false')
]); ]);
finally finally
FStateLock.Leave; FStateLock.Leave;
@@ -1222,7 +1224,7 @@ procedure TWebServer.PushSpectrum(
CenterHz: Double; FilterIdx: Integer; CenterHz: Double; FilterIdx: Integer;
VfoB: Double; ActiveVfo: Integer; VfoB: Double; ActiveVfo: Integer;
Transmitting: Boolean; DriveLevel: Integer; Transmitting: Boolean; DriveLevel: Integer;
AttnIdx: Integer; Tuning: Boolean); AttnIdx: Integer; Tuning: Boolean; Duplex: Boolean);
var N, i: Integer; var N, i: Integer;
begin begin
if not FRunning then Exit; if not FRunning then Exit;
@@ -1258,6 +1260,7 @@ begin
FDriveLevel := DriveLevel; FDriveLevel := DriveLevel;
FAttnIdx := AttnIdx; FAttnIdx := AttnIdx;
FTuning := Tuning; FTuning := Tuning;
FDuplex := Duplex;
finally finally
FStateLock.Leave; FStateLock.Leave;
end; end;