mirror of
https://git.vladimir.cc/vladimir/ewsdr.git
synced 2026-08-25 17:27:32 +00:00
fix(tx): профиль по модуляции — детерминированное правило + пробелы вызова
Три связанных правки по отзывам с эфира. 1. Активный профиль однозначно определяется парой «TX-источник + его модуляция»: ячейка таблицы заполнена — её профиль, пуста — базовый (первый в списке). Прежняя «точка возврата» (запомнить, что было активно до автоматики) ломалась в самом частом случае: заходя в FM, оператор обычно УЖЕ имел активным профиль FM с прошлого захода, точка возврата записывала его же, и выход в USB ничего не менял. Плюс она жила только в сессии и после перезапуска не работала вовсе. Поле FTXProfPreAuto удалено. Ручной выбор (дропдаун TX, список настроек, пилюля флага) дополнительно ЗАПОМИНАЕТСЯ за текущей парой — это и есть обещанное «профиль помнится по виду модуляции»: раньше в таблицу писала только пилюля, а выбор дропдауном следа не оставлял. В DMR и FMRAW автоматика активный профиль не трогает вовсе. 2. Смена диапазона и вход/выход трансвертера меняют режим главного в ApplyBandDSP (FMode := B.Mode) МИМО SetMode, поэтому автоматика там не вызывалась и при переходе КВ↔трансвертер оставался профиль прошлого режима. Зовём и оттуда. Заодно: FDSPEngine.SetMode насильно ставит FTXMode в режим главного, а SetMode контроллера следом возвращает режим источника — ApplyBandDSP этого не делала, и передача со слайса после смены диапазона уезжала в чужую модуляцию. 3. Кнопка выбора TX-профиля гаснет, когда режим ИСТОЧНИКА передачи DMR или FMRAW (в DMR передатчика нет, в FMRAW профиль обходится); открытый список закрывается. Гейт по источнику, а не по главному: с главным в DMR можно передавать со слайса. Смена режима на слайсе теперь тоже пересчитывает доступность TX-контролов — это чинит и MOX/TUN/PS. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -3840,6 +3840,18 @@ begin
|
||||
TuneAllowed := MOXAllowed and (FController.ActiveTXMode <> MODE_FMRAW);
|
||||
BtnMOX.Enabled := MOXAllowed;
|
||||
BtnTUN.Enabled := TuneAllowed;
|
||||
// Выбор TX-профиля: в DMR передатчика нет вовсе, в FM RAW профиль ни на что
|
||||
// не влияет (ApplyTXModeSettings глушит там всю обработку). Гейт по режиму
|
||||
// ИСТОЧНИКА передачи, а не главного приёмника: с главным в DMR можно
|
||||
// передавать со слайса, и там профиль по-прежнему нужен. Run не требуем —
|
||||
// профиль выбирается и оффлайн, как и на вкладке настроек.
|
||||
if BtnTXProfile <> nil then
|
||||
begin
|
||||
BtnTXProfile.Enabled :=
|
||||
not (FController.ActiveTXMode in [MODE_DMR, MODE_FMRAW]);
|
||||
if (not BtnTXProfile.Enabled) and (FTXProfileDropDown <> nil) then
|
||||
FTXProfileDropDown.ClosePopup; // открытый список закрываем сами
|
||||
end;
|
||||
UpdatePSButtons;
|
||||
end;
|
||||
|
||||
@@ -6026,6 +6038,8 @@ begin
|
||||
FController.SetSliceModeBW(CurSliceId, Mode, FilterBW);
|
||||
PushFlagStateAllPans(CurSliceId);
|
||||
LayoutFlagsAllPans;
|
||||
// Режим ИСТОЧНИКА передачи мог смениться — MOX/TUN/PS/профиль гейтятся им.
|
||||
UpdateTXControlAvailability;
|
||||
Exit;
|
||||
end;
|
||||
// Main flag A and the left panel edit the same receiver. Use the public
|
||||
|
||||
+53
-7
@@ -594,7 +594,10 @@ type
|
||||
function TXProfileCount: Integer;
|
||||
function TXProfileName(Idx: Integer): string;
|
||||
function ActiveTXProfile: Integer;
|
||||
procedure SelectTXProfile(Idx: Integer);
|
||||
// Auto=True — переключение сделала автоматика привязок; ручной выбор
|
||||
// (дропдаун, список настроек) дополнительно ЗАПОМИНАЕТСЯ за текущей парой
|
||||
// «источник + модуляция» (BindTXProfileToCurrentMode).
|
||||
procedure SelectTXProfile(Idx: Integer; Auto: Boolean = False);
|
||||
procedure StoreActiveTXProfile(Persist: Boolean = False);
|
||||
function AddTXProfile(const AName: string): Integer; // форк текущего звука
|
||||
procedure RenameTXProfile(Idx: Integer; const AName: string);
|
||||
@@ -604,6 +607,7 @@ type
|
||||
// звучит активный). Таблица у каждого флага своя: главный в FTXProfiles,
|
||||
// слайсы в своих записях.
|
||||
function FlagMode(SliceId: Integer): Integer;
|
||||
procedure BindTXProfileToCurrentMode(Idx: Integer); // ручной выбор → в таблицу
|
||||
function SliceTXProfile(SliceId: Integer): Integer;
|
||||
procedure SetSliceTXProfile(SliceId, ProfIdx: Integer);
|
||||
function SliceTXProfileTable(SliceId: Integer): TTXProfModeTable;
|
||||
@@ -3631,6 +3635,16 @@ begin
|
||||
FFMRptOffsetHz := B.FMRptOffsetHz;
|
||||
if FFMRptOffsetHz <= 0 then FFMRptOffsetHz := RptDefaultOffsetHz(B.VfoA);
|
||||
|
||||
// --- TX-профиль под новый режим ---
|
||||
// Смена диапазона и вход/выход трансвертера меняют режим ГЛАВНОГО здесь, а
|
||||
// не через SetMode, поэтому автоматику привязок надо звать и отсюда — иначе
|
||||
// при переходе КВ↔трансвертер оставался профиль прошлого режима.
|
||||
if FTxSliceId = 0 then ApplyBoundTXProfile;
|
||||
// FDSPEngine.SetMode выше насильно выставил TXA в режим главного приёмника,
|
||||
// но передавать можем со слайса — возвращаем режим настоящего источника.
|
||||
if FWDSPReady and Assigned(FDSPEngine) and (ActiveTXMode <> FMode) then
|
||||
FDSPEngine.SetTXMode(ActiveTXMode);
|
||||
|
||||
// --- CTUN ---
|
||||
FCTun := B.CTun;
|
||||
if FWDSPReady and Assigned(FDSPEngine) and not FCTun then FDSPEngine.SetShift(0.0);
|
||||
@@ -4991,7 +5005,7 @@ begin
|
||||
if Persist then SaveTXProfilesToConfig;
|
||||
end;
|
||||
|
||||
procedure TRadioController.SelectTXProfile(Idx: Integer);
|
||||
procedure TRadioController.SelectTXProfile(Idx: Integer; Auto: Boolean);
|
||||
var
|
||||
OldMic: Byte;
|
||||
NewDrive: Integer;
|
||||
@@ -5012,6 +5026,11 @@ begin
|
||||
SetDrive(NewDrive);
|
||||
if FTuning and FWDSPReady then
|
||||
FDSPEngine.SetDriveLevel(EnsureRange(FTXSettings.TUNLevel, 0, 100) / 100.0);
|
||||
// ★Ручной выбор ЗАПОМИНАЕТСЯ за парой «источник передачи + его модуляция» —
|
||||
// это и есть обещанное «профиль помнится по виду модуляции». Без этого в
|
||||
// таблице оказывалось только то, что назначено пилюлей во флаге, а профиль,
|
||||
// выбранный дропдауном в блоке TX, нигде не оставался следа.
|
||||
if not Auto then BindTXProfileToCurrentMode(Idx);
|
||||
if FDevConnected and Assigned(FSettings) then
|
||||
begin
|
||||
FSettings.SaveTX(FDevMAC, FTXSettings);
|
||||
@@ -5094,6 +5113,23 @@ begin
|
||||
for m := 0 to CFG_MODE_MAX do Fix(FSlices[i].TXProfByMode[m]);
|
||||
end;
|
||||
|
||||
procedure TRadioController.BindTXProfileToCurrentMode(Idx: Integer);
|
||||
// Пишет профиль в ячейку «текущий TX-источник + его модуляция». Отдельно от
|
||||
// SetSliceTXProfile: там ещё и применение в эфир, а здесь профиль уже применён
|
||||
// (нас зовут из SelectTXProfile), повторный ApplyBoundTXProfile был бы циклом.
|
||||
var m, Slot: Integer;
|
||||
begin
|
||||
if (Idx < 0) or (Idx >= FTXProfiles.Count) then Exit;
|
||||
m := FlagMode(FTxSliceId);
|
||||
if FTxSliceId <= 0 then
|
||||
FTXProfiles.MainByMode[m] := Idx // персист — общим блоком в SelectTXProfile
|
||||
else
|
||||
begin
|
||||
Slot := FindSliceIndex(FTxSliceId);
|
||||
if Slot >= 0 then FSlices[Slot].TXProfByMode[m] := Idx;
|
||||
end;
|
||||
end;
|
||||
|
||||
function TRadioController.FlagMode(SliceId: Integer): Integer;
|
||||
// Режим, в котором сейчас стоит этот флаг: у главного — FMode, у слайса — свой.
|
||||
var idx: Integer;
|
||||
@@ -5182,13 +5218,23 @@ begin
|
||||
end;
|
||||
|
||||
procedure TRadioController.ApplyBoundTXProfile;
|
||||
// Профиль текущего TX-источника → в эфир. Ничего не делает, если источник ни к
|
||||
// чему не привязан (-1) или нужный профиль уже активен.
|
||||
var P: Integer;
|
||||
// Активный профиль ОДНОЗНАЧНО определяется парой «TX-источник + его модуляция»:
|
||||
// ячейка таблицы заполнена → её профиль;
|
||||
// ячейка пуста (−1) → базовый профиль (первый в списке).
|
||||
// Фолбэк обязателен: без него профиль прошлого режима оставался висеть в новом
|
||||
// (симптом «перешёл из FM в USB, а звучит FM»). Правило детерминированное —
|
||||
// работает и после перезапуска, в отличие от «вернуть, что было до автоматики».
|
||||
var P, M: Integer;
|
||||
begin
|
||||
if FTXProfiles.Count = 0 then Exit;
|
||||
M := FlagMode(FTxSliceId);
|
||||
// В DMR передатчика нет, в FM RAW профиль ни на что не влияет
|
||||
// (ApplyTXModeSettings глушит там всю обработку) — активный не трогаем вовсе,
|
||||
// иначе заход в эти режимы молча перебивал бы выбор оператора.
|
||||
if (M = MODE_DMR) or (M = MODE_FMRAW) then Exit;
|
||||
P := SliceTXProfile(FTxSliceId);
|
||||
if (P < 0) or (P = FTXProfiles.ActiveIdx) then Exit;
|
||||
SelectTXProfile(P);
|
||||
if P < 0 then P := 0;
|
||||
if P <> FTXProfiles.ActiveIdx then SelectTXProfile(P, True);
|
||||
end;
|
||||
|
||||
procedure TRadioController.ResetTXProfilesToFactory;
|
||||
|
||||
Reference in New Issue
Block a user