Description
*(Possibly related to #97)
First off, this library is excellent! Using Track
instead of rodio's Sink
has been a major improvement for me. The ability to treat everything as Static and clone()able instead of stream-based makes integration smooth. Thanks for your work!
That said, the only major blocker for me is achieving true gapless playback and looping.
Current Approach to Gapless/Looping
I currently use a pattern where I:
- Loop in a thread and check if the current
StaticSoundHandle
state isPlaybackState::Stopped
. - When true, I play a new
StaticSoundData
on the track.
This gets close to gapless playback, but there is still an audible gap—even when pre-loading StaticSoundData
for the 'next file'. Increasing the monitoring loop frequency helps but introduces performance concerns.
I've also experimented with:
- Preloading the next
StaticSoundData
into a paused second track: This helps somewhat but also creates a more complex and harder-to-maintain pattern. - Using
set_loop_region()
: Works almost gapless for same-StaticSoundData looping, but even with perfectly loopable files, I still get slight pops compared to other software.
It's entirely possible I missed something. Have I?
A potential direction
I'm not sure this is a goal you're interested in. If it is, obviously events or mpsc would provide an elegant solution but would require more design choices and might still depend on polling frequency.
A simpler solution towards gapless might be to implement a system similar to rodio
/ playback_rs
, where the user can preload and manage a StaticSoundData
queue on a Track
(Even something basic like a pub VecDeque<StaticSoundData>
). If something is present in the queue, on sound-end, the Track (ResourceController
?) could then pop and continue playback immediately without the complexity and delays of messaging or user monitoring.
Do you feel like that would fit with your design?
Activity