mirror of
https://git.vladimir.cc/vladimir/ewsdr.git
synced 2026-08-25 20:37:33 +00:00
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:
co-authored by
Claude Opus 4.8
parent
8be98b72e1
commit
3d2d76452c
+2
-35
@@ -375,7 +375,6 @@ type
|
|||||||
Count: Integer);
|
Count: Integer);
|
||||||
procedure OnWDSPOpenDone(Success: Boolean);
|
procedure OnWDSPOpenDone(Success: Boolean);
|
||||||
procedure DoConnectDevice(const Dev: THPSDRDevice);
|
procedure DoConnectDevice(const Dev: THPSDRDevice);
|
||||||
procedure OnMicPacketCB(const Data: TMicDataPacket);
|
|
||||||
|
|
||||||
// DSP/Audio callbacks (вызываются из рабочих потоков)
|
// DSP/Audio callbacks (вызываются из рабочих потоков)
|
||||||
procedure OnAudioReady(const Left, Right: array of Single; Count: Integer);
|
procedure OnAudioReady(const Left, Right: array of Single; Count: Integer);
|
||||||
@@ -640,7 +639,6 @@ type
|
|||||||
// (mic-биты Boost/Bias/LineIn/PTT попадают в byte 50 DUCSpecific).
|
// (mic-биты Boost/Bias/LineIn/PTT попадают в byte 50 DUCSpecific).
|
||||||
procedure ApplyTXSettingsToDSP;
|
procedure ApplyTXSettingsToDSP;
|
||||||
procedure SendDUCSpecificFromSettings;
|
procedure SendDUCSpecificFromSettings;
|
||||||
function PullSoundCardMic(MaxN: Integer): Integer;
|
|
||||||
function BuildMicLineSelectByte: Byte;
|
function BuildMicLineSelectByte: Byte;
|
||||||
procedure ApplyVisibility(ShowSpectrum, ShowWaterfall, ShowWideband,
|
procedure ApplyVisibility(ShowSpectrum, ShowWaterfall, ShowWideband,
|
||||||
WidebandFill, SpectrumFill: Boolean);
|
WidebandFill, SpectrumFill: Boolean);
|
||||||
@@ -1158,7 +1156,7 @@ begin
|
|||||||
FController.FNetwork.OnDeviceFound := OnDeviceFound;
|
FController.FNetwork.OnDeviceFound := OnDeviceFound;
|
||||||
FController.FNetwork.OnHPStatus := OnHPStatusCB;
|
FController.FNetwork.OnHPStatus := OnHPStatusCB;
|
||||||
FController.FNetwork.OnDDCIQ := OnDDCIQCB;
|
FController.FNetwork.OnDDCIQ := OnDDCIQCB;
|
||||||
FController.FNetwork.OnMicPacket := OnMicPacketCB;
|
FController.FNetwork.OnMicPacket := FController.OnMicPacket;
|
||||||
FController.FNetwork.OnWideband := OnWidebandCB;
|
FController.FNetwork.OnWideband := OnWidebandCB;
|
||||||
// Дефолты TX, Alex и XVTR (на случай если устройство ещё не выбрано).
|
// Дефолты TX, Alex и XVTR (на случай если устройство ещё не выбрано).
|
||||||
TSettingsManager.DefaultTX(FController.FTXSettings);
|
TSettingsManager.DefaultTX(FController.FTXSettings);
|
||||||
@@ -1180,7 +1178,7 @@ begin
|
|||||||
FController.FDSPEngine.OnTXIQ := OnTXIQReady;
|
FController.FDSPEngine.OnTXIQ := OnTXIQReady;
|
||||||
// Sound-card mic путь: WDSP TX-thread дёргает этот колбэк перед каждым
|
// Sound-card mic путь: WDSP TX-thread дёргает этот колбэк перед каждым
|
||||||
// тиком, если выбран источник SoundCard. Для Radio колбэк не вызывается.
|
// тиком, если выбран источник SoundCard. Для Radio колбэк не вызывается.
|
||||||
FController.FDSPEngine.OnPullMicSamples := PullSoundCardMic;
|
FController.FDSPEngine.OnPullMicSamples := FController.PullSoundCardMic;
|
||||||
|
|
||||||
FMeterTimer := TTimer.Create(Self);
|
FMeterTimer := TTimer.Create(Self);
|
||||||
FMeterTimer.Interval := 100;
|
FMeterTimer.Interval := 100;
|
||||||
@@ -3565,15 +3563,6 @@ begin
|
|||||||
SetStatusText(4, 'RX running');
|
SetStatusText(4, 'RX running');
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TMainForm.OnMicPacketCB(const Data: TMicDataPacket);
|
|
||||||
begin
|
|
||||||
// HW mic-стрим уходит в WDSP только если выбран источник Radio.
|
|
||||||
// Иначе сэмплы игнорируются (mic берётся со звуковой карты).
|
|
||||||
if FController.FTransmitting and FController.FWDSPReady and
|
|
||||||
(FController.FDSPEngine.TXMicSource = txmsRadio) then
|
|
||||||
FController.FDSPEngine.PushTXMicSamples16(Data.Samples, 64);
|
|
||||||
end;
|
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
// TX settings — применение к WDSP, сборка DUC Specific, sound-card pull
|
// TX settings — применение к WDSP, сборка DUC Specific, sound-card pull
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
@@ -3670,28 +3659,6 @@ begin
|
|||||||
FController.FTXSettings.TXWfAvgTimeMS);
|
FController.FTXSettings.TXWfAvgTimeMS);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TMainForm.PullSoundCardMic(MaxN: Integer): Integer;
|
|
||||||
// Колбэк, который TTXDSPThread зовёт при TXMicSource=txmsSoundCard.
|
|
||||||
// Тянем только реально доступные сэмплы из FController.FAudioIn — иначе мы пушили бы
|
|
||||||
// нули и mic-цепь в WDSP получала бы тишину вместо реального сигнала.
|
|
||||||
// Читаем пачкой в локальный буфер и пушим одним вызовом — экономим
|
|
||||||
// будилки семафора и предотвращаем подмену TX-блока тишиной.
|
|
||||||
var
|
|
||||||
i, n: Integer;
|
|
||||||
Buf: array[0..2047] of Double;
|
|
||||||
begin
|
|
||||||
Result := 0;
|
|
||||||
if (FController.FAudioIn = nil) or (not FController.FAudioIn.IsOpen) then Exit;
|
|
||||||
n := FController.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] := FController.FAudioIn.ReadSample;
|
|
||||||
if n > 0 then
|
|
||||||
FController.FDSPEngine.PushTXMicSamplesD(Buf, n);
|
|
||||||
Result := n;
|
|
||||||
end;
|
|
||||||
|
|
||||||
// ===========================================================================
|
// ===========================================================================
|
||||||
// Button handlers
|
// Button handlers
|
||||||
// ===========================================================================
|
// ===========================================================================
|
||||||
|
|||||||
@@ -210,6 +210,12 @@ type
|
|||||||
procedure CreateEngines(ASampleRate: Integer);
|
procedure CreateEngines(ASampleRate: Integer);
|
||||||
procedure FreeEngines;
|
procedure FreeEngines;
|
||||||
|
|
||||||
|
// ---- Колбэки движков (вызываются из рабочих потоков сети/DSP) ----
|
||||||
|
// Чистая обработка данных без UI; навешиваются на FNetwork/FDSPEngine
|
||||||
|
// вызывающим (GUI или демон) после CreateEngines.
|
||||||
|
procedure OnMicPacket(const Data: TMicDataPacket);
|
||||||
|
function PullSoundCardMic(MaxN: Integer): Integer;
|
||||||
|
|
||||||
// Маршалинг команды в поток контроллера (GUI: TThread.Synchronize).
|
// Маршалинг команды в поток контроллера (GUI: TThread.Synchronize).
|
||||||
procedure Invoke(M: TThreadMethod);
|
procedure Invoke(M: TThreadMethod);
|
||||||
|
|
||||||
@@ -418,6 +424,35 @@ begin
|
|||||||
end;
|
end;
|
||||||
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);
|
procedure TRadioController.Invoke(M: TThreadMethod);
|
||||||
begin
|
begin
|
||||||
if Assigned(FOnInvoke) then FOnInvoke(M)
|
if Assigned(FOnInvoke) then FOnInvoke(M)
|
||||||
|
|||||||
Reference in New Issue
Block a user