diff --git a/src/audio/CMakeLists.txt b/src/audio/CMakeLists.txt index 34fcd8ee..6361f827 100644 --- a/src/audio/CMakeLists.txt +++ b/src/audio/CMakeLists.txt @@ -1,7 +1,7 @@ idf_component_register( SRCS "audio_decoder.cpp" "audio_task.cpp" "chunk.cpp" "fatfs_audio_input.cpp" "stream_message.cpp" "i2s_audio_output.cpp" "stream_buffer.cpp" - "audio_playback.cpp" "stream_event.cpp" "pipeline.cpp" + "audio_playback.cpp" "stream_event.cpp" "pipeline.cpp" "stream_info.cpp" INCLUDE_DIRS "include" REQUIRES "codecs" "drivers" "cbor" "result" "tasks" "span" "memory") diff --git a/src/audio/audio_decoder.cpp b/src/audio/audio_decoder.cpp index faaadb3e..af9abb94 100644 --- a/src/audio/audio_decoder.cpp +++ b/src/audio/audio_decoder.cpp @@ -68,8 +68,10 @@ auto AudioDecoder::Process(const std::vector& inputs, OutputStream* output) -> void { auto input = inputs.begin(); const StreamInfo& info = input->info(); - if (std::holds_alternative(info.format) || info.bytes_in_stream == 0) { - output->prepare({}); + if (std::holds_alternative(info.format) || + info.bytes_in_stream == 0) { + // TODO(jacqueline): should we clear the stream format? + // output->prepare({}); return; } @@ -126,7 +128,6 @@ auto AudioDecoder::Process(const std::vector& inputs, } } - ESP_LOGI(kTag, "decoded %u bytes", current_codec_->GetInputPosition() - 1); input->consume(current_codec_->GetInputPosition() - 1); } diff --git a/src/audio/audio_task.cpp b/src/audio/audio_task.cpp index 464879d8..3a2a5941 100644 --- a/src/audio/audio_task.cpp +++ b/src/audio/audio_task.cpp @@ -124,7 +124,7 @@ void AudioTaskMain(void* args) { RawStream raw_sink_stream = elements.front()->OutStream(&out_region); InputStream sink_stream(&raw_sink_stream); - if (sink_stream.data().size_bytes() == 0) { + if (sink_stream.info().bytes_in_stream == 0) { out_region.Unmap(); vTaskDelay(pdMS_TO_TICKS(100)); continue; @@ -143,7 +143,8 @@ void AudioTaskMain(void* args) { // We've reconfigured the sink, or it was already configured correctly. // Send through some data. - if (output_format == sink_stream.info().format && !std::holds_alternative(*output_format)) { + if (output_format == sink_stream.info().format && + !std::holds_alternative(*output_format)) { // TODO: tune the delay on this, as it's currently the only way to // throttle this task's CPU time. Maybe also hold off on the pipeline // if the buffer is already close to full? @@ -160,7 +161,7 @@ void AudioTaskMain(void* args) { vTaskDelete(NULL); } -static std::byte sDrainBuf[1024]; +static std::byte sDrainBuf[8 * 1024]; void AudioDrainMain(void* args) { { diff --git a/src/audio/fatfs_audio_input.cpp b/src/audio/fatfs_audio_input.cpp index b4e6db75..22d707d6 100644 --- a/src/audio/fatfs_audio_input.cpp +++ b/src/audio/fatfs_audio_input.cpp @@ -48,7 +48,8 @@ auto FatfsAudioInput::OpenFile(const std::string& path) -> void { auto FatfsAudioInput::Process(const std::vector& inputs, OutputStream* output) -> void { if (!is_file_open_) { - output->prepare({}); + // TODO(jacqueline): should we clear the stream format? + // output->prepare({}); return; } diff --git a/src/audio/include/audio_sink.hpp b/src/audio/include/audio_sink.hpp index ad63ec2e..03a4690d 100644 --- a/src/audio/include/audio_sink.hpp +++ b/src/audio/include/audio_sink.hpp @@ -6,7 +6,8 @@ namespace audio { class IAudioSink { private: - static const std::size_t kDrainBufferSize = 8 * 1024; + // TODO: tune. at least about 12KiB seems right for mp3 + static const std::size_t kDrainBufferSize = 24 * 1024; StreamBufferHandle_t buffer_; public: diff --git a/src/audio/include/stream_info.hpp b/src/audio/include/stream_info.hpp index 6256f2ee..28095935 100644 --- a/src/audio/include/stream_info.hpp +++ b/src/audio/include/stream_info.hpp @@ -66,20 +66,13 @@ class InputStream { public: explicit InputStream(RawStream* s) : raw_(s) {} - void consume(std::size_t bytes) const { - assert(raw_->info->bytes_in_stream >= bytes); - auto new_data = raw_->data.subspan(bytes); - std::move(new_data.begin(), new_data.end(), raw_->data.begin()); - raw_->info->bytes_in_stream = new_data.size_bytes(); - } + void consume(std::size_t bytes) const; - void mark_incomplete() const { raw_->is_incomplete = true; } + void mark_incomplete() const; - const StreamInfo& info() const { return *raw_->info; } + const StreamInfo& info() const; - cpp::span data() const { - return raw_->data.first(raw_->info->bytes_in_stream); - } + cpp::span data() const; private: RawStream* raw_; @@ -89,34 +82,15 @@ class OutputStream { public: explicit OutputStream(RawStream* s) : raw_(s) {} - void add(std::size_t bytes) const { - assert(raw_->info->bytes_in_stream + bytes <= raw_->data.size_bytes()); - raw_->info->bytes_in_stream += bytes; - } - - bool prepare(const StreamInfo::Format& new_format) { - if (std::holds_alternative(raw_->info->format)) { - raw_->info->format = new_format; - raw_->info->bytes_in_stream = 0; - } - if (new_format == raw_->info->format) { - return true; - } - if (raw_->is_incomplete) { - raw_->info->format = new_format; - raw_->info->bytes_in_stream = 0; - return true; - } - return false; - } - - const StreamInfo& info() const { return *raw_->info; } - - cpp::span data() const { - return raw_->data.subspan(raw_->info->bytes_in_stream); - } - - bool is_incomplete() const { return raw_->is_incomplete; } + void add(std::size_t bytes) const; + + bool prepare(const StreamInfo::Format& new_format); + + const StreamInfo& info() const; + + cpp::span data() const; + + bool is_incomplete() const; private: RawStream* raw_; diff --git a/src/drivers/dac.cpp b/src/drivers/dac.cpp index 40663219..c99c88b0 100644 --- a/src/drivers/dac.cpp +++ b/src/drivers/dac.cpp @@ -91,11 +91,11 @@ auto AudioDac::create(GpioExpander* expander) // dac->WriteRegister(Register::PLL_CLOCK_SOURCE, 1 << 4); // dac->WriteRegister(Register::DAC_CLOCK_SOURCE, 0b11 << 5); - //dac->WriteRegister(Register::PLL_ENABLE, 0); - //dac->WriteRegister(Register::DAC_CLOCK_SOURCE, 0b0110000); - //dac->WriteRegister(Register::CLOCK_ERRORS, 0b01000001); - //dac->WriteRegister(Register::I2S_FORMAT, 0b110000); - // dac->WriteRegister(Register::INTERPOLATION, 1 << 4); + // dac->WriteRegister(Register::PLL_ENABLE, 0); + // dac->WriteRegister(Register::DAC_CLOCK_SOURCE, 0b0110000); + // dac->WriteRegister(Register::CLOCK_ERRORS, 0b01000001); + // dac->WriteRegister(Register::I2S_FORMAT, 0b110000); + // dac->WriteRegister(Register::INTERPOLATION, 1 << 4); dac->Reconfigure(BPS_16, SAMPLE_RATE_44_1);