W12 follow-up: consume in-band FEC, drop redundant DTX

Fixes the two P2 efficacy findings from the Codex audit of the W12
profiles feature.

FEC was enabled on the encoder but never used: the jitter buffer's
loss path did pure PLC, so the redundancy was wasted bitrate. Now the
gap path reconstructs the lost frame from the next buffered packet via
Opus in-band FEC (new `AudioDecoder::decode_fec`, libopus decode with
fec=true into a one-frame buffer), keeping that packet for its own
normal decode and falling back to PLC if FEC decode fails. This is the
documented libopus FEC pattern; receiver-side only, no wire change.

DTX was enabled on BadNetwork but provided no benefit — the capture
noise gate already suppresses silence transmission, and the broadcast
DTX silence packets only created seq gaps that grew the jitter cushion.
All profiles now set dtx=false (plumbing kept for a future revisit).

Adds a jitter-buffer test proving FEC reconstruction beats pure PLC
(RMS error < 0.75x) and that the FEC source packet stays buffered.
500 lib tests, clippy + fmt clean, release build clean.

Co-Authored-By: Codex (gpt-5.5) <noreply@openai.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-06-30 16:56:19 -04:00
co-authored by Codex Claude Opus 4.8
parent d92d0f6f6b
commit 5f52aa1506
5 changed files with 116 additions and 12 deletions
+1 -1
View File
@@ -3139,7 +3139,7 @@ fn audio_profile_hint(profile: AudioProfile) -> &'static str {
}
AudioProfile::Balanced => "Default: voice quality with light loss recovery.",
AudioProfile::BadNetwork => {
"Most resilient on a lossy/congested link: extra loss recovery, lower bitrate."
"Most resilient on a lossy/congested link: heavier loss recovery, lower bitrate."
}
}
}