diff --git a/src/audio/audio_decoder.cpp b/src/audio/audio_decoder.cpp index b0a973d9..02cf27e3 100644 --- a/src/audio/audio_decoder.cpp +++ b/src/audio/audio_decoder.cpp @@ -51,9 +51,10 @@ static constexpr std::size_t kCodecBufferLength = drivers::kI2SBufferLengthFrames * sizeof(sample::Sample); Timer::Timer(std::shared_ptr t, - const codecs::ICodec::OutputFormat& format) + const codecs::ICodec::OutputFormat& format, + uint32_t current_seconds) : track_(t), - current_seconds_(0), + current_seconds_(current_seconds), current_sample_in_second_(0), samples_per_second_(format.sample_rate_hz * format.num_channels), total_duration_seconds_(format.total_samples.value_or(0) / @@ -131,7 +132,7 @@ auto Decoder::BeginDecoding(std::shared_ptr stream) -> bool { return false; } - auto open_res = codec_->OpenStream(stream); + auto open_res = codec_->OpenStream(stream, stream->Offset()); if (open_res.has_error()) { ESP_LOGE(kTag, "codec failed to start: %s", codecs::ICodec::ErrorString(open_res.error()).c_str()); @@ -147,6 +148,7 @@ auto Decoder::BeginDecoding(std::shared_ptr stream) -> bool { ESP_LOGI(kTag, "stream started ok"); events::Audio().Dispatch(internal::InputFileOpened{}); + // TODO: How does this need to change? auto tags = std::make_shared(Track{ .tags = stream->tags(), .db_info = {}, @@ -155,7 +157,8 @@ auto Decoder::BeginDecoding(std::shared_ptr stream) -> bool { }); timer_.reset(new Timer(tags, open_res.value())); - PlaybackUpdate ev{.seconds_elapsed = 0, .track = tags}; + // TODO: How does *this?* need to change? + PlaybackUpdate ev{.seconds_elapsed = stream->Offset(), .track = tags}; events::Audio().Dispatch(ev); events::Ui().Dispatch(ev); diff --git a/src/audio/audio_fsm.cpp b/src/audio/audio_fsm.cpp index ba6e5ffe..c67cfc7a 100644 --- a/src/audio/audio_fsm.cpp +++ b/src/audio/audio_fsm.cpp @@ -244,11 +244,19 @@ void Uninitialised::react(const system_fsm::BootComplete& ev) { } void Standby::react(const PlayFile& ev) { - sFileSource->SetPath(ev.filename); + sFileSource->SetPath(ev.filename, 10); } void Playback::react(const PlayFile& ev) { - sFileSource->SetPath(ev.filename); + sFileSource->SetPath(ev.filename, 15); +} + +void Standby::react(const SeekFile& ev) { + sFileSource->SetPath(ev.filename, ev.offset); +} + +void Playback::react(const SeekFile& ev) { + sFileSource->SetPath(ev.filename, ev.offset); } void Standby::react(const internal::InputFileOpened& ev) { diff --git a/src/audio/audio_source.cpp b/src/audio/audio_source.cpp index 44de1d1b..2543db44 100644 --- a/src/audio/audio_source.cpp +++ b/src/audio/audio_source.cpp @@ -11,8 +11,9 @@ namespace audio { TaggedStream::TaggedStream(std::shared_ptr t, - std::unique_ptr w) - : codecs::IStream(w->type()), tags_(t), wrapped_(std::move(w)) {} + std::unique_ptr w, + uint32_t offset) + : codecs::IStream(w->type()), tags_(t), wrapped_(std::move(w)), offset_(offset) {} auto TaggedStream::tags() -> std::shared_ptr { return tags_; @@ -38,6 +39,10 @@ auto TaggedStream::Size() -> std::optional { return wrapped_->Size(); } +auto TaggedStream::Offset() -> uint32_t { + return offset_; +} + auto TaggedStream::SetPreambleFinished() -> void { wrapped_->SetPreambleFinished(); } diff --git a/src/audio/fatfs_audio_input.cpp b/src/audio/fatfs_audio_input.cpp index 7726a94a..665e8c1d 100644 --- a/src/audio/fatfs_audio_input.cpp +++ b/src/audio/fatfs_audio_input.cpp @@ -62,9 +62,9 @@ auto FatfsAudioInput::SetPath(std::optional path) -> void { } } -auto FatfsAudioInput::SetPath(const std::string& path) -> void { +auto FatfsAudioInput::SetPath(const std::string& path,uint32_t offset) -> void { std::lock_guard guard{new_stream_mutex_}; - if (OpenFile(path)) { + if (OpenFile(path, offset)) { has_new_stream_ = true; has_new_stream_.notify_one(); } @@ -103,7 +103,7 @@ auto FatfsAudioInput::NextStream() -> std::shared_ptr { } } -auto FatfsAudioInput::OpenFile(const std::string& path) -> bool { +auto FatfsAudioInput::OpenFile(const std::string& path,uint32_t offset) -> bool { ESP_LOGI(kTag, "opening file %s", path.c_str()); auto tags = tag_parser_.ReadAndParseTags(path); @@ -136,7 +136,7 @@ auto FatfsAudioInput::OpenFile(const std::string& path) -> bool { auto source = std::make_unique(stream_type.value(), std::move(file)); - new_stream_.reset(new TaggedStream(tags, std::move(source))); + new_stream_.reset(new TaggedStream(tags, std::move(source), offset)); return true; } diff --git a/src/audio/include/audio_decoder.hpp b/src/audio/include/audio_decoder.hpp index 318e6fd4..b8aac710 100644 --- a/src/audio/include/audio_decoder.hpp +++ b/src/audio/include/audio_decoder.hpp @@ -24,7 +24,7 @@ namespace audio { */ class Timer { public: - Timer(std::shared_ptr, const codecs::ICodec::OutputFormat& format); + Timer(std::shared_ptr, const codecs::ICodec::OutputFormat& format, uint32_t current_seconds = 0); auto AddSamples(std::size_t) -> void; diff --git a/src/audio/include/audio_events.hpp b/src/audio/include/audio_events.hpp index 03584062..8459333f 100644 --- a/src/audio/include/audio_events.hpp +++ b/src/audio/include/audio_events.hpp @@ -45,6 +45,11 @@ struct PlayFile : tinyfsm::Event { std::string filename; }; +struct SeekFile : tinyfsm::Event { + std::string filename; + uint32_t offset; +}; + struct StepUpVolume : tinyfsm::Event {}; struct StepDownVolume : tinyfsm::Event {}; struct SetVolume : tinyfsm::Event { diff --git a/src/audio/include/audio_fsm.hpp b/src/audio/include/audio_fsm.hpp index 29ec489a..71cd2701 100644 --- a/src/audio/include/audio_fsm.hpp +++ b/src/audio/include/audio_fsm.hpp @@ -57,6 +57,7 @@ class AudioState : public tinyfsm::Fsm { virtual void react(const system_fsm::BluetoothEvent&); virtual void react(const PlayFile&) {} + virtual void react(const SeekFile&) {} virtual void react(const QueueUpdate&) {} virtual void react(const PlaybackUpdate&) {} void react(const TogglePlayPause&); @@ -99,6 +100,7 @@ class Uninitialised : public AudioState { class Standby : public AudioState { public: void react(const PlayFile&) override; + void react(const SeekFile&) override; void react(const internal::InputFileOpened&) override; void react(const QueueUpdate&) override; void react(const system_fsm::KeyLockChanged&) override; @@ -115,6 +117,7 @@ class Playback : public AudioState { void react(const system_fsm::HasPhonesChanged&) override; void react(const PlayFile&) override; + void react(const SeekFile&) override; void react(const QueueUpdate&) override; void react(const PlaybackUpdate&) override; diff --git a/src/audio/include/audio_source.hpp b/src/audio/include/audio_source.hpp index 68145f5b..b2fd173d 100644 --- a/src/audio/include/audio_source.hpp +++ b/src/audio/include/audio_source.hpp @@ -16,7 +16,8 @@ namespace audio { class TaggedStream : public codecs::IStream { public: TaggedStream(std::shared_ptr, - std::unique_ptr wrapped); + std::unique_ptr wrapped, + uint32_t offset = 0); auto tags() -> std::shared_ptr; @@ -30,11 +31,14 @@ class TaggedStream : public codecs::IStream { auto Size() -> std::optional override; + auto Offset() -> uint32_t; + auto SetPreambleFinished() -> void override; private: std::shared_ptr tags_; std::unique_ptr wrapped_; + int32_t offset_; }; class IAudioSource { diff --git a/src/audio/include/fatfs_audio_input.hpp b/src/audio/include/fatfs_audio_input.hpp index 4cccbb46..10b7433e 100644 --- a/src/audio/include/fatfs_audio_input.hpp +++ b/src/audio/include/fatfs_audio_input.hpp @@ -39,7 +39,7 @@ class FatfsAudioInput : public IAudioSource { * given file path. */ auto SetPath(std::optional) -> void; - auto SetPath(const std::string&) -> void; + auto SetPath(const std::string&,uint32_t offset = 0) -> void; auto SetPath() -> void; auto HasNewStream() -> bool override; @@ -49,7 +49,7 @@ class FatfsAudioInput : public IAudioSource { FatfsAudioInput& operator=(const FatfsAudioInput&) = delete; private: - auto OpenFile(const std::string& path) -> bool; + auto OpenFile(const std::string& path,uint32_t offset) -> bool; auto ContainerToStreamType(database::Container) -> std::optional; diff --git a/src/codecs/include/codec.hpp b/src/codecs/include/codec.hpp index 8aa391b6..fb1ec771 100644 --- a/src/codecs/include/codec.hpp +++ b/src/codecs/include/codec.hpp @@ -117,7 +117,7 @@ class ICodec { * Decodes metadata or headers from the given input stream, and returns the * format for the samples that will be decoded from it. */ - virtual auto OpenStream(std::shared_ptr input) + virtual auto OpenStream(std::shared_ptr input,uint32_t offset) -> cpp::result = 0; struct OutputInfo { diff --git a/src/codecs/include/mad.hpp b/src/codecs/include/mad.hpp index 813aa86d..35e3284d 100644 --- a/src/codecs/include/mad.hpp +++ b/src/codecs/include/mad.hpp @@ -26,7 +26,7 @@ class MadMp3Decoder : public ICodec { MadMp3Decoder(); ~MadMp3Decoder(); - auto OpenStream(std::shared_ptr input) + auto OpenStream(std::shared_ptr input,uint32_t offset) -> cpp::result override; auto DecodeTo(cpp::span destination) diff --git a/src/codecs/include/miniflac.hpp b/src/codecs/include/miniflac.hpp index d57b08a3..d1daca2f 100644 --- a/src/codecs/include/miniflac.hpp +++ b/src/codecs/include/miniflac.hpp @@ -28,7 +28,7 @@ class MiniFlacDecoder : public ICodec { MiniFlacDecoder(); ~MiniFlacDecoder(); - auto OpenStream(std::shared_ptr input) + auto OpenStream(std::shared_ptr input,uint32_t offset) -> cpp::result override; auto DecodeTo(cpp::span destination) diff --git a/src/codecs/include/opus.hpp b/src/codecs/include/opus.hpp index 45b1b07a..1431fa54 100644 --- a/src/codecs/include/opus.hpp +++ b/src/codecs/include/opus.hpp @@ -26,7 +26,7 @@ class XiphOpusDecoder : public ICodec { XiphOpusDecoder(); ~XiphOpusDecoder(); - auto OpenStream(std::shared_ptr input) + auto OpenStream(std::shared_ptr input,uint32_t offset) -> cpp::result override; auto DecodeTo(cpp::span destination) diff --git a/src/codecs/include/vorbis.hpp b/src/codecs/include/vorbis.hpp index 2f93c37e..b32ef8d5 100644 --- a/src/codecs/include/vorbis.hpp +++ b/src/codecs/include/vorbis.hpp @@ -28,7 +28,7 @@ class TremorVorbisDecoder : public ICodec { TremorVorbisDecoder(); ~TremorVorbisDecoder(); - auto OpenStream(std::shared_ptr input) + auto OpenStream(std::shared_ptr input,uint32_t offset) -> cpp::result override; auto DecodeTo(cpp::span destination) diff --git a/src/codecs/include/wav.hpp b/src/codecs/include/wav.hpp index 896976dd..e884a9bb 100644 --- a/src/codecs/include/wav.hpp +++ b/src/codecs/include/wav.hpp @@ -31,7 +31,7 @@ class WavDecoder : public ICodec { WavDecoder(); ~WavDecoder(); - auto OpenStream(std::shared_ptr input) + auto OpenStream(std::shared_ptr input,uint32_t offset) -> cpp::result override; auto DecodeTo(cpp::span destination) diff --git a/src/codecs/mad.cpp b/src/codecs/mad.cpp index f36636a1..0617295f 100644 --- a/src/codecs/mad.cpp +++ b/src/codecs/mad.cpp @@ -58,7 +58,7 @@ auto MadMp3Decoder::GetBytesUsed() -> std::size_t { } } -auto MadMp3Decoder::OpenStream(std::shared_ptr input) +auto MadMp3Decoder::OpenStream(std::shared_ptr input,uint32_t offset) -> cpp::result { input_ = input; diff --git a/src/codecs/miniflac.cpp b/src/codecs/miniflac.cpp index ace73466..d15410fe 100644 --- a/src/codecs/miniflac.cpp +++ b/src/codecs/miniflac.cpp @@ -42,7 +42,7 @@ MiniFlacDecoder::~MiniFlacDecoder() { } } -auto MiniFlacDecoder::OpenStream(std::shared_ptr input) +auto MiniFlacDecoder::OpenStream(std::shared_ptr input,uint32_t offset) -> cpp::result { input_ = input; diff --git a/src/codecs/opus.cpp b/src/codecs/opus.cpp index e4917a33..2f700510 100644 --- a/src/codecs/opus.cpp +++ b/src/codecs/opus.cpp @@ -78,7 +78,7 @@ XiphOpusDecoder::~XiphOpusDecoder() { } } -auto XiphOpusDecoder::OpenStream(std::shared_ptr input) +auto XiphOpusDecoder::OpenStream(std::shared_ptr input,uint32_t offset) -> cpp::result { input_ = input; diff --git a/src/codecs/vorbis.cpp b/src/codecs/vorbis.cpp index 3b3798cb..66237c28 100644 --- a/src/codecs/vorbis.cpp +++ b/src/codecs/vorbis.cpp @@ -84,7 +84,7 @@ TremorVorbisDecoder::~TremorVorbisDecoder() { ov_clear(&vorbis_); } -auto TremorVorbisDecoder::OpenStream(std::shared_ptr input) +auto TremorVorbisDecoder::OpenStream(std::shared_ptr input,uint32_t offset) -> cpp::result { int res = ov_open_callbacks(input.get(), &vorbis_, NULL, 0, kCallbacks); if (res < 0) { diff --git a/src/codecs/wav.cpp b/src/codecs/wav.cpp index a67f3ff4..652f4f88 100644 --- a/src/codecs/wav.cpp +++ b/src/codecs/wav.cpp @@ -84,7 +84,7 @@ WavDecoder::WavDecoder() : input_(), buffer_() {} WavDecoder::~WavDecoder() {} -auto WavDecoder::OpenStream(std::shared_ptr input) +auto WavDecoder::OpenStream(std::shared_ptr input,uint32_t offset) -> cpp::result { input_ = input; @@ -199,8 +199,10 @@ auto WavDecoder::OpenStream(std::shared_ptr input) return cpp::fail(Error::kUnsupportedFormat); } + auto data_offset = offset * samples_per_second * bits_per_sample; + // Seek track to start of data - input->SeekTo(data_chunk_index + 8, IStream::SeekFrom::kStartOfStream); + input->SeekTo(data_chunk_index + 8 + data_offset, IStream::SeekFrom::kStartOfStream); output_format_ = {.num_channels = (uint8_t)num_channels_, .sample_rate_hz = samples_per_second,