From 41eaa75418d70db7020577b7e56ab2a1dbba085e Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 12 Sep 2025 17:20:53 +0000 Subject: [PATCH 1/2] Initial plan From 8887ec76f9a0d1661aaac1c5adc48c4a4cdf17c9 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 12 Sep 2025 17:26:07 +0000 Subject: [PATCH 2/2] Fix code formatting and linting issues throughout the codebase Co-authored-by: carlinkkit <200429681+carlinkkit@users.noreply.github.com> --- esphome/components/adf_pipeline/__init__.py | 2 +- .../adf_pipeline/adf_audio_element.h | 17 +- .../adf_pipeline/adf_audio_process.cpp | 56 ++- .../adf_pipeline/adf_audio_process.h | 2 +- .../adf_pipeline/adf_audio_sinks.cpp | 19 +- .../adf_pipeline/adf_audio_sources.cpp | 55 ++- .../adf_pipeline/adf_audio_sources.h | 4 +- .../components/adf_pipeline/adf_pipeline.cpp | 138 ++++---- .../components/adf_pipeline/adf_pipeline.h | 17 +- .../adf_pipeline/adf_pipeline_controller.cpp | 9 +- .../adf_pipeline/adf_pipeline_controller.h | 9 +- .../media_player/adf_media_player.cpp | 7 +- .../media_player/adf_media_player.h | 6 +- .../microphone/esp_adf_microphone.cpp | 49 ++- .../microphone/esp_adf_microphone.h | 3 +- esphome/components/adf_pipeline/sdk_ext.h | 127 ++++--- .../adf_pipeline/speaker/esp_adf_speaker.cpp | 86 ++--- .../adf_pipeline/speaker/esp_adf_speaker.h | 9 +- .../i2s_audio/adf_pipeline/adf_i2s_in.cpp | 16 +- .../i2s_audio/adf_pipeline/adf_i2s_in.h | 3 +- .../i2s_audio/adf_pipeline/adf_i2s_out.cpp | 44 +-- .../i2s_audio/adf_pipeline/adf_i2s_out.h | 3 +- .../i2s_audio/adf_pipeline/i2s_stream_mod.h | 324 ++++++++---------- esphome/components/i2s_audio/external_adc.cpp | 117 +++---- esphome/components/i2s_audio/external_adc.h | 22 +- esphome/components/i2s_audio/external_dac.cpp | 96 +++--- esphome/components/i2s_audio/external_dac.h | 33 +- esphome/components/i2s_audio/i2s_audio.cpp | 81 ++--- esphome/components/i2s_audio/i2s_audio.h | 126 ++++--- .../microphone/i2s_audio_microphone.cpp | 15 +- .../microphone/i2s_audio_microphone.h | 2 +- .../i2s_audio/speaker/i2s_audio_speaker.cpp | 11 +- .../voice_assistant/voice_assistant.cpp | 39 +-- 33 files changed, 706 insertions(+), 841 deletions(-) diff --git a/esphome/components/adf_pipeline/__init__.py b/esphome/components/adf_pipeline/__init__.py index 3cdebad..4b09ae6 100644 --- a/esphome/components/adf_pipeline/__init__.py +++ b/esphome/components/adf_pipeline/__init__.py @@ -87,7 +87,7 @@ async def setup_pipeline_controller(cntrl, config: dict) -> None: @coroutine_with_priority(55.0) async def to_code(config): cg.add_define("USE_ESP_ADF_VAD") - + cg.add_platformio_option("build_unflags", "-Wl,--end-group") cg.add_platformio_option( diff --git a/esphome/components/adf_pipeline/adf_audio_element.h b/esphome/components/adf_pipeline/adf_audio_element.h index 5e9725d..225f82c 100644 --- a/esphome/components/adf_pipeline/adf_audio_element.h +++ b/esphome/components/adf_pipeline/adf_audio_element.h @@ -16,8 +16,14 @@ typedef struct { int channels; } pcm_format; - -enum class PipelineElementState : uint8_t { UNINITIALIZED = 0, INITIALIZED, PREPARE, PREPARING, WAIT_FOR_PREPARATION_DONE, READY }; +enum class PipelineElementState : uint8_t { + UNINITIALIZED = 0, + INITIALIZED, + PREPARE, + PREPARING, + WAIT_FOR_PREPARATION_DONE, + READY +}; class ADFPipeline; class ADFPipelineElement; @@ -60,16 +66,15 @@ class ADFPipelineElement { virtual void on_pipeline_status_change() {} virtual void on_settings_request(AudioPipelineSettingsRequest &request) {} - std::vector get_adf_elements() { return sdk_audio_elements_; } std::string get_adf_element_tag(int element_indx); bool init_adf_elements() { return init_adf_elements_(); } - void destroy_adf_elements() {clear_adf_elements_();} + void destroy_adf_elements() { clear_adf_elements_(); } virtual void prepare_elements() {} void set_pipeline(ADFPipeline *pipeline) { pipeline_ = pipeline; } - virtual bool is_ready() {return true;} - virtual bool requires_destruction_on_stop(){ return false; } + virtual bool is_ready() { return true; } + virtual bool requires_destruction_on_stop() { return false; } protected: friend class ADFPipeline; diff --git a/esphome/components/adf_pipeline/adf_audio_process.cpp b/esphome/components/adf_pipeline/adf_audio_process.cpp index 00364f8..45c7b10 100644 --- a/esphome/components/adf_pipeline/adf_audio_process.cpp +++ b/esphome/components/adf_pipeline/adf_audio_process.cpp @@ -1,6 +1,5 @@ #include "adf_audio_process.h" - #ifdef USE_ESP_IDF #include "adf_pipeline.h" @@ -12,17 +11,17 @@ namespace esp_adf { static const char *const TAG = "esp_audio_processors"; typedef struct rsp_filter { - resample_info_t *resample_info; - unsigned char *out_buf; - unsigned char *in_buf; - void *rsp_hd; - int in_offset; - int8_t flag; //the flag must be 0 or 1. 1 means the parameter in `resample_info_t` changed. 0 means the parameter in `resample_info_t` is original. + resample_info_t *resample_info; + unsigned char *out_buf; + unsigned char *in_buf; + void *rsp_hd; + int in_offset; + int8_t flag; // the flag must be 0 or 1. 1 means the parameter in `resample_info_t` changed. 0 means the parameter in + // `resample_info_t` is original. } rsp_filter_t; - -bool ADFResampler::init_adf_elements_(){ - rsp_filter_cfg_t rsp_cfg = { +bool ADFResampler::init_adf_elements_() { + rsp_filter_cfg_t rsp_cfg = { .src_rate = this->src_rate_, .src_ch = this->src_num_channels_, .dest_rate = this->dst_rate_, @@ -42,51 +41,48 @@ bool ADFResampler::init_adf_elements_(){ .task_prio = RSP_FILTER_TASK_PRIO, .stack_in_ext = true, }; - this->sdk_resampler_= rsp_filter_init(&rsp_cfg); + this->sdk_resampler_ = rsp_filter_init(&rsp_cfg); sdk_audio_elements_.push_back(this->sdk_resampler_); sdk_element_tags_.push_back("resampler"); return true; } -void ADFResampler::on_settings_request(AudioPipelineSettingsRequest &request){ +void ADFResampler::on_settings_request(AudioPipelineSettingsRequest &request) { bool settings_changed = false; - if( request.sampling_rate > -1 ){ - if( request.sampling_rate != this->src_rate_ ) - { + if (request.sampling_rate > -1) { + if (request.sampling_rate != this->src_rate_) { this->src_rate_ = request.sampling_rate; settings_changed = true; } uint32_t dst_rate = request.final_sampling_rate > -1 ? request.final_sampling_rate : this->src_rate_; - if( dst_rate != this->dst_rate_ ) - { + if (dst_rate != this->dst_rate_) { this->dst_rate_ = dst_rate; settings_changed = true; } } - if( request.number_of_channels > -1 ){ - if( request.number_of_channels != this->src_num_channels_ ) - { + if (request.number_of_channels > -1) { + if (request.number_of_channels != this->src_num_channels_) { this->src_num_channels_ = request.number_of_channels; settings_changed = true; } - uint32_t dst_num_channels = request.final_number_of_channels > -1 ? request.final_number_of_channels : this->src_num_channels_; - if( dst_num_channels != this->dst_num_channels_ ) - { + uint32_t dst_num_channels = + request.final_number_of_channels > -1 ? request.final_number_of_channels : this->src_num_channels_; + if (dst_num_channels != this->dst_num_channels_) { this->dst_num_channels_ = dst_num_channels; settings_changed = true; } } - esph_log_d(TAG, "New settings: SRC: rate: %d, ch: %d DST: rate: %d, ch: %d ", this->src_rate_,this->src_num_channels_, this->dst_rate_, this->dst_num_channels_); + esph_log_d(TAG, "New settings: SRC: rate: %d, ch: %d DST: rate: %d, ch: %d ", this->src_rate_, + this->src_num_channels_, this->dst_rate_, this->dst_num_channels_); - if( this->sdk_resampler_ && settings_changed) - { - if( audio_element_get_state(this->sdk_resampler_) == AEL_STATE_RUNNING) - { + if (this->sdk_resampler_ && settings_changed) { + if (audio_element_get_state(this->sdk_resampler_) == AEL_STATE_RUNNING) { audio_element_stop(this->sdk_resampler_); audio_element_wait_for_stop(this->sdk_resampler_); } - esph_log_d(TAG, "New settings: SRC: rate: %d, ch: %d DST: rate: %d, ch: %d ", this->src_rate_, this->src_num_channels_, this->dst_rate_, this->dst_num_channels_); - rsp_filter_t *filter = (rsp_filter_t *)audio_element_getdata(this->sdk_resampler_); + esph_log_d(TAG, "New settings: SRC: rate: %d, ch: %d DST: rate: %d, ch: %d ", this->src_rate_, + this->src_num_channels_, this->dst_rate_, this->dst_num_channels_); + rsp_filter_t *filter = (rsp_filter_t *) audio_element_getdata(this->sdk_resampler_); resample_info_t &resample_info = *(filter->resample_info); resample_info.src_rate = this->src_rate_; resample_info.dest_rate = this->dst_rate_; diff --git a/esphome/components/adf_pipeline/adf_audio_process.h b/esphome/components/adf_pipeline/adf_audio_process.h index 3884a48..9be529a 100644 --- a/esphome/components/adf_pipeline/adf_audio_process.h +++ b/esphome/components/adf_pipeline/adf_audio_process.h @@ -18,7 +18,7 @@ class ADFResampler : public ADFPipelineProcessElement { protected: bool init_adf_elements_() override; - //void clear_adf_elements_() override; + // void clear_adf_elements_() override; void on_settings_request(AudioPipelineSettingsRequest &request) override; int src_rate_{16000}; diff --git a/esphome/components/adf_pipeline/adf_audio_sinks.cpp b/esphome/components/adf_pipeline/adf_audio_sinks.cpp index 88f25e7..6e08988 100644 --- a/esphome/components/adf_pipeline/adf_audio_sinks.cpp +++ b/esphome/components/adf_pipeline/adf_audio_sinks.cpp @@ -11,11 +11,11 @@ namespace esp_adf { static const char *const TAG = "esp_audio_sinks"; bool PCMSink::init_adf_elements_() { - if ( this->sdk_audio_elements_.size() ){ + if (this->sdk_audio_elements_.size()) { esph_log_e(TAG, "Called init, but elements already created."); return true; } - assert( this->adf_raw_stream_reader_ == nullptr ); + assert(this->adf_raw_stream_reader_ == nullptr); raw_stream_cfg_t raw_cfg = { .type = AUDIO_STREAM_READER, @@ -29,8 +29,8 @@ bool PCMSink::init_adf_elements_() { return true; } -void PCMSink::clear_adf_elements_(){ - //make sure that audio_element_deinit was called before for freeing allocated memory +void PCMSink::clear_adf_elements_() { + // make sure that audio_element_deinit was called before for freeing allocated memory this->adf_raw_stream_reader_ = nullptr; this->sdk_audio_elements_.clear(); this->sdk_element_tags_.clear(); @@ -47,13 +47,11 @@ int PCMSink::stream_read_bytes(char *buffer, int len) { } void PCMSink::on_settings_request(AudioPipelineSettingsRequest &request) { - if (request.bit_depth > 0 && (uint8_t) request.bit_depth != this->bits_per_sample_ ){ - if ( request.bit_depth == 16 || request.bit_depth == 24 || request.bit_depth == 32 ) - { - esph_log_d(TAG, "Set bitdepth to %d", request.bit_depth ); + if (request.bit_depth > 0 && (uint8_t) request.bit_depth != this->bits_per_sample_) { + if (request.bit_depth == 16 || request.bit_depth == 24 || request.bit_depth == 32) { + esph_log_d(TAG, "Set bitdepth to %d", request.bit_depth); this->bits_per_sample_ = request.bit_depth; - } - else { + } else { request.failed = true; request.failed_by = this; } @@ -66,7 +64,6 @@ void PCMSink::on_settings_request(AudioPipelineSettingsRequest &request) { } } - } // namespace esp_adf } // namespace esphome diff --git a/esphome/components/adf_pipeline/adf_audio_sources.cpp b/esphome/components/adf_pipeline/adf_audio_sources.cpp index 325c698..bef4b5c 100644 --- a/esphome/components/adf_pipeline/adf_audio_sources.cpp +++ b/esphome/components/adf_pipeline/adf_audio_sources.cpp @@ -17,7 +17,6 @@ static const char *const TAG = "esp_audio_sources"; HTTPStreamReaderAndDecoder */ - bool HTTPStreamReaderAndDecoder::init_adf_elements_() { if (sdk_audio_elements_.size() > 0) return true; @@ -26,7 +25,7 @@ bool HTTPStreamReaderAndDecoder::init_adf_elements_() { http_cfg.task_core = 0; http_cfg.out_rb_size = 4 * 1024; http_stream_reader_ = http_stream_init(&http_cfg); - http_stream_reader_->buf_size = 1024; + http_stream_reader_->buf_size = 1024; audio_element_set_uri(this->http_stream_reader_, this->current_url_.c_str()); sdk_audio_elements_.push_back(this->http_stream_reader_); @@ -43,27 +42,21 @@ bool HTTPStreamReaderAndDecoder::init_adf_elements_() { } void HTTPStreamReaderAndDecoder::clear_adf_elements_() { - //make sure that deinit of pipeline was called first + // make sure that deinit of pipeline was called first this->sdk_audio_elements_.clear(); this->sdk_element_tags_.clear(); this->element_state_ = PipelineElementState::UNINITIALIZED; } -void HTTPStreamReaderAndDecoder::reset_() { - this->element_state_ = PipelineElementState::INITIALIZED; -} +void HTTPStreamReaderAndDecoder::reset_() { this->element_state_ = PipelineElementState::INITIALIZED; } -void HTTPStreamReaderAndDecoder::set_stream_uri(const std::string& new_url) { - this->current_url_ = new_url; -} +void HTTPStreamReaderAndDecoder::set_stream_uri(const std::string &new_url) { this->current_url_ = new_url; } -void HTTPStreamReaderAndDecoder::prepare_elements(){ - this->element_state_ = PipelineElementState::PREPARE; -} +void HTTPStreamReaderAndDecoder::prepare_elements() { this->element_state_ = PipelineElementState::PREPARE; } // called while pipeline is in PREPARING state -bool HTTPStreamReaderAndDecoder::is_ready(){ - switch(this->element_state_){ +bool HTTPStreamReaderAndDecoder::is_ready() { + switch (this->element_state_) { case PipelineElementState::READY: return true; case PipelineElementState::PREPARE: @@ -79,35 +72,33 @@ bool HTTPStreamReaderAndDecoder::is_ready(){ } // Start pipeline elements necessary for receiving audio settings from stream -void HTTPStreamReaderAndDecoder::start_prepare_pipeline_(){ - if( audio_element_run(this->http_stream_reader_) != ESP_OK ) - { +void HTTPStreamReaderAndDecoder::start_prepare_pipeline_() { + if (audio_element_run(this->http_stream_reader_) != ESP_OK) { esph_log_e(TAG, "Starting http streamer failed"); } - if( audio_element_run(this->decoder_) != ESP_OK ){ + if (audio_element_run(this->decoder_) != ESP_OK) { esph_log_e(TAG, "Starting decoder streamer failed"); } - if( audio_element_resume(this->http_stream_reader_, 0, 2000 / portTICK_RATE_MS) != ESP_OK) - { + if (audio_element_resume(this->http_stream_reader_, 0, 2000 / portTICK_RATE_MS) != ESP_OK) { esph_log_e(TAG, "Resuming http streamer failed"); } - if( audio_element_resume(this->decoder_, 0, 2000 / portTICK_RATE_MS) != ESP_OK ){ + if (audio_element_resume(this->decoder_, 0, 2000 / portTICK_RATE_MS) != ESP_OK) { esph_log_e(TAG, "Resuming decoder failed"); } - esph_log_d(TAG, "Streamer status: %d", audio_element_get_state(this->http_stream_reader_) ); - esph_log_d(TAG, "decoder status: %d", audio_element_get_state(this->decoder_) ); + esph_log_d(TAG, "Streamer status: %d", audio_element_get_state(this->http_stream_reader_)); + esph_log_d(TAG, "decoder status: %d", audio_element_get_state(this->decoder_)); } -void HTTPStreamReaderAndDecoder::terminate_prepare_pipeline_(){ +void HTTPStreamReaderAndDecoder::terminate_prepare_pipeline_() { audio_element_stop(this->http_stream_reader_); audio_element_stop(this->decoder_); this->element_state_ = PipelineElementState::WAIT_FOR_PREPARATION_DONE; } -bool HTTPStreamReaderAndDecoder::set_ready_when_prepare_pipeline_stopped_(){ +bool HTTPStreamReaderAndDecoder::set_ready_when_prepare_pipeline_stopped_() { bool stopped = audio_element_wait_for_stop_ms(this->http_stream_reader_, 0) == ESP_OK; - stopped = stopped && audio_element_wait_for_stop_ms(this->decoder_, 0) == ESP_OK; - if( stopped ){ + stopped = stopped && audio_element_wait_for_stop_ms(this->decoder_, 0) == ESP_OK; + if (stopped) { audio_element_reset_state(this->http_stream_reader_); audio_element_reset_state(this->decoder_); audio_element_reset_input_ringbuf(this->decoder_); @@ -117,7 +108,7 @@ bool HTTPStreamReaderAndDecoder::set_ready_when_prepare_pipeline_stopped_(){ return stopped; } -//wait for audio information in stream and send new audio settings to pipeline +// wait for audio information in stream and send new audio settings to pipeline void HTTPStreamReaderAndDecoder::sdk_event_handler_(audio_event_iface_msg_t &msg) { audio_element_handle_t mp3_decoder = this->decoder_; if (msg.source_type == AUDIO_ELEMENT_TYPE_ELEMENT && msg.source == (void *) mp3_decoder && @@ -138,8 +129,7 @@ void HTTPStreamReaderAndDecoder::sdk_event_handler_(audio_event_iface_msg_t &msg } // necessary audio information has been received, terminate preparation pipeline - if( this->element_state_ == PipelineElementState::PREPARING ) - { + if (this->element_state_ == PipelineElementState::PREPARING) { this->terminate_prepare_pipeline_(); } } @@ -162,8 +152,8 @@ bool PCMSource::init_adf_elements_() { return true; } -//int PCMSource::stream_write(char *buffer, int len) { return len ? raw_stream_write(adf_raw_stream_writer_, buffer, len) : 0; } - +// int PCMSource::stream_write(char *buffer, int len) { return len ? raw_stream_write(adf_raw_stream_writer_, buffer, +// len) : 0; } int PCMSource::stream_write(char *buffer, int len) { int ret = audio_element_output(this->adf_raw_stream_writer_, buffer, len); @@ -175,7 +165,6 @@ int PCMSource::stream_write(char *buffer, int len) { return ret; } - bool PCMSource::has_buffered_data() const { ringbuf_handle_t rb = audio_element_get_output_ringbuf(adf_raw_stream_writer_); return rb_bytes_filled(rb) > 0; diff --git a/esphome/components/adf_pipeline/adf_audio_sources.h b/esphome/components/adf_pipeline/adf_audio_sources.h index 8a5d15f..175af99 100644 --- a/esphome/components/adf_pipeline/adf_audio_sources.h +++ b/esphome/components/adf_pipeline/adf_audio_sources.h @@ -14,7 +14,7 @@ class ADFPipelineSourceElement : public ADFPipelineElement { class HTTPStreamReaderAndDecoder : public ADFPipelineSourceElement { public: - void set_stream_uri(const std::string& new_url); + void set_stream_uri(const std::string &new_url); const std::string get_name() override { return "HTTPStreamReader"; } bool is_ready() override; void prepare_elements() override; @@ -30,14 +30,12 @@ class HTTPStreamReaderAndDecoder : public ADFPipelineSourceElement { void sdk_event_handler_(audio_event_iface_msg_t &msg); void cfg_event_handler_(audio_event_iface_msg_t &msg); - PipelineElementState element_state_{PipelineElementState::UNINITIALIZED}; std::string current_url_{"https://dl.espressif.com/dl/audio/ff-16b-2c-44100hz.mp3"}; audio_element_handle_t http_stream_reader_{}; audio_element_handle_t decoder_{}; }; - class PCMSource : public ADFPipelineSourceElement { public: const std::string get_name() override { return "PCMSource"; } diff --git a/esphome/components/adf_pipeline/adf_pipeline.cpp b/esphome/components/adf_pipeline/adf_pipeline.cpp index 8082bc4..0b305af 100644 --- a/esphome/components/adf_pipeline/adf_pipeline.cpp +++ b/esphome/components/adf_pipeline/adf_pipeline.cpp @@ -40,7 +40,7 @@ static const LogString *pipeline_state_to_string(PipelineState state) { } } -void ADFPipeline::dump_element_configs(){ +void ADFPipeline::dump_element_configs() { for (auto &element : pipeline_elements_) { element->dump_config(); } @@ -48,12 +48,11 @@ void ADFPipeline::dump_element_configs(){ void ADFPipeline::start() { esph_log_d(TAG, "Starting request, current state %s", LOG_STR_ARG(pipeline_state_to_string(this->state_))); - switch( this->state_ ){ + switch (this->state_) { case PipelineState::UNINITIALIZED: - if( init_() ){ + if (init_()) { prepare_elements_(); - } - else{ + } else { deinit_(); } break; @@ -73,7 +72,7 @@ void ADFPipeline::start() { } void ADFPipeline::stop() { - switch (this->state_ ){ + switch (this->state_) { case PipelineState::PREPARING: case PipelineState::STARTING: case PipelineState::RUNNING: @@ -82,7 +81,7 @@ void ADFPipeline::stop() { set_state_(PipelineState::STOPPING); break; default: - esph_log_d(TAG, "Called 'stop' while in %s state.",LOG_STR_ARG(pipeline_state_to_string(this->state_)) ); + esph_log_d(TAG, "Called 'stop' while in %s state.", LOG_STR_ARG(pipeline_state_to_string(this->state_))); break; } } @@ -92,7 +91,8 @@ void ADFPipeline::pause() { set_state_(PipelineState::PAUSING); pause_(); } else { - esph_log_d(TAG, "Pipeline was not RUNNING while calling pause! Current state: %s",LOG_STR_ARG(pipeline_state_to_string(this->state_)) ); + esph_log_d(TAG, "Pipeline was not RUNNING while calling pause! Current state: %s", + LOG_STR_ARG(pipeline_state_to_string(this->state_))); } } @@ -100,9 +100,9 @@ void ADFPipeline::resume() { if (state_ == PipelineState::PAUSED) { set_state_(PipelineState::RESUMING); resume_(); - } - else { - esph_log_d(TAG, "Pipeline was not PAUSED while calling resume! Current state: %s",LOG_STR_ARG(pipeline_state_to_string(this->state_)) ); + } else { + esph_log_d(TAG, "Pipeline was not PAUSED while calling resume! Current state: %s", + LOG_STR_ARG(pipeline_state_to_string(this->state_))); } } @@ -113,7 +113,7 @@ void ADFPipeline::destroy() { } } -void ADFPipeline::prepare_elements_(){ +void ADFPipeline::prepare_elements_() { this->preparation_started_at_ = millis(); for (auto &element : pipeline_elements_) { element->prepare_elements(); @@ -121,15 +121,14 @@ void ADFPipeline::prepare_elements_(){ this->set_state_(PipelineState::PREPARING); } -void ADFPipeline::check_all_started_(){ - if( this->state_ != PipelineState::STARTING) - { +void ADFPipeline::check_all_started_() { + if (this->state_ != PipelineState::STARTING) { return; } for (auto &comp : pipeline_elements_) { for (auto el : comp->get_adf_elements()) { esph_log_d(TAG, "Check element [%s] status, %d", audio_element_get_tag(el), audio_element_get_state(el)); - if (audio_element_get_state(el) != AEL_STATE_RUNNING){ + if (audio_element_get_state(el) != AEL_STATE_RUNNING) { return; } } @@ -137,23 +136,19 @@ void ADFPipeline::check_all_started_(){ set_state_(PipelineState::RUNNING); } - -void ADFPipeline::check_all_stopped_(){ +void ADFPipeline::check_all_stopped_() { static uint32_t timeout_invoke = 0; - if(timeout_invoke == 0){ + if (timeout_invoke == 0) { timeout_invoke = millis(); } for (auto &comp : pipeline_elements_) { for (auto el : comp->get_adf_elements()) { - //esph_log_d(TAG, "Check element for stop [%s] status, %d", audio_element_get_tag(el), audio_element_get_state(el)); - if ( (millis() - timeout_invoke < 3000 ) && - ( - audio_element_get_state(el) == AEL_STATE_INITIALIZING || - audio_element_get_state(el) == AEL_STATE_RUNNING || - audio_element_get_state(el) == AEL_STATE_PAUSED - ) - ){ + // esph_log_d(TAG, "Check element for stop [%s] status, %d", audio_element_get_tag(el), + // audio_element_get_state(el)); + if ((millis() - timeout_invoke < 3000) && + (audio_element_get_state(el) == AEL_STATE_INITIALIZING || audio_element_get_state(el) == AEL_STATE_RUNNING || + audio_element_get_state(el) == AEL_STATE_PAUSED)) { return; } } @@ -170,8 +165,7 @@ void ADFPipeline::check_all_stopped_(){ reset_(); } - -void ADFPipeline::check_if_components_are_ready_(){ +void ADFPipeline::check_if_components_are_ready_() { bool ready = true; for (auto &element : this->pipeline_elements_) { ready = ready && element->is_ready(); @@ -179,9 +173,8 @@ void ADFPipeline::check_if_components_are_ready_(){ if (ready) { this->set_state_(PipelineState::STARTING); this->start_(); - } - else { - if ( millis() - this->preparation_started_at_ > PIPELINE_PREPARATION_TIMEOUT_MS ){ + } else { + if (millis() - this->preparation_started_at_ > PIPELINE_PREPARATION_TIMEOUT_MS) { esph_log_i(TAG, "Pipeline preparation timeout!"); this->stop(); return; @@ -194,47 +187,47 @@ void ADFPipeline::check_if_components_are_ready_(){ } } -void ADFPipeline::check_for_pipeline_events_(){ +void ADFPipeline::check_for_pipeline_events_() { audio_event_iface_msg_t msg; esp_err_t ret = audio_event_iface_listen(this->adf_pipeline_event_, &msg, 0); if (ret == ESP_OK) { forward_event_to_pipeline_elements_(msg); - if (parent_ != nullptr) { - parent_->pipeline_event_handler(msg); - } + if (parent_ != nullptr) { + parent_->pipeline_event_handler(msg); + } - assert( this->state_ != PipelineState::PREPARING ); - - //trigger state changes on events received from pipeline - if (msg.source_type == AUDIO_ELEMENT_TYPE_ELEMENT && msg.cmd == AEL_MSG_CMD_REPORT_STATUS){ - audio_element_status_t status; - std::memcpy(&status, &msg.data, sizeof(audio_element_status_t)); - audio_element_handle_t el = (audio_element_handle_t) msg.source; - esph_log_i(TAG, "[ %s ] status: %d", audio_element_get_tag(el), status); - switch (status) { - case AEL_STATUS_STATE_STOPPED: - case AEL_STATUS_STATE_FINISHED: - if( this->state_ == PipelineState::RUNNING){ - this->set_state_(PipelineState::STOPPING); - check_all_stopped_(); - } - break; - case AEL_STATUS_STATE_RUNNING: - check_all_started_(); - break; - case AEL_STATUS_STATE_PAUSED: - set_state_(PipelineState::PAUSED); - break; - default: - break; - } + assert(this->state_ != PipelineState::PREPARING); + + // trigger state changes on events received from pipeline + if (msg.source_type == AUDIO_ELEMENT_TYPE_ELEMENT && msg.cmd == AEL_MSG_CMD_REPORT_STATUS) { + audio_element_status_t status; + std::memcpy(&status, &msg.data, sizeof(audio_element_status_t)); + audio_element_handle_t el = (audio_element_handle_t) msg.source; + esph_log_i(TAG, "[ %s ] status: %d", audio_element_get_tag(el), status); + switch (status) { + case AEL_STATUS_STATE_STOPPED: + case AEL_STATUS_STATE_FINISHED: + if (this->state_ == PipelineState::RUNNING) { + this->set_state_(PipelineState::STOPPING); + check_all_stopped_(); + } + break; + case AEL_STATUS_STATE_RUNNING: + check_all_started_(); + break; + case AEL_STATUS_STATE_PAUSED: + set_state_(PipelineState::PAUSED); + break; + default: + break; } } - } + } +} void ADFPipeline::watch_() { - switch(this->state_){ + switch (this->state_) { case PipelineState::UNINITIALIZED: case PipelineState::PAUSED: case PipelineState::DESTROYING: @@ -336,8 +329,8 @@ bool ADFPipeline::build_adf_pipeline_() { std::vector tags_vector; for (auto &comp : pipeline_elements_) { - if (! comp->init_adf_elements() ){ - esph_log_e(TAG, "Couldn't init [%s].", comp->get_name().c_str() ) ; + if (!comp->init_adf_elements()) { + esph_log_e(TAG, "Couldn't init [%s].", comp->get_name().c_str()); return false; } this->destroy_on_stop_ = this->destroy_on_stop_ || comp->requires_destruction_on_stop(); @@ -379,15 +372,12 @@ bool ADFPipeline::build_adf_pipeline_() { bool ADFPipeline::reset_() { bool ret = false; - if ( this->destroy_on_stop_ ){ + if (this->destroy_on_stop_) { ret = deinit_(); - } - else { + } else { audio_pipeline_handle_t pipeline = this->adf_pipeline_; - ret = ( audio_pipeline_reset_ringbuffer(pipeline) == ESP_OK - && audio_pipeline_reset_elements(pipeline) == ESP_OK - && audio_pipeline_change_state(pipeline, AEL_STATE_INIT) == ESP_OK - ); + ret = (audio_pipeline_reset_ringbuffer(pipeline) == ESP_OK && audio_pipeline_reset_elements(pipeline) == ESP_OK && + audio_pipeline_change_state(pipeline, AEL_STATE_INIT) == ESP_OK); for (auto &element : pipeline_elements_) { element->reset_(); } @@ -397,9 +387,9 @@ bool ADFPipeline::reset_() { } void ADFPipeline::deinit_all_() { - esph_log_d(TAG, "Called deinit_all" ); + esph_log_d(TAG, "Called deinit_all"); audio_pipeline_deinit(this->adf_pipeline_); - if ( this->adf_pipeline_event_){ + if (this->adf_pipeline_event_) { audio_event_iface_destroy(this->adf_pipeline_event_); } diff --git a/esphome/components/adf_pipeline/adf_pipeline.h b/esphome/components/adf_pipeline/adf_pipeline.h index 9d43246..436e7b5 100644 --- a/esphome/components/adf_pipeline/adf_pipeline.h +++ b/esphome/components/adf_pipeline/adf_pipeline.h @@ -16,7 +16,6 @@ namespace esphome { namespace esp_adf { - /* Audio Pipeline States: UNINITIALIZED -> STOPPED -> (PREPARING) -> STARTING -> RUNNING @@ -37,8 +36,18 @@ State Explanations: - DESTROYING: Freeing all memory and hardware reservations. */ -enum PipelineState : uint8_t { UNINITIALIZED = 0, PREPARING, STARTING, RUNNING, STOPPING, STOPPED, PAUSING, PAUSED, RESUMING, DESTROYING }; - +enum PipelineState : uint8_t { + UNINITIALIZED = 0, + PREPARING, + STARTING, + RUNNING, + STOPPING, + STOPPED, + PAUSING, + PAUSED, + RESUMING, + DESTROYING +}; class ADFPipelineController; @@ -59,7 +68,7 @@ class ADFPipeline { PipelineState getState() { return state_; } void loop() { this->watch_(); } - void set_destroy_on_stop(bool value){ this->destroy_on_stop_ = value; } + void set_destroy_on_stop(bool value) { this->destroy_on_stop_ = value; } void append_element(ADFPipelineElement *element); int get_number_of_elements() { return pipeline_elements_.size(); } std::vector get_element_names(); diff --git a/esphome/components/adf_pipeline/adf_pipeline_controller.cpp b/esphome/components/adf_pipeline/adf_pipeline_controller.cpp index ebb1364..de7889a 100644 --- a/esphome/components/adf_pipeline/adf_pipeline_controller.cpp +++ b/esphome/components/adf_pipeline/adf_pipeline_controller.cpp @@ -1,10 +1,5 @@ #include "adf_pipeline_controller.h" namespace esphome { -namespace esp_adf { - - - - -} -} +namespace esp_adf {} +} // namespace esphome diff --git a/esphome/components/adf_pipeline/adf_pipeline_controller.h b/esphome/components/adf_pipeline/adf_pipeline_controller.h index 866668e..d6b1efb 100644 --- a/esphome/components/adf_pipeline/adf_pipeline_controller.h +++ b/esphome/components/adf_pipeline/adf_pipeline_controller.h @@ -19,7 +19,7 @@ class ADFPipelineElement; An ESPHome Component for managing an ADFPipeline */ class ADFPipelineController : public Component { -public: + public: ADFPipelineController() : pipeline(this) {} ~ADFPipelineController() {} @@ -31,7 +31,7 @@ class ADFPipelineController : public Component { void dump_config() override { pipeline.dump_element_configs(); }; void loop() override { pipeline.loop(); } -protected: + protected: friend ADFPipeline; virtual void pipeline_event_handler(audio_event_iface_msg_t &msg) {} virtual void on_pipeline_state_change(PipelineState state) {} @@ -39,8 +39,7 @@ class ADFPipelineController : public Component { ADFPipeline pipeline; }; - -} -} +} // namespace esp_adf +} // namespace esphome #endif diff --git a/esphome/components/adf_pipeline/media_player/adf_media_player.cpp b/esphome/components/adf_pipeline/media_player/adf_media_player.cpp index be7d57d..e08b5cd 100644 --- a/esphome/components/adf_pipeline/media_player/adf_media_player.cpp +++ b/esphome/components/adf_pipeline/media_player/adf_media_player.cpp @@ -11,9 +11,7 @@ void ADFMediaPlayer::setup() { pipeline.setup(); } -void ADFMediaPlayer::loop() { - pipeline.loop(); -} +void ADFMediaPlayer::loop() { pipeline.loop(); } void ADFMediaPlayer::control(const media_player::MediaPlayerCall &call) { if (call.get_command().has_value()) { @@ -23,7 +21,8 @@ void ADFMediaPlayer::control(const media_player::MediaPlayerCall &call) { pipeline.start(); } else if (pipeline.getState() == PipelineState::PAUSED) { pipeline.restart(); - } else if (state == media_player::MEDIA_PLAYER_STATE_PLAYING || state == media_player::MEDIA_PLAYER_STATE_PAUSED) { + } else if (state == media_player::MEDIA_PLAYER_STATE_PLAYING || + state == media_player::MEDIA_PLAYER_STATE_PAUSED) { this->play_intent_ = true; pipeline.stop(); } diff --git a/esphome/components/adf_pipeline/media_player/adf_media_player.h b/esphome/components/adf_pipeline/media_player/adf_media_player.h index cae5d4c..6e1f53a 100644 --- a/esphome/components/adf_pipeline/media_player/adf_media_player.h +++ b/esphome/components/adf_pipeline/media_player/adf_media_player.h @@ -25,9 +25,9 @@ class ADFMediaPlayer : public media_player::MediaPlayer, public ADFPipelineContr media_player::MediaPlayerTraits get_traits() override; // - void set_stream_uri(const std::string& new_uri); - void start() {pipeline.start();} - void stop() {pipeline.stop();} + void set_stream_uri(const std::string &new_uri); + void start() { pipeline.start(); } + void stop() { pipeline.stop(); } protected: // MediaPlayer implementation diff --git a/esphome/components/adf_pipeline/microphone/esp_adf_microphone.cpp b/esphome/components/adf_pipeline/microphone/esp_adf_microphone.cpp index a29513e..135077a 100644 --- a/esphome/components/adf_pipeline/microphone/esp_adf_microphone.cpp +++ b/esphome/components/adf_pipeline/microphone/esp_adf_microphone.cpp @@ -12,9 +12,7 @@ namespace esp_adf { static const char *const TAG = "esp_adf_pipeline.microphone"; -void ADFMicrophone::setup() { - esp_log_level_set("wifi", ESP_LOG_WARN); -} +void ADFMicrophone::setup() { esp_log_level_set("wifi", ESP_LOG_WARN); } void ADFMicrophone::dump_config() { esph_log_config(TAG, "ADF-Microphone"); @@ -22,7 +20,7 @@ void ADFMicrophone::dump_config() { } void ADFMicrophone::start() { - if ( this->state_ == microphone::STATE_RUNNING){ + if (this->state_ == microphone::STATE_RUNNING) { return; } pipeline.start(); @@ -36,29 +34,28 @@ void ADFMicrophone::stop() { // len and return size are both in bytes size_t ADFMicrophone::read(int16_t *buf, size_t len) { - len = (len << 1) >> 1; - if (this->pcm_stream_.get_bits_per_sample() == 32 || this->pcm_stream_.get_bits_per_sample() == 24) - { - len = ( len << 2 ) >> 2; - size_t bytes_read = this->pcm_stream_.stream_read_bytes((char *) buf, len << 1 ); - size_t samples_read = bytes_read / sizeof(int32_t); - if( samples_read == 0 ){ - return 0; - } + len = (len << 1) >> 1; + if (this->pcm_stream_.get_bits_per_sample() == 32 || this->pcm_stream_.get_bits_per_sample() == 24) { + len = (len << 2) >> 2; + size_t bytes_read = this->pcm_stream_.stream_read_bytes((char *) buf, len << 1); + size_t samples_read = bytes_read / sizeof(int32_t); + if (samples_read == 0) { + return 0; + } - std::vector samples; - uint8_t shift = 16 - this->gain_log2_ ; - samples.resize(samples_read); - for (size_t i = 0; i < samples_read; i++) { - int32_t temp = ( reinterpret_cast(buf)[i] ) >> shift; - samples[i] = (int16_t) clamp(temp, INT16_MIN, INT16_MAX ); - } - memcpy(buf, samples.data(), samples_read * sizeof(int16_t)); - return samples_read * sizeof(int16_t); + std::vector samples; + uint8_t shift = 16 - this->gain_log2_; + samples.resize(samples_read); + for (size_t i = 0; i < samples_read; i++) { + int32_t temp = (reinterpret_cast(buf)[i]) >> shift; + samples[i] = (int16_t) clamp(temp, INT16_MIN, INT16_MAX); } - size_t bytes_read = 0; - bytes_read = this->pcm_stream_.stream_read_bytes((char *) buf, len); - return bytes_read; + memcpy(buf, samples.data(), samples_read * sizeof(int16_t)); + return samples_read * sizeof(int16_t); + } + size_t bytes_read = 0; + bytes_read = this->pcm_stream_.stream_read_bytes((char *) buf, len); + return bytes_read; } void ADFMicrophone::on_pipeline_state_change(PipelineState state) { @@ -87,7 +84,7 @@ void ADFMicrophone::on_pipeline_state_change(PipelineState state) { case PipelineState::PREPARING: case PipelineState::DESTROYING: break; - } + } } } // namespace esp_adf diff --git a/esphome/components/adf_pipeline/microphone/esp_adf_microphone.h b/esphome/components/adf_pipeline/microphone/esp_adf_microphone.h index 82cf89d..ac4bc51 100644 --- a/esphome/components/adf_pipeline/microphone/esp_adf_microphone.h +++ b/esphome/components/adf_pipeline/microphone/esp_adf_microphone.h @@ -26,7 +26,8 @@ class ADFMicrophone : public microphone::Microphone, public ADFPipelineControlle size_t read(int16_t *buf, size_t len) override; // additional setup - void set_gain_log2( uint8_t gain_log2){this->gain_log2_ = gain_log2;} + void set_gain_log2(uint8_t gain_log2) { this->gain_log2_ = gain_log2; } + protected: void on_pipeline_state_change(PipelineState state) override; diff --git a/esphome/components/adf_pipeline/sdk_ext.h b/esphome/components/adf_pipeline/sdk_ext.h index 870fa28..711f57d 100644 --- a/esphome/components/adf_pipeline/sdk_ext.h +++ b/esphome/components/adf_pipeline/sdk_ext.h @@ -34,89 +34,86 @@ * I/O Element Abstract */ typedef struct io_callback { - stream_func cb; - void *ctx; + stream_func cb; + void *ctx; } io_callback_t; /** * Audio Callback Abstract */ typedef struct audio_callback { - event_cb_func cb; - void *ctx; + event_cb_func cb; + void *ctx; } audio_callback_t; typedef struct audio_multi_rb { - ringbuf_handle_t *rb; - int max_rb_num; + ringbuf_handle_t *rb; + int max_rb_num; } audio_multi_rb_t; typedef enum { - IO_TYPE_RB = 1, /* I/O through ringbuffer */ - IO_TYPE_CB, /* I/O through callback */ + IO_TYPE_RB = 1, /* I/O through ringbuffer */ + IO_TYPE_CB, /* I/O through callback */ } io_type_t; typedef enum { - EVENTS_TYPE_Q = 1, /* Events through MessageQueue */ - EVENTS_TYPE_CB, /* Events through Callback function */ + EVENTS_TYPE_Q = 1, /* Events through MessageQueue */ + EVENTS_TYPE_CB, /* Events through Callback function */ } events_type_t; - struct audio_element { - /* Functions/RingBuffers */ - el_io_func open; - ctrl_func seek; - process_func process; - el_io_func close; - el_io_func destroy; - io_type_t read_type; - union { - ringbuf_handle_t input_rb; - io_callback_t read_cb; - } in; - io_type_t write_type; - union { - ringbuf_handle_t output_rb; - io_callback_t write_cb; - } out; - - audio_multi_rb_t multi_in; - audio_multi_rb_t multi_out; - - /* Properties */ - volatile bool is_open; - audio_element_state_t state; - - events_type_t events_type; - audio_event_iface_handle_t iface_event; - audio_callback_t callback_event; - - int buf_size; - char *buf; - - char *tag; - int task_stack; - int task_prio; - int task_core; - xSemaphoreHandle lock; - audio_element_info_t info; - audio_element_info_t *report_info; - - bool stack_in_ext; - audio_thread_t audio_thread; - - /* PrivateData */ - void *data; - EventGroupHandle_t state_event; - int input_wait_time; - int output_wait_time; - int out_buf_size_expect; - int out_rb_size; - volatile bool is_running; - volatile bool task_run; - volatile bool stopping; + /* Functions/RingBuffers */ + el_io_func open; + ctrl_func seek; + process_func process; + el_io_func close; + el_io_func destroy; + io_type_t read_type; + union { + ringbuf_handle_t input_rb; + io_callback_t read_cb; + } in; + io_type_t write_type; + union { + ringbuf_handle_t output_rb; + io_callback_t write_cb; + } out; + + audio_multi_rb_t multi_in; + audio_multi_rb_t multi_out; + + /* Properties */ + volatile bool is_open; + audio_element_state_t state; + + events_type_t events_type; + audio_event_iface_handle_t iface_event; + audio_callback_t callback_event; + + int buf_size; + char *buf; + + char *tag; + int task_stack; + int task_prio; + int task_core; + xSemaphoreHandle lock; + audio_element_info_t info; + audio_element_info_t *report_info; + + bool stack_in_ext; + audio_thread_t audio_thread; + + /* PrivateData */ + void *data; + EventGroupHandle_t state_event; + int input_wait_time; + int output_wait_time; + int out_buf_size_expect; + int out_rb_size; + volatile bool is_running; + volatile bool task_run; + volatile bool stopping; }; - - #endif diff --git a/esphome/components/adf_pipeline/speaker/esp_adf_speaker.cpp b/esphome/components/adf_pipeline/speaker/esp_adf_speaker.cpp index c63df8c..0da6bbd 100644 --- a/esphome/components/adf_pipeline/speaker/esp_adf_speaker.cpp +++ b/esphome/components/adf_pipeline/speaker/esp_adf_speaker.cpp @@ -11,20 +11,13 @@ namespace esp_adf { static const char *const TAG = "esp_adf.speaker"; -void ADFSpeaker::setup() { - ESP_LOGCONFIG(TAG, "Setting up ESP ADF Speaker..."); -} - -void ADFSpeaker::dump_config() { - ESP_LOGCONFIG(TAG, "ESP ADF Speaker Configs:"); -} +void ADFSpeaker::setup() { ESP_LOGCONFIG(TAG, "Setting up ESP ADF Speaker..."); } +void ADFSpeaker::dump_config() { ESP_LOGCONFIG(TAG, "ESP ADF Speaker Configs:"); } void ADFSpeaker::start() { this->state_ = speaker::STATE_STARTING; } -void ADFSpeaker::start_() { - pipeline.start(); -} +void ADFSpeaker::start_() { pipeline.start(); } void ADFSpeaker::stop() { if (this->state_ == speaker::STATE_STOPPED) @@ -34,30 +27,30 @@ void ADFSpeaker::stop() { } void ADFSpeaker::on_pipeline_state_change(PipelineState state) { - switch (state) { - case PipelineState::PREPARING: - this->request_pipeline_settings_(); - break; - case PipelineState::STARTING: - break; - case PipelineState::STOPPING: - this->state_ = speaker::STATE_STOPPING; - break; - case PipelineState::RUNNING: - this->state_ = speaker::STATE_RUNNING; - break; - case PipelineState::UNINITIALIZED: - case PipelineState::STOPPED: - this->state_ = speaker::STATE_STOPPED; - break; - case PipelineState::PAUSED: - ESP_LOGI(TAG, "pipeline paused"); - break; - case PipelineState::PAUSING: - case PipelineState::RESUMING: - case PipelineState::DESTROYING: - break; - } + switch (state) { + case PipelineState::PREPARING: + this->request_pipeline_settings_(); + break; + case PipelineState::STARTING: + break; + case PipelineState::STOPPING: + this->state_ = speaker::STATE_STOPPING; + break; + case PipelineState::RUNNING: + this->state_ = speaker::STATE_RUNNING; + break; + case PipelineState::UNINITIALIZED: + case PipelineState::STOPPED: + this->state_ = speaker::STATE_STOPPED; + break; + case PipelineState::PAUSED: + ESP_LOGI(TAG, "pipeline paused"); + break; + case PipelineState::PAUSING: + case PipelineState::RESUMING: + case PipelineState::DESTROYING: + break; + } } void ADFSpeaker::loop() { @@ -85,29 +78,26 @@ size_t ADFSpeaker::play(const uint8_t *data, size_t length) { size_t index = 0; while (remaining > 0) { size_t to_send_length = std::min(remaining, BUFFER_SIZE); - pcm_stream_.stream_write( (char *) data + index, to_send_length ); + pcm_stream_.stream_write((char *) data + index, to_send_length); remaining -= to_send_length; index += to_send_length; } return index; } -bool ADFSpeaker::has_buffered_data() const { - return pcm_stream_.has_buffered_data(); -} +bool ADFSpeaker::has_buffered_data() const { return pcm_stream_.has_buffered_data(); } -void ADFSpeaker::request_pipeline_settings_(){ - AudioPipelineSettingsRequest request{&this->pcm_stream_}; - request.sampling_rate = 16000; - request.bit_depth = 16; - request.number_of_channels = 1; - if (!this->pipeline.request_settings(request)) { - esph_log_e(TAG, "Requested audio settings, didn't get accepted"); - this->pipeline.on_settings_request_failed(request); - } +void ADFSpeaker::request_pipeline_settings_() { + AudioPipelineSettingsRequest request{&this->pcm_stream_}; + request.sampling_rate = 16000; + request.bit_depth = 16; + request.number_of_channels = 1; + if (!this->pipeline.request_settings(request)) { + esph_log_e(TAG, "Requested audio settings, didn't get accepted"); + this->pipeline.on_settings_request_failed(request); + } } - } // namespace esp_adf } // namespace esphome diff --git a/esphome/components/adf_pipeline/speaker/esp_adf_speaker.h b/esphome/components/adf_pipeline/speaker/esp_adf_speaker.h index 1f64c78..3864234 100644 --- a/esphome/components/adf_pipeline/speaker/esp_adf_speaker.h +++ b/esphome/components/adf_pipeline/speaker/esp_adf_speaker.h @@ -15,14 +15,13 @@ static const size_t BUFFER_SIZE = 1024; class ADFSpeaker : public speaker::Speaker, public ADFPipelineController { public: // Pipeline implementations - void append_own_elements(){ add_element_to_pipeline( (ADFPipelineElement*) &(this->pcm_stream_) ); } + void append_own_elements() { add_element_to_pipeline((ADFPipelineElement *) &(this->pcm_stream_)); } // ESPHome-Component implementations float get_setup_priority() const override { return esphome::setup_priority::LATE; } - void setup() override; - void dump_config() override; - void loop() override; - + void setup() override; + void dump_config() override; + void loop() override; // Speaker implemenations void start() override; diff --git a/esphome/components/i2s_audio/adf_pipeline/adf_i2s_in.cpp b/esphome/components/i2s_audio/adf_pipeline/adf_i2s_in.cpp index 0514580..705323b 100644 --- a/esphome/components/i2s_audio/adf_pipeline/adf_i2s_in.cpp +++ b/esphome/components/i2s_audio/adf_pipeline/adf_i2s_in.cpp @@ -19,11 +19,11 @@ bool ADFElementI2SIn::init_adf_elements_() { return true; #ifdef I2S_EXTERNAL_ADC - if (this->external_adc_ != nullptr){ + if (this->external_adc_ != nullptr) { this->external_adc_->init_device(); } #endif - if ( !this->claim_i2s_access() ){ + if (!this->claim_i2s_access()) { return false; } @@ -52,7 +52,7 @@ bool ADFElementI2SIn::init_adf_elements_() { this->install_i2s_driver(i2s_config); #ifdef I2S_EXTERNAL_ADC - if (this->external_adc_ != nullptr){ + if (this->external_adc_ != nullptr) { this->external_adc_->apply_i2s_settings(i2s_config); } #endif @@ -65,12 +65,11 @@ bool ADFElementI2SIn::init_adf_elements_() { return true; }; -bool ADFElementI2SIn::is_ready(){ - if( !this->claim_i2s_access() ) - { +bool ADFElementI2SIn::is_ready() { + if (!this->claim_i2s_access()) { return false; } - if( !this->valid_settings_){ + if (!this->valid_settings_) { AudioPipelineSettingsRequest request{this}; request.sampling_rate = this->sample_rate_; request.bit_depth = this->bits_per_sample_; @@ -80,13 +79,12 @@ bool ADFElementI2SIn::is_ready(){ return this->valid_settings_; } -void ADFElementI2SIn::clear_adf_elements_(){ +void ADFElementI2SIn::clear_adf_elements_() { this->sdk_audio_elements_.clear(); this->sdk_element_tags_.clear(); this->uninstall_i2s_driver(); } - } // namespace i2s_audio } // namespace esphome diff --git a/esphome/components/i2s_audio/adf_pipeline/adf_i2s_in.h b/esphome/components/i2s_audio/adf_pipeline/adf_i2s_in.h index f3f0d56..ddf4c24 100644 --- a/esphome/components/i2s_audio/adf_pipeline/adf_i2s_in.h +++ b/esphome/components/i2s_audio/adf_pipeline/adf_i2s_in.h @@ -22,8 +22,7 @@ class ADFElementI2SIn : public I2SReader, public ADFPipelineSourceElement, publi void dump_config() override { this->dump_i2s_settings(); } bool is_ready() override; - protected: - + protected: bool valid_settings_{false}; bool init_adf_elements_() override; void clear_adf_elements_() override; diff --git a/esphome/components/i2s_audio/adf_pipeline/adf_i2s_out.cpp b/esphome/components/i2s_audio/adf_pipeline/adf_i2s_out.cpp index f17ed2f..70236dd 100644 --- a/esphome/components/i2s_audio/adf_pipeline/adf_i2s_out.cpp +++ b/esphome/components/i2s_audio/adf_pipeline/adf_i2s_out.cpp @@ -14,20 +14,18 @@ namespace i2s_audio { static const char *const TAG = "adf_i2s_out"; - -void ADFElementI2SOut::setup() { -} +void ADFElementI2SOut::setup() {} bool ADFElementI2SOut::init_adf_elements_() { if (this->sdk_audio_elements_.size() > 0) return true; - if ( !this->claim_i2s_access() ){ + if (!this->claim_i2s_access()) { return false; } #ifdef I2S_EXTERNAL_DAC - if (this->external_dac_ != nullptr){ + if (this->external_dac_ != nullptr) { this->external_dac_->init_device(); } #endif @@ -57,7 +55,7 @@ bool ADFElementI2SOut::init_adf_elements_() { this->install_i2s_driver(i2s_config); #ifdef I2S_EXTERNAL_DAC - if (this->external_dac_ != nullptr){ + if (this->external_dac_ != nullptr) { this->external_dac_->apply_i2s_settings(i2s_config); } #endif @@ -68,30 +66,27 @@ bool ADFElementI2SOut::init_adf_elements_() { return true; } -void ADFElementI2SOut::clear_adf_elements_(){ +void ADFElementI2SOut::clear_adf_elements_() { this->sdk_audio_elements_.clear(); this->sdk_element_tags_.clear(); this->uninstall_i2s_driver(); } -bool ADFElementI2SOut::is_ready(){ - return this->claim_i2s_access(); -} +bool ADFElementI2SOut::is_ready() { return this->claim_i2s_access(); } void ADFElementI2SOut::on_settings_request(AudioPipelineSettingsRequest &request) { - if ( !this->adf_i2s_stream_writer_ ){ + if (!this->adf_i2s_stream_writer_) { return; } - if (this->is_adjustable()){ + if (this->is_adjustable()) { bool rate_bits_channels_updated = false; if (request.sampling_rate > 0 && (uint32_t) request.sampling_rate != this->sample_rate_) { this->sample_rate_ = request.sampling_rate; rate_bits_channels_updated = true; } - if(request.number_of_channels > 0 && (uint8_t) request.number_of_channels != this->num_of_channels()) - { + if (request.number_of_channels > 0 && (uint8_t) request.number_of_channels != this->num_of_channels()) { this->channel_fmt_ = request.number_of_channels == 1 ? I2S_CHANNEL_FMT_ONLY_RIGHT : I2S_CHANNEL_FMT_RIGHT_LEFT; rate_bits_channels_updated = true; } @@ -108,12 +103,13 @@ void ADFElementI2SOut::on_settings_request(AudioPipelineSettingsRequest &request } if (rate_bits_channels_updated) { + audio_element_set_music_info(this->adf_i2s_stream_writer_, this->sample_rate_, this->num_of_channels(), + this->bits_per_sample_); - audio_element_set_music_info(this->adf_i2s_stream_writer_,this->sample_rate_, this->num_of_channels(), this->bits_per_sample_ ); - - esph_log_d(TAG, "update i2s clk settings: rate:%d bits:%d ch:%d",this->sample_rate_, this->bits_per_sample_, this->num_of_channels()); + esph_log_d(TAG, "update i2s clk settings: rate:%d bits:%d ch:%d", this->sample_rate_, this->bits_per_sample_, + this->num_of_channels()); if (i2s_stream_set_clk(this->adf_i2s_stream_writer_, this->sample_rate_, this->bits_per_sample_, - this->num_of_channels()) != ESP_OK) { + this->num_of_channels()) != ESP_OK) { esph_log_e(TAG, "error while setting sample rate and bit depth,"); request.failed = true; request.failed_by = this; @@ -128,12 +124,8 @@ void ADFElementI2SOut::on_settings_request(AudioPipelineSettingsRequest &request request.final_sampling_rate = this->sample_rate_; request.final_bit_depth = this->bits_per_sample_; request.final_number_of_channels = this->num_of_channels(); - } else if ( - request.final_sampling_rate != this->sample_rate_ - || request.final_bit_depth != this->bits_per_sample_ - || request.final_number_of_channels != this->num_of_channels() - ) - { + } else if (request.final_sampling_rate != this->sample_rate_ || request.final_bit_depth != this->bits_per_sample_ || + request.final_number_of_channels != this->num_of_channels()) { request.failed = true; request.failed_by = this; } @@ -148,8 +140,8 @@ void ADFElementI2SOut::on_settings_request(AudioPipelineSettingsRequest &request } } #ifdef I2S_EXTERNAL_DAC - if( this->external_dac_ != nullptr && request.target_volume > -1){ - this->external_dac_->set_volume( request.target_volume); + if (this->external_dac_ != nullptr && request.target_volume > -1) { + this->external_dac_->set_volume(request.target_volume); } #endif } diff --git a/esphome/components/i2s_audio/adf_pipeline/adf_i2s_out.h b/esphome/components/i2s_audio/adf_pipeline/adf_i2s_out.h index 327ba6b..b953522 100644 --- a/esphome/components/i2s_audio/adf_pipeline/adf_i2s_out.h +++ b/esphome/components/i2s_audio/adf_pipeline/adf_i2s_out.h @@ -22,8 +22,7 @@ class ADFElementI2SOut : public I2SWriter, public ADFPipelineSinkElement, public void dump_config() override { this->dump_i2s_settings(); } bool is_ready() override; - void set_use_adf_alc(bool use_alc){ this->use_adf_alc_ = use_alc; } - + void set_use_adf_alc(bool use_alc) { this->use_adf_alc_ = use_alc; } protected: void on_settings_request(AudioPipelineSettingsRequest &request) override; diff --git a/esphome/components/i2s_audio/adf_pipeline/i2s_stream_mod.h b/esphome/components/i2s_audio/adf_pipeline/i2s_stream_mod.h index 3fb2445..ab52cbf 100644 --- a/esphome/components/i2s_audio/adf_pipeline/i2s_stream_mod.h +++ b/esphome/components/i2s_audio/adf_pipeline/i2s_stream_mod.h @@ -39,200 +39,146 @@ extern "C" { * Default value will be used if any entry is zero */ typedef struct { - audio_stream_type_t type; /*!< Type of stream */ - i2s_config_t i2s_config; /*!< I2S driver configurations */ - i2s_port_t i2s_port; /*!< I2S driver hardware port */ - bool use_alc; /*!< It is a flag for ALC. If use ALC, the value is true. Or the value is false */ - int volume; /*!< The volume of audio input data will be set. */ - int out_rb_size; /*!< Size of output ringbuffer */ - int task_stack; /*!< Task stack size */ - int task_core; /*!< Task running in core (0 or 1) */ - int task_prio; /*!< Task priority (based on freeRTOS priority) */ - bool stack_in_ext; /*!< Try to allocate stack in external memory */ - int multi_out_num; /*!< The number of multiple output */ - bool uninstall_drv; /*!< whether uninstall the i2s driver when stream destroyed*/ - bool need_expand; /*!< whether to expand i2s data */ - i2s_bits_per_sample_t expand_src_bits; /*!< The source bits per sample when data expand */ + audio_stream_type_t type; /*!< Type of stream */ + i2s_config_t i2s_config; /*!< I2S driver configurations */ + i2s_port_t i2s_port; /*!< I2S driver hardware port */ + bool use_alc; /*!< It is a flag for ALC. If use ALC, the value is true. Or the value is false */ + int volume; /*!< The volume of audio input data will be set. */ + int out_rb_size; /*!< Size of output ringbuffer */ + int task_stack; /*!< Task stack size */ + int task_core; /*!< Task running in core (0 or 1) */ + int task_prio; /*!< Task priority (based on freeRTOS priority) */ + bool stack_in_ext; /*!< Try to allocate stack in external memory */ + int multi_out_num; /*!< The number of multiple output */ + bool uninstall_drv; /*!< whether uninstall the i2s driver when stream destroyed*/ + bool need_expand; /*!< whether to expand i2s data */ + i2s_bits_per_sample_t expand_src_bits; /*!< The source bits per sample when data expand */ } i2s_stream_cfg_t; -#define I2S_STREAM_TASK_STACK (3072+512) -#define I2S_STREAM_BUF_SIZE (2048) -#define I2S_STREAM_TASK_PRIO (23) -#define I2S_STREAM_TASK_CORE (0) -#define I2S_STREAM_RINGBUFFER_SIZE (8 * 1024) +#define I2S_STREAM_TASK_STACK (3072 + 512) +#define I2S_STREAM_BUF_SIZE (2048) +#define I2S_STREAM_TASK_PRIO (23) +#define I2S_STREAM_TASK_CORE (0) +#define I2S_STREAM_RINGBUFFER_SIZE (8 * 1024) #if (ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(4, 2, 0)) -#define I2S_STREAM_CFG_DEFAULT() { \ - .type = AUDIO_STREAM_WRITER, \ - .i2s_config = { \ - .mode = (i2s_mode_t)(I2S_MODE_MASTER | I2S_MODE_TX | I2S_MODE_RX), \ - .sample_rate = 44100, \ - .bits_per_sample = I2S_BITS_PER_SAMPLE_16BIT, \ - .channel_format = I2S_CHANNEL_FMT_RIGHT_LEFT, \ - .communication_format = I2S_COMM_FORMAT_I2S, \ - .intr_alloc_flags = ESP_INTR_FLAG_LEVEL2 | ESP_INTR_FLAG_IRAM, \ - .dma_buf_count = 3, \ - .dma_buf_len = 300, \ - .use_apll = true, \ - .tx_desc_auto_clear = true, \ - .fixed_mclk = 0 \ - }, \ - .i2s_port = I2S_NUM_0, \ - .use_alc = false, \ - .volume = 0, \ - .out_rb_size = I2S_STREAM_RINGBUFFER_SIZE, \ - .task_stack = I2S_STREAM_TASK_STACK, \ - .task_core = I2S_STREAM_TASK_CORE, \ - .task_prio = I2S_STREAM_TASK_PRIO, \ - .stack_in_ext = false, \ - .multi_out_num = 0, \ - .uninstall_drv = true, \ - .need_expand = false, \ - .expand_src_bits = I2S_BITS_PER_SAMPLE_16BIT, \ -} - -#define I2S_STREAM_INTERNAL_DAC_CFG_DEFAULT() { \ - .type = AUDIO_STREAM_WRITER, \ - .i2s_config = { \ - .mode = (i2s_mode_t)(I2S_MODE_MASTER | I2S_MODE_DAC_BUILT_IN | I2S_MODE_TX),\ - .sample_rate = 44100, \ - .bits_per_sample = I2S_BITS_PER_SAMPLE_16BIT, \ - .channel_format = I2S_CHANNEL_FMT_RIGHT_LEFT, \ - .communication_format = I2S_COMM_FORMAT_I2S_MSB, \ - .intr_alloc_flags = ESP_INTR_FLAG_LEVEL2, \ - .dma_buf_count = 3, \ - .dma_buf_len = 300, \ - .use_apll = false, \ - .tx_desc_auto_clear = true, \ - .fixed_mclk = 0 \ - }, \ - .i2s_port = I2S_NUM_0, \ - .use_alc = false, \ - .volume = 0, \ - .out_rb_size = I2S_STREAM_RINGBUFFER_SIZE, \ - .task_stack = I2S_STREAM_TASK_STACK, \ - .task_core = I2S_STREAM_TASK_CORE, \ - .task_prio = I2S_STREAM_TASK_PRIO, \ - .stack_in_ext = false, \ - .multi_out_num = 0, \ - .uninstall_drv = false, \ - .need_expand = false, \ - .expand_src_bits = I2S_BITS_PER_SAMPLE_16BIT, \ -} - -#define I2S_STREAM_TX_PDM_CFG_DEFAULT() { \ - .type = AUDIO_STREAM_WRITER, \ - .i2s_config = { \ - .mode = (i2s_mode_t)(I2S_MODE_MASTER | I2S_MODE_PDM | I2S_MODE_TX), \ - .sample_rate = 44100, \ - .bits_per_sample = I2S_BITS_PER_SAMPLE_16BIT, \ - .channel_format = I2S_CHANNEL_FMT_RIGHT_LEFT, \ - .communication_format = I2S_COMM_FORMAT_I2S_MSB, \ - .dma_buf_count = 3, \ - .dma_buf_len = 300, \ - .use_apll = true, \ - .tx_desc_auto_clear = true, \ - .fixed_mclk = 0 \ - }, \ - .i2s_port = I2S_NUM_0, \ - .use_alc = false, \ - .volume = 0, \ - .out_rb_size = I2S_STREAM_RINGBUFFER_SIZE, \ - .task_stack = I2S_STREAM_TASK_STACK, \ - .task_core = I2S_STREAM_TASK_CORE, \ - .task_prio = I2S_STREAM_TASK_PRIO, \ - .stack_in_ext = false, \ - .multi_out_num = 0, \ - .uninstall_drv = false, \ - .need_expand = false, \ - .expand_src_bits = I2S_BITS_PER_SAMPLE_16BIT, \ -} +#define I2S_STREAM_CFG_DEFAULT() \ + { \ + .type = AUDIO_STREAM_WRITER, \ + .i2s_config = {.mode = (i2s_mode_t) (I2S_MODE_MASTER | I2S_MODE_TX | I2S_MODE_RX), \ + .sample_rate = 44100, \ + .bits_per_sample = I2S_BITS_PER_SAMPLE_16BIT, \ + .channel_format = I2S_CHANNEL_FMT_RIGHT_LEFT, \ + .communication_format = I2S_COMM_FORMAT_I2S, \ + .intr_alloc_flags = ESP_INTR_FLAG_LEVEL2 | ESP_INTR_FLAG_IRAM, \ + .dma_buf_count = 3, \ + .dma_buf_len = 300, \ + .use_apll = true, \ + .tx_desc_auto_clear = true, \ + .fixed_mclk = 0}, \ + .i2s_port = I2S_NUM_0, .use_alc = false, .volume = 0, .out_rb_size = I2S_STREAM_RINGBUFFER_SIZE, \ + .task_stack = I2S_STREAM_TASK_STACK, .task_core = I2S_STREAM_TASK_CORE, .task_prio = I2S_STREAM_TASK_PRIO, \ + .stack_in_ext = false, .multi_out_num = 0, .uninstall_drv = true, .need_expand = false, \ + .expand_src_bits = I2S_BITS_PER_SAMPLE_16BIT, \ + } + +#define I2S_STREAM_INTERNAL_DAC_CFG_DEFAULT() \ + { \ + .type = AUDIO_STREAM_WRITER, \ + .i2s_config = {.mode = (i2s_mode_t) (I2S_MODE_MASTER | I2S_MODE_DAC_BUILT_IN | I2S_MODE_TX), \ + .sample_rate = 44100, \ + .bits_per_sample = I2S_BITS_PER_SAMPLE_16BIT, \ + .channel_format = I2S_CHANNEL_FMT_RIGHT_LEFT, \ + .communication_format = I2S_COMM_FORMAT_I2S_MSB, \ + .intr_alloc_flags = ESP_INTR_FLAG_LEVEL2, \ + .dma_buf_count = 3, \ + .dma_buf_len = 300, \ + .use_apll = false, \ + .tx_desc_auto_clear = true, \ + .fixed_mclk = 0}, \ + .i2s_port = I2S_NUM_0, .use_alc = false, .volume = 0, .out_rb_size = I2S_STREAM_RINGBUFFER_SIZE, \ + .task_stack = I2S_STREAM_TASK_STACK, .task_core = I2S_STREAM_TASK_CORE, .task_prio = I2S_STREAM_TASK_PRIO, \ + .stack_in_ext = false, .multi_out_num = 0, .uninstall_drv = false, .need_expand = false, \ + .expand_src_bits = I2S_BITS_PER_SAMPLE_16BIT, \ + } + +#define I2S_STREAM_TX_PDM_CFG_DEFAULT() \ + { \ + .type = AUDIO_STREAM_WRITER, \ + .i2s_config = {.mode = (i2s_mode_t) (I2S_MODE_MASTER | I2S_MODE_PDM | I2S_MODE_TX), \ + .sample_rate = 44100, \ + .bits_per_sample = I2S_BITS_PER_SAMPLE_16BIT, \ + .channel_format = I2S_CHANNEL_FMT_RIGHT_LEFT, \ + .communication_format = I2S_COMM_FORMAT_I2S_MSB, \ + .dma_buf_count = 3, \ + .dma_buf_len = 300, \ + .use_apll = true, \ + .tx_desc_auto_clear = true, \ + .fixed_mclk = 0}, \ + .i2s_port = I2S_NUM_0, .use_alc = false, .volume = 0, .out_rb_size = I2S_STREAM_RINGBUFFER_SIZE, \ + .task_stack = I2S_STREAM_TASK_STACK, .task_core = I2S_STREAM_TASK_CORE, .task_prio = I2S_STREAM_TASK_PRIO, \ + .stack_in_ext = false, .multi_out_num = 0, .uninstall_drv = false, .need_expand = false, \ + .expand_src_bits = I2S_BITS_PER_SAMPLE_16BIT, \ + } #else -#define I2S_STREAM_CFG_DEFAULT() { \ - .type = AUDIO_STREAM_WRITER, \ - .i2s_config = { \ - .mode = (i2s_mode_t)(I2S_MODE_MASTER | I2S_MODE_TX | I2S_MODE_RX), \ - .sample_rate = 44100, \ - .bits_per_sample = I2S_BITS_PER_SAMPLE_16BIT, \ - .channel_format = I2S_CHANNEL_FMT_RIGHT_LEFT, \ - .communication_format = I2S_COMM_FORMAT_STAND_I2S, \ - .intr_alloc_flags = ESP_INTR_FLAG_LEVEL2 | ESP_INTR_FLAG_IRAM, \ - .dma_buf_count = 3, \ - .dma_buf_len = 300, \ - .use_apll = true, \ - .tx_desc_auto_clear = true, \ - .fixed_mclk = 0 \ - }, \ - .i2s_port = I2S_NUM_0, \ - .use_alc = false, \ - .volume = 0, \ - .out_rb_size = I2S_STREAM_RINGBUFFER_SIZE, \ - .task_stack = I2S_STREAM_TASK_STACK, \ - .task_core = I2S_STREAM_TASK_CORE, \ - .task_prio = I2S_STREAM_TASK_PRIO, \ - .stack_in_ext = false, \ - .multi_out_num = 0, \ - .uninstall_drv = true, \ - .need_expand = false, \ - .expand_src_bits = I2S_BITS_PER_SAMPLE_16BIT, \ -} - -#define I2S_STREAM_INTERNAL_DAC_CFG_DEFAULT() { \ - .type = AUDIO_STREAM_WRITER, \ - .i2s_config = { \ - .mode = (i2s_mode_t)(I2S_MODE_MASTER | I2S_MODE_DAC_BUILT_IN | I2S_MODE_TX),\ - .sample_rate = 44100, \ - .bits_per_sample = I2S_BITS_PER_SAMPLE_16BIT, \ - .channel_format = I2S_CHANNEL_FMT_RIGHT_LEFT, \ - .communication_format = I2S_COMM_FORMAT_STAND_MSB, \ - .intr_alloc_flags = ESP_INTR_FLAG_LEVEL2, \ - .dma_buf_count = 3, \ - .dma_buf_len = 300, \ - .use_apll = false, \ - .tx_desc_auto_clear = true, \ - .fixed_mclk = 0 \ - }, \ - .i2s_port = I2S_NUM_0, \ - .use_alc = false, \ - .volume = 0, \ - .out_rb_size = I2S_STREAM_RINGBUFFER_SIZE, \ - .task_stack = I2S_STREAM_TASK_STACK, \ - .task_core = I2S_STREAM_TASK_CORE, \ - .task_prio = I2S_STREAM_TASK_PRIO, \ - .stack_in_ext = false, \ - .multi_out_num = 0, \ - .uninstall_drv = false, \ - .need_expand = false, \ - .expand_src_bits = I2S_BITS_PER_SAMPLE_16BIT, \ -} - -#define I2S_STREAM_TX_PDM_CFG_DEFAULT() { \ - .type = AUDIO_STREAM_WRITER, \ - .i2s_config = { \ - .mode = (i2s_mode_t)(I2S_MODE_MASTER | I2S_MODE_PDM | I2S_MODE_TX), \ - .sample_rate = 48000, \ - .bits_per_sample = I2S_BITS_PER_SAMPLE_16BIT, \ - .channel_format = I2S_CHANNEL_FMT_RIGHT_LEFT, \ - .communication_format = I2S_COMM_FORMAT_STAND_MSB, \ - .dma_buf_count = 3, \ - .dma_buf_len = 300, \ - .use_apll = true, \ - .tx_desc_auto_clear = true, \ - .fixed_mclk = 0 \ - }, \ - .i2s_port = I2S_NUM_0, \ - .use_alc = false, \ - .volume = 0, \ - .out_rb_size = I2S_STREAM_RINGBUFFER_SIZE, \ - .task_stack = I2S_STREAM_TASK_STACK, \ - .task_core = I2S_STREAM_TASK_CORE, \ - .task_prio = I2S_STREAM_TASK_PRIO, \ - .stack_in_ext = false, \ - .multi_out_num = 0, \ - .uninstall_drv = false, \ - .need_expand = false, \ - .expand_src_bits = I2S_BITS_PER_SAMPLE_16BIT, \ -} +#define I2S_STREAM_CFG_DEFAULT() \ + { \ + .type = AUDIO_STREAM_WRITER, \ + .i2s_config = {.mode = (i2s_mode_t) (I2S_MODE_MASTER | I2S_MODE_TX | I2S_MODE_RX), \ + .sample_rate = 44100, \ + .bits_per_sample = I2S_BITS_PER_SAMPLE_16BIT, \ + .channel_format = I2S_CHANNEL_FMT_RIGHT_LEFT, \ + .communication_format = I2S_COMM_FORMAT_STAND_I2S, \ + .intr_alloc_flags = ESP_INTR_FLAG_LEVEL2 | ESP_INTR_FLAG_IRAM, \ + .dma_buf_count = 3, \ + .dma_buf_len = 300, \ + .use_apll = true, \ + .tx_desc_auto_clear = true, \ + .fixed_mclk = 0}, \ + .i2s_port = I2S_NUM_0, .use_alc = false, .volume = 0, .out_rb_size = I2S_STREAM_RINGBUFFER_SIZE, \ + .task_stack = I2S_STREAM_TASK_STACK, .task_core = I2S_STREAM_TASK_CORE, .task_prio = I2S_STREAM_TASK_PRIO, \ + .stack_in_ext = false, .multi_out_num = 0, .uninstall_drv = true, .need_expand = false, \ + .expand_src_bits = I2S_BITS_PER_SAMPLE_16BIT, \ + } + +#define I2S_STREAM_INTERNAL_DAC_CFG_DEFAULT() \ + { \ + .type = AUDIO_STREAM_WRITER, \ + .i2s_config = {.mode = (i2s_mode_t) (I2S_MODE_MASTER | I2S_MODE_DAC_BUILT_IN | I2S_MODE_TX), \ + .sample_rate = 44100, \ + .bits_per_sample = I2S_BITS_PER_SAMPLE_16BIT, \ + .channel_format = I2S_CHANNEL_FMT_RIGHT_LEFT, \ + .communication_format = I2S_COMM_FORMAT_STAND_MSB, \ + .intr_alloc_flags = ESP_INTR_FLAG_LEVEL2, \ + .dma_buf_count = 3, \ + .dma_buf_len = 300, \ + .use_apll = false, \ + .tx_desc_auto_clear = true, \ + .fixed_mclk = 0}, \ + .i2s_port = I2S_NUM_0, .use_alc = false, .volume = 0, .out_rb_size = I2S_STREAM_RINGBUFFER_SIZE, \ + .task_stack = I2S_STREAM_TASK_STACK, .task_core = I2S_STREAM_TASK_CORE, .task_prio = I2S_STREAM_TASK_PRIO, \ + .stack_in_ext = false, .multi_out_num = 0, .uninstall_drv = false, .need_expand = false, \ + .expand_src_bits = I2S_BITS_PER_SAMPLE_16BIT, \ + } + +#define I2S_STREAM_TX_PDM_CFG_DEFAULT() \ + { \ + .type = AUDIO_STREAM_WRITER, \ + .i2s_config = {.mode = (i2s_mode_t) (I2S_MODE_MASTER | I2S_MODE_PDM | I2S_MODE_TX), \ + .sample_rate = 48000, \ + .bits_per_sample = I2S_BITS_PER_SAMPLE_16BIT, \ + .channel_format = I2S_CHANNEL_FMT_RIGHT_LEFT, \ + .communication_format = I2S_COMM_FORMAT_STAND_MSB, \ + .dma_buf_count = 3, \ + .dma_buf_len = 300, \ + .use_apll = true, \ + .tx_desc_auto_clear = true, \ + .fixed_mclk = 0}, \ + .i2s_port = I2S_NUM_0, .use_alc = false, .volume = 0, .out_rb_size = I2S_STREAM_RINGBUFFER_SIZE, \ + .task_stack = I2S_STREAM_TASK_STACK, .task_core = I2S_STREAM_TASK_CORE, .task_prio = I2S_STREAM_TASK_PRIO, \ + .stack_in_ext = false, .multi_out_num = 0, .uninstall_drv = false, .need_expand = false, \ + .expand_src_bits = I2S_BITS_PER_SAMPLE_16BIT, \ + } #endif /** diff --git a/esphome/components/i2s_audio/external_adc.cpp b/esphome/components/i2s_audio/external_adc.cpp index 0c7b7a4..2b1e55f 100644 --- a/esphome/components/i2s_audio/external_adc.cpp +++ b/esphome/components/i2s_audio/external_adc.cpp @@ -9,48 +9,45 @@ namespace i2s_audio { static const char *const TAG = "i2s_external_adc"; -bool ES7210::init_device(){ - esph_log_d(TAG, "Init ES7210..."); - struct __attribute__((packed)) reg_data_t - { - uint8_t reg; - uint8_t value; - }; +bool ES7210::init_device() { + esph_log_d(TAG, "Init ES7210..."); + struct __attribute__((packed)) reg_data_t { + uint8_t reg; + uint8_t value; + }; - static constexpr reg_data_t data[] = - { - { 0x00, 0x41 }, // RESET_CTL - { 0x01, 0x1f }, // CLK_ON_OFF + static constexpr reg_data_t data[] = { + {0x00, 0x41}, // RESET_CTL + {0x01, 0x1f}, // CLK_ON_OFF - { 0x06, 0x00 }, // DIGITAL_PDN - //{ 0x06, 0x01 }, // DIGITAL_PDN (disable pull down resistors) + {0x06, 0x00}, // DIGITAL_PDN + //{ 0x06, 0x01 }, // DIGITAL_PDN (disable pull down resistors) - { 0x07, 0x20 }, // ADC_OSR - { 0x08, 0x10 }, // MODE_CFG [2ch, no_invert, EQ on, single speed, LRCK: slave mode] + {0x07, 0x20}, // ADC_OSR + {0x08, 0x10}, // MODE_CFG [2ch, no_invert, EQ on, single speed, LRCK: slave mode] - { 0x09, 0x30 }, // TCT0 CHIPINI_LGTH [48] period=CHIPINI_LGTH/(LRCK frequency)*16 - { 0x0A, 0x30 }, // TCT1 PWRUP_LGTH [48] period=PWRUP_LGTH/(LRCK frequency)*16 + {0x09, 0x30}, // TCT0 CHIPINI_LGTH [48] period=CHIPINI_LGTH/(LRCK frequency)*16 + {0x0A, 0x30}, // TCT1 PWRUP_LGTH [48] period=PWRUP_LGTH/(LRCK frequency)*16 - //{0x0B,0x00}, // CLEAR_RAM, FORCE_CSM, ADC34_MUTE_FLAG, ADC12_MUTE_FLAG, CSM_STATE - //{0x0C,0x00}, // Interrupt control - //{0,0D,0x09}, // I2C_IBTHD_SEL, CLKDBLK_PW_SEL, CLKDBL_PATH_SEL, LRCK_EXTEND, DELAY_SEL + //{0x0B,0x00}, // CLEAR_RAM, FORCE_CSM, ADC34_MUTE_FLAG, ADC12_MUTE_FLAG, CSM_STATE + //{0x0C,0x00}, // Interrupt control + //{0,0D,0x09}, // I2C_IBTHD_SEL, CLKDBLK_PW_SEL, CLKDBL_PATH_SEL, LRCK_EXTEND, DELAY_SEL - //{0x10, 0x00}, // DMIC-Ctrl ADC34_DMIC_ON, ADC12_DMIC_ON, ADC34_DMIC_GAIN, ADC12_DMIC_GAIN + //{0x10, 0x00}, // DMIC-Ctrl ADC34_DMIC_ON, ADC12_DMIC_ON, ADC34_DMIC_GAIN, ADC12_DMIC_GAIN + {0x20, 0x0a}, // ADC34_HPF2 + {0x21, 0x2a}, // ADC34_HPF1 + {0x22, 0x0a}, // ADC12_HPF2 + {0x23, 0x2a}, // ADC12_HPF1 - { 0x20, 0x0a }, // ADC34_HPF2 - { 0x21, 0x2a }, // ADC34_HPF1 - { 0x22, 0x0a }, // ADC12_HPF2 - { 0x23, 0x2a }, // ADC12_HPF1 + // 0x24 to 0x37 EQ coefficients - //0x24 to 0x37 EQ coefficients + {0x02, 0xC1}, // Main clk cntrl [bypass DLL, use clock doubler, CLK_ADC_DIV: no divide] + //{ 0x03, 0x04 }, // MCL cntrl [MCLK from pad, divide by 4] + {0x04, 0x01}, // Master LRCK divider 1 [ M_LRCK_DIV[11:8] ] + {0x05, 0x00}, // Master LRCK divider 0 [ M_LRCK_DIV[ 7:0] ] - { 0x02, 0xC1 }, // Main clk cntrl [bypass DLL, use clock doubler, CLK_ADC_DIV: no divide] - //{ 0x03, 0x04 }, // MCL cntrl [MCLK from pad, divide by 4] - { 0x04, 0x01 }, // Master LRCK divider 1 [ M_LRCK_DIV[11:8] ] - { 0x05, 0x00 }, // Master LRCK divider 0 [ M_LRCK_DIV[ 7:0] ] - - { 0x11, 0x60 }, //SDP IF: SP_WL, SP_LRP, SP_PROTOCOL [16bit, L/R normal polarity, I2S] + {0x11, 0x60}, // SDP IF: SP_WL, SP_LRP, SP_PROTOCOL [16bit, L/R normal polarity, I2S] //{ 0x12, 0x00 }, // SDOUT_MODE: [ADC12 to SDOUT1, ADC34 to SDOUT2] //{ 0x13, 0x00 }, // ADC AUTO-MUTE [no auto-mute] //{ 0x14, 0x00 }, // ADC34 MUTE Cntrl @@ -61,38 +58,34 @@ bool ES7210::init_device(){ //{ 0x19, 0xF7 }, // ADC12 ALC LEVEL //{ 0x1A, 0x00 }, // ALC common cfg 2 - { 0x40, 0x42 }, // ANALOG_SYS [ VX2OFF: turn off (VDDA=3.3V), VMIDSEL: 500 kΩ divider enabled] - { 0x41, 0x70 }, // MICBIAS12 [LVL_MICBIAS12: 2.87V (VDDM=3.3V), ADC12BIAS_SWH: x1] - { 0x42, 0x70 }, // MICBIAS34 [LVL_MICBIAS34: 2.87V (VDDM=3.3V), ADC34BIAS_SWH: x1] - { 0x43, 0x1B }, // MIC1_GAIN [SELMIC1: select MIC1P and MIC1N, GAIN: 33dB] - { 0x44, 0x1B }, // MIC2_GAIN [SELMIC2: select MIC2P and MIC2N, GAIN: 33dB] - { 0x45, 0x00 }, // MIC3_GAIN [deselect MIC3] - { 0x46, 0x00 }, // MIC4_GAIN [deselect MIC4] - { 0x47, 0x00 }, // MIC1 Low Power [all set to normal] - { 0x48, 0x00 }, // MIC2 Low Power [all set to normal] - { 0x49, 0x00 }, // MIC3 Low Power [all set to normal] - { 0x4A, 0x00 }, // MIC4 Low Power [all set to normal] - { 0x4B, 0x00 }, // MIC 1/2 power down [all set to normal] - { 0x4C, 0xFF }, // MIC3 3/4 power down [all set to power down] - - { 0x01, 0x14 }, // CLK_ON_OFF - //{ 0x01, 0xBF }, // CLK_ON_OFF - }; - for (auto& d: data) - { - this->reg(d.reg) = d.value; - } - return true; + {0x40, 0x42}, // ANALOG_SYS [ VX2OFF: turn off (VDDA=3.3V), VMIDSEL: 500 kΩ divider enabled] + {0x41, 0x70}, // MICBIAS12 [LVL_MICBIAS12: 2.87V (VDDM=3.3V), ADC12BIAS_SWH: x1] + {0x42, 0x70}, // MICBIAS34 [LVL_MICBIAS34: 2.87V (VDDM=3.3V), ADC34BIAS_SWH: x1] + {0x43, 0x1B}, // MIC1_GAIN [SELMIC1: select MIC1P and MIC1N, GAIN: 33dB] + {0x44, 0x1B}, // MIC2_GAIN [SELMIC2: select MIC2P and MIC2N, GAIN: 33dB] + {0x45, 0x00}, // MIC3_GAIN [deselect MIC3] + {0x46, 0x00}, // MIC4_GAIN [deselect MIC4] + {0x47, 0x00}, // MIC1 Low Power [all set to normal] + {0x48, 0x00}, // MIC2 Low Power [all set to normal] + {0x49, 0x00}, // MIC3 Low Power [all set to normal] + {0x4A, 0x00}, // MIC4 Low Power [all set to normal] + {0x4B, 0x00}, // MIC 1/2 power down [all set to normal] + {0x4C, 0xFF}, // MIC3 3/4 power down [all set to power down] + + {0x01, 0x14}, // CLK_ON_OFF + //{ 0x01, 0xBF }, // CLK_ON_OFF + }; + for (auto &d : data) { + this->reg(d.reg) = d.value; + } + return true; } -bool ES7210::apply_i2s_settings(const i2s_driver_config_t& i2s_cfg){ - //hard coded to 16bit, - return true; +bool ES7210::apply_i2s_settings(const i2s_driver_config_t &i2s_cfg) { + // hard coded to 16bit, + return true; } - - - -} -} +} // namespace i2s_audio +} // namespace esphome #endif diff --git a/esphome/components/i2s_audio/external_adc.h b/esphome/components/i2s_audio/external_adc.h index e033009..1c3083a 100644 --- a/esphome/components/i2s_audio/external_adc.h +++ b/esphome/components/i2s_audio/external_adc.h @@ -11,26 +11,26 @@ namespace esphome { namespace i2s_audio { - class ExternalADC : public i2c::I2CDevice { -public: + public: virtual bool init_device() = 0; - virtual bool deinit_device() {return true;} + virtual bool deinit_device() { return true; } + + virtual bool apply_i2s_settings(const i2s_driver_config_t &i2s_cfg) { return true; } - virtual bool apply_i2s_settings(const i2s_driver_config_t& i2s_cfg) {return true;} + void set_gpio_enable(GPIOPin *enable_pin) { this->enable_pin_ = enable_pin; } - void set_gpio_enable(GPIOPin* enable_pin){this->enable_pin_ = enable_pin;} -protected: - GPIOPin* enable_pin_{nullptr}; + protected: + GPIOPin *enable_pin_{nullptr}; }; class ES7210 : public ExternalADC { -public: + public: bool init_device() override; - bool apply_i2s_settings(const i2s_driver_config_t& i2s_cfg) override; + bool apply_i2s_settings(const i2s_driver_config_t &i2s_cfg) override; }; -} -} +} // namespace i2s_audio +} // namespace esphome #endif diff --git a/esphome/components/i2s_audio/external_dac.cpp b/esphome/components/i2s_audio/external_dac.cpp index 8194279..0679cad 100644 --- a/esphome/components/i2s_audio/external_dac.cpp +++ b/esphome/components/i2s_audio/external_dac.cpp @@ -10,94 +10,94 @@ namespace i2s_audio { static const char *const TAG = "i2s_external_dac"; -bool AW88298::init_device(){ - if( this->enable_pin_ != nullptr ){ +bool AW88298::init_device() { + if (this->enable_pin_ != nullptr) { this->enable_pin_->digital_write(true); } uint16_t val = 0x0673; - this->write_bytes_16(0x61, &val, 1 ); // AW88298_REG_BSTCTRL2 + this->write_bytes_16(0x61, &val, 1); // AW88298_REG_BSTCTRL2 // enabled I2EN and switch to operation mode - val = 0x4042; // I2SEN=1 AMPPD=1 PWDN=0 - this->write_bytes_16(0x04, &val, 1); // AW88298_REG_SYSCTRL + val = 0x4042; // I2SEN=1 AMPPD=1 PWDN=0 + this->write_bytes_16(0x04, &val, 1); // AW88298_REG_SYSCTRL - val = 0x0008; // RMSE=0 HAGCE=0 HDCCE=0 HMUTE=0 - this->write_bytes_16(0x05, &val, 1); //AW88298_REG_SYSCTRL2 + val = 0x0008; // RMSE=0 HAGCE=0 HDCCE=0 HMUTE=0 + this->write_bytes_16(0x05, &val, 1); // AW88298_REG_SYSCTRL2 return true; } -bool AW88298::apply_i2s_settings(const i2s_driver_config_t& i2s_cfg){ +bool AW88298::apply_i2s_settings(const i2s_driver_config_t &i2s_cfg) { esph_log_d(TAG, "Setup AW88298"); - uint16_t val = 0x4000; // I2SEN=1 AMPPD=0 PWDN=0 - val |= (1 << 6) ; // I2S Enable - val |= (1 << 1) ; // power down amp for configuration - this->write_bytes_16(0x04, &val, 1); + uint16_t val = 0x4000; // I2SEN=1 AMPPD=0 PWDN=0 + val |= (1 << 6); // I2S Enable + val |= (1 << 1); // power down amp for configuration + this->write_bytes_16(0x04, &val, 1); - //sampling rate - static constexpr uint8_t rate_tbl[] = {4,5,6,8,10,11,15,20,22,44}; + // sampling rate + static constexpr uint8_t rate_tbl[] = {4, 5, 6, 8, 10, 11, 15, 20, 22, 44}; uint8_t rate_idx = 0; - size_t rate = ( i2s_cfg.sample_rate + 1102) / 2205; - while (rate > rate_tbl[rate_idx] && ++rate_idx < sizeof(rate_tbl)) {} + size_t rate = (i2s_cfg.sample_rate + 1102) / 2205; + while (rate > rate_tbl[rate_idx] && ++rate_idx < sizeof(rate_tbl)) { + } - //bits_per_sample - static constexpr uint8_t supported_bps[] = {16,20,24,32}; + // bits_per_sample + static constexpr uint8_t supported_bps[] = {16, 20, 24, 32}; uint8_t bps = (uint8_t) i2s_cfg.bits_per_sample; uint8_t bps_idx = 0; - while( bps != supported_bps[bps_idx] && ++bps_idx < sizeof(supported_bps)) {} - if( bps_idx == sizeof(supported_bps)) - { + while (bps != supported_bps[bps_idx] && ++bps_idx < sizeof(supported_bps)) { + } + if (bps_idx == sizeof(supported_bps)) { esph_log_e(TAG, "Unsupported bits per sample: %d", bps); return false; } - //bits_per_frame - //00: 16*2 01: 24*2 10: 32*2 11:reserved + // bits_per_frame + // 00: 16*2 01: 24*2 10: 32*2 11:reserved uint8_t i2sbck = 0; - size_t reg0x06_value = (1 << 12); //enable I2S receiver module - reg0x06_value |= (3 << 10); // mono, (L+R)/2 - reg0x06_value |= bps_idx << 6; - reg0x06_value |= i2sbck << 4; + size_t reg0x06_value = (1 << 12); // enable I2S receiver module + reg0x06_value |= (3 << 10); // mono, (L+R)/2 + reg0x06_value |= bps_idx << 6; + reg0x06_value |= i2sbck << 4; reg0x06_value |= rate_idx; - //reg0x06_value |= 0x1C00; // I2SBCK=0 (BCK mode 16*2) - this->write_bytes_16(0x06, (uint16_t *) ®0x06_value, 1 ); + // reg0x06_value |= 0x1C00; // I2SBCK=0 (BCK mode 16*2) + this->write_bytes_16(0x06, (uint16_t *) ®0x06_value, 1); - val = 0x4000; // I2SEN=1 AMPPD=0 PWDN=0 - val |= (1 << 6) ; // I2S Enable - val |= (0 << 1) ; // power up amp for configuration - this->write_bytes_16(0x04, &val, 1); + val = 0x4000; // I2SEN=1 AMPPD=0 PWDN=0 + val |= (1 << 6); // I2S Enable + val |= (0 << 1); // power up amp for configuration + this->write_bytes_16(0x04, &val, 1); return true; } -bool AW88298::set_volume( float volume ){ +bool AW88298::set_volume(float volume) { // 0 to 96 dB // 7:4 in unit of -6dB // 3:0 in unit of -0.5dB uint16_t val = (1. - volume) * 192.; val = (val / 12) << 4 | (val % 12); - val = (val << 8 ) | 0x0064; - this->write_bytes_16(0x0C, &val, 1 ); // AW88298_REG_HAGCCFG3 + val = (val << 8) | 0x0064; + this->write_bytes_16(0x0C, &val, 1); // AW88298_REG_HAGCCFG3 return true; } -bool AW88298::set_mute_audio( bool mute ){ +bool AW88298::set_mute_audio(bool mute) { // Hardware mute module SYSCTRL2 (0x05) register bit 4 uint16_t val; this->read_bytes_16(0x05, &val, 1); - if( mute ){ + if (mute) { val |= (1 << 4); - } - else { + } else { val &= ~(1 << 4); } this->write_bytes_16(0x05, &val, 1); return true; } -bool ES8388::init_device(){ +bool ES8388::init_device() { // mute this->write_byte(0x19, 0x04); // powerup @@ -160,21 +160,19 @@ bool ES8388::init_device(){ return true; } - -bool ES8388::apply_i2s_settings(const i2s_driver_config_t& i2s_cfg){ +bool ES8388::apply_i2s_settings(const i2s_driver_config_t &i2s_cfg) { // i2s 16 bits - //this->write_byte(0x17, 0x18); + // this->write_byte(0x17, 0x18); return true; } -bool ES8388::set_mute_audio( bool mute ){ +bool ES8388::set_mute_audio(bool mute) { // mute / unmute - this->write_byte(0x19, mute ? 0x04 : 0x00 ); + this->write_byte(0x19, mute ? 0x04 : 0x00); return true; } - -} -} +} // namespace i2s_audio +} // namespace esphome #endif diff --git a/esphome/components/i2s_audio/external_dac.h b/esphome/components/i2s_audio/external_dac.h index 9d3eaa5..fc085e3 100644 --- a/esphome/components/i2s_audio/external_dac.h +++ b/esphome/components/i2s_audio/external_dac.h @@ -11,35 +11,34 @@ namespace esphome { namespace i2s_audio { - class ExternalDAC : public i2c::I2CDevice { -public: + public: virtual bool init_device() = 0; - virtual bool deinit_device() {return true;} + virtual bool deinit_device() { return true; } + + virtual bool apply_i2s_settings(const i2s_driver_config_t &i2s_cfg) { return true; } + virtual bool set_mute_audio(bool mute) { return true; } + virtual bool set_volume(float volume) { return true; } - virtual bool apply_i2s_settings(const i2s_driver_config_t& i2s_cfg) {return true;} - virtual bool set_mute_audio( bool mute ){return true;} - virtual bool set_volume( float volume ){return true;} + void set_gpio_enable(GPIOPin *enable_pin) { this->enable_pin_ = enable_pin; } - void set_gpio_enable(GPIOPin* enable_pin){this->enable_pin_ = enable_pin;} -protected: - GPIOPin* enable_pin_{nullptr}; + protected: + GPIOPin *enable_pin_{nullptr}; }; class AW88298 : public ExternalDAC { bool init_device() override; - bool apply_i2s_settings(const i2s_driver_config_t& i2s_cfg) override; - bool set_mute_audio( bool mute ); - bool set_volume( float volume ); + bool apply_i2s_settings(const i2s_driver_config_t &i2s_cfg) override; + bool set_mute_audio(bool mute); + bool set_volume(float volume); }; class ES8388 : public ExternalDAC { bool init_device() override; - bool apply_i2s_settings(const i2s_driver_config_t& i2s_cfg) override; - bool set_mute_audio( bool mute ); + bool apply_i2s_settings(const i2s_driver_config_t &i2s_cfg) override; + bool set_mute_audio(bool mute); }; - -} -} +} // namespace i2s_audio +} // namespace esphome #endif diff --git a/esphome/components/i2s_audio/i2s_audio.cpp b/esphome/components/i2s_audio/i2s_audio.cpp index da01999..0c8bb29 100644 --- a/esphome/components/i2s_audio/i2s_audio.cpp +++ b/esphome/components/i2s_audio/i2s_audio.cpp @@ -24,71 +24,67 @@ void I2SAudioComponent::setup() { ESP_LOGCONFIG(TAG, "Setting up I2S Audio..."); } -void I2SAudioComponent::dump_config(){ +void I2SAudioComponent::dump_config() { esph_log_config(TAG, "I2SController:"); - esph_log_config(TAG, " AccessMode: %s", this->access_mode_ == I2SAccessMode::DUPLEX ? "duplex" : "exclusive" ); - esph_log_config(TAG, " Port: %d", this->get_port() ); - if( this->audio_in_ != nullptr ){ + esph_log_config(TAG, " AccessMode: %s", this->access_mode_ == I2SAccessMode::DUPLEX ? "duplex" : "exclusive"); + esph_log_config(TAG, " Port: %d", this->get_port()); + if (this->audio_in_ != nullptr) { esph_log_config(TAG, " Reader registered."); } - if( this->audio_out_ != nullptr ){ + if (this->audio_out_ != nullptr) { esph_log_config(TAG, " Writer registered."); } } - -bool I2SAudioComponent::claim_access_(uint8_t access){ +bool I2SAudioComponent::claim_access_(uint8_t access) { bool success = false; this->lock(); - if( this->access_mode_ == I2SAccessMode::DUPLEX ){ + if (this->access_mode_ == I2SAccessMode::DUPLEX) { this->access_state_ |= access; success = true; - } - else { - if( this->access_state_ == I2SAccess::FREE ){ + } else { + if (this->access_state_ == I2SAccess::FREE) { this->access_state_ = access; } success = this->access_state_ & access; } this->unlock(); return success; - } +} -bool I2SAudioComponent::release_access_(uint8_t access){ +bool I2SAudioComponent::release_access_(uint8_t access) { this->lock(); this->access_state_ = this->access_state_ & (~access); this->unlock(); return true; } -bool I2SAudioComponent::install_i2s_driver_(i2s_driver_config_t i2s_cfg, uint8_t access){ +bool I2SAudioComponent::install_i2s_driver_(i2s_driver_config_t i2s_cfg, uint8_t access) { bool success = false; this->lock(); - if( this->access_state_ == I2SAccess::FREE || this->access_state_ == access ){ - if(this->access_mode_ == I2SAccessMode::DUPLEX){ + if (this->access_state_ == I2SAccess::FREE || this->access_state_ == access) { + if (this->access_mode_ == I2SAccessMode::DUPLEX) { i2s_cfg.mode = (i2s_mode_t) (i2s_cfg.mode | I2S_MODE_TX | I2S_MODE_RX); } success = ESP_OK == i2s_driver_install(this->get_port(), &i2s_cfg, 0, nullptr); - esph_log_d(TAG, "Installing driver : %s", success ? "yes" : "no" ); + esph_log_d(TAG, "Installing driver : %s", success ? "yes" : "no"); i2s_pin_config_t pin_config = this->get_pin_config(); - if( success ){ - if( this->audio_in_ != nullptr ) - { + if (success) { + if (this->audio_in_ != nullptr) { pin_config.data_in_num = this->audio_in_->get_din_pin(); } - if( this->audio_out_ != nullptr ) - { + if (this->audio_out_ != nullptr) { pin_config.data_out_num = this->audio_out_->get_dout_pin(); } success &= ESP_OK == i2s_set_pin(this->get_port(), &pin_config); - if( success ){ + if (success) { this->access_state_ = access; this->installed_cfg_ = i2s_cfg; } } - } else if (this->access_mode_ == I2SAccessMode::DUPLEX && (this->access_state_ & access) == 0){ + } else if (this->access_mode_ == I2SAccessMode::DUPLEX && (this->access_state_ & access) == 0) { success = this->validate_cfg_for_duplex_(i2s_cfg); - if(success){ + if (success) { this->access_state_ |= access; } } @@ -96,11 +92,11 @@ bool I2SAudioComponent::install_i2s_driver_(i2s_driver_config_t i2s_cfg, uint8_t return success; } -bool I2SAudioComponent::uninstall_i2s_driver_(uint8_t access){ +bool I2SAudioComponent::uninstall_i2s_driver_(uint8_t access) { bool success = false; this->lock(); // check that i2s is not occupied by others - if( (this->access_state_ & ~access) == 0 ){ + if ((this->access_state_ & ~access) == 0) { i2s_zero_dma_buffer(this->get_port()); esp_err_t err = i2s_driver_uninstall(this->get_port()); if (err == ESP_OK) { @@ -109,8 +105,7 @@ bool I2SAudioComponent::uninstall_i2s_driver_(uint8_t access){ } else { esph_log_e(TAG, "Couldn't unload driver"); } - } - else { + } else { // other component hasn't released yet // don't uninstall driver, just release caller esph_log_d(TAG, "Other component hasn't released"); @@ -120,34 +115,28 @@ bool I2SAudioComponent::uninstall_i2s_driver_(uint8_t access){ return success; } -bool I2SAudioComponent::validate_cfg_for_duplex_(i2s_driver_config_t& i2s_cfg){ - i2s_driver_config_t& installed = this->installed_cfg_; - return ( - installed.sample_rate == i2s_cfg.sample_rate - && installed.bits_per_chan == i2s_cfg.bits_per_chan - ); +bool I2SAudioComponent::validate_cfg_for_duplex_(i2s_driver_config_t &i2s_cfg) { + i2s_driver_config_t &installed = this->installed_cfg_; + return (installed.sample_rate == i2s_cfg.sample_rate && installed.bits_per_chan == i2s_cfg.bits_per_chan); } - void I2SSettings::dump_i2s_settings() const { std::string init_str = this->is_fixed_ ? "Fixed-CFG" : "Initial-CFG"; - if( this->i2s_access_ == I2SAccess::RX ){ + if (this->i2s_access_ == I2SAccess::RX) { esph_log_config(TAG, "I2S-Reader (%s):", init_str.c_str()); - } - else{ + } else { esph_log_config(TAG, "I2S-Writer (%s):", init_str.c_str()); } - esph_log_config(TAG, " sample-rate: %d bits_per_sample: %d", this->sample_rate_, this->bits_per_sample_ ); - esph_log_config(TAG, " channel_fmt: %d channels: %d", this->channel_fmt_, this->num_of_channels() ); - esph_log_config(TAG, " use_apll: %s, use_pdm: %s", this->use_apll_ ? "yes": "no", this->pdm_ ? "yes": "no"); + esph_log_config(TAG, " sample-rate: %d bits_per_sample: %d", this->sample_rate_, this->bits_per_sample_); + esph_log_config(TAG, " channel_fmt: %d channels: %d", this->channel_fmt_, this->num_of_channels()); + esph_log_config(TAG, " use_apll: %s, use_pdm: %s", this->use_apll_ ? "yes" : "no", this->pdm_ ? "yes" : "no"); } - i2s_driver_config_t I2SSettings::get_i2s_cfg() const { - uint8_t mode = I2S_MODE_MASTER | ( this->i2s_access_ == I2SAccess::RX ? I2S_MODE_RX : I2S_MODE_TX); + uint8_t mode = I2S_MODE_MASTER | (this->i2s_access_ == I2SAccess::RX ? I2S_MODE_RX : I2S_MODE_TX); - if( this->pdm_){ - mode = (i2s_mode_t) (mode | I2S_MODE_PDM); + if (this->pdm_) { + mode = (i2s_mode_t) (mode | I2S_MODE_PDM); } i2s_driver_config_t config = { diff --git a/esphome/components/i2s_audio/i2s_audio.h b/esphome/components/i2s_audio/i2s_audio.h index 6146d53..17f0397 100644 --- a/esphome/components/i2s_audio/i2s_audio.h +++ b/esphome/components/i2s_audio/i2s_audio.h @@ -10,15 +10,14 @@ namespace esphome { namespace i2s_audio { -enum class I2SAccessMode : uint8_t {EXCLUSIVE, DUPLEX}; +enum class I2SAccessMode : uint8_t { EXCLUSIVE, DUPLEX }; class I2SAccess { -public: - static constexpr uint8_t FREE = 0; - static constexpr uint8_t RX = 1; - static constexpr uint8_t TX = 2; + public: + static constexpr uint8_t FREE = 0; + static constexpr uint8_t RX = 1; + static constexpr uint8_t TX = 2; }; - class I2SReader; class I2SWriter; class I2SAudioComponent : public Component { @@ -45,11 +44,11 @@ class I2SAudioComponent : public Component { void unlock() { this->lock_.unlock(); } i2s_port_t get_port() const { return this->port_; } - void set_audio_in(I2SReader* comp_in){ this->audio_in_ = comp_in;} - void set_audio_out(I2SWriter* comp_out){ this->audio_out_ = comp_out;} + void set_audio_in(I2SReader *comp_in) { this->audio_in_ = comp_in; } + void set_audio_out(I2SWriter *comp_out) { this->audio_out_ = comp_out; } - void set_access_mode(I2SAccessMode access_mode){this->access_mode_ = access_mode;} - bool is_exclusive(){return this->access_mode_ == I2SAccessMode::EXCLUSIVE;} + void set_access_mode(I2SAccessMode access_mode) { this->access_mode_ = access_mode; } + bool is_exclusive() { return this->access_mode_ == I2SAccessMode::EXCLUSIVE; } protected: friend I2SReader; @@ -63,7 +62,7 @@ class I2SAudioComponent : public Component { bool release_access_(uint8_t access); bool install_i2s_driver_(i2s_driver_config_t i2s_cfg, uint8_t access); bool uninstall_i2s_driver_(uint8_t access); - bool validate_cfg_for_duplex_(i2s_driver_config_t& i2s_cfg); + bool validate_cfg_for_duplex_(i2s_driver_config_t &i2s_cfg); I2SReader *audio_in_{nullptr}; I2SWriter *audio_out_{nullptr}; @@ -80,7 +79,7 @@ class ExternalADC; class ExternalDAC; class I2SSettings { -public: + public: I2SSettings() = default; I2SSettings(uint8_t access) : i2s_access_(access) {} @@ -92,34 +91,36 @@ class I2SSettings { void set_channel(i2s_channel_fmt_t channel_fmt) { this->channel_fmt_ = channel_fmt; } void set_pdm(bool pdm) { this->pdm_ = pdm; } void set_sample_rate(uint32_t sample_rate) { this->sample_rate_ = sample_rate; } - void set_fixed_settings(bool is_fixed){ this->is_fixed_ = is_fixed; } - int num_of_channels() const { return (this->channel_fmt_ == I2S_CHANNEL_FMT_ONLY_RIGHT - || this->channel_fmt_ == I2S_CHANNEL_FMT_ONLY_LEFT) ? 1 : 2; } - -protected: - bool use_apll_{false}; - i2s_bits_per_sample_t bits_per_sample_; - i2s_channel_fmt_t channel_fmt_; - i2s_mode_t i2s_clk_mode_; - i2s_mode_t i2s_access_mode_; - bool pdm_{false}; - uint32_t sample_rate_; - - bool is_fixed_{false}; - uint8_t i2s_access_; -}; + void set_fixed_settings(bool is_fixed) { this->is_fixed_ = is_fixed; } + int num_of_channels() const { + return (this->channel_fmt_ == I2S_CHANNEL_FMT_ONLY_RIGHT || this->channel_fmt_ == I2S_CHANNEL_FMT_ONLY_LEFT) ? 1 + : 2; + } + protected: + bool use_apll_{false}; + i2s_bits_per_sample_t bits_per_sample_; + i2s_channel_fmt_t channel_fmt_; + i2s_mode_t i2s_clk_mode_; + i2s_mode_t i2s_access_mode_; + bool pdm_{false}; + uint32_t sample_rate_; + + bool is_fixed_{false}; + uint8_t i2s_access_; +}; class I2SReader : public I2SSettings, public Parented { -public: - I2SReader() : I2SSettings( I2SAccess::RX ) {} - - bool install_i2s_driver(i2s_driver_config_t i2s_cfg){ - return this->parent_->install_i2s_driver_(i2s_cfg, I2SAccess::RX);} - bool uninstall_i2s_driver(){ return this->parent_->uninstall_i2s_driver_(I2SAccess::RX);} - bool claim_i2s_access(){return this->parent_->claim_access_(I2SAccess::RX);} - bool release_i2s_access(){return this->parent_->release_access_(I2SAccess::RX);} - bool is_adjustable(){return !this->is_fixed_ && this->parent_->is_exclusive();} + public: + I2SReader() : I2SSettings(I2SAccess::RX) {} + + bool install_i2s_driver(i2s_driver_config_t i2s_cfg) { + return this->parent_->install_i2s_driver_(i2s_cfg, I2SAccess::RX); + } + bool uninstall_i2s_driver() { return this->parent_->uninstall_i2s_driver_(I2SAccess::RX); } + bool claim_i2s_access() { return this->parent_->claim_access_(I2SAccess::RX); } + bool release_i2s_access() { return this->parent_->release_access_(I2SAccess::RX); } + bool is_adjustable() { return !this->is_fixed_ && this->parent_->is_exclusive(); } #if SOC_I2S_SUPPORTS_ADC void set_adc_channel(adc1_channel_t channel) { this->adc_channel_ = channel; @@ -127,57 +128,54 @@ class I2SReader : public I2SSettings, public Parented { } #endif #ifdef I2S_EXTERNAL_ADC - void set_external_adc(ExternalADC* adc){this->external_adc_ = adc;} + void set_external_adc(ExternalADC *adc) { this->external_adc_ = adc; } #endif - void set_din_pin(int8_t pin) { this->din_pin_ = pin; } - int8_t get_din_pin() { return this->din_pin_; } + void set_din_pin(int8_t pin) { this->din_pin_ = pin; } + int8_t get_din_pin() { return this->din_pin_; } -protected: + protected: #if SOC_I2S_SUPPORTS_ADC - adc1_channel_t adc_channel_{ADC1_CHANNEL_MAX}; - bool use_internal_adc_{false}; + adc1_channel_t adc_channel_{ADC1_CHANNEL_MAX}; + bool use_internal_adc_{false}; #endif #ifdef I2S_EXTERNAL_ADC - ExternalADC* external_adc_{}; + ExternalADC *external_adc_{}; #endif - int8_t din_pin_{I2S_PIN_NO_CHANGE}; + int8_t din_pin_{I2S_PIN_NO_CHANGE}; }; - class I2SWriter : public I2SSettings, public Parented { -public: - I2SWriter() : I2SSettings(I2SAccess::TX ) {} + public: + I2SWriter() : I2SSettings(I2SAccess::TX) {} - bool install_i2s_driver(i2s_driver_config_t i2s_cfg){ - return this->parent_->install_i2s_driver_(i2s_cfg, I2SAccess::TX); } - bool uninstall_i2s_driver(){ return this->parent_->uninstall_i2s_driver_(I2SAccess::TX);} - bool claim_i2s_access(){return this->parent_->claim_access_(I2SAccess::TX);} - bool release_i2s_access(){return this->parent_->release_access_(I2SAccess::TX);} - bool is_adjustable(){return !this->is_fixed_ && this->parent_->is_exclusive();} + bool install_i2s_driver(i2s_driver_config_t i2s_cfg) { + return this->parent_->install_i2s_driver_(i2s_cfg, I2SAccess::TX); + } + bool uninstall_i2s_driver() { return this->parent_->uninstall_i2s_driver_(I2SAccess::TX); } + bool claim_i2s_access() { return this->parent_->claim_access_(I2SAccess::TX); } + bool release_i2s_access() { return this->parent_->release_access_(I2SAccess::TX); } + bool is_adjustable() { return !this->is_fixed_ && this->parent_->is_exclusive(); } #if SOC_I2S_SUPPORTS_DAC void set_internal_dac_mode(i2s_dac_mode_t mode) { this->internal_dac_mode_ = mode; } #endif #ifdef I2S_EXTERNAL_DAC - void set_external_dac(ExternalDAC* dac){this->external_dac_ = dac;} + void set_external_dac(ExternalDAC *dac) { this->external_dac_ = dac; } #endif - void set_dout_pin(int8_t pin) { this->dout_pin_ = pin; } - int8_t get_dout_pin() { return this->dout_pin_; } + void set_dout_pin(int8_t pin) { this->dout_pin_ = pin; } + int8_t get_dout_pin() { return this->dout_pin_; } -protected: + protected: #if SOC_I2S_SUPPORTS_DAC - i2s_dac_mode_t internal_dac_mode_{I2S_DAC_CHANNEL_DISABLE}; + i2s_dac_mode_t internal_dac_mode_{I2S_DAC_CHANNEL_DISABLE}; #endif #ifdef I2S_EXTERNAL_DAC - ExternalDAC* external_dac_{}; + ExternalDAC *external_dac_{}; #endif - int8_t dout_pin_{I2S_PIN_NO_CHANGE}; + int8_t dout_pin_{I2S_PIN_NO_CHANGE}; }; - - - } // namespace i2s_audio } // namespace esphome diff --git a/esphome/components/i2s_audio/microphone/i2s_audio_microphone.cpp b/esphome/components/i2s_audio/microphone/i2s_audio_microphone.cpp index 90c7063..b855f0f 100644 --- a/esphome/components/i2s_audio/microphone/i2s_audio_microphone.cpp +++ b/esphome/components/i2s_audio/microphone/i2s_audio_microphone.cpp @@ -36,9 +36,7 @@ void I2SAudioMicrophone::setup() { } } } -void I2SAudioMicrophone::dump_config() { - this->dump_i2s_settings(); -} +void I2SAudioMicrophone::dump_config() { this->dump_i2s_settings(); } void I2SAudioMicrophone::start() { if (this->is_failed()) @@ -53,13 +51,13 @@ void I2SAudioMicrophone::start_() { } #ifdef I2S_EXTERNAL_ADC - if( this->external_adc_ != nullptr ){ + if (this->external_adc_ != nullptr) { this->external_adc_->init_device(); } #endif -i2s_driver_config_t config = this->get_i2s_cfg(); -//config.mode = (i2s_mode_t) (I2S_MODE_MASTER | I2S_MODE_RX); + i2s_driver_config_t config = this->get_i2s_cfg(); + // config.mode = (i2s_mode_t) (I2S_MODE_MASTER | I2S_MODE_RX); #if SOC_I2S_SUPPORTS_ADC if (this->use_internal_adc_) { @@ -75,11 +73,10 @@ i2s_driver_config_t config = this->get_i2s_cfg(); config.mode = (i2s_mode_t) (config.mode | I2S_MODE_PDM); this->install_i2s_driver(config); - } #ifdef I2S_EXTERNAL_ADC - if( this->external_adc_ != nullptr ){ + if (this->external_adc_ != nullptr) { this->external_adc_->apply_i2s_settings(config); } #endif @@ -124,7 +121,7 @@ size_t I2SAudioMicrophone::read(int16_t *buf, size_t len) { } else if (this->bits_per_sample_ == I2S_BITS_PER_SAMPLE_32BIT) { std::vector samples; size_t samples_read = bytes_read / sizeof(int32_t); - uint8_t shift = 16 - this->gain_log2_ ; + uint8_t shift = 16 - this->gain_log2_; samples.resize(samples_read); for (size_t i = 0; i < samples_read; i++) { int32_t temp = reinterpret_cast(buf)[i] >> shift; diff --git a/esphome/components/i2s_audio/microphone/i2s_audio_microphone.h b/esphome/components/i2s_audio/microphone/i2s_audio_microphone.h index b95d3d8..49304a6 100644 --- a/esphome/components/i2s_audio/microphone/i2s_audio_microphone.h +++ b/esphome/components/i2s_audio/microphone/i2s_audio_microphone.h @@ -20,7 +20,7 @@ class I2SAudioMicrophone : public I2SReader, public microphone::Microphone, publ void dump_config() override; size_t read(int16_t *buf, size_t len) override; - void set_gain_log2(uint8_t gain_log2){this->gain_log2_ = gain_log2;} + void set_gain_log2(uint8_t gain_log2) { this->gain_log2_ = gain_log2; } protected: void start_(); diff --git a/esphome/components/i2s_audio/speaker/i2s_audio_speaker.cpp b/esphome/components/i2s_audio/speaker/i2s_audio_speaker.cpp index cb82029..8a5597a 100644 --- a/esphome/components/i2s_audio/speaker/i2s_audio_speaker.cpp +++ b/esphome/components/i2s_audio/speaker/i2s_audio_speaker.cpp @@ -28,10 +28,7 @@ void I2SAudioSpeaker::setup() { this->event_queue_ = xQueueCreate(BUFFER_COUNT, sizeof(TaskEvent)); } -void I2SAudioSpeaker::dump_config() { - this->dump_i2s_settings(); -} - +void I2SAudioSpeaker::dump_config() { this->dump_i2s_settings(); } void I2SAudioSpeaker::start() { this->state_ = speaker::STATE_STARTING; } @@ -48,7 +45,7 @@ void I2SAudioSpeaker::player_task(void *params) { I2SAudioSpeaker *this_speaker = (I2SAudioSpeaker *) params; #ifdef I2S_EXTERNAL_DAC - if( this_speaker->external_dac_ != nullptr ){ + if (this_speaker->external_dac_ != nullptr) { this_speaker->external_dac_->init_device(); } #endif @@ -92,7 +89,7 @@ void I2SAudioSpeaker::player_task(void *params) { #endif #ifdef I2S_EXTERNAL_DAC - if( this_speaker->external_dac_ != nullptr ){ + if (this_speaker->external_dac_ != nullptr) { this_speaker->external_dac_->apply_i2s_settings(config); } #endif @@ -113,7 +110,7 @@ void I2SAudioSpeaker::player_task(void *params) { } size_t bytes_written; esp_err_t err = i2s_write(this_speaker->parent_->get_port(), data_event.data, data_event.len, &bytes_written, - (10 / portTICK_PERIOD_MS)); + (10 / portTICK_PERIOD_MS)); if (err != ESP_OK) { event = {.type = TaskEventType::WARNING, .err = err}; xQueueSend(this_speaker->event_queue_, &event, portMAX_DELAY); diff --git a/esphome/components/voice_assistant/voice_assistant.cpp b/esphome/components/voice_assistant/voice_assistant.cpp index d3e874a..71e32ea 100644 --- a/esphome/components/voice_assistant/voice_assistant.cpp +++ b/esphome/components/voice_assistant/voice_assistant.cpp @@ -20,7 +20,7 @@ static const size_t INPUT_BUFFER_SIZE = 32 * SAMPLE_RATE_HZ / 1000; // 32ms * 1 #ifdef USE_ESP_ADF_VAD static const size_t VAD_SAMPLES_PER_CHUNK = VAD_FRAME_LENGTH_MS * SAMPLE_RATE_HZ / 1000; -static const size_t BUFFER_LENGTH_MSEC = 2048; //cached audio which is send after VAD detection +static const size_t BUFFER_LENGTH_MSEC = 2048; // cached audio which is send after VAD detection static const size_t BUFFER_SIZE = BUFFER_LENGTH_MSEC * SAMPLE_RATE_HZ / 1000; #else static const size_t BUFFER_SIZE = 1024 * SAMPLE_RATE_HZ / 1000; @@ -92,9 +92,7 @@ void VoiceAssistant::setup() { } #ifdef USE_ESP_ADF_VAD - { - this->vad_instance_ = vad_create(VAD_MODE_4); - } + { this->vad_instance_ = vad_create(VAD_MODE_4); } #endif this->ring_buffer_ = RingBuffer::create(BUFFER_SIZE * sizeof(int16_t)); @@ -134,18 +132,19 @@ int VoiceAssistant::read_microphone_vad_(size_t request_samples) { size_t bytes_read = 0; if (this->mic_->is_running()) { // Read audio into input buffer uint32_t elapsed_time = (millis() - prior_invoke); - if( elapsed_time < 15 ){ + if (elapsed_time < 15) { return 0; } - request_samples = std::min(request_samples, INPUT_BUFFER_SIZE- this->samples_in_read_buffer_); - int16_t* dst = this->input_buffer_ + this->samples_in_read_buffer_; + request_samples = std::min(request_samples, INPUT_BUFFER_SIZE - this->samples_in_read_buffer_); + int16_t *dst = this->input_buffer_ + this->samples_in_read_buffer_; bytes_read = this->mic_->read(dst, request_samples * sizeof(int16_t)); // Write audio into ring buffer - if (bytes_read){ + if (bytes_read) { this->ring_buffer_->write((void *) this->input_buffer_, bytes_read); this->samples_in_read_buffer_ += bytes_read / sizeof(int16_t); - //ESP_LOGV(TAG, "VAD read: elapsed time=%u ms, read: %u in_read_buffer: %u ringbuffer: %u",elapsed_time, bytes_read, this->samples_in_read_buffer_, this->ring_buffer_->available()); + // ESP_LOGV(TAG, "VAD read: elapsed time=%u ms, read: %u in_read_buffer: %u ringbuffer: %u",elapsed_time, + // bytes_read, this->samples_in_read_buffer_, this->ring_buffer_->available()); } } else { ESP_LOGD(TAG, "microphone not running"); @@ -206,20 +205,20 @@ void VoiceAssistant::loop() { this->samples_in_read_buffer_ = 0; this->read_microphone_vad_(VAD_SAMPLES_PER_CHUNK); ESP_LOGD(TAG, "Waiting for speech..."); - //prior_invoke = millis(); + // prior_invoke = millis(); this->set_state_(State::WAITING_FOR_VAD); break; } case State::WAITING_FOR_VAD: { size_t missing_samples = VAD_SAMPLES_PER_CHUNK - this->samples_in_read_buffer_; - if (missing_samples > 0){ - this->read_microphone_vad_(missing_samples); + if (missing_samples > 0) { + this->read_microphone_vad_(missing_samples); } - if( this->samples_in_read_buffer_ >= VAD_SAMPLES_PER_CHUNK){ - //uint32_t elapsed_time = (millis() - prior_invoke); - //ESP_LOGV(TAG, "elapsed time=%u ms",elapsed_time); - //prior_invoke = millis(); - //ESP_LOGD(TAG, "VAD processing"); + if (this->samples_in_read_buffer_ >= VAD_SAMPLES_PER_CHUNK) { + // uint32_t elapsed_time = (millis() - prior_invoke); + // ESP_LOGV(TAG, "elapsed time=%u ms",elapsed_time); + // prior_invoke = millis(); + // ESP_LOGD(TAG, "VAD processing"); vad_state_t vad_state = vad_process(this->vad_instance_, this->input_buffer_, SAMPLE_RATE_HZ, VAD_FRAME_LENGTH_MS); prior_invoke = millis(); @@ -659,7 +658,7 @@ void VoiceAssistant::on_event(const api::VoiceAssistantEventResponse &msg) { } case api::enums::VOICE_ASSISTANT_RUN_END: { ESP_LOGD(TAG, "Assist Pipeline ended"); - ESP_LOGD(TAG, "Current State: %s", LOG_STR_ARG(voice_assistant_state_to_string(this->state_)) ); + ESP_LOGD(TAG, "Current State: %s", LOG_STR_ARG(voice_assistant_state_to_string(this->state_))); if (this->state_ == State::STREAMING_MICROPHONE) { this->ring_buffer_->reset(); #ifdef USE_ESP_ADF_VAD @@ -674,8 +673,8 @@ void VoiceAssistant::on_event(const api::VoiceAssistantEventResponse &msg) { } else if (this->state_ == State::AWAITING_RESPONSE) { // No TTS start event ("nevermind") this->set_state_(State::IDLE, State::IDLE); - } else if (this->state_ == State::STREAMING_RESPONSE){ - //this->set_state_(State::IDLE, State::IDLE); + } else if (this->state_ == State::STREAMING_RESPONSE) { + // this->set_state_(State::IDLE, State::IDLE); } this->defer([this]() { this->end_trigger_->trigger(); });