Skip to content

Fix vdsd speaker audio pacing drift#4

Merged
LordVicky merged 1 commit into
mainfrom
fix-speaker-audio
Jul 8, 2026
Merged

Fix vdsd speaker audio pacing drift#4
LordVicky merged 1 commit into
mainfrom
fix-speaker-audio

Conversation

@LordVicky

Copy link
Copy Markdown
Owner

Problem

DS5 controller speaker crackled/dropped. The field log showed vdsd dropping ~1000 BT 0x36 packets per minute — all queue-overflow drops (blocked=0). Each 0x36 packet carries a 10 ms Opus speaker frame, so every drop is an audible gap.

Root cause

flush_pending_audio_chunk set the next send deadline to now + 10ms, where now was sampled after the epoll wait. Scheduler + processing jitter accumulated every cycle, so the effective send cadence fell just below the 100 Hz the controller consumes at 48 kHz, and the 8-slot pending queue overflowed continuously.

Fix

Advance the deadline from the previous deadline (prev + interval) so the long-run cadence stays exactly 100 Hz, with a bounded catch-up: fresh deadlines or ones more than kMaxAudioCatchup (50 ms) behind resync to now + interval rather than replaying stale audio. Deadline math covered by a standalone test (drift-free across jittery wakeups, catch-up, resync guard).

Result

Overflow drops fell from ~1000/min to ~0; clearly audible improvement.

Not fully fixed

A residual periodic crackle remains that this does not resolve — investigation and evidence tracked in #3 (leading theory: Bluetooth-transport / MediaTek adapter bound, not host-side).

The Linux speaker/haptics sender computed each 0x36 send deadline as
now + 10ms, where now was sampled after the epoll wait. Wakeup and
processing jitter therefore accumulated on every cycle, so the effective
send cadence fell below the 100 Hz the controller consumes at 48 kHz.
The pending-audio queue overflowed continuously (~1000 dropped 0x36
packets/min in the field log), and each dropped packet is a lost 10 ms
Opus speaker frame -> audible crackle.

Advance the deadline from the previous deadline (prev + interval) so the
long-run cadence stays exactly 100 Hz and a backlog drains back-to-back
until caught up. A fresh deadline or one that has fallen more than
kMaxAudioCatchup (50ms) behind resyncs to now + interval instead of
replaying stale audio.
@LordVicky
LordVicky merged commit 0d86053 into main Jul 8, 2026
@LordVicky
LordVicky deleted the fix-speaker-audio branch July 9, 2026 16:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant