diff --git a/src/tangara/audio/audio_fsm.cpp b/src/tangara/audio/audio_fsm.cpp index a7c006f5..71f41938 100644 --- a/src/tangara/audio/audio_fsm.cpp +++ b/src/tangara/audio/audio_fsm.cpp @@ -191,6 +191,11 @@ void AudioState::react(const internal::StreamStarted& ev) { if (!sIsPaused && !is_in_state()) { transit(); + } else { + // Make sure everyone knows we've got a track ready to go, even if we're + // not playing it yet. This mostly matters when restoring the queue from + // disk after booting. + emitPlaybackUpdate(true); } } @@ -485,12 +490,13 @@ void Playback::react(const system_fsm::SdStateChanged& ev) { void Playback::react(const internal::StreamHeartbeat& ev) { sStreamCues.update(sOutput->samplesUsed()); - auto current = sStreamCues.current(); - if (!current.first) { - transit(); - } else { + if (sStreamCues.hasStream()) { emitPlaybackUpdate(false); + } else { + // Finished the current stream, and there's nothing upcoming. We must be + // finished. + transit(); } } diff --git a/src/tangara/audio/stream_cues.cpp b/src/tangara/audio/stream_cues.cpp index 0161fbf4..7a6a1426 100644 --- a/src/tangara/audio/stream_cues.cpp +++ b/src/tangara/audio/stream_cues.cpp @@ -32,10 +32,14 @@ auto StreamCues::update(uint32_t sample) -> void { auto StreamCues::addCue(std::shared_ptr track, uint32_t sample) -> void { - upcoming_.push_back(Cue{ - .track = track, - .start_at = sample, - }); + if (sample == now_) { + current_ = {track, now_}; + } else { + upcoming_.push_back(Cue{ + .track = track, + .start_at = sample, + }); + } } auto StreamCues::current() -> std::pair, uint32_t> { @@ -54,4 +58,8 @@ auto StreamCues::current() -> std::pair, uint32_t> { return {current_->track, duration}; } +auto StreamCues::hasStream() -> bool { + return current_ || !upcoming_.empty(); +} + } // namespace audio diff --git a/src/tangara/audio/stream_cues.hpp b/src/tangara/audio/stream_cues.hpp index f55865b7..cd0782b0 100644 --- a/src/tangara/audio/stream_cues.hpp +++ b/src/tangara/audio/stream_cues.hpp @@ -26,9 +26,12 @@ class StreamCues { /* Updates the current track given the new most recently played sample. */ auto update(uint32_t sample) -> void; + /* Returns the current track, and how long it has been playing for. */ auto current() -> std::pair, uint32_t>; + auto hasStream() -> bool; + auto addCue(std::shared_ptr, uint32_t start_at) -> void; private: