mirror of
https://git.vladimir.cc/vladimir/ewsdr.git
synced 2026-08-25 20:37:33 +00:00
feat(tx): TX-профиль на слайс — пилюля в шапке флага
Передатчик один, профиль до сих пор был один на устройство: активный профиль звучал независимо от того, какой слайс взял передачу. С панадаптером на FT8 и вторым на FM это значит, что компрессия и EQ голосового профиля уходили в эфир на FT8 (FMRAW прикрыт сам — ApplyTXModeSettings глушит там всю обработку, а DIGU/DIGL нет). У Flex это решается дисциплиной и внешним API; делаем в радио. Привязка «источник передачи → профиль» (-1 = не переключать, звучит активный): TCtrlSlice.TXProfile для B..G, TTXProfileList.MainBind для главного (слайс A). Персист: ключ tx_profile в слайсе пана и main_bind в секции tx_profiles. SetTxSlice зовёт ApplyBoundTXProfile ДО пуша режима и цепи, иначе ApplyTXSettingsToDSP лёг бы на старый режим. Привязали источник, который передаёт прямо сейчас, — применяем сразу. Привязки — индексы, поэтому RemapTXProfileBindings: удаление профиля из середины снимает привязки на него и сдвигает те, что правее; Factory-сброс снимает все (список заменён целиком). UI: пилюля с именем профиля в первой строке флага сразу за шириной фильтра (ЛКМ — fly-out список, первая строка «As active»). Правая граница считается до SPLIT у главного и до RXM у слайса; не рисуем при пустом списке, в DMR (передачи нет) и в FMRAW (профиль там ни на что не влияет). Прокрутка списка общая с AUD — блок стрелок вынесен в DrawScrollArrows. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -177,6 +177,7 @@ type
|
||||
FMSQLevel: Integer;
|
||||
DevName: string; // имя PortAudio-устройства вывода ('' = default)
|
||||
InDevName: string; // имя устройства ВВОДА слайса ('' = общий вход)
|
||||
TXProfile: Integer; // TX-профиль слайса: -1 = какой активен, тот и звучит
|
||||
end;
|
||||
|
||||
TPanCfg = record
|
||||
@@ -349,6 +350,9 @@ type
|
||||
TTXProfileList = record
|
||||
Count: Integer;
|
||||
ActiveIdx: Integer;
|
||||
// Привязка профиля к ГЛАВНОМУ приёмнику (слайс A). У слайсов B..G то же
|
||||
// самое лежит в TSliceCfg.TXProfile; -1 = ничего не переключать.
|
||||
MainBind: Integer;
|
||||
Items: array[0..TXPROF_MAX-1] of TTXProfile;
|
||||
end;
|
||||
|
||||
@@ -1938,6 +1942,7 @@ begin
|
||||
FillChar(L, SizeOf(L), 0);
|
||||
L.Count := 0;
|
||||
L.ActiveIdx := 0;
|
||||
L.MainBind := -1; // главный приёмник профиль не переключает
|
||||
// «Default» — текущее состояние устройства (микрофонный вход, полоса,
|
||||
// динамика, мощность), но с заводским EQ: после миграции старого конфига
|
||||
// звук в эфире не меняется, а сброс к заводским возвращает ровный тембр.
|
||||
@@ -1970,6 +1975,7 @@ begin
|
||||
FillChar(L, SizeOf(L), 0);
|
||||
L.Count := 0;
|
||||
L.ActiveIdx := 0;
|
||||
L.MainBind := -1;
|
||||
Result := False;
|
||||
MacStr := MacToStr(MAC);
|
||||
if FRoot.Find(MacStr) = nil then Exit;
|
||||
@@ -2030,6 +2036,8 @@ begin
|
||||
if L.Count = 0 then Exit; // пустой список = как будто секции нет
|
||||
L.ActiveIdx := JI(Root, 'active', 0);
|
||||
if (L.ActiveIdx < 0) or (L.ActiveIdx >= L.Count) then L.ActiveIdx := 0;
|
||||
L.MainBind := JI(Root, 'main_bind', -1);
|
||||
if (L.MainBind < -1) or (L.MainBind >= L.Count) then L.MainBind := -1;
|
||||
Result := True;
|
||||
end;
|
||||
|
||||
@@ -2042,6 +2050,7 @@ var
|
||||
begin
|
||||
Root := EnsureObj(GetDevObj(MacToStr(MAC)), 'tx_profiles');
|
||||
JW(Root, 'active', EnsureRange(L.ActiveIdx, 0, Max(0, L.Count - 1)));
|
||||
JW(Root, 'main_bind', EnsureRange(L.MainBind, -1, Max(-1, L.Count - 1)));
|
||||
// Список пересоздаётся целиком: удаление профиля не должно оставлять хвост.
|
||||
Idx := Root.IndexOfName('list');
|
||||
if Idx >= 0 then Root.Delete(Idx);
|
||||
@@ -2732,6 +2741,7 @@ begin
|
||||
SliceObj.Add('fmsq_level', P.Pans[i].Slices[j].FMSQLevel);
|
||||
SliceObj.Add('dev_name', P.Pans[i].Slices[j].DevName);
|
||||
SliceObj.Add('in_dev_name', P.Pans[i].Slices[j].InDevName);
|
||||
SliceObj.Add('tx_profile', P.Pans[i].Slices[j].TXProfile);
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
@@ -2812,6 +2822,8 @@ begin
|
||||
P.Pans[id].Slices[n].FMSQLevel := JI(SliceObj, 'fmsq_level', 30);
|
||||
P.Pans[id].Slices[n].DevName := JS(SliceObj, 'dev_name', '');
|
||||
P.Pans[id].Slices[n].InDevName := JS(SliceObj, 'in_dev_name', '');
|
||||
P.Pans[id].Slices[n].TXProfile := EnsureRange(
|
||||
JI(SliceObj, 'tx_profile', -1), -1, TXPROF_MAX - 1);
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
Reference in New Issue
Block a user