From c60f134093ad9be829eb5311e08ea7a1bdbfb731 Mon Sep 17 00:00:00 2001 From: Terrence Date: Tue, 4 Mar 2025 05:30:35 +0800 Subject: [PATCH] =?UTF-8?q?=E6=94=AF=E6=8C=81=E5=88=86=E5=88=AB=E5=85=B3?= =?UTF-8?q?=E9=97=AD=E9=99=8D=E5=99=AA=E5=92=8C=E5=94=A4=E9=86=92=E5=8A=9F?= =?UTF-8?q?=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- main/CMakeLists.txt | 7 ++++-- main/Kconfig.projbuild | 12 +++++++-- main/application.cc | 25 ++++++++++-------- main/application.h | 8 ++++-- main/boards/atoms3-echo-base/config.json | 2 +- main/boards/tudouzi/config.json | 9 +++++++ main/boards/tudouzi/kevin_box_board.cc | 32 +++++++++++------------- 7 files changed, 60 insertions(+), 35 deletions(-) create mode 100644 main/boards/tudouzi/config.json diff --git a/main/CMakeLists.txt b/main/CMakeLists.txt index 591d203d..6660af4f 100644 --- a/main/CMakeLists.txt +++ b/main/CMakeLists.txt @@ -124,8 +124,11 @@ elseif(CONFIG_CONNECTION_TYPE_WEBSOCKET) list(APPEND SOURCES "protocols/websocket_protocol.cc") endif() -if(CONFIG_USE_AUDIO_PROCESSING) - list(APPEND SOURCES "audio_processing/audio_processor.cc" "audio_processing/wake_word_detect.cc") +if(CONFIG_USE_AUDIO_PROCESSOR) + list(APPEND SOURCES "audio_processing/audio_processor.cc") +endif() +if(CONFIG_USE_WAKE_WORD_DETECT) + list(APPEND SOURCES "audio_processing/wake_word_detect.cc") endif() # 根据Kconfig选择语言目录 diff --git a/main/Kconfig.projbuild b/main/Kconfig.projbuild index 5d46605c..fedd3cd9 100644 --- a/main/Kconfig.projbuild +++ b/main/Kconfig.projbuild @@ -180,10 +180,18 @@ choice DISPLAY_LCD_TYPE bool "自定义屏幕参数" endchoice -config USE_AUDIO_PROCESSING - bool "启用语音唤醒与音频处理" +config USE_AUDIO_PROCESSOR + bool "启用音频降噪、增益处理" default y depends on IDF_TARGET_ESP32S3 && USE_AFE help 需要 ESP32 S3 与 AFE 支持 + +config USE_WAKE_WORD_DETECT + bool "启用唤醒词检测" + default y + depends on IDF_TARGET_ESP32S3 && USE_AFE + help + 需要 ESP32 S3 与 AFE 支持 + endmenu diff --git a/main/application.cc b/main/application.cc index 7682a0f2..b11deb81 100644 --- a/main/application.cc +++ b/main/application.cc @@ -100,7 +100,7 @@ void Application::CheckNewVersion() { auto& board = Board::GetInstance(); board.SetPowerSaveMode(false); -#if CONFIG_USE_AUDIO_PROCESSING +#if CONFIG_USE_WAKE_WORD_DETECT wake_word_detect_.StopDetection(); #endif // 预先关闭音频输出,避免升级过程有音频操作 @@ -470,8 +470,7 @@ void Application::Start() { vTaskDelete(NULL); }, "check_new_version", 4096 * 2, this, 1, nullptr); - -#if CONFIG_USE_AUDIO_PROCESSING +#if CONFIG_USE_AUDIO_PROCESSOR audio_processor_.Initialize(codec->input_channels(), codec->input_reference()); audio_processor_.OnOutput([this](std::vector&& data) { background_task_->Schedule([this, data = std::move(data)]() mutable { @@ -482,7 +481,9 @@ void Application::Start() { }); }); }); +#endif +#if CONFIG_USE_WAKE_WORD_DETECT wake_word_detect_.Initialize(codec->input_channels(), codec->input_reference()); wake_word_detect_.OnVadStateChange([this](bool speaking) { Schedule([this, speaking]() { @@ -682,14 +683,16 @@ void Application::InputAudio() { data = std::move(resampled); } } - -#if CONFIG_USE_AUDIO_PROCESSING - if (audio_processor_.IsRunning()) { - audio_processor_.Input(data); - } + +#if CONFIG_USE_WAKE_WORD_DETECT if (wake_word_detect_.IsDetectionRunning()) { wake_word_detect_.Feed(data); } +#endif +#if CONFIG_USE_AUDIO_PROCESSOR + if (audio_processor_.IsRunning()) { + audio_processor_.Input(data); + } #else if (device_state_ == kDeviceStateListening) { background_task_->Schedule([this, data = std::move(data)]() mutable { @@ -730,7 +733,7 @@ void Application::SetDeviceState(DeviceState state) { case kDeviceStateIdle: display->SetStatus(Lang::Strings::STANDBY); display->SetEmotion("neutral"); -#ifdef CONFIG_USE_AUDIO_PROCESSING +#if CONFIG_USE_AUDIO_PROCESSOR audio_processor_.Stop(); #endif break; @@ -744,7 +747,7 @@ void Application::SetDeviceState(DeviceState state) { display->SetEmotion("neutral"); ResetDecoder(); opus_encoder_->ResetState(); -#if CONFIG_USE_AUDIO_PROCESSING +#if CONFIG_USE_AUDIO_PROCESSOR audio_processor_.Start(); #endif UpdateIotStates(); @@ -757,7 +760,7 @@ void Application::SetDeviceState(DeviceState state) { display->SetStatus(Lang::Strings::SPEAKING); ResetDecoder(); codec->EnableOutput(true); -#if CONFIG_USE_AUDIO_PROCESSING +#if CONFIG_USE_AUDIO_PROCESSOR audio_processor_.Stop(); #endif break; diff --git a/main/application.h b/main/application.h index bb94b93e..cbcc0643 100644 --- a/main/application.h +++ b/main/application.h @@ -18,8 +18,10 @@ #include "ota.h" #include "background_task.h" -#if CONFIG_USE_AUDIO_PROCESSING +#if CONFIG_USE_WAKE_WORD_DETECT #include "wake_word_detect.h" +#endif +#if CONFIG_USE_AUDIO_PROCESSOR #include "audio_processor.h" #endif @@ -72,8 +74,10 @@ private: Application(); ~Application(); -#if CONFIG_USE_AUDIO_PROCESSING +#if CONFIG_USE_WAKE_WORD_DETECT WakeWordDetect wake_word_detect_; +#endif +#if CONFIG_USE_AUDIO_PROCESSOR AudioProcessor audio_processor_; #endif Ota ota_; diff --git a/main/boards/atoms3-echo-base/config.json b/main/boards/atoms3-echo-base/config.json index 33dcae9d..3062ce03 100644 --- a/main/boards/atoms3-echo-base/config.json +++ b/main/boards/atoms3-echo-base/config.json @@ -5,7 +5,7 @@ "name": "atoms3-echo-base", "sdkconfig_append": [ "CONFIG_SPIRAM=n", - "CONFIG_USE_AUDIO_PROCESSING=n", + "CONFIG_USE_AFE=n", "CONFIG_ESPTOOLPY_FLASHSIZE_8MB=y", "CONFIG_PARTITION_TABLE_CUSTOM_FILENAME=\"partitions_8M.csv\"" ] diff --git a/main/boards/tudouzi/config.json b/main/boards/tudouzi/config.json new file mode 100644 index 00000000..886aa43f --- /dev/null +++ b/main/boards/tudouzi/config.json @@ -0,0 +1,9 @@ +{ + "target": "esp32s3", + "builds": [ + { + "name": "tudouzi", + "sdkconfig_append": ["CONFIG_USE_WAKE_WORD_DETECT=n"] + } + ] +} \ No newline at end of file diff --git a/main/boards/tudouzi/kevin_box_board.cc b/main/boards/tudouzi/kevin_box_board.cc index e3189a57..11c104a7 100644 --- a/main/boards/tudouzi/kevin_box_board.cc +++ b/main/boards/tudouzi/kevin_box_board.cc @@ -10,7 +10,6 @@ #include "assets/lang_config.h" #include -#include #include #include #include @@ -28,8 +27,8 @@ private: Button boot_button_; Button volume_up_button_; Button volume_down_button_; - uint8_t _data_buffer[2]; esp_timer_handle_t power_save_timer_ = nullptr; + bool show_low_power_warning_ = false; void InitializePowerSaveTimer() { esp_timer_create_args_t power_save_timer_args = { @@ -50,29 +49,29 @@ private: // 电池放电模式下,如果待机超过一定时间,则自动关机 const int seconds_to_shutdown = 600; static int seconds = 0; - if (Application::GetInstance().GetDeviceState() != kDeviceStateIdle) { + auto& app = Application::GetInstance(); + if (app.GetDeviceState() != kDeviceStateIdle) { seconds = 0; return; } if (!axp2101_->IsDischarging()) { seconds = 0; + if (show_low_power_warning_) { + app.DismissAlert(); + show_low_power_warning_ = false; + } return; } - - if (seconds >= seconds_to_shutdown) { - axp2101_->PowerOff(); + // 电量低于 10% 时,显示低电量警告 + if (axp2101_->GetBatteryLevel() <= 10 && !show_low_power_warning_) { + app.Alert(Lang::Strings::WARNING, Lang::Strings::BATTERY_LOW, "sad", Lang::Sounds::P3_VIBRATION); + show_low_power_warning_ = true; } - } - void MountStorage() { - // Mount the storage partition - esp_vfs_spiffs_conf_t conf = { - .base_path = "/storage", - .partition_label = "storage", - .max_files = 5, - .format_if_mount_failed = true, - }; - esp_vfs_spiffs_register(&conf); + seconds++; + if (seconds >= seconds_to_shutdown) { + // axp2101_->PowerOff(); + } } void Enable4GModule() { @@ -175,7 +174,6 @@ public: InitializeCodecI2c(); axp2101_ = new Axp2101(codec_i2c_bus_, AXP2101_I2C_ADDR); - MountStorage(); Enable4GModule(); InitializeButtons();