From 827902f3e2111925e4fdc1d895acb5e896b00c2d Mon Sep 17 00:00:00 2001 From: Vladimir Date: Mon, 10 Aug 2026 14:33:22 +0300 Subject: [PATCH] =?UTF-8?q?fix(xvtr):=20=D0=BF=D1=80=D0=B0=D0=B2=D0=BA?= =?UTF-8?q?=D0=B8=20=D0=B2=20=D1=82=D1=80=D0=B0=D0=BD=D1=81=D0=B2=D0=B5?= =?UTF-8?q?=D1=80=D1=82=D0=B5=D1=80=D0=B5=20=D0=B1=D0=BE=D0=BB=D1=8C=D1=88?= =?UTF-8?q?=D0=B5=20=D0=BD=D0=B5=20=D1=82=D1=80=D0=B0=D0=B2=D1=8F=D1=82=20?= =?UTF-8?q?=D0=BF=D0=B0=D0=BC=D1=8F=D1=82=D1=8C=20=D0=9A=D0=92-=D0=B4?= =?UTF-8?q?=D0=B8=D0=B0=D0=BF=D0=B0=D0=B7=D0=BE=D0=BD=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit При входе в слот трансвертера FCurrentBand не меняется — он продолжает указывать на тот КВ-диапазон, с которого зашли. Поэтому всё, что помнится по диапазону, из трансвертера писалось в чужую ячейку: модуляция, слот фильтра, режим и порог АРУ, CTUN. Поставил в трансвертере FM — 40 метров запомнили FM. Развилка «мы сейчас в трансвертере?» в проекте уже была, но стояла только у двух писателей из семи — у шагового аттенюатора и у зума. Их правили когда-то по симптому, отчего баг и возвращался: затыкали поле, а не класс. Заведена XvtrSlotActive, через неё идут все оставшиеся писатели. Слот трансвертера соответствующие поля уже имел (LastMode, LastFilterIdx, LastAGCMode, LastAGCTop, LastCTun) — они просто не заполнялись живыми правками, только снимком на выходе из слота. SpanHz в кэше оставлен как есть: поле помечено легаси, при восстановлении диапазона его никто не читает. Уже испорченные записи конфига правка не лечит: чтобы починить диапазон, надо встать на него, выставить нужную модуляцию и уйти — SaveCurrentBand перезапишет ячейку. Co-Authored-By: Claude Opus 5 --- RadioController.pas | 31 ++++++++++++++++++++++++++----- 1 file changed, 26 insertions(+), 5 deletions(-) diff --git a/RadioController.pas b/RadioController.pas index 3a44aca..15cae6d 100644 --- a/RadioController.pas +++ b/RadioController.pas @@ -609,6 +609,12 @@ type procedure SendDUCSpecificFromSettings; // DUC Specific (mic/keyer/atten) в сеть procedure ApplyTXSettingsToDSP; // TX-цепь (фильтр/gain/EQ/comp/...) → WDSP // ---- Телеграф ---------------------------------------------------------- + // Живой контекст «где мы сейчас»: в трансвертере правки запоминаются в его + // слоте, иначе в кэше диапазона. ★Развилка обязана стоять у КАЖДОГО поля, + // которое помнится по диапазону: пока её не было у режима/фильтра/AGC/CTUN, + // трансвертер травил ими тот HF-диапазон, на котором стоял до входа + // (FCurrentBand при входе в слот не меняется). + function XvtrSlotActive: Boolean; function TXProhibited: Boolean; // DoNotTx-бэнд / RX-only XVTR function CWTXActive: Boolean; // передачей владеет FPGA-кейер function CWOptionsByte: Byte; // DUC Specific байт 5 @@ -4068,7 +4074,8 @@ begin begin // Частота за окном — сбрасываем CTUN и центрируемся на ней. FCTun := False; - FBandCache[FCurrentBand].CTun := False; + if XvtrSlotActive then FXvtrSettings.Entries[FCurrentXvtr].LastCTun := False + else FBandCache[FCurrentBand].CTun := False; FCenterFreq := ActiveFreq; if FWDSPReady and Assigned(FDSPEngine) then FDSPEngine.SetShift(0.0); NeedPush := True; @@ -4175,7 +4182,8 @@ begin end; if Assigned(FDMRDec) then FDMRDec.SetEnabled(FMode = MODE_DMR); ApplyModeDefaults; // дефолтный фильтр/девиация под режим - FBandCache[FCurrentBand].Mode := FMode; + if XvtrSlotActive then FXvtrSettings.Entries[FCurrentXvtr].LastMode := FMode + else FBandCache[FCurrentBand].Mode := FMode; // Профиль привязан к паре «флаг + модуляция»: если передаём с главного, // новый режим приносит свой профиль. До пуша в WDSP — ApplyTXChainSettings // внутри SetTXMode ниже перешьёт цепь уже с новыми значениями. @@ -4221,6 +4229,11 @@ end; procedure TRadioController.CacheFilterToBand; begin + if XvtrSlotActive then + begin + FXvtrSettings.Entries[FCurrentXvtr].LastFilterIdx := FFilter; + Exit; + end; FBandCache[FCurrentBand].FilterIdx := FFilter; FBandCache[FCurrentBand].FilterBW := FFilterBW; // легаси-поле, для старых конфигов end; @@ -4356,7 +4369,8 @@ begin if (M < 0) or (M > 4) then Exit; FAGCMode := M; ApplyAGCToEngine; - FBandCache[FCurrentBand].AGCMode := FAGCMode; + if XvtrSlotActive then FXvtrSettings.Entries[FCurrentXvtr].LastAGCMode := FAGCMode + else FBandCache[FCurrentBand].AGCMode := FAGCMode; Changed(rfAGCMode); end; @@ -4366,7 +4380,8 @@ begin FAGCTop := DB; if FWDSPReady and Assigned(FDSPEngine) then FDSPEngine.SetAGCTop(FAGCTop); ApplyAGCToEngine; // ре-применяем режим с новым уровнем - FBandCache[FCurrentBand].AGCTop := FAGCTop; + if XvtrSlotActive then FXvtrSettings.Entries[FCurrentXvtr].LastAGCTop := FAGCTop + else FBandCache[FCurrentBand].AGCTop := FAGCTop; Changed(rfAGCTop); end; @@ -4989,7 +5004,8 @@ end; procedure TRadioController.SetCTun(On_: Boolean); begin FCTun := On_; - FBandCache[FCurrentBand].CTun := FCTun; + if XvtrSlotActive then FXvtrSettings.Entries[FCurrentXvtr].LastCTun := FCTun + else FBandCache[FCurrentBand].CTun := FCTun; if not FCTun then begin // Выключили CTUN: центрируемся на АКТИВНОМ VFO, shift=0. (Включение CTUN не @@ -5101,6 +5117,11 @@ begin FDSPEngine.SetANF(FANF); end; +function TRadioController.XvtrSlotActive: Boolean; +begin + Result := (FCurrentXvtr >= 0) and (FCurrentXvtr < CFG_XVTR_COUNT); +end; + function TRadioController.TXProhibited: Boolean; // Единая точка запретов передачи: диапазон с DoNotTx (Alex) и RX-only слот // трансвертера. Раньше эта пара была скопирована в SetMOX/SetTune/SetTwoTone —