From ce431164904aab5d60d76f41510380f96ab7aea7 Mon Sep 17 00:00:00 2001 From: Vladimir Date: Tue, 4 Aug 2026 13:22:56 +0300 Subject: [PATCH] =?UTF-8?q?fix(filter):=20=D1=81=D0=BB=D0=BE=D1=82=20VAR?= =?UTF-8?q?=20=D0=BF=D0=B5=D1=80=D0=B5=D0=B6=D0=B8=D0=B2=D0=B0=D0=B5=D1=82?= =?UTF-8?q?=20=D0=BF=D0=B5=D1=80=D0=B5=D0=B7=D0=B0=D0=BF=D1=83=D1=81=D0=BA?= =?UTF-8?q?=20=D0=B2=20=D1=80=D0=B5=D0=B6=D0=B8=D0=BC=D0=B5=20=D1=82=D1=80?= =?UTF-8?q?=D0=B0=D0=BD=D1=81=D0=B2=D0=B5=D1=80=D1=82=D0=B5=D1=80=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Симптом: в XVTR-режиме выбрать VAR1, выключить и включить трансивер — фильтр откатывался на заводской (в FM это NFM). Вне трансвертера всё сохранялось. Причина: персист XVTR клампил last_filt диапазоном 0..9, оставшимся от эпохи десяти пресетов. VAR1/VAR2 (10/11) при загрузке схлопывались в 9, а дальше ClampFilterIdx видел индекс вне таблицы режима (у FM пресетов всего два) и по своему правилу откатывался на заводской индекс — отсюда NFM. У band-cache такой границы нет, поэтому в обычном режиме баг не проявлялся. Граница поднята до FILT_SLOTS-1. Проверено round-trip-тестом SaveXvtr/LoadXvtr: слот 10 сохраняется и читается как 10. Проверены заодно остальные пути, где слот мог потеряться: band-cache (клэмпа нет), каналы памяти (фильтр не хранят вовсе), рендер rfMode (сброс обёрнут save/restore), web SetFilterBW, SanitizeFilterForMode. Клэмп 0..9 в CAT-командах FW/SH/ZZBI намеренно оставлен — это ограничение протокола, а не хранения; VAR снаружи доступен через ZZFL/ZZFH. Co-Authored-By: Claude Opus 5 --- Settings.pas | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/Settings.pas b/Settings.pas index 4362409..ae1f861 100644 --- a/Settings.pas +++ b/Settings.pas @@ -340,7 +340,7 @@ type LastFreq: Double; // Hz — последняя tuned visible частота VFO A (BandStack) LastFreqB: Double; // Hz — последняя tuned visible частота VFO B LastMode: Integer; // Mode (LSB=0,USB=1,…FM=5) - LastFilterIdx: Integer; // FM: 0=NFM, 1=WFM; иначе 0..FILT_COUNT-1 + LastFilterIdx: Integer; // слот фильтра 0..FILT_SLOTS-1 (10/11 = VAR1/VAR2) LastFMSQOn: Boolean; LastFMSQLevel: Integer; LastCTCSSOn: Boolean; @@ -2085,7 +2085,10 @@ begin X.Entries[i].LastFreq := JD(EObj, 'last_freq', X.Entries[i].LastFreq); X.Entries[i].LastFreqB := JD(EObj, 'last_freq_b', X.Entries[i].LastFreqB); X.Entries[i].LastMode := EnsureRange(JI(EObj, 'last_mode', X.Entries[i].LastMode), CFG_MODE_MIN, CFG_MODE_MAX); - X.Entries[i].LastFilterIdx := EnsureRange(JI(EObj, 'last_filt', X.Entries[i].LastFilterIdx), 0, 9); + // Верхняя граница = FILT_SLOTS-1, а не 9: слоты VAR1/VAR2 (10/11) иначе + // схлопывались в 9, и при восстановлении трансвертера ClampFilterIdx + // видел индекс вне таблицы режима и откатывал на заводской фильтр. + X.Entries[i].LastFilterIdx := EnsureRange(JI(EObj, 'last_filt', X.Entries[i].LastFilterIdx), 0, FILT_SLOTS - 1); X.Entries[i].LastFMSQOn := JB(EObj, 'last_fmsq_on', X.Entries[i].LastFMSQOn); X.Entries[i].LastFMSQLevel := EnsureRange(JI(EObj, 'last_fmsq_lvl', X.Entries[i].LastFMSQLevel), 0, 100); X.Entries[i].LastCTCSSOn := JB(EObj, 'last_ctcss_on', X.Entries[i].LastCTCSSOn);