Fix unwanted catch-up when joining mid-stream playback#246
Merged
Conversation
A near-now scheduled start with a converged time filter is a real mid-stream join, not the `now + 500ms` fallback in `compute_play_time`. Require the clock to be unsynced before suspecting fallback.
Contributor
There was a problem hiding this comment.
Pull request overview
This PR adjusts early-start detection in the audio playback pipeline so that joining a server mid-stream (with a synchronized clock) no longer gets misclassified as an unsynchronized compute_play_time fallback, which previously suppressed frame-drop catch-up and could leave persistent audio lag.
Changes:
- Add an
is_clock_syncedcallback toAudioPlayerto distinguish “real near-now start” vs “unsynced fallback near-now start”. - Gate
_early_start_suspecton both “near-now scheduled start” and “clock not synced”. - Thread the clock-sync callback from
SendspinClientthroughAudioStreamHandler→_AudioSyncWorker→AudioPlayer.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| sendspin/audio.py | Adds a clock-sync signal and uses it to refine early-start fallback detection so catch-up suppression only happens when unsynced. |
| sendspin/audio_connector.py | Plumbs the clock-sync callback from the client into the audio worker and AudioPlayer construction. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
5 tasks
trudenboy
added a commit
to trudenboy/sendspin-bt-bridge
that referenced
this pull request
May 8, 2026
Upstream rolled two minors with material fixes for our flows: 7.2.0 (PR Sendspin/sendspin-cli#240, #241): - Better PulseAudio / PipeWire integration and audio device discovery - Fixed an ALSA device leak 7.3.0 (PR Sendspin/sendspin-cli#246, #245, #244, #247): - Fixed unwanted catch-up when joining mid-stream playback — the bridge rejoins streams routinely (after BT reconnect, after warm_restart from /api/config saves, after standby exit), so this was a recurring source of audible artifacts at the start of speaker resumes. - Fixed wrong audio sync delta after a server-driven delay change — matters because MA pushes per-player static_delay_ms (we advertise set_static_delay since v2.68.0), and a slider drag in MA produced a brief glitch from the bad delta. - Aligned stream/clear and stream/end with the protocol spec (drops role versions). - Bumped aiosendspin to 5.2 — already on our side via #271. No breaking changes between 7.1.0 and 7.3.0; the 7.0.0 per-player delay break is already absorbed (see CHANGELOG 2.68.0). Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.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.
Joining a server that is already playing schedules a near-now start.
_early_start_suspectflagged that the same way as the unsyncednow + 500msfallback incompute_play_time, suppressing frame-drop catch-up and leaving audio with a constant lag offset.It's a workaround for now. Root cause is
compute_play_timesilently returning a fallback that we cannot distinguish from a real timestamp. Proper fix will follow.