mirror of
https://git.vladimir.cc/vladimir/ewsdr.git
synced 2026-08-25 20:37:33 +00:00
Phase 5 (batch 24): move OnDDCIQ + seq telemetry into the controller
The DDC IQ receive handler (sequence-error tracking + feeding the active DDC into WDSP) moves verbatim into TRadioController.OnDDCIQ, along with the 12 RX/seq telemetry fields it owns (FRXPacketCount, FRXStartTime, FRXLastPktTime, FActiveDDC, FLastDDCSeq, FLastDDCIndex, FDDCLastSeq, FDDCSeqValid, FSeqErrorCount, FLastSeqErrorDDC, FLastSeqErrorDelta, FSeqOkStreak). FNetwork.OnDDCIQ is wired to the controller method; all MainForm readers (meter timer RX-running/stall detection, status-bar SEQ text, web seq text) and the START/STOP/connect resets now go through FController. Behaviour unchanged; backend-agnostic (a future Pluto backend synthesises the same TDDCIQPacket). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
3d2d76452c
commit
239ff54942
+36
-108
@@ -149,18 +149,7 @@ type
|
|||||||
FSMeterPeak: Double; // верхняя граница светлой зоны
|
FSMeterPeak: Double; // верхняя граница светлой зоны
|
||||||
FSMeterMin: Double; // нижняя граница светлой зоны
|
FSMeterMin: Double; // нижняя граница светлой зоны
|
||||||
FSMeterAvg: Double; // сглаженное среднее (EMA)
|
FSMeterAvg: Double; // сглаженное среднее (EMA)
|
||||||
FRXPacketCount: LongWord; // счётчик принятых IQ пакетов
|
// RX/seq телеметрия переехала в TRadioController (пишется из OnDDCIQ).
|
||||||
FRXStartTime: QWord; // GetTickCount64 момента нажатия START
|
|
||||||
FRXLastPktTime: QWord; // GetTickCount64 последнего принятого пакета
|
|
||||||
FActiveDDC: Integer; // DDC index для текущей платы (0 или 2)
|
|
||||||
FLastDDCSeq: LongWord; // последний seq (пишется из сетевого потока)
|
|
||||||
FLastDDCIndex: Integer; // последний DDC index
|
|
||||||
FDDCLastSeq: array[0..6] of LongWord;
|
|
||||||
FDDCSeqValid: array[0..6] of Boolean;
|
|
||||||
FSeqErrorCount: LongWord;
|
|
||||||
FLastSeqErrorDDC: Integer;
|
|
||||||
FLastSeqErrorDelta: Int64;
|
|
||||||
FSeqOkStreak: Integer;
|
|
||||||
FLastFwdW: Double;
|
FLastFwdW: Double;
|
||||||
FLastSWR: Double;
|
FLastSWR: Double;
|
||||||
// Эти значения приходят с HP Status пакетами (50..200 раз/с). UI обновляется
|
// Эти значения приходят с HP Status пакетами (50..200 раз/с). UI обновляется
|
||||||
@@ -370,7 +359,6 @@ type
|
|||||||
// Network callbacks
|
// Network callbacks
|
||||||
procedure OnDeviceFound(const Dev: THPSDRDevice);
|
procedure OnDeviceFound(const Dev: THPSDRDevice);
|
||||||
procedure OnHPStatusCB(const Status: THighPriorityStatus);
|
procedure OnHPStatusCB(const Status: THighPriorityStatus);
|
||||||
procedure OnDDCIQCB(DDCIndex: Integer; const Data: TDDCIQPacket);
|
|
||||||
procedure OnWidebandCB(ADCIndex: Integer; const Samples: array of SmallInt;
|
procedure OnWidebandCB(ADCIndex: Integer; const Samples: array of SmallInt;
|
||||||
Count: Integer);
|
Count: Integer);
|
||||||
procedure OnWDSPOpenDone(Success: Boolean);
|
procedure OnWDSPOpenDone(Success: Boolean);
|
||||||
@@ -1068,16 +1056,16 @@ begin
|
|||||||
FSMeterPeak := -130;
|
FSMeterPeak := -130;
|
||||||
FSMeterMin := -130;
|
FSMeterMin := -130;
|
||||||
FSMeterAvg := -130;
|
FSMeterAvg := -130;
|
||||||
FRXPacketCount := 0;
|
FController.FRXPacketCount := 0;
|
||||||
FActiveDDC := 0;
|
FController.FActiveDDC := 0;
|
||||||
FLastDDCSeq := 0;
|
FController.FLastDDCSeq := 0;
|
||||||
FLastDDCIndex := 0;
|
FController.FLastDDCIndex := 0;
|
||||||
FillChar(FDDCLastSeq, SizeOf(FDDCLastSeq), 0);
|
FillChar(FController.FDDCLastSeq, SizeOf(FController.FDDCLastSeq), 0);
|
||||||
FillChar(FDDCSeqValid, SizeOf(FDDCSeqValid), 0);
|
FillChar(FController.FDDCSeqValid, SizeOf(FController.FDDCSeqValid), 0);
|
||||||
FSeqErrorCount := 0;
|
FController.FSeqErrorCount := 0;
|
||||||
FLastSeqErrorDDC := -1;
|
FController.FLastSeqErrorDDC := -1;
|
||||||
FLastSeqErrorDelta:= 0;
|
FController.FLastSeqErrorDelta:= 0;
|
||||||
FSeqOkStreak := 0;
|
FController.FSeqOkStreak := 0;
|
||||||
FLastFwdW := 0;
|
FLastFwdW := 0;
|
||||||
FLastSWR := 1;
|
FLastSWR := 1;
|
||||||
FLastSupplyV:= -1;
|
FLastSupplyV:= -1;
|
||||||
@@ -1155,7 +1143,7 @@ begin
|
|||||||
FController.CreateEngines(FController.FSampleRate);
|
FController.CreateEngines(FController.FSampleRate);
|
||||||
FController.FNetwork.OnDeviceFound := OnDeviceFound;
|
FController.FNetwork.OnDeviceFound := OnDeviceFound;
|
||||||
FController.FNetwork.OnHPStatus := OnHPStatusCB;
|
FController.FNetwork.OnHPStatus := OnHPStatusCB;
|
||||||
FController.FNetwork.OnDDCIQ := OnDDCIQCB;
|
FController.FNetwork.OnDDCIQ := FController.OnDDCIQ;
|
||||||
FController.FNetwork.OnMicPacket := FController.OnMicPacket;
|
FController.FNetwork.OnMicPacket := FController.OnMicPacket;
|
||||||
FController.FNetwork.OnWideband := OnWidebandCB;
|
FController.FNetwork.OnWideband := OnWidebandCB;
|
||||||
// Дефолты TX, Alex и XVTR (на случай если устройство ещё не выбрано).
|
// Дефолты TX, Alex и XVTR (на случай если устройство ещё не выбрано).
|
||||||
@@ -2699,11 +2687,11 @@ begin
|
|||||||
FSpecView.ADCOverloadVisible := False;
|
FSpecView.ADCOverloadVisible := False;
|
||||||
if PbSpectrum <> nil then
|
if PbSpectrum <> nil then
|
||||||
PbSpectrum.Invalidate;
|
PbSpectrum.Invalidate;
|
||||||
FillChar(FDDCSeqValid, SizeOf(FDDCSeqValid), 0);
|
FillChar(FController.FDDCSeqValid, SizeOf(FController.FDDCSeqValid), 0);
|
||||||
FSeqErrorCount := 0;
|
FController.FSeqErrorCount := 0;
|
||||||
FLastSeqErrorDDC := -1;
|
FController.FLastSeqErrorDDC := -1;
|
||||||
FLastSeqErrorDelta := 0;
|
FController.FLastSeqErrorDelta := 0;
|
||||||
FSeqOkStreak := 0;
|
FController.FSeqOkStreak := 0;
|
||||||
if ClearDevice then
|
if ClearDevice then
|
||||||
begin
|
begin
|
||||||
SetStatusText(0, 'Board --');
|
SetStatusText(0, 'Board --');
|
||||||
@@ -3054,9 +3042,9 @@ begin
|
|||||||
if FController.FRunning and FController.FNetwork.Running then
|
if FController.FRunning and FController.FNetwork.Running then
|
||||||
begin
|
begin
|
||||||
NowTick := GetTickCount64;
|
NowTick := GetTickCount64;
|
||||||
ElapsedTick := NowTick - FRXStartTime;
|
ElapsedTick := NowTick - FController.FRXStartTime;
|
||||||
// Ждём первый пакет 5 секунд после старта
|
// Ждём первый пакет 5 секунд после старта
|
||||||
if (FRXLastPktTime = 0) and (ElapsedTick > 5000) then
|
if (FController.FRXLastPktTime = 0) and (ElapsedTick > 5000) then
|
||||||
begin
|
begin
|
||||||
BtnStartStop.Caption := 'START';
|
BtnStartStop.Caption := 'START';
|
||||||
StyleButton(BtnStartStop, False);
|
StyleButton(BtnStartStop, False);
|
||||||
@@ -3068,7 +3056,7 @@ begin
|
|||||||
Exit;
|
Exit;
|
||||||
end;
|
end;
|
||||||
// После первого пакета — следим чтобы поток не прерывался более 3 сек
|
// После первого пакета — следим чтобы поток не прерывался более 3 сек
|
||||||
if (FRXLastPktTime > 0) and ((NowTick - FRXLastPktTime) > 3000) then
|
if (FController.FRXLastPktTime > 0) and ((NowTick - FController.FRXLastPktTime) > 3000) then
|
||||||
begin
|
begin
|
||||||
BtnStartStop.Caption := 'START';
|
BtnStartStop.Caption := 'START';
|
||||||
StyleButton(BtnStartStop, False);
|
StyleButton(BtnStartStop, False);
|
||||||
@@ -3085,8 +3073,8 @@ begin
|
|||||||
begin
|
begin
|
||||||
// Обновляем статус из таймера — без Synchronize в сетевом потоке.
|
// Обновляем статус из таймера — без Synchronize в сетевом потоке.
|
||||||
SetStatusText(4, 'RX running');
|
SetStatusText(4, 'RX running');
|
||||||
if FSeqErrorCount > 0 then
|
if FController.FSeqErrorCount > 0 then
|
||||||
SetStatusText(6, Format('SEQ ERR DDC%d', [FLastSeqErrorDDC]))
|
SetStatusText(6, Format('SEQ ERR DDC%d', [FController.FLastSeqErrorDDC]))
|
||||||
else
|
else
|
||||||
SetStatusText(6, 'SEQ OK');
|
SetStatusText(6, 'SEQ OK');
|
||||||
|
|
||||||
@@ -3229,8 +3217,8 @@ begin
|
|||||||
else
|
else
|
||||||
WebTXText := 'TX idle';
|
WebTXText := 'TX idle';
|
||||||
|
|
||||||
if FSeqErrorCount > 0 then
|
if FController.FSeqErrorCount > 0 then
|
||||||
WebSeqText := Format('SEQ ERR DDC%d', [FLastSeqErrorDDC])
|
WebSeqText := Format('SEQ ERR DDC%d', [FController.FLastSeqErrorDDC])
|
||||||
else if FController.FRunning then
|
else if FController.FRunning then
|
||||||
WebSeqText := 'SEQ OK'
|
WebSeqText := 'SEQ OK'
|
||||||
else
|
else
|
||||||
@@ -3490,66 +3478,6 @@ begin
|
|||||||
SetStatusText(3, 'Supply --');
|
SetStatusText(3, 'Supply --');
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TMainForm.OnDDCIQCB(DDCIndex: Integer; const Data: TDDCIQPacket);
|
|
||||||
var
|
|
||||||
SamplesPerFrame: Integer;
|
|
||||||
Seq, ExpectedSeq: LongWord;
|
|
||||||
Delta: Int64;
|
|
||||||
begin
|
|
||||||
// Вызывается из сетевого потока — UI не трогаем напрямую
|
|
||||||
|
|
||||||
// Счётчик принятых пакетов
|
|
||||||
Inc(FRXPacketCount);
|
|
||||||
FRXLastPktTime := GetTickCount64; // фиксируем время последнего пакета
|
|
||||||
Seq := (LongWord(Data.Seq[0]) shl 24) or (LongWord(Data.Seq[1]) shl 16)
|
|
||||||
or (LongWord(Data.Seq[2]) shl 8) or LongWord(Data.Seq[3]);
|
|
||||||
|
|
||||||
if (DDCIndex >= Low(FDDCLastSeq)) and (DDCIndex <= High(FDDCLastSeq)) then
|
|
||||||
begin
|
|
||||||
if Seq <> 0 then
|
|
||||||
begin
|
|
||||||
ExpectedSeq := FDDCLastSeq[DDCIndex] + 1;
|
|
||||||
if FDDCSeqValid[DDCIndex] and (Seq <> ExpectedSeq) then
|
|
||||||
begin
|
|
||||||
Inc(FSeqErrorCount);
|
|
||||||
FLastSeqErrorDDC := DDCIndex;
|
|
||||||
Delta := Int64(Seq) - Int64(ExpectedSeq);
|
|
||||||
FLastSeqErrorDelta := Delta;
|
|
||||||
FSeqOkStreak := 0;
|
|
||||||
end
|
|
||||||
else if FDDCSeqValid[DDCIndex] then
|
|
||||||
begin
|
|
||||||
if FSeqErrorCount > 0 then
|
|
||||||
begin
|
|
||||||
Inc(FSeqOkStreak);
|
|
||||||
if FSeqOkStreak >= 20 then
|
|
||||||
begin
|
|
||||||
FSeqErrorCount := 0;
|
|
||||||
FLastSeqErrorDDC := -1;
|
|
||||||
FLastSeqErrorDelta := 0;
|
|
||||||
FSeqOkStreak := 0;
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
FDDCLastSeq[DDCIndex] := Seq;
|
|
||||||
FDDCSeqValid[DDCIndex] := True;
|
|
||||||
end;
|
|
||||||
|
|
||||||
// 1. Подаём IQ данные в DSP — только с активного DDC
|
|
||||||
if (DDCIndex = FActiveDDC) and FController.FWDSPReady then
|
|
||||||
begin
|
|
||||||
SamplesPerFrame := (Integer(Data.SamplesPerFrame[0]) shl 8) or
|
|
||||||
Integer(Data.SamplesPerFrame[1]);
|
|
||||||
if SamplesPerFrame <= 0 then SamplesPerFrame := 238; // fallback
|
|
||||||
FController.FDSPEngine.PushDDCPacket(Data.IQData, 0, SamplesPerFrame);
|
|
||||||
end;
|
|
||||||
|
|
||||||
// 2. Запоминаем последний seq — статус обновит таймер (без Synchronize в горячем пути)
|
|
||||||
FLastDDCSeq := Seq;
|
|
||||||
FLastDDCIndex := DDCIndex;
|
|
||||||
end;
|
|
||||||
|
|
||||||
procedure TMainForm.OnWidebandCB(ADCIndex: Integer;
|
procedure TMainForm.OnWidebandCB(ADCIndex: Integer;
|
||||||
const Samples: array of SmallInt; Count: Integer);
|
const Samples: array of SmallInt; Count: Integer);
|
||||||
begin
|
begin
|
||||||
@@ -3888,8 +3816,8 @@ begin
|
|||||||
if FController.FWDSPReady then FController.FDSPEngine.SetTXRun(False);
|
if FController.FWDSPReady then FController.FDSPEngine.SetTXRun(False);
|
||||||
StyleButton(BtnMOX, False);
|
StyleButton(BtnMOX, False);
|
||||||
end;
|
end;
|
||||||
FRXPacketCount := 0;
|
FController.FRXPacketCount := 0;
|
||||||
FActiveDDC := 0;
|
FController.FActiveDDC := 0;
|
||||||
// Сохраняем текущую частоту/настройки чтобы следующий START восстановил их
|
// Сохраняем текущую частоту/настройки чтобы следующий START восстановил их
|
||||||
if FController.FDevConnected then
|
if FController.FDevConnected then
|
||||||
begin
|
begin
|
||||||
@@ -4187,9 +4115,9 @@ begin
|
|||||||
FController.FNetwork.ConfigureWideband(0, FShowWideband, 512, 16, 70, 32);
|
FController.FNetwork.ConfigureWideband(0, FShowWideband, 512, 16, 70, 32);
|
||||||
|
|
||||||
if FController.FNetwork.Device.BoardType in [3, 4, 5] then
|
if FController.FNetwork.Device.BoardType in [3, 4, 5] then
|
||||||
FActiveDDC := 2
|
FController.FActiveDDC := 2
|
||||||
else
|
else
|
||||||
FActiveDDC := 0;
|
FController.FActiveDDC := 0;
|
||||||
|
|
||||||
// Синхронизируем samplerate WDSP если нужно
|
// Синхронизируем samplerate WDSP если нужно
|
||||||
if FController.FWDSPReady and (FController.FDSPEngine.SampleRate <> FController.FSampleRate) then
|
if FController.FWDSPReady and (FController.FDSPEngine.SampleRate <> FController.FSampleRate) then
|
||||||
@@ -4218,14 +4146,14 @@ begin
|
|||||||
FController.FNetwork.SetRunAndFreq(True, XvtrTranslate(FController.FCenterFreq), XvtrTranslate(FController.FCenterFreq), FController.FDriveLevel);
|
FController.FNetwork.SetRunAndFreq(True, XvtrTranslate(FController.FCenterFreq), XvtrTranslate(FController.FCenterFreq), FController.FDriveLevel);
|
||||||
FController.FRunning := True;
|
FController.FRunning := True;
|
||||||
InhibitSleep;
|
InhibitSleep;
|
||||||
FRXStartTime := GetTickCount64;
|
FController.FRXStartTime := GetTickCount64;
|
||||||
FRXLastPktTime := 0;
|
FController.FRXLastPktTime := 0;
|
||||||
FRXPacketCount := 0;
|
FController.FRXPacketCount := 0;
|
||||||
FillChar(FDDCSeqValid, SizeOf(FDDCSeqValid), 0);
|
FillChar(FController.FDDCSeqValid, SizeOf(FController.FDDCSeqValid), 0);
|
||||||
FSeqErrorCount := 0;
|
FController.FSeqErrorCount := 0;
|
||||||
FLastSeqErrorDDC := -1;
|
FController.FLastSeqErrorDDC := -1;
|
||||||
FLastSeqErrorDelta := 0;
|
FController.FLastSeqErrorDelta := 0;
|
||||||
FSeqOkStreak := 0;
|
FController.FSeqOkStreak := 0;
|
||||||
SetStatusText(6, 'SEQ OK');
|
SetStatusText(6, 'SEQ OK');
|
||||||
|
|
||||||
// DDC и DUC Specific — теперь потоки эмулятора слушают на своих портах.
|
// DDC и DUC Specific — теперь потоки эмулятора слушают на своих портах.
|
||||||
|
|||||||
@@ -200,6 +200,20 @@ type
|
|||||||
FLastSMeter, FLastFwdW, FLastSWR, FLastSupplyV, FLastSupplyA: Double;
|
FLastSMeter, FLastFwdW, FLastSWR, FLastSupplyV, FLastSupplyA: Double;
|
||||||
FLastPLLLock: Boolean;
|
FLastPLLLock: Boolean;
|
||||||
|
|
||||||
|
// ---- RX/seq телеметрия data-path (пишется из сетевого колбэка OnDDCIQ) ----
|
||||||
|
FRXPacketCount: LongWord; // счётчик принятых IQ пакетов
|
||||||
|
FRXStartTime: QWord; // GetTickCount64 момента START
|
||||||
|
FRXLastPktTime: QWord; // GetTickCount64 последнего принятого пакета
|
||||||
|
FActiveDDC: Integer; // DDC index для текущей платы (0 или 2)
|
||||||
|
FLastDDCSeq: LongWord; // последний seq (из сетевого потока)
|
||||||
|
FLastDDCIndex: Integer; // последний DDC index
|
||||||
|
FDDCLastSeq: array[0..6] of LongWord;
|
||||||
|
FDDCSeqValid: array[0..6] of Boolean;
|
||||||
|
FSeqErrorCount: LongWord;
|
||||||
|
FLastSeqErrorDDC: Integer;
|
||||||
|
FLastSeqErrorDelta: Int64;
|
||||||
|
FSeqOkStreak: Integer;
|
||||||
|
|
||||||
constructor Create;
|
constructor Create;
|
||||||
destructor Destroy; override;
|
destructor Destroy; override;
|
||||||
|
|
||||||
@@ -215,6 +229,7 @@ type
|
|||||||
// вызывающим (GUI или демон) после CreateEngines.
|
// вызывающим (GUI или демон) после CreateEngines.
|
||||||
procedure OnMicPacket(const Data: TMicDataPacket);
|
procedure OnMicPacket(const Data: TMicDataPacket);
|
||||||
function PullSoundCardMic(MaxN: Integer): Integer;
|
function PullSoundCardMic(MaxN: Integer): Integer;
|
||||||
|
procedure OnDDCIQ(DDCIndex: Integer; const Data: TDDCIQPacket);
|
||||||
|
|
||||||
// Маршалинг команды в поток контроллера (GUI: TThread.Synchronize).
|
// Маршалинг команды в поток контроллера (GUI: TThread.Synchronize).
|
||||||
procedure Invoke(M: TThreadMethod);
|
procedure Invoke(M: TThreadMethod);
|
||||||
@@ -424,6 +439,66 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure TRadioController.OnDDCIQ(DDCIndex: Integer; const Data: TDDCIQPacket);
|
||||||
|
// Сетевой поток: трекинг seq + подача IQ активного DDC в WDSP. UI не трогаем —
|
||||||
|
// статус рисует таймер по полям ниже. Backend-агностичен (Pluto синтезирует
|
||||||
|
// тот же TDDCIQPacket).
|
||||||
|
var
|
||||||
|
SamplesPerFrame: Integer;
|
||||||
|
Seq, ExpectedSeq: LongWord;
|
||||||
|
Delta: Int64;
|
||||||
|
begin
|
||||||
|
Inc(FRXPacketCount);
|
||||||
|
FRXLastPktTime := GetTickCount64;
|
||||||
|
Seq := (LongWord(Data.Seq[0]) shl 24) or (LongWord(Data.Seq[1]) shl 16)
|
||||||
|
or (LongWord(Data.Seq[2]) shl 8) or LongWord(Data.Seq[3]);
|
||||||
|
|
||||||
|
if (DDCIndex >= Low(FDDCLastSeq)) and (DDCIndex <= High(FDDCLastSeq)) then
|
||||||
|
begin
|
||||||
|
if Seq <> 0 then
|
||||||
|
begin
|
||||||
|
ExpectedSeq := FDDCLastSeq[DDCIndex] + 1;
|
||||||
|
if FDDCSeqValid[DDCIndex] and (Seq <> ExpectedSeq) then
|
||||||
|
begin
|
||||||
|
Inc(FSeqErrorCount);
|
||||||
|
FLastSeqErrorDDC := DDCIndex;
|
||||||
|
Delta := Int64(Seq) - Int64(ExpectedSeq);
|
||||||
|
FLastSeqErrorDelta := Delta;
|
||||||
|
FSeqOkStreak := 0;
|
||||||
|
end
|
||||||
|
else if FDDCSeqValid[DDCIndex] then
|
||||||
|
begin
|
||||||
|
if FSeqErrorCount > 0 then
|
||||||
|
begin
|
||||||
|
Inc(FSeqOkStreak);
|
||||||
|
if FSeqOkStreak >= 20 then
|
||||||
|
begin
|
||||||
|
FSeqErrorCount := 0;
|
||||||
|
FLastSeqErrorDDC := -1;
|
||||||
|
FLastSeqErrorDelta := 0;
|
||||||
|
FSeqOkStreak := 0;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
FDDCLastSeq[DDCIndex] := Seq;
|
||||||
|
FDDCSeqValid[DDCIndex] := True;
|
||||||
|
end;
|
||||||
|
|
||||||
|
// Подаём IQ в DSP — только с активного DDC
|
||||||
|
if (DDCIndex = FActiveDDC) and FWDSPReady then
|
||||||
|
begin
|
||||||
|
SamplesPerFrame := (Integer(Data.SamplesPerFrame[0]) shl 8) or
|
||||||
|
Integer(Data.SamplesPerFrame[1]);
|
||||||
|
if SamplesPerFrame <= 0 then SamplesPerFrame := 238; // fallback
|
||||||
|
FDSPEngine.PushDDCPacket(Data.IQData, 0, SamplesPerFrame);
|
||||||
|
end;
|
||||||
|
|
||||||
|
// Запоминаем последний seq — статус обновит таймер (без Synchronize в hot path)
|
||||||
|
FLastDDCSeq := Seq;
|
||||||
|
FLastDDCIndex := DDCIndex;
|
||||||
|
end;
|
||||||
|
|
||||||
procedure TRadioController.OnMicPacket(const Data: TMicDataPacket);
|
procedure TRadioController.OnMicPacket(const Data: TMicDataPacket);
|
||||||
// HW mic-стрим уходит в WDSP только если выбран источник Radio; иначе сэмплы
|
// HW mic-стрим уходит в WDSP только если выбран источник Radio; иначе сэмплы
|
||||||
// игнорируются (mic берётся со звуковой карты).
|
// игнорируются (mic берётся со звуковой карты).
|
||||||
|
|||||||
Reference in New Issue
Block a user