mirror of
https://git.vladimir.cc/vladimir/ewsdr.git
synced 2026-08-25 18:43:51 +00:00
Fix TX mic hoarseness: pre-roll flush bug and wider stall margin
Pre-roll bug: when MIC_PREROLL_SAMP is an exact multiple of OPUS_FRAME_SAMP (1920/960=2), the N<=Want branch filled the buffer but never flushed it, losing the first 40ms of audio and leaving the ring empty long enough for silence blocks to be injected into WDSP. StallCount threshold raised from 2 to 4 (~43ms) to cover OS scheduler jitter of up to 22ms, preventing false silence injection when an Opus frame arrives slightly late relative to the DSP tick. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
+18
-1
@@ -562,12 +562,14 @@ var
|
||||
PeriodUs: Integer;
|
||||
AccUs: Integer;
|
||||
DidBlock: Boolean;
|
||||
StallCount: Integer;
|
||||
begin
|
||||
// 512 samples / 48000 Hz = 10.666 ms. Do not floor this to 10 ms:
|
||||
// that over-produces TX IQ by ~6.7%, eventually forcing DUC queue
|
||||
// corrections/drops and producing periodic sidebands on a pure TUN tone.
|
||||
PeriodUs := Max(1000, FEngine.FAudioBufSize * 1000000 div FEngine.FAudioRate);
|
||||
AccUs := 0;
|
||||
StallCount := 0;
|
||||
|
||||
while not Terminated do
|
||||
begin
|
||||
@@ -616,8 +618,23 @@ begin
|
||||
// лишний TX-блок тишины вместо ожидания полного 512-sample блока.
|
||||
Avail := (FEngine.FTXMicHead - FEngine.FTXMicTail + TX_MIC_RING)
|
||||
and (TX_MIC_RING - 1);
|
||||
if (not DidBlock) and (Avail = 0) then
|
||||
// Тишину генерируем только после 4 подряд пустых тиков (~43 ms).
|
||||
// Порог 43 ms даёт 22 ms запаса относительно периода Opus-фрейма (20 ms),
|
||||
// что покрывает джиттер планировщика ОС (~10 ms) и сетевой джиттер.
|
||||
// При реальной потере пакета тишина всё равно инжектируется.
|
||||
if not DidBlock then
|
||||
begin
|
||||
if Avail = 0 then
|
||||
begin
|
||||
Inc(StallCount);
|
||||
if StallCount >= 4 then
|
||||
FEngine.ProcessTXBlock;
|
||||
end
|
||||
else
|
||||
StallCount := 0;
|
||||
end
|
||||
else
|
||||
StallCount := 0;
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
+3
-1
@@ -603,9 +603,11 @@ begin
|
||||
Want := MIC_PREROLL_SAMP - FMicPreRollPos;
|
||||
if N <= Want then
|
||||
begin
|
||||
// Pre-roll ещё не набран: просто копим
|
||||
Move(P^, FMicPreRoll[FMicPreRollPos], N * SizeOf(Single));
|
||||
Inc(FMicPreRollPos, N);
|
||||
// N = Want точно заполняет pre-roll — надо слить (иначе буфер потерян)
|
||||
if FMicPreRollPos = MIC_PREROLL_SAMP then
|
||||
FlushMicToCallback(@FMicPreRoll[0], MIC_PREROLL_SAMP);
|
||||
end
|
||||
else
|
||||
begin
|
||||
|
||||
Reference in New Issue
Block a user