Repository navigation
fix(audio): keep stream open on clear() so DACs hold lock across pause - #303
Closed
kiwipaulrob wants to merge 1 commit into
Closed
kiwipaulrob wants to merge 1 commit into
kiwipaulrob wants to merge 1 commit into
Conversation
kiwipaulrob
force-pushed
the
fix/keep-stream-open-on-clear
branch
from
October 25, 2026 20:15
c239b81 to
f5f0418
Compare
Pause arrives as stream/end, which ran close_stream() and fully closed the PortAudio stream; resume then recreated it via set_format(). Each close/open drops USB lock, clicking muting relays on XMOS-based DACs (verified live: the click survives full digital silence, so no server-side mute or fade can suppress it). clear() and close_stream() now drain the queue but leave the stream running - the callback already renders silence while starved - and set_format() skips recreating the stream when the format is unchanged. The device releases on stop() (shutdown) and on real format changes only.
kiwipaulrob
force-pushed
the
fix/keep-stream-open-on-clear
branch
from
October 25, 2026 20:15
f5f0418 to
74416f1
Compare
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.
Problem
Pausing (or seeking/skipping) makes USB DACs with lock-loss muting relays click audibly on every transition. Pause arrives as
stream/end, which ranclose_stream()and fully closed the PortAudio stream; resume then recreated it viaset_format(). Each close/open drops USB lock and the relay ticks. No server-side mute or fade can suppress a hardware relay: I verified live against an SMSL USB DAC on a moOde Raspberry Pi that the click sounds identical through full digital silence.Evidence
AudioPlayer.clear()submittedstream.stopto release the device on pause;close_stream()went further and fully closed it;set_format()unconditionally closed and recreated the stream even for an identical format./proc/asoundPCM state) confirmed the device FD closes on pause with the released code.Fix
clear()andclose_stream()now drain the queue but leave the stream running. The callback already renders silence while starved (_read_input_frames_bulkpads with zeros), so the device stays open at zero audible cost.set_format()skips the close/recreate cycle when the incoming format equals the current one (dataclass equality), so resume on the same format is a no-op and music continues on the held-open stream.stop()(daemon shutdown) andset_format()on a real format change.Known cosmetic trade-off, disclosed: while paused with the stream held open, DAC-derived playback position keeps advancing (silence still ticks the clock). It resyncs on resume. Happy to freeze the cursor too if preferred - kept out to hold this change minimal and out of the callback hot path.
Verification
clear()andclose_stream()drain without stopping/closing (queue empty,_stream_startedtrue, same stream object, zero stop/close calls);set_format()with an identical format keeps the existing stream untouched.ruff format --check,ruff check,mypy sendspinall clean.Types of changes
bugfix