From 62f6179abe24339c2e5b7350528afbcad4c52067 Mon Sep 17 00:00:00 2001 From: ailurux Date: Thu, 15 Feb 2024 16:12:07 +1100 Subject: Added offset for track seeking, wav impl. only rn --- src/audio/audio_decoder.cpp | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) (limited to 'src/audio/audio_decoder.cpp') 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); -- cgit v1.2.3 From a49d754da6c293445be16ac643d10849c01ea96b Mon Sep 17 00:00:00 2001 From: ailurux Date: Fri, 16 Feb 2024 10:57:47 +1100 Subject: Seeking working with hardcoded event, wav only --- src/audio/audio_decoder.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/audio/audio_decoder.cpp') diff --git a/src/audio/audio_decoder.cpp b/src/audio/audio_decoder.cpp index 02cf27e3..eaa9ff9c 100644 --- a/src/audio/audio_decoder.cpp +++ b/src/audio/audio_decoder.cpp @@ -155,7 +155,7 @@ auto Decoder::BeginDecoding(std::shared_ptr stream) -> bool { .bitrate_kbps = open_res->sample_rate_hz, .encoding = stream->type(), }); - timer_.reset(new Timer(tags, open_res.value())); + timer_.reset(new Timer(tags, open_res.value(), stream->Offset())); // TODO: How does *this?* need to change? PlaybackUpdate ev{.seconds_elapsed = stream->Offset(), .track = tags}; -- cgit v1.2.3 From 665679b8854d34c13d8eb92167aa8a4691619d8b Mon Sep 17 00:00:00 2001 From: ailurux Date: Fri, 16 Feb 2024 12:55:11 +1100 Subject: WIP: seeking in lua example --- src/audio/audio_decoder.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'src/audio/audio_decoder.cpp') diff --git a/src/audio/audio_decoder.cpp b/src/audio/audio_decoder.cpp index eaa9ff9c..68a8a86b 100644 --- a/src/audio/audio_decoder.cpp +++ b/src/audio/audio_decoder.cpp @@ -148,16 +148,15 @@ 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 = {}, .bitrate_kbps = open_res->sample_rate_hz, .encoding = stream->type(), + .filepath = stream->Filepath(), }); timer_.reset(new Timer(tags, open_res.value(), stream->Offset())); - // TODO: How does *this?* need to change? PlaybackUpdate ev{.seconds_elapsed = stream->Offset(), .track = tags}; events::Audio().Dispatch(ev); events::Ui().Dispatch(ev); -- cgit v1.2.3 From f54347794f45261e0c0fde1104a70d1063c77305 Mon Sep 17 00:00:00 2001 From: ailurux Date: Thu, 22 Feb 2024 14:37:14 +1100 Subject: WIP: Flac not working-- coming back to this later --- src/audio/audio_decoder.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'src/audio/audio_decoder.cpp') diff --git a/src/audio/audio_decoder.cpp b/src/audio/audio_decoder.cpp index 68a8a86b..6c26dec8 100644 --- a/src/audio/audio_decoder.cpp +++ b/src/audio/audio_decoder.cpp @@ -167,6 +167,7 @@ auto Decoder::BeginDecoding(std::shared_ptr stream) -> bool { auto Decoder::ContinueDecoding() -> bool { auto res = codec_->DecodeTo(codec_buffer_); if (res.has_error()) { + ESP_LOGI(kTag, "RAN INTO DECODING ERROR"); return true; } -- cgit v1.2.3 From 77145e56f4062cd060ee7fa0af9ad1a2e46df5b1 Mon Sep 17 00:00:00 2001 From: jacqueline Date: Wed, 28 Feb 2024 21:21:23 +1100 Subject: basic working flac and mp3 seeking flac impl is fairly slow as it doesn't use the seek tables; for some reason miniflac seems to get *really* upset if you seek the stream. --- src/audio/audio_decoder.cpp | 1 - 1 file changed, 1 deletion(-) (limited to 'src/audio/audio_decoder.cpp') diff --git a/src/audio/audio_decoder.cpp b/src/audio/audio_decoder.cpp index 6c26dec8..68a8a86b 100644 --- a/src/audio/audio_decoder.cpp +++ b/src/audio/audio_decoder.cpp @@ -167,7 +167,6 @@ auto Decoder::BeginDecoding(std::shared_ptr stream) -> bool { auto Decoder::ContinueDecoding() -> bool { auto res = codec_->DecodeTo(codec_buffer_); if (res.has_error()) { - ESP_LOGI(kTag, "RAN INTO DECODING ERROR"); return true; } -- cgit v1.2.3 From 175bfc4e3e9f7aa39e084d3f1625347f1d5711ec Mon Sep 17 00:00:00 2001 From: jacqueline Date: Mon, 25 Mar 2024 17:34:41 +1100 Subject: WIP rewrie audio pipeline+fsm guts for more reliability --- src/audio/audio_decoder.cpp | 78 +++++++++++++-------------------------------- 1 file changed, 22 insertions(+), 56 deletions(-) (limited to 'src/audio/audio_decoder.cpp') diff --git a/src/audio/audio_decoder.cpp b/src/audio/audio_decoder.cpp index 68a8a86b..55ebc0ec 100644 --- a/src/audio/audio_decoder.cpp +++ b/src/audio/audio_decoder.cpp @@ -5,6 +5,7 @@ */ #include "audio_decoder.hpp" +#include #include #include @@ -50,39 +51,6 @@ namespace audio { static constexpr std::size_t kCodecBufferLength = drivers::kI2SBufferLengthFrames * sizeof(sample::Sample); -Timer::Timer(std::shared_ptr t, - const codecs::ICodec::OutputFormat& format, - uint32_t current_seconds) - : track_(t), - 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) / - format.num_channels / format.sample_rate_hz) { - track_->duration = total_duration_seconds_; -} - -auto Timer::AddSamples(std::size_t samples) -> void { - bool incremented = false; - current_sample_in_second_ += samples; - while (current_sample_in_second_ >= samples_per_second_) { - current_seconds_++; - current_sample_in_second_ -= samples_per_second_; - incremented = true; - } - - if (incremented) { - if (total_duration_seconds_ < current_seconds_) { - total_duration_seconds_ = current_seconds_; - track_->duration = total_duration_seconds_; - } - - PlaybackUpdate ev{.seconds_elapsed = current_seconds_, .track = track_}; - events::Audio().Dispatch(ev); - events::Ui().Dispatch(ev); - } -} - auto Decoder::Start(std::shared_ptr source, std::shared_ptr sink) -> Decoder* { Decoder* task = new Decoder(source, sink); @@ -92,11 +60,7 @@ auto Decoder::Start(std::shared_ptr source, Decoder::Decoder(std::shared_ptr source, std::shared_ptr mixer) - : source_(source), - converter_(mixer), - codec_(), - timer_(), - current_format_() { + : source_(source), converter_(mixer), codec_(), current_format_() { ESP_LOGI(kTag, "allocating codec buffer, %u KiB", kCodecBufferLength / 1024); codec_buffer_ = { reinterpret_cast(heap_caps_calloc( @@ -117,7 +81,6 @@ void Decoder::Main() { } if (ContinueDecoding()) { - events::Audio().Dispatch(internal::InputFileFinished{}); stream_.reset(); } } @@ -129,6 +92,7 @@ auto Decoder::BeginDecoding(std::shared_ptr stream) -> bool { codec_.reset(codecs::CreateCodecForType(stream->type()).value_or(nullptr)); if (!codec_) { ESP_LOGE(kTag, "no codec found"); + events::Audio().Dispatch(internal::DecoderError{}); return false; } @@ -136,6 +100,7 @@ auto Decoder::BeginDecoding(std::shared_ptr stream) -> bool { if (open_res.has_error()) { ESP_LOGE(kTag, "codec failed to start: %s", codecs::ICodec::ErrorString(open_res.error()).c_str()); + events::Audio().Dispatch(internal::DecoderError{}); return false; } stream->SetPreambleFinished(); @@ -146,20 +111,23 @@ auto Decoder::BeginDecoding(std::shared_ptr stream) -> bool { }; ESP_LOGI(kTag, "stream started ok"); - events::Audio().Dispatch(internal::InputFileOpened{}); - - auto tags = std::make_shared(Track{ - .tags = stream->tags(), - .db_info = {}, - .bitrate_kbps = open_res->sample_rate_hz, - .encoding = stream->type(), - .filepath = stream->Filepath(), - }); - timer_.reset(new Timer(tags, open_res.value(), stream->Offset())); - PlaybackUpdate ev{.seconds_elapsed = stream->Offset(), .track = tags}; - events::Audio().Dispatch(ev); - events::Ui().Dispatch(ev); + std::optional duration; + if (open_res->total_samples) { + duration = open_res->total_samples.value() / open_res->num_channels / + open_res->sample_rate_hz; + } + + events::Audio().Dispatch(internal::DecoderOpened{ + .track = std::make_shared(TrackInfo{ + .tags = stream->tags(), + .uri = stream->Filepath(), + .duration = duration, + .start_offset = stream->Offset(), + .bitrate_kbps = open_res->sample_rate_hz, + .encoding = stream->type(), + }), + }); return true; } @@ -167,6 +135,7 @@ auto Decoder::BeginDecoding(std::shared_ptr stream) -> bool { auto Decoder::ContinueDecoding() -> bool { auto res = codec_->DecodeTo(codec_buffer_); if (res.has_error()) { + events::Audio().Dispatch(internal::DecoderError{}); return true; } @@ -176,11 +145,8 @@ auto Decoder::ContinueDecoding() -> bool { res->is_stream_finished); } - if (timer_) { - timer_->AddSamples(res->samples_written); - } - if (res->is_stream_finished) { + events::Audio().Dispatch(internal::DecoderClosed{}); codec_.reset(); } -- cgit v1.2.3 From 078b77d0f796be3c787f62b9b830512e38d3b076 Mon Sep 17 00:00:00 2001 From: jacqueline Date: Tue, 26 Mar 2024 12:12:42 +1100 Subject: pass stream start/update/end events through the whole pipeline --- src/audio/audio_decoder.cpp | 34 +++++++++++++--------------------- 1 file changed, 13 insertions(+), 21 deletions(-) (limited to 'src/audio/audio_decoder.cpp') diff --git a/src/audio/audio_decoder.cpp b/src/audio/audio_decoder.cpp index 55ebc0ec..90c69c16 100644 --- a/src/audio/audio_decoder.cpp +++ b/src/audio/audio_decoder.cpp @@ -72,7 +72,6 @@ void Decoder::Main() { for (;;) { if (source_->HasNewStream() || !stream_) { std::shared_ptr new_stream = source_->NextStream(); - ESP_LOGI(kTag, "decoder has new stream"); if (new_stream && BeginDecoding(new_stream)) { stream_ = new_stream; } else { @@ -91,8 +90,7 @@ auto Decoder::BeginDecoding(std::shared_ptr stream) -> bool { codec_.reset(); codec_.reset(codecs::CreateCodecForType(stream->type()).value_or(nullptr)); if (!codec_) { - ESP_LOGE(kTag, "no codec found"); - events::Audio().Dispatch(internal::DecoderError{}); + ESP_LOGE(kTag, "no codec found for stream"); return false; } @@ -100,7 +98,6 @@ auto Decoder::BeginDecoding(std::shared_ptr stream) -> bool { if (open_res.has_error()) { ESP_LOGE(kTag, "codec failed to start: %s", codecs::ICodec::ErrorString(open_res.error()).c_str()); - events::Audio().Dispatch(internal::DecoderError{}); return false; } stream->SetPreambleFinished(); @@ -110,24 +107,21 @@ auto Decoder::BeginDecoding(std::shared_ptr stream) -> bool { .bits_per_sample = 16, }; - ESP_LOGI(kTag, "stream started ok"); - std::optional duration; if (open_res->total_samples) { duration = open_res->total_samples.value() / open_res->num_channels / open_res->sample_rate_hz; } - events::Audio().Dispatch(internal::DecoderOpened{ - .track = std::make_shared(TrackInfo{ - .tags = stream->tags(), - .uri = stream->Filepath(), - .duration = duration, - .start_offset = stream->Offset(), - .bitrate_kbps = open_res->sample_rate_hz, - .encoding = stream->type(), - }), - }); + converter_->beginStream(std::make_shared(TrackInfo{ + .tags = stream->tags(), + .uri = stream->Filepath(), + .duration = duration, + .start_offset = stream->Offset(), + .bitrate_kbps = open_res->sample_rate_hz, + .encoding = stream->type(), + .format = *current_sink_format_, + })); return true; } @@ -135,18 +129,16 @@ auto Decoder::BeginDecoding(std::shared_ptr stream) -> bool { auto Decoder::ContinueDecoding() -> bool { auto res = codec_->DecodeTo(codec_buffer_); if (res.has_error()) { - events::Audio().Dispatch(internal::DecoderError{}); + converter_->endStream(); return true; } if (res->samples_written > 0) { - converter_->ConvertSamples(codec_buffer_.first(res->samples_written), - current_sink_format_.value(), - res->is_stream_finished); + converter_->continueStream(codec_buffer_.first(res->samples_written)); } if (res->is_stream_finished) { - events::Audio().Dispatch(internal::DecoderClosed{}); + converter_->endStream(); codec_.reset(); } -- cgit v1.2.3