From 485eed28903a0bc23df9c1ced1417e35fd58c43c Mon Sep 17 00:00:00 2001 From: jacqueline Date: Mon, 31 Jul 2023 09:41:49 +1000 Subject: [PATCH] use libtag duration where available --- src/app_console/app_console.cpp | 6 +----- src/audio/audio_fsm.cpp | 7 +++++++ src/audio/audio_task.cpp | 14 ++++++++++++-- src/audio/fatfs_audio_input.cpp | 3 +++ src/audio/include/audio_events.hpp | 4 ++++ src/audio/include/audio_fsm.hpp | 2 ++ src/audio/include/audio_task.hpp | 2 ++ src/audio/include/stream_info.hpp | 8 ++++++++ 8 files changed, 39 insertions(+), 7 deletions(-) diff --git a/src/app_console/app_console.cpp b/src/app_console/app_console.cpp index 3e2d8067..6faa27d0 100644 --- a/src/app_console/app_console.cpp +++ b/src/app_console/app_console.cpp @@ -112,17 +112,13 @@ int CmdPlayFile(int argc, char** argv) { database::TrackId id = std::atoi(argv[1]); AppConsole::sTrackQueue->AddLast(id); } else { - // TODO. - /* std::ostringstream path; path << '/' << argv[1]; for (int i = 2; i < argc; i++) { path << ' ' << argv[i]; } - events::Dispatch( - audio::PlayFile{.filename = path.str()}); - */ + events::Audio().Dispatch(audio::PlayFile{.filename = path.str()}); } return 0; diff --git a/src/audio/audio_fsm.cpp b/src/audio/audio_fsm.cpp index fc263351..79080c9a 100644 --- a/src/audio/audio_fsm.cpp +++ b/src/audio/audio_fsm.cpp @@ -93,6 +93,10 @@ void Uninitialised::react(const system_fsm::BootComplete&) { transit(); } +void Standby::react(const PlayFile& ev) { + sFileSource->SetPath(ev.filename); +} + void Standby::react(const internal::InputFileOpened& ev) { transit(); } @@ -161,6 +165,9 @@ void Playback::react(const internal::InputFileClosed& ev) {} void Playback::react(const internal::InputFileFinished& ev) { ESP_LOGI(kTag, "finished playing file"); sTrackQueue->Next(); + if (!sTrackQueue->GetCurrent()) { + transit(); + } } void Playback::react(const internal::AudioPipelineIdle& ev) { diff --git a/src/audio/audio_task.cpp b/src/audio/audio_task.cpp index ca6a3824..4fad3114 100644 --- a/src/audio/audio_task.cpp +++ b/src/audio/audio_task.cpp @@ -61,10 +61,12 @@ Timer::Timer(StreamInfo::Pcm format) auto Timer::SetLengthSeconds(uint32_t len) -> void { total_duration_seconds_ = len; + has_duration_ = true; } auto Timer::SetLengthBytes(uint32_t len) -> void { total_duration_seconds_ = bytes_to_samples(len) / format_.sample_rate; + has_duration_ = true; } auto Timer::AddBytes(std::size_t bytes) -> void { @@ -135,8 +137,14 @@ void AudioTask::Main() { if (ForwardPcmStream(*pcm, stream.data())) { stream.consume(stream.data().size_bytes()); } - timer_->SetLengthBytes( - stream.info().total_length_bytes().value_or(0)); + if (!timer_->has_duration()) { + if (stream.info().total_length_seconds()) { + timer_->SetLengthSeconds(*stream.info().total_length_seconds()); + } else { + timer_->SetLengthBytes( + stream.info().total_length_bytes().value_or(0)); + } + } return; } @@ -233,6 +241,8 @@ auto AudioTask::BeginDecoding(InputStream& stream) -> bool { if (format.duration_seconds) { timer_->SetLengthSeconds(*format.duration_seconds); + } else if (stream.info().total_length_seconds()) { + timer_->SetLengthSeconds(*stream.info().total_length_seconds()); } else { timer_->SetLengthBytes(stream.info().total_length_bytes().value_or(0)); } diff --git a/src/audio/fatfs_audio_input.cpp b/src/audio/fatfs_audio_input.cpp index 07474fd7..b1d4108a 100644 --- a/src/audio/fatfs_audio_input.cpp +++ b/src/audio/fatfs_audio_input.cpp @@ -283,6 +283,9 @@ auto FatfsAudioInput::OpenFile(const std::string& path) -> void { OutputStream writer{input_buffer_.get()}; writer.prepare(format, info.fsize); + if (tags.duration) { + writer.info().total_length_seconds() = *tags.duration; + } streamer_->Restart(std::move(file)); is_first_read_ = true; diff --git a/src/audio/include/audio_events.hpp b/src/audio/include/audio_events.hpp index 933eb7a2..9c945f33 100644 --- a/src/audio/include/audio_events.hpp +++ b/src/audio/include/audio_events.hpp @@ -30,6 +30,10 @@ struct QueueUpdate : tinyfsm::Event { bool current_changed; }; +struct PlayFile : tinyfsm::Event { + std::string filename; +}; + struct VolumeChanged : tinyfsm::Event {}; namespace internal { diff --git a/src/audio/include/audio_fsm.hpp b/src/audio/include/audio_fsm.hpp index 3a598902..cc3dae0e 100644 --- a/src/audio/include/audio_fsm.hpp +++ b/src/audio/include/audio_fsm.hpp @@ -51,6 +51,7 @@ class AudioState : public tinyfsm::Fsm { virtual void react(const system_fsm::BootComplete&) {} + virtual void react(const PlayFile&) {} virtual void react(const QueueUpdate&) {} virtual void react(const PlaybackUpdate&) {} @@ -82,6 +83,7 @@ class Uninitialised : public AudioState { class Standby : public AudioState { public: + void react(const PlayFile&) override; void react(const internal::InputFileOpened&) override; void react(const QueueUpdate&) override; diff --git a/src/audio/include/audio_task.hpp b/src/audio/include/audio_task.hpp index ae4c2221..72732021 100644 --- a/src/audio/include/audio_task.hpp +++ b/src/audio/include/audio_task.hpp @@ -26,6 +26,7 @@ class Timer { auto SetLengthBytes(uint32_t) -> void; auto AddBytes(std::size_t) -> void; + auto has_duration() const -> bool { return has_duration_; } private: auto bytes_to_samples(uint32_t) -> uint32_t; @@ -35,6 +36,7 @@ class Timer { uint32_t current_seconds_; uint32_t current_sample_in_second_; + bool has_duration_; uint32_t total_duration_seconds_; }; diff --git a/src/audio/include/stream_info.hpp b/src/audio/include/stream_info.hpp index 77789c24..d48c39a8 100644 --- a/src/audio/include/stream_info.hpp +++ b/src/audio/include/stream_info.hpp @@ -42,6 +42,13 @@ class StreamInfo { return total_length_bytes_; } + auto total_length_seconds() -> std::optional& { + return total_length_seconds_; + } + auto total_length_seconds() const -> std::optional { + return total_length_seconds_; + } + struct Encoded { // The codec that this stream is associated with. codecs::StreamType type; @@ -77,6 +84,7 @@ class StreamInfo { private: std::size_t bytes_in_stream_; std::optional total_length_bytes_; + std::optional total_length_seconds_; Format format_{}; };