From 39f7545cd5ef7a30bbd482f3579df7744c6b688d Mon Sep 17 00:00:00 2001 From: jacqueline Date: Fri, 7 Jul 2023 15:29:47 +1000 Subject: wire up the playing screen with some real data Includes implementing song duration calculation for CBR MP3 files --- src/audio/audio_fsm.cpp | 82 +++++++++++++++++++++++++++---------------------- 1 file changed, 45 insertions(+), 37 deletions(-) (limited to 'src/audio/audio_fsm.cpp') diff --git a/src/audio/audio_fsm.cpp b/src/audio/audio_fsm.cpp index 805dffc4..ef33d583 100644 --- a/src/audio/audio_fsm.cpp +++ b/src/audio/audio_fsm.cpp @@ -19,6 +19,7 @@ #include "pipeline.hpp" #include "system_events.hpp" #include "track.hpp" +#include "track_queue.hpp" namespace audio { @@ -32,11 +33,13 @@ std::unique_ptr AudioState::sFileSource; std::unique_ptr AudioState::sI2SOutput; std::vector> AudioState::sPipeline; -std::deque AudioState::sTrackQueue; +TrackQueue* AudioState::sTrackQueue; auto AudioState::Init(drivers::IGpios* gpio_expander, - std::weak_ptr database) -> bool { + std::weak_ptr database, + TrackQueue* queue) -> bool { sIGpios = gpio_expander; + sTrackQueue = queue; auto dac = drivers::I2SDac::create(gpio_expander); if (!dac) { @@ -94,26 +97,23 @@ void Uninitialised::react(const system_fsm::BootComplete&) { transit(); } -void Standby::react(const InputFileOpened& ev) { +void Standby::react(const internal::InputFileOpened& ev) { transit(); } -void Standby::react(const PlayTrack& ev) { +void Standby::react(const QueueUpdate& ev) { + auto current_track = sTrackQueue->GetCurrent(); + if (!current_track) { + return; + } + auto db = sDatabase.lock(); if (!db) { ESP_LOGW(kTag, "database not open; ignoring play request"); return; } - if (ev.data) { - sFileSource->OpenFile(ev.data->filepath()); - } else { - sFileSource->OpenFile(db->GetTrackPath(ev.id)); - } -} - -void Standby::react(const PlayFile& ev) { - sFileSource->OpenFile(ev.filename); + sFileSource->OpenFile(db->GetTrackPath(*current_track)); } void Playback::entry() { @@ -126,42 +126,50 @@ void Playback::exit() { sI2SOutput->SetInUse(false); } -void Playback::react(const PlayTrack& ev) { - sTrackQueue.push_back(EnqueuedItem(ev.id)); -} +void Playback::react(const QueueUpdate& ev) { + auto current_track = sTrackQueue->GetCurrent(); + if (!current_track) { + // TODO: return to standby? + return; + } -void Playback::react(const PlayFile& ev) { - sTrackQueue.push_back(EnqueuedItem(ev.filename)); + auto db = sDatabase.lock(); + if (!db) { + return; + } + + // TODO: what if we just finished this, and are preemptively loading the next + // one? + sFileSource->OpenFile(db->GetTrackPath(*current_track)); } void Playback::react(const PlaybackUpdate& ev) { - ESP_LOGI(kTag, "elapsed: %lu", ev.seconds_elapsed); + // ESP_LOGI(kTag, "elapsed: %lu, total: %lu", ev.seconds_elapsed, + // ev.seconds_total); } -void Playback::react(const InputFileOpened& ev) {} +void Playback::react(const internal::InputFileOpened& ev) {} -void Playback::react(const InputFileFinished& ev) { - ESP_LOGI(kTag, "finished file"); - if (sTrackQueue.empty()) { +void Playback::react(const internal::InputFileClosed& ev) { + ESP_LOGI(kTag, "finished reading file"); + auto upcoming = sTrackQueue->GetUpcoming(1); + if (upcoming.empty()) { return; } - EnqueuedItem next_item = sTrackQueue.front(); - sTrackQueue.pop_front(); - - if (std::holds_alternative(next_item)) { - sFileSource->OpenFile(std::get(next_item)); - } else if (std::holds_alternative(next_item)) { - auto db = sDatabase.lock(); - if (!db) { - ESP_LOGW(kTag, "database not open; ignoring play request"); - return; - } - sFileSource->OpenFile( - db->GetTrackPath(std::get(next_item))); + auto db = sDatabase.lock(); + if (!db) { + return; } + ESP_LOGI(kTag, "preemptively opening next file"); + sFileSource->OpenFile(db->GetTrackPath(upcoming.front())); +} + +void Playback::react(const internal::InputFileFinished& ev) { + ESP_LOGI(kTag, "finished playing file"); + sTrackQueue->Next(); } -void Playback::react(const AudioPipelineIdle& ev) { +void Playback::react(const internal::AudioPipelineIdle& ev) { transit(); } -- cgit v1.2.3