wip(audio): выбор устройства ВВОДА на каждом слайсе + вкладки OUT/IN в AUD

Паритет с уже существующим выбором вывода: на каждом слайсе своё устройство
входа (микрофон/виртуальный кабель).

- RadioController: TCtrlSlice += InDeviceIndex/InDevName/AudioIn (ссылка, не
  владение); mic-пул FMicPool с refcount (Acquire/ReleaseMicInput) — один
  открытый TAudioInput на уникальное PA-устройство, смена TX-слайса не
  переоткрывает поток; ActiveMicInput/ActiveMicInDevName для PullSoundCardMic,
  Flush и DefaultMicSource; SetMainMicDevice перепривязывает ссылки слайсов.
- VfoOverlay: во fly-out AUD ряд вкладок OUT | IN, событие OnAudioInDevice.
- PanafallPanel: проброс списка входных устройств во флаги слайсов и главный.
- Settings: персист in_dev_name.

НЕ ГОТОВО: зависание GUI при выборе на слайсе того же входа, что в настройках
(пул открывает поток вместо шортката на общий FAudioIn). В коде оставлена
временная диагностика [MIC] в stderr. Также подозрение на замедление потока
данных от радио — проверяем сравнением с main.

Со мной в коммите временные тестовые программы PortAudio (other/pa*.lpr).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-07-21 21:52:24 +03:00
co-authored by Claude Opus 4.8
parent 317e9b732c
commit 4aa180e7b2
9 changed files with 493 additions and 49 deletions
+24
View File
@@ -1353,6 +1353,20 @@ begin
Names.Free;
end;
end;
// Устройства ВВОДА + свой вход слайса ('' = общий вход приложения).
if Assigned(FController.FAudioIn) then
begin
Names := TStringList.Create;
try
Cnt := 0;
FController.FAudioIn.EnumInputDevices(Names, Indices, Cnt);
SetLength(Idx, Cnt);
for I := 0 to Cnt - 1 do Idx[I] := Indices[I];
O.SetAudioInDevices(Names, Idx, S.InDevName);
finally
Names.Free;
end;
end;
end;
procedure TPanafallPanel.PushAllSliceFlagStates;
@@ -1390,6 +1404,16 @@ begin
SetLength(Idx, Cnt);
for I := 0 to Cnt - 1 do Idx[I] := Indices[I];
FMainFlag.SetAudioDevices(Names, Idx, FController.FAudioOutDevName);
// Вход главного VFO = общее устройство ввода (то же, что в Settings).
if Assigned(FController.FAudioIn) then
begin
Cnt := 0;
Names.Clear;
FController.FAudioIn.EnumInputDevices(Names, Indices, Cnt);
SetLength(Idx, Cnt);
for I := 0 to Cnt - 1 do Idx[I] := Indices[I];
FMainFlag.SetAudioInDevices(Names, Idx, FController.FAudioInDevName);
end;
finally
Names.Free;
end;