Phase 5 (batch 23): move TX mic callbacks into the controller

OnMicPacket (HW mic packet -> WDSP, only when TX mic source is Radio) and
PullSoundCardMic (sound-card input -> WDSP, when source is SoundCard) are
pure data-path handlers with no UI/MainForm state, so they move verbatim
into TRadioController. FormCreate now wires FNetwork.OnMicPacket and
FDSPEngine.OnPullMicSamples to the controller's own methods. These are
backend-agnostic consumers (they operate on the common interchange
format), so they belong in the core regardless of HPSDR vs future Pluto
backends. Behaviour unchanged.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Uladzimir Karpenka
2026-06-05 17:33:11 +03:00
co-authored by Claude Opus 4.8
parent 8be98b72e1
commit 3d2d76452c
2 changed files with 37 additions and 35 deletions
+35
View File
@@ -210,6 +210,12 @@ type
procedure CreateEngines(ASampleRate: Integer);
procedure FreeEngines;
// ---- Колбэки движков (вызываются из рабочих потоков сети/DSP) ----
// Чистая обработка данных без UI; навешиваются на FNetwork/FDSPEngine
// вызывающим (GUI или демон) после CreateEngines.
procedure OnMicPacket(const Data: TMicDataPacket);
function PullSoundCardMic(MaxN: Integer): Integer;
// Маршалинг команды в поток контроллера (GUI: TThread.Synchronize).
procedure Invoke(M: TThreadMethod);
@@ -418,6 +424,35 @@ begin
end;
end;
procedure TRadioController.OnMicPacket(const Data: TMicDataPacket);
// HW mic-стрим уходит в WDSP только если выбран источник Radio; иначе сэмплы
// игнорируются (mic берётся со звуковой карты).
begin
if FTransmitting and FWDSPReady and
(FDSPEngine.TXMicSource = txmsRadio) then
FDSPEngine.PushTXMicSamples16(Data.Samples, 64);
end;
function TRadioController.PullSoundCardMic(MaxN: Integer): Integer;
// Колбэк TTXDSPThread при TXMicSource=txmsSoundCard. Тянем только реально
// доступные сэмплы из FAudioIn (иначе пушили бы тишину в mic-цепь WDSP),
// пачкой в локальный буфер — экономим будилки семафора.
var
i, n: Integer;
Buf: array[0..2047] of Double;
begin
Result := 0;
if (FAudioIn = nil) or (not FAudioIn.IsOpen) then Exit;
n := FAudioIn.Available;
if n > MaxN then n := MaxN;
if n > Length(Buf) then n := Length(Buf);
for i := 0 to n - 1 do
Buf[i] := FAudioIn.ReadSample;
if n > 0 then
FDSPEngine.PushTXMicSamplesD(Buf, n);
Result := n;
end;
procedure TRadioController.Invoke(M: TThreadMethod);
begin
if Assigned(FOnInvoke) then FOnInvoke(M)