fix(voice): advance RTP timestamp across silence gaps#1695
Open
Stieneee wants to merge 1 commit intobwmarrin:masterfrom
Open
fix(voice): advance RTP timestamp across silence gaps#1695Stieneee wants to merge 1 commit intobwmarrin:masterfrom
Stieneee wants to merge 1 commit intobwmarrin:masterfrom
Conversation
…er buffer growth
The opusSender loop blocks on the opus channel waiting for data.
During silence, no data arrives and the RTP timestamp freezes because
it only increments when a packet is actually sent. When speech resumes,
the first packet carries a timestamp that implies it was generated
20ms after the last packet — but seconds or minutes may have passed.
Receivers (e.g. Discord) interpret this as an extremely late packet and
may grow their adaptive jitter buffer. Over many speaking/silence
cycles (typical in voice chat), this causes audio playout delay to
accumulate monotonically. In our voice bridging application we observed
Mumble-to-Discord latency growing to 2+ seconds after approximately
one hour of use with frequent speaking pauses. After this change, audio
latency remained consistent with no observable growth over extended
sessions.
Fix: measure how long we blocked waiting for opus data. If it exceeds
40ms (2× the normal 20ms send interval), treat it as a silence gap:
1. Advance the RTP timestamp by the gap duration (rounded to frame
boundary) so it stays aligned with wall-clock time.
2. Set the RTP marker bit (RFC 3551) on the first post-silence
packet to signal a new "talk-spurt", allowing the receiver to
reset its jitter buffer timing.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
9 tasks
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.
Summary
Problem
opusSenderblocks on the opus channel while waiting for audio data. During silence the ticker fires and drops ticks, but the RTP timestamp only advances when a packet is actually sent (by+960per 20ms frame). After a silence gap the next packet carries a timestamp that is far behind wall-clock time, making the receiver believe it arrived extremely late.Over many speaking/silence cycles the receiver's adaptive jitter buffer grows monotonically. In our voice bridging application we observed Mumble-to-Discord latency growing to 2+ seconds after approximately one hour of use with frequent speaking pauses. After this change, audio latency remained consistent with no observable growth over extended sessions.
Changes
When
opusSenderreceives opus data after blocking for longer than 40ms (2x frame size):timestampby that amount0x80) on the RTP header to signal the start of a new talk-spurtTest plan
go test -race)