docs: record the jitter buffer's unreachable shrink path as a known bug
CI / check (push) Canceled after 0s
CI / check (push) Canceled after 0s
`target_delay` grows +1 per disruption to MAX_DELAY_FRAMES (240 ms) but only shrinks after 250 consecutive clean frames — 5 s of unbroken audio. Two of the five `clean_run` resets fire on every natural pause in speech (jitter.rs:201 benign underrun, jitter.rs:181 re-prime), and the sender stops transmitting outright while the gate is closed (core/mod.rs:2041). The AIMD decrease half is therefore unreachable under conversational voice: one early jitter burst pins the extra latency for the rest of the session. Found by code review; not yet reproduced live. Pairs with field-test debt #5. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -137,6 +137,35 @@ covers internals). When you ship a feature, add it here.
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
## Known bugs
|
||||||
|
|
||||||
|
Defects found by code review, not yet fixed.
|
||||||
|
|
||||||
|
1. **Adaptive playout delay never shrinks back in real conversation**
|
||||||
|
(`src/core/jitter.rs`) — `target_delay` grows +1 per disruption up to
|
||||||
|
`MAX_DELAY_FRAMES` (12 frames = 240 ms) but only shrinks after
|
||||||
|
`CLEAN_RUN_TO_SHRINK` = 250 consecutive cleanly-played frames, i.e. **5 s of
|
||||||
|
unbroken audio**. `clean_run` is reset in five places; two of them fire on
|
||||||
|
every natural pause in speech: the benign-underrun branch (`jitter.rs:201`,
|
||||||
|
talker went quiet) and the subsequent re-prime (`jitter.rs:181`). Because the
|
||||||
|
sender skips transmitting entirely while the noise gate is closed
|
||||||
|
(`src/core/mod.rs:2041`), a pause between sentences *always* underruns the
|
||||||
|
receiver and zeroes the clean run — twice.
|
||||||
|
|
||||||
|
Net effect: the controller is a one-way ratchet. A single burst of jitter
|
||||||
|
early in a call pins up to 240 ms of extra playout latency for the rest of
|
||||||
|
the session, because no conversational speaker talks for 5 continuous
|
||||||
|
seconds without the gate closing. The AIMD "decrease" half is effectively
|
||||||
|
unreachable under the workload the app is built for.
|
||||||
|
|
||||||
|
Likely fix: let `clean_run` survive a benign idle→re-prime transition rather
|
||||||
|
than resetting it. Silence is not evidence the link is bad, so it should not
|
||||||
|
count against the clean run. Distinguish "talker stopped" (benign) from
|
||||||
|
"playout broke" (real) at `jitter.rs:195-202`.
|
||||||
|
|
||||||
|
Found 2026-07-31 by code review. Not yet reproduced in a live call — pairs
|
||||||
|
with field-test debt item 5 below.
|
||||||
|
|
||||||
## Known field-test debt (the 🧪 rows above, collected)
|
## Known field-test debt (the 🧪 rows above, collected)
|
||||||
|
|
||||||
Re-run on a real desktop ↔ dopedart call before calling these done:
|
Re-run on a real desktop ↔ dopedart call before calling these done:
|
||||||
|
|||||||
Reference in New Issue
Block a user