You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
rodio backend: pause drains the queued buffer, delaying the audio and PlayerEvent::Paused by up to ~0.5s #1835
With rodio-backend, Player::pause() takes up to about half a second to take
effect: the audio keeps playing for that long, and PlayerEvent::Paused is only
emitted afterwards. Resuming is immediate, so pausing feels noticeably slower than
playing.
sleep_until_end() waits until everything already appended to the sink has
played. handle_pause calls ensure_sink_stopped(false)before it sends the
event:
handle_play is the other way round — it sends Playingbefore it touches
the sink — which is why resuming does not pay the same cost.
The upper bound is the queue depth, which RodioSink::write caps:
// Chunk sizes seem to be about 256 to 3000 ish items long.// Assuming they're on average 1628 then a half second buffer is:// 44100 elements --> about 27 chunkswhileself.rodio_sink.len() > 26{
thread::sleep(Duration::from_millis(10));}
So sleep_until_end() waits for up to ~27 chunks, roughly half a second of
already-decoded audio.
Why it matters
Any client that reflects pause state from PlayerEvent::Paused shows it late, and
the listener hears up to half a second of audio after pressing pause. The other
backends do not have this shape: alsa::stop and pulseaudio::stop call drain(), which is bounded by the device buffer rather than by everything the
decoder has queued ahead.
Suggested direction
A pause does not need the sink closed. rodio_sink.pause() returns immediately and
keeps the queue, and a later start() (play()) continues from where it stopped.
Either:
give the sink a suspended state that handle_pause uses instead of ensure_sink_stopped, or
have RodioSink::stop stop the audio first and not block on the queue.
Draining plays out what is already buffered so that nothing is cut mid-packet,
which is presumably the intent — but pause() does not lose those samples either,
it keeps them queued. So pausing first, and not draining, is both immediate and
lossless.
Reproducing
cargo run --features rodio-backend --example play -- <track uri>
Press pause while a track is playing: the audio stops and Paused arrives about
half a second later. Resume is immediate.
Activity