From 222c810b07ffc635fc7908d121e97e4d65ccc5c8 Mon Sep 17 00:00:00 2001 From: jacqueline Date: Fri, 2 Dec 2022 13:39:00 +1100 Subject: fix build errors --- src/audio/audio_decoder.cpp | 70 +++++++++++++++++++++++++++++++++------------ 1 file changed, 51 insertions(+), 19 deletions(-) (limited to 'src/audio/audio_decoder.cpp') diff --git a/src/audio/audio_decoder.cpp b/src/audio/audio_decoder.cpp index 02217187..a19fd5bf 100644 --- a/src/audio/audio_decoder.cpp +++ b/src/audio/audio_decoder.cpp @@ -1,29 +1,41 @@ #include "audio_decoder.hpp" + #include + #include #include -#include "chunk.hpp" + +#include "freertos/FreeRTOS.h" + #include "esp_heap_caps.h" +#include "freertos/message_buffer.h" #include "freertos/portmacro.h" -#include "include/audio_element.hpp" -#include "include/fatfs_audio_input.hpp" + +#include "audio_element.hpp" +#include "chunk.hpp" +#include "fatfs_audio_input.hpp" + +static const char* kTag = "DEC"; namespace audio { AudioDecoder::AudioDecoder() : IAudioElement(), - chunk_buffer_(heap_caps_malloc(kMaxChunkSize, MALLOC_CAP_SPIRAM)), - stream_info_({}) {} + stream_info_({}), + chunk_buffer_(static_cast( + heap_caps_malloc(kMaxChunkSize, MALLOC_CAP_SPIRAM))) + +{} AudioDecoder::~AudioDecoder() { free(chunk_buffer_); } -auto AudioDecoder::SetInputBuffer(StreamBufferHandle_t* buffer) -> void { +auto AudioDecoder::SetInputBuffer(MessageBufferHandle_t* buffer) -> void { input_buffer_ = buffer; } -auto AudioDecoder::SetOutputBuffer(StreamBufferHandle_t* buffer) -> void { +auto AudioDecoder::SetOutputBuffer(MessageBufferHandle_t* buffer) -> void { output_buffer_ = buffer; } @@ -34,12 +46,12 @@ auto AudioDecoder::ProcessStreamInfo(StreamInfo&& info) // Reuse the existing codec if we can. This will help with gapless playback, // since we can potentially just continue to decode as we were before, // without any setup overhead. - if (current_codec_->CanHandleFile(info.path)) { + if (current_codec_->CanHandleFile(info.Path().value_or(""))) { current_codec_->ResetForNewStream(); return {}; } - auto result = codecs::CreateCodecForFile(info.path); + auto result = codecs::CreateCodecForFile(info.Path().value()); if (result.has_value()) { current_codec_ = std::move(result.value()); } else { @@ -57,26 +69,46 @@ auto AudioDecoder::ProcessChunk(uint8_t* data, std::size_t length) } current_codec_->SetInput(data, length); - cpp::result result; + + bool has_samples_to_send = false; + bool needs_more_input = false; + std::optional error = std::nullopt; WriteChunksToStream( - output_buffer_, working_buffer_, kWorkingBufferSize, - [&](uint8_t* buf, size_t len) { - result = current_codec_->Process(data, length, buf, len); - if (result.has_error()) { - // End our output stream immediately if the codec barfed. - return 0; + output_buffer_, chunk_buffer_, kMaxChunkSize, + [&](uint8_t* buf, size_t len) -> std::size_t { + std::size_t bytes_written = 0; + // Continue filling up the output buffer so long as we have samples + // leftover, or are able to synthesize more samples from the input. + while (has_samples_to_send || !needs_more_input) { + if (!has_samples_to_send) { + auto result = current_codec_->ProcessNextFrame(); + has_samples_to_send = true; + if (result.has_error()) { + error = result.error(); + // End our output stream immediately if the codec barfed. + return 0; + } else { + needs_more_input = result.value(); + } + } else { + auto result = current_codec_->WriteOutputSamples( + buf + bytes_written, len - bytes_written); + bytes_written += result.first; + has_samples_to_send = !result.second; + } } - return result.value(); + return bytes_written; }, // This element doesn't support any kind of out of band commands, so we // can just suspend the whole task if the output buffer fills up. portMAX_DELAY); - if (result.has_error()) { + if (error) { + ESP_LOGE(kTag, "Codec encountered error %d", error.value()); return cpp::fail(IO_ERROR); } - return current_codec_->GetOutputProcessed(); + return current_codec_->GetInputPosition(); } auto AudioDecoder::ProcessIdle() -> cpp::result { -- cgit v1.2.3