fix(desktop): keep the huddle playout tick on schedule on Windows - #5973
Open
kaalph wants to merge 1 commit into
Open
fix(desktop): keep the huddle playout tick on schedule on Windows#5973kaalph wants to merge 1 commit into
kaalph wants to merge 1 commit into
Conversation
The 10 ms playout tick uses MissedTickBehavior::Delay, which never shortens the ticks that follow a missed one. Windows timers default to a 15.6 ms resolution and tokio intervals fire ~14.6 ms late there on average (tokio-rs/tokio#5021), so the loop settles at ~62 of the 100 pulls/s the pipeline needs. The per-peer rodio queues run dry (audible gaps, dropped words) while NetEq stays full and time-compresses playback (metallic, sped-up voices) - on every peer, regardless of network quality. Matches the choppy-audio reports in block#2652; block#4281 changed the drop threshold but not the tick rate. Measured on Windows 11 with a standalone reproduction of this loop: 62.4 ticks/s with Delay at default resolution, 100.2 ticks/s with timeBeginPeriod(1) raised for the loop lifetime and Burst making up missed ticks. Catch-up bursts are absorbed by the existing queue recovery (hysteresis 10-4, emergency trim at 30). Signed-off-by: kaalph <alexsanker@hotmail.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Huddle audio on my Windows 11 box was constantly choppy — metallic voices, dropped words, every call, every peer. Sounded exactly like the reports in #2652. Network was my first suspect and it was a dead end: I measured the incoming frame stream over ten minutes and got p99 inter-frame gap of 22 ms with zero losses. So the frames arrive fine and something eats them locally.
Root cause is the 10 ms playout tick in
run_playout_recv_loop. It usesMissedTickBehavior::Delay, andDelaynever shortens the ticks that follow a missed one. Windows timers default to a 15.6 ms resolution, and tokio intervals fire ~14.6 ms late there on average (tokio-rs/tokio#5021). Put those together and the loop settles at ~62 pulls per second instead of 100. The per-peer rodio queues run dry and the mixer plays silence gaps, while NetEq sits at its 200 ms cap and time-compresses playback forever — that's the robot voice. #4281 later moved the drop threshold to speed recovery, but the tick rate itself never changed, which would be why the reports kept coming.To verify I wrote a small standalone program with exactly this interval setup and ran it on Windows 11 (IoT LTSC 2024): 62.4 ticks/s with
Delayat default resolution, 100.2 ticks/s withtimeBeginPeriod(1)active andBurst. The machine dependence falls out of this too — any other process can raise the global timer resolution, so some machines never show the bug.The fix does two things:
timeEndPeriod). Gated behind#[cfg(windows)], so other platforms are untouched.Burst, so missed ticks are made up instead of silently lost. The short catch-up bursts stay bounded by the queue recovery that's already there (hysteresis 10→4, emergency trim at 30).We've been running this in real calls since yesterday and the audio is clean — no gaps, no acceleration, and I couldn't hear any regression. I haven't exercised macOS or Linux beyond the fact that the resolution guard doesn't compile there and
Burstonly changes behavior when ticks are actually missed.The
unsafeblocks are the twowinmmFFI calls; there was no way around them that I could find, and the desktop crate already does OS-level FFI the same way inmouse_nav.rsandshutdown.rs.