diff --git a/main/application.cc b/main/application.cc index 5a640c85..d69d43d0 100644 --- a/main/application.cc +++ b/main/application.cc @@ -309,13 +309,15 @@ void Application::HandleActivationDoneEvent() { display->ShowNotification(message.c_str()); display->SetChatMessage("system", ""); - // Play the success sound to indicate the device is ready - audio_service_.PlaySound(Lang::Sounds::OGG_SUCCESS); - // Release OTA object after activation is complete ota_.reset(); auto& board = Board::GetInstance(); board.SetPowerSaveLevel(PowerSaveLevel::LOW_POWER); + + Schedule([this]() { + // Play the success sound to indicate the device is ready + audio_service_.PlaySound(Lang::Sounds::OGG_SUCCESS); + }); } void Application::ActivationTask() { diff --git a/main/audio/audio_codec.cc b/main/audio/audio_codec.cc index 055cd82a..03e2baa3 100644 --- a/main/audio/audio_codec.cc +++ b/main/audio/audio_codec.cc @@ -34,16 +34,6 @@ void AudioCodec::Start() { output_volume_ = 10; } - if (tx_handle_ != nullptr) { - ESP_ERROR_CHECK(i2s_channel_enable(tx_handle_)); - } - - if (rx_handle_ != nullptr) { - ESP_ERROR_CHECK(i2s_channel_enable(rx_handle_)); - } - - EnableInput(true); - EnableOutput(true); ESP_LOGI(TAG, "Audio codec started"); } diff --git a/main/audio/audio_service.cc b/main/audio/audio_service.cc index 62f29e0f..bd45c7d5 100644 --- a/main/audio/audio_service.cc +++ b/main/audio/audio_service.cc @@ -39,15 +39,6 @@ AudioService::AudioService() { event_group_ = xEventGroupCreate(); - - demuxer_.OnDemuxerFinished([this](const uint8_t* data, int sample_rate, size_t size){ - auto packet = std::make_unique(); - packet->sample_rate = sample_rate; - packet->frame_duration = 60; - packet->payload.resize(size); - std::memcpy(packet->payload.data(), data, size); - PushPacketToDecodeQueue(std::move(packet), true); - }); } AudioService::~AudioService() { @@ -314,6 +305,7 @@ void AudioService::AudioOutputTask() { esp_timer_start_periodic(audio_power_timer_, AUDIO_POWER_CHECK_INTERVAL_MS * 1000); codec_->EnableOutput(true); } + codec_->OutputData(task->pcm); /* Update the last output time */ @@ -647,8 +639,18 @@ void AudioService::PlaySound(const std::string_view& ogg) { const auto* buf = reinterpret_cast(ogg.data()); size_t size = ogg.size(); - demuxer_.Reset(); - demuxer_.Process(buf, size); + + auto demuxer = std::make_unique(); + demuxer->OnDemuxerFinished([this](const uint8_t* data, int sample_rate, size_t size){ + auto packet = std::make_unique(); + packet->sample_rate = sample_rate; + packet->frame_duration = 60; + packet->payload.resize(size); + std::memcpy(packet->payload.data(), data, size); + PushPacketToDecodeQueue(std::move(packet), true); + }); + demuxer->Reset(); + demuxer->Process(buf, size); } bool AudioService::IsIdle() { diff --git a/main/audio/audio_service.h b/main/audio/audio_service.h index 20b2d513..99db5461 100644 --- a/main/audio/audio_service.h +++ b/main/audio/audio_service.h @@ -146,8 +146,6 @@ private: std::mutex input_resampler_mutex_; esp_ae_rate_cvt_handle_t input_resampler_ = nullptr; esp_ae_rate_cvt_handle_t output_resampler_ = nullptr; - - OggDemuxer demuxer_; // Encoder/Decoder state int encoder_sample_rate_ = 16000; diff --git a/main/audio/codecs/box_audio_codec.cc b/main/audio/codecs/box_audio_codec.cc index a3db34fa..8bbe07d3 100644 --- a/main/audio/codecs/box_audio_codec.cc +++ b/main/audio/codecs/box_audio_codec.cc @@ -176,6 +176,8 @@ void BoxAudioCodec::CreateDuplexChannels(gpio_num_t mclk, gpio_num_t bclk, gpio_ ESP_ERROR_CHECK(i2s_channel_init_std_mode(tx_handle_, &std_cfg)); ESP_ERROR_CHECK(i2s_channel_init_tdm_mode(rx_handle_, &tdm_cfg)); + ESP_ERROR_CHECK(i2s_channel_enable(tx_handle_)); + ESP_ERROR_CHECK(i2s_channel_enable(rx_handle_)); ESP_LOGI(TAG, "Duplex channels created"); } diff --git a/main/audio/codecs/es8311_audio_codec.cc b/main/audio/codecs/es8311_audio_codec.cc index 0a03e87b..708b7dac 100644 --- a/main/audio/codecs/es8311_audio_codec.cc +++ b/main/audio/codecs/es8311_audio_codec.cc @@ -150,6 +150,8 @@ void Es8311AudioCodec::CreateDuplexChannels(gpio_num_t mclk, gpio_num_t bclk, gp ESP_ERROR_CHECK(i2s_channel_init_std_mode(tx_handle_, &std_cfg)); ESP_ERROR_CHECK(i2s_channel_init_std_mode(rx_handle_, &std_cfg)); + ESP_ERROR_CHECK(i2s_channel_enable(tx_handle_)); + ESP_ERROR_CHECK(i2s_channel_enable(rx_handle_)); ESP_LOGI(TAG, "Duplex channels created"); } diff --git a/main/audio/codecs/es8374_audio_codec.cc b/main/audio/codecs/es8374_audio_codec.cc index 30b1ba36..699e777e 100644 --- a/main/audio/codecs/es8374_audio_codec.cc +++ b/main/audio/codecs/es8374_audio_codec.cc @@ -126,6 +126,8 @@ void Es8374AudioCodec::CreateDuplexChannels(gpio_num_t mclk, gpio_num_t bclk, gp ESP_ERROR_CHECK(i2s_channel_init_std_mode(tx_handle_, &std_cfg)); ESP_ERROR_CHECK(i2s_channel_init_std_mode(rx_handle_, &std_cfg)); + ESP_ERROR_CHECK(i2s_channel_enable(tx_handle_)); + ESP_ERROR_CHECK(i2s_channel_enable(rx_handle_)); ESP_LOGI(TAG, "Duplex channels created"); } diff --git a/main/audio/codecs/es8388_audio_codec.cc b/main/audio/codecs/es8388_audio_codec.cc index f3fd6fbb..821db78d 100644 --- a/main/audio/codecs/es8388_audio_codec.cc +++ b/main/audio/codecs/es8388_audio_codec.cc @@ -131,6 +131,8 @@ void Es8388AudioCodec::CreateDuplexChannels(gpio_num_t mclk, gpio_num_t bclk, gp ESP_ERROR_CHECK(i2s_channel_init_std_mode(tx_handle_, &std_cfg)); ESP_ERROR_CHECK(i2s_channel_init_std_mode(rx_handle_, &std_cfg)); + ESP_ERROR_CHECK(i2s_channel_enable(tx_handle_)); + ESP_ERROR_CHECK(i2s_channel_enable(rx_handle_)); ESP_LOGI(TAG, "Duplex channels created"); } diff --git a/main/audio/codecs/es8389_audio_codec.cc b/main/audio/codecs/es8389_audio_codec.cc index 351ad454..48820f36 100644 --- a/main/audio/codecs/es8389_audio_codec.cc +++ b/main/audio/codecs/es8389_audio_codec.cc @@ -132,6 +132,8 @@ void Es8389AudioCodec::CreateDuplexChannels(gpio_num_t mclk, gpio_num_t bclk, gp ESP_ERROR_CHECK(i2s_channel_init_std_mode(tx_handle_, &std_cfg)); ESP_ERROR_CHECK(i2s_channel_init_std_mode(rx_handle_, &std_cfg)); + ESP_ERROR_CHECK(i2s_channel_enable(tx_handle_)); + ESP_ERROR_CHECK(i2s_channel_enable(rx_handle_)); ESP_LOGI(TAG, "Duplex channels created"); } diff --git a/main/audio/codecs/no_audio_codec.cc b/main/audio/codecs/no_audio_codec.cc index 4c839c87..c679a226 100644 --- a/main/audio/codecs/no_audio_codec.cc +++ b/main/audio/codecs/no_audio_codec.cc @@ -254,6 +254,32 @@ int NoAudioCodec::Read(int16_t* dest, int samples) { return samples; } +void NoAudioCodec::EnableInput(bool enable) { + std::lock_guard lock(data_if_mutex_); + if (enable == input_enabled_) { + return; + } + if (enable) { + ESP_ERROR_CHECK(i2s_channel_enable(rx_handle_)); + } else { + ESP_ERROR_CHECK(i2s_channel_disable(rx_handle_)); + } + AudioCodec::EnableInput(enable); +} + +void NoAudioCodec::EnableOutput(bool enable) { + std::lock_guard lock(data_if_mutex_); + if (enable == output_enabled_) { + return; + } + if (enable) { + ESP_ERROR_CHECK(i2s_channel_enable(tx_handle_)); + } else { + ESP_ERROR_CHECK(i2s_channel_disable(tx_handle_)); + } + AudioCodec::EnableOutput(enable); +} + // Delegating constructor: calls the main constructor with default slot mask NoAudioCodecSimplexPdm::NoAudioCodecSimplexPdm(int input_sample_rate, int output_sample_rate, gpio_num_t spk_bclk, gpio_num_t spk_ws, gpio_num_t spk_dout, gpio_num_t mic_sck, gpio_num_t mic_din) : NoAudioCodecSimplexPdm(input_sample_rate, output_sample_rate, spk_bclk, spk_ws, spk_dout, I2S_STD_SLOT_LEFT, mic_sck, mic_din) { diff --git a/main/audio/codecs/no_audio_codec.h b/main/audio/codecs/no_audio_codec.h index 098ee001..dec803f7 100644 --- a/main/audio/codecs/no_audio_codec.h +++ b/main/audio/codecs/no_audio_codec.h @@ -13,6 +13,8 @@ protected: virtual int Write(const int16_t* data, int samples) override; virtual int Read(int16_t* dest, int samples) override; + virtual void EnableInput(bool enable) override; + virtual void EnableOutput(bool enable) override; public: virtual ~NoAudioCodec(); diff --git a/main/boards/bread-compact-wifi-s3cam/README.md b/main/boards/bread-compact-wifi-s3cam/README.md index 51e7fdc5..80727682 100644 --- a/main/boards/bread-compact-wifi-s3cam/README.md +++ b/main/boards/bread-compact-wifi-s3cam/README.md @@ -24,26 +24,6 @@ idf.py menuconfig Xiaozhi Assistant -> Board Type ->面包板新版接线(WiFi)+ LCD + Camera ``` -**配置摄像头传感器:** - -> **注意:** 确认摄像头传感器型号,确定型号在 esp_cam_sensor 支持的范围内。当前板子用的是 OV2640,是符合支持范围。 - -在 menuconfig 中按以下步骤启用对应型号的支持: - -1. **导航到传感器配置:** - ``` - (Top) → Component config → Espressif Camera Sensors Configurations → Camera Sensor Configuration → Select and Set Camera Sensor - ``` - -2. **选择传感器型号:** - - 选中所需的传感器型号(OV2640) - -3. **配置传感器参数:** - - 按 → 进入传感器详细设置 - - 启用 **Auto detect** - - 推荐将 **default output format** 调整为 **YUV422** 及合适的分辨率大小 - - (目前支持 YUV422、RGB565,YUV422 更节省内存空间) - **编译烧入:** ```bash diff --git a/main/boards/bread-compact-wifi-s3cam/compact_wifi_board_s3cam.cc b/main/boards/bread-compact-wifi-s3cam/compact_wifi_board_s3cam.cc index 8a44c4ed..25bc3557 100644 --- a/main/boards/bread-compact-wifi-s3cam/compact_wifi_board_s3cam.cc +++ b/main/boards/bread-compact-wifi-s3cam/compact_wifi_board_s3cam.cc @@ -8,7 +8,7 @@ #include "mcp_server.h" #include "lamp_controller.h" #include "led/single_led.h" -#include "esp_video.h" +#include "esp32_camera.h" #include #include @@ -65,7 +65,7 @@ private: Button boot_button_; LcdDisplay* display_; - EspVideo* camera_; + Esp32Camera* camera_; void InitializeSpi() { spi_bus_config_t buscfg = {}; @@ -125,47 +125,32 @@ private: } void InitializeCamera() { - static esp_cam_ctlr_dvp_pin_config_t dvp_pin_config = { - .data_width = CAM_CTLR_DATA_WIDTH_8, - .data_io = { - [0] = CAMERA_PIN_D0, - [1] = CAMERA_PIN_D1, - [2] = CAMERA_PIN_D2, - [3] = CAMERA_PIN_D3, - [4] = CAMERA_PIN_D4, - [5] = CAMERA_PIN_D5, - [6] = CAMERA_PIN_D6, - [7] = CAMERA_PIN_D7, - }, - .vsync_io = CAMERA_PIN_VSYNC, - .de_io = CAMERA_PIN_HREF, - .pclk_io = CAMERA_PIN_PCLK, - .xclk_io = CAMERA_PIN_XCLK, - }; - - esp_video_init_sccb_config_t sccb_config = { - .init_sccb = true, - .i2c_config = { - .port = 0, - .scl_pin = CAMERA_PIN_SIOC, - .sda_pin = CAMERA_PIN_SIOD, - }, - .freq = 100000, - }; - - esp_video_init_dvp_config_t dvp_config = { - .sccb_config = sccb_config, - .reset_pin = CAMERA_PIN_RESET, - .pwdn_pin = CAMERA_PIN_PWDN, - .dvp_pin = dvp_pin_config, - .xclk_freq = XCLK_FREQ_HZ, - }; - - esp_video_init_config_t video_config = { - .dvp = &dvp_config, - }; - - camera_ = new EspVideo(video_config); + camera_config_t config = {}; + config.pin_d0 = CAMERA_PIN_D0; + config.pin_d1 = CAMERA_PIN_D1; + config.pin_d2 = CAMERA_PIN_D2; + config.pin_d3 = CAMERA_PIN_D3; + config.pin_d4 = CAMERA_PIN_D4; + config.pin_d5 = CAMERA_PIN_D5; + config.pin_d6 = CAMERA_PIN_D6; + config.pin_d7 = CAMERA_PIN_D7; + config.pin_xclk = CAMERA_PIN_XCLK; + config.pin_pclk = CAMERA_PIN_PCLK; + config.pin_vsync = CAMERA_PIN_VSYNC; + config.pin_href = CAMERA_PIN_HREF; + config.pin_sccb_sda = CAMERA_PIN_SIOD; + config.pin_sccb_scl = CAMERA_PIN_SIOC; + config.sccb_i2c_port = 0; + config.pin_pwdn = CAMERA_PIN_PWDN; + config.pin_reset = CAMERA_PIN_RESET; + config.xclk_freq_hz = XCLK_FREQ_HZ; + config.pixel_format = PIXFORMAT_RGB565; + config.frame_size = FRAMESIZE_VGA; + config.jpeg_quality = 12; + config.fb_count = 1; + config.fb_location = CAMERA_FB_IN_PSRAM; + config.grab_mode = CAMERA_GRAB_WHEN_EMPTY; + camera_ = new Esp32Camera(config); camera_->SetHMirror(false); } diff --git a/main/boards/df-k10/k10_audio_codec.cc b/main/boards/df-k10/k10_audio_codec.cc index 5a309481..c927eaad 100644 --- a/main/boards/df-k10/k10_audio_codec.cc +++ b/main/boards/df-k10/k10_audio_codec.cc @@ -152,6 +152,8 @@ void K10AudioCodec::CreateDuplexChannels(gpio_num_t mclk, gpio_num_t bclk, gpio_ ESP_ERROR_CHECK(i2s_channel_init_std_mode(tx_handle_, &std_cfg)); ESP_ERROR_CHECK(i2s_channel_init_tdm_mode(rx_handle_, &tdm_cfg)); + ESP_ERROR_CHECK(i2s_channel_enable(tx_handle_)); + ESP_ERROR_CHECK(i2s_channel_enable(rx_handle_)); ESP_LOGI(TAG, "Duplex channels created"); } diff --git a/main/boards/esp-box-lite/box_audio_codec_lite.cc b/main/boards/esp-box-lite/box_audio_codec_lite.cc index 658f49a8..2d7b8343 100644 --- a/main/boards/esp-box-lite/box_audio_codec_lite.cc +++ b/main/boards/esp-box-lite/box_audio_codec_lite.cc @@ -165,6 +165,8 @@ void BoxAudioCodecLite::CreateDuplexChannels(gpio_num_t mclk, gpio_num_t bclk, g ESP_ERROR_CHECK(i2s_channel_init_std_mode(tx_handle_, &std_cfg)); ESP_ERROR_CHECK(i2s_channel_init_tdm_mode(rx_handle_, &tdm_cfg)); + ESP_ERROR_CHECK(i2s_channel_enable(tx_handle_)); + ESP_ERROR_CHECK(i2s_channel_enable(rx_handle_)); ESP_LOGI(TAG, "Duplex channels created"); } diff --git a/main/boards/esp-hi/adc_pdm_audio_codec.cc b/main/boards/esp-hi/adc_pdm_audio_codec.cc index db5d8e17..462720cf 100644 --- a/main/boards/esp-hi/adc_pdm_audio_codec.cc +++ b/main/boards/esp-hi/adc_pdm_audio_codec.cc @@ -81,6 +81,7 @@ AdcPdmAudioCodec::AdcPdmAudioCodec(int input_sample_rate, int output_sample_rate const i2s_pdm_tx_config_t *p_i2s_cfg = &pdm_cfg_default; ESP_ERROR_CHECK(i2s_channel_init_pdm_tx_mode(tx_handle_, p_i2s_cfg)); + ESP_ERROR_CHECK(i2s_channel_enable(tx_handle_)); audio_codec_i2s_cfg_t i2s_cfg = { .port = I2S_NUM_0, diff --git a/main/boards/esp-sensairshuttle/adc_pdm_audio_codec.cc b/main/boards/esp-sensairshuttle/adc_pdm_audio_codec.cc index e48792b1..c458169a 100644 --- a/main/boards/esp-sensairshuttle/adc_pdm_audio_codec.cc +++ b/main/boards/esp-sensairshuttle/adc_pdm_audio_codec.cc @@ -81,6 +81,7 @@ AdcPdmAudioCodec::AdcPdmAudioCodec(int input_sample_rate, int output_sample_rate const i2s_pdm_tx_config_t *p_i2s_cfg = &pdm_cfg_default; ESP_ERROR_CHECK(i2s_channel_init_pdm_tx_mode(tx_handle_, p_i2s_cfg)); + ESP_ERROR_CHECK(i2s_channel_enable(tx_handle_)); audio_codec_i2s_cfg_t i2s_cfg = { .port = I2S_NUM_0, diff --git a/main/boards/lichuang-dev/lichuang_dev_board.cc b/main/boards/lichuang-dev/lichuang_dev_board.cc index 42b287e4..8b136f4b 100644 --- a/main/boards/lichuang-dev/lichuang_dev_board.cc +++ b/main/boards/lichuang-dev/lichuang_dev_board.cc @@ -230,7 +230,7 @@ private: config.pin_reset = CAMERA_PIN_RESET; config.xclk_freq_hz = XCLK_FREQ_HZ; config.pixel_format = PIXFORMAT_RGB565; - config.frame_size = FRAMESIZE_VGA; + config.frame_size = FRAMESIZE_QVGA; config.jpeg_quality = 12; config.fb_count = 1; config.fb_location = CAMERA_FB_IN_PSRAM; diff --git a/main/boards/m5stack-core-s3/cores3_audio_codec.cc b/main/boards/m5stack-core-s3/cores3_audio_codec.cc index 25963918..84c4af61 100644 --- a/main/boards/m5stack-core-s3/cores3_audio_codec.cc +++ b/main/boards/m5stack-core-s3/cores3_audio_codec.cc @@ -177,6 +177,8 @@ void CoreS3AudioCodec::CreateDuplexChannels(gpio_num_t mclk, gpio_num_t bclk, gp ESP_ERROR_CHECK(i2s_channel_init_std_mode(tx_handle_, &std_cfg)); ESP_ERROR_CHECK(i2s_channel_init_tdm_mode(rx_handle_, &tdm_cfg)); + ESP_ERROR_CHECK(i2s_channel_enable(tx_handle_)); + ESP_ERROR_CHECK(i2s_channel_enable(rx_handle_)); ESP_LOGI(TAG, "Duplex channels created"); } diff --git a/main/boards/m5stack-tab5/tab5_audio_codec.cc b/main/boards/m5stack-tab5/tab5_audio_codec.cc index 74dfe2e4..b0ddaced 100644 --- a/main/boards/m5stack-tab5/tab5_audio_codec.cc +++ b/main/boards/m5stack-tab5/tab5_audio_codec.cc @@ -176,6 +176,8 @@ void Tab5AudioCodec::CreateDuplexChannels(gpio_num_t mclk, gpio_num_t bclk, gpio ESP_ERROR_CHECK(i2s_channel_init_std_mode(tx_handle_, &std_cfg)); ESP_ERROR_CHECK(i2s_channel_init_tdm_mode(rx_handle_, &tdm_cfg)); + ESP_ERROR_CHECK(i2s_channel_enable(tx_handle_)); + ESP_ERROR_CHECK(i2s_channel_enable(rx_handle_)); ESP_LOGI(TAG, "Duplex channels created"); } diff --git a/main/boards/sensecap-watcher/sensecap_audio_codec.cc b/main/boards/sensecap-watcher/sensecap_audio_codec.cc index ac474d77..4c709831 100644 --- a/main/boards/sensecap-watcher/sensecap_audio_codec.cc +++ b/main/boards/sensecap-watcher/sensecap_audio_codec.cc @@ -143,6 +143,8 @@ void SensecapAudioCodec::CreateDuplexChannels(gpio_num_t mclk, gpio_num_t bclk, std_cfg.slot_cfg.slot_mask = I2S_STD_SLOT_RIGHT; ESP_ERROR_CHECK(i2s_channel_init_std_mode(rx_handle_, &std_cfg)); + ESP_ERROR_CHECK(i2s_channel_enable(tx_handle_)); + ESP_ERROR_CHECK(i2s_channel_enable(rx_handle_)); ESP_LOGI(TAG, "Duplex channels created"); } diff --git a/main/display/lcd_display.cc b/main/display/lcd_display.cc index 1a75f181..bd79e194 100644 --- a/main/display/lcd_display.cc +++ b/main/display/lcd_display.cc @@ -1032,8 +1032,6 @@ void LcdDisplay::SetEmotion(const char* emotion) { gif_controller_ = std::make_unique(image->image_dsc()); if (gif_controller_->IsLoaded()) { - // Set loop delay to 1000ms - gif_controller_->SetLoopDelay(3000); // Set up frame update callback gif_controller_->SetFrameCallback([this]() { lv_image_set_src(emoji_image_, gif_controller_->image_dsc()); diff --git a/main/idf_component.yml b/main/idf_component.yml index 3afe92de..539badb5 100644 --- a/main/idf_component.yml +++ b/main/idf_component.yml @@ -22,9 +22,9 @@ dependencies: 78/esp-wifi-connect: ~3.0.2 espressif/esp_audio_effects: ~1.2.1 espressif/esp_audio_codec: ~2.4.1 - 78/esp-ml307: ~3.6.3 + 78/esp-ml307: ~3.6.4 78/uart-eth-modem: - version: ~0.3.1 + version: ~0.3.2 rules: - if: target not in [esp32] 78/xiaozhi-fonts: ~1.6.0 diff --git a/main/system_info.cc b/main/system_info.cc index 51b00724..3c011d10 100644 --- a/main/system_info.cc +++ b/main/system_info.cc @@ -8,6 +8,7 @@ #include #include #include +#include #if CONFIG_IDF_TARGET_ESP32P4 #include "esp_wifi_remote.h" #endif @@ -149,3 +150,7 @@ void SystemInfo::PrintHeapStats() { int min_free_sram = heap_caps_get_minimum_free_size(MALLOC_CAP_INTERNAL); ESP_LOGI(TAG, "free sram: %u minimal sram: %u", free_sram, min_free_sram); } + +void SystemInfo::PrintPmLocks() { + esp_pm_dump_locks(stdout); +} diff --git a/main/system_info.h b/main/system_info.h index a466d712..1c0d410d 100644 --- a/main/system_info.h +++ b/main/system_info.h @@ -17,6 +17,7 @@ public: static esp_err_t PrintTaskCpuUsage(TickType_t xTicksToWait); static void PrintTaskList(); static void PrintHeapStats(); + static void PrintPmLocks(); }; #endif // _SYSTEM_INFO_H_