mirror of
https://git.vladimir.cc/vladimir/ewsdr.git
synced 2026-08-25 20:37:33 +00:00
Phase 5 (batch 26): move OnTXIQ + DUC queue into the controller
The TX IQ handler (batch WDSP TXA output into 240-sample DUC packets, 24-bit clamp, FNetwork.SendDUCIQ) moves into TRadioController.OnTXIQ, along with the FDUCPendingI/Q/Count queue fields. The DUC-queue reset on a TX-state change moves from the rfTransmitting render into SetMOX itself (the render does not run headless). Both DSP-callback wiring sites (FormCreate and RecreateDSPEngine) now point at FController.OnTXIQ. Backend-agnostic: a Pluto backend converts 24-bit->int16 in SendDUCIQ. Pre-existing gap noted: RecreateDSPEngine never re-wires OnPullMicSamples, so sound-card mic is lost after a sample-rate change (unchanged here). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
c1da506f73
commit
3a387e06ce
+4
-45
@@ -139,12 +139,7 @@ type
|
||||
FSpecDragX0: Integer; // X при нажатии
|
||||
FSpecDragFreq: Double; // FCenterFreq при нажатии
|
||||
FSpectrumDirty: Boolean; // таймер должен перерисовать спектр/водопад
|
||||
// DUC IQ packetizer: TXA отдаёт блок FTXOutBufSize пар, который
|
||||
// не обязан быть кратен 240 (DUC packet). Хвост переносим в следующий
|
||||
// вызов OnTXIQReady, иначе зануление давало 47 Гц гул.
|
||||
FDUCPendingI: array[0..239] of Integer;
|
||||
FDUCPendingQ: array[0..239] of Integer;
|
||||
FDUCPendingCount: Integer;
|
||||
// TX DUC-очередь (FDUCPending*) переехала в TRadioController (OnTXIQ).
|
||||
FSMeterPeak: Double; // верхняя граница светлой зоны
|
||||
FSMeterMin: Double; // нижняя граница светлой зоны
|
||||
FSMeterAvg: Double; // сглаженное среднее (EMA)
|
||||
@@ -577,7 +572,6 @@ type
|
||||
function ActiveTXFreqHz: Double;
|
||||
function DefaultMicSource: TTXMicSource;
|
||||
procedure ApplyMOX(Active: Boolean);
|
||||
procedure OnTXIQReady(const Buf: array of Double; Count: Integer);
|
||||
procedure OnPASettingsChange(MaxPower: Double; const BandCal: array of Double);
|
||||
procedure OnVHFCalSettingsChange(const VHFCal: array of Double);
|
||||
procedure OnTXSettingsChange(const T: TTXSettings);
|
||||
@@ -914,7 +908,6 @@ begin
|
||||
FController.FRunning := False;
|
||||
FController.FTransmitting := False;
|
||||
FController.FSplitTxB := False;
|
||||
FDUCPendingCount := 0;
|
||||
FController.FDisplayDuplex := False;
|
||||
FController.FTuning := False;
|
||||
FController.FMuted := False;
|
||||
@@ -1157,7 +1150,7 @@ begin
|
||||
FController.FDSPEngine.OnAudio := OnAudioReady;
|
||||
FController.FDSPEngine.OnSpectrum := OnSpectrumReady;
|
||||
FController.FDSPEngine.OnWaterfall := OnWaterfallReady;
|
||||
FController.FDSPEngine.OnTXIQ := OnTXIQReady;
|
||||
FController.FDSPEngine.OnTXIQ := FController.OnTXIQ;
|
||||
// Sound-card mic путь: WDSP TX-thread дёргает этот колбэк перед каждым
|
||||
// тиком, если выбран источник SoundCard. Для Radio колбэк не вызывается.
|
||||
FController.FDSPEngine.OnPullMicSamples := FController.PullSoundCardMic;
|
||||
@@ -1310,8 +1303,7 @@ begin
|
||||
FSpecView.TXMode := FController.FTransmitting and not FController.FDisplayDuplex;
|
||||
FSpecView.TXOverlay := FController.FTransmitting;
|
||||
ApplySpecViewGridFromState; // сетка спектра под активный тракт
|
||||
FDUCPendingCount := 0;
|
||||
end;
|
||||
end; // (DUC-очередь сбрасывает SetMOX)
|
||||
rfTuning:
|
||||
StyleButton(BtnTUN, FController.FTuning);
|
||||
rfADCOverload:
|
||||
@@ -3542,7 +3534,7 @@ begin
|
||||
FController.FDSPEngine.OnAudio := OnAudioReady;
|
||||
FController.FDSPEngine.OnSpectrum := OnSpectrumReady;
|
||||
FController.FDSPEngine.OnWaterfall := OnWaterfallReady;
|
||||
FController.FDSPEngine.OnTXIQ := OnTXIQReady;
|
||||
FController.FDSPEngine.OnTXIQ := FController.OnTXIQ;
|
||||
end;
|
||||
|
||||
function TMainForm.EnsureWDSPWisdom: Boolean;
|
||||
@@ -5758,39 +5750,6 @@ begin
|
||||
Result := FController.CalcDriveByte;
|
||||
end;
|
||||
|
||||
procedure TMainForm.OnTXIQReady(const Buf: array of Double; Count: Integer);
|
||||
// FTXOutBufSize не обязан быть кратен 240, поэтому копим хвост между
|
||||
// вызовами и шлём только полные DUC-пакеты. Иначе зануление хвоста
|
||||
// последнего пакета давало периодический провал на каждом TX-блоке
|
||||
// (≈47 Гц гул при 192k IQ rate). Также клампим в 24-bit чтобы пики
|
||||
// от компрессора/EQ (значение чуть >1.0) не оборачивались через wrap.
|
||||
function ScaleIQ24(V: Double): Integer;
|
||||
var S: Double;
|
||||
begin
|
||||
S := V * 8388607.0;
|
||||
if S > 8388607.0 then Result := 8388607
|
||||
else if S < -8388608.0 then Result := -8388608
|
||||
else Result := Round(S);
|
||||
end;
|
||||
var
|
||||
i: Integer;
|
||||
begin
|
||||
if not FController.FNetwork.Connected then Exit;
|
||||
|
||||
for i := 0 to Count - 1 do
|
||||
begin
|
||||
FDUCPendingI[FDUCPendingCount] := ScaleIQ24(Buf[i * 2]);
|
||||
FDUCPendingQ[FDUCPendingCount] := ScaleIQ24(Buf[i * 2 + 1]);
|
||||
Inc(FDUCPendingCount);
|
||||
|
||||
if FDUCPendingCount >= 240 then
|
||||
begin
|
||||
FController.FNetwork.SendDUCIQ(FDUCPendingI, FDUCPendingQ);
|
||||
FDUCPendingCount := 0;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TMainForm.OnPASettingsChange(MaxPower: Double;
|
||||
const BandCal: array of Double);
|
||||
var i: Integer;
|
||||
|
||||
Reference in New Issue
Block a user