From 564018c762307ad11a67452862605bc133102ec2 Mon Sep 17 00:00:00 2001 From: Xiaoxia Date: Mon, 15 Dec 2025 12:54:17 +0800 Subject: [PATCH] Enhance audio feedback mechanism by introducing a flag to play a popup (#1560) * Enhance audio feedback mechanism by introducing a flag to play a popup sound after transitioning to listening mode. Update Schedule method to accept rvalue references for callbacks. Bump esp-ml307 component version to 3.5.3. Adjust signal strength thresholds in Ml307Board for better accuracy. * Update esp-wifi-connect component version to 3.0.2 in idf_component.yml * Adjust Wi-Fi signal strength thresholds in WifiBoard for improved accuracy in network state icon representation. --- main/application.cc | 18 +++++++++++++----- main/application.h | 3 ++- main/boards/common/ml307_board.cc | 8 ++++---- main/boards/common/wifi_board.cc | 4 ++-- main/idf_component.yml | 4 ++-- 5 files changed, 23 insertions(+), 14 deletions(-) diff --git a/main/application.cc b/main/application.cc index 2ab244f1..09803862 100644 --- a/main/application.cc +++ b/main/application.cc @@ -780,9 +780,10 @@ void Application::HandleWakeWordDetectedEvent() { protocol_->SendWakeWordDetected(wake_word); SetListeningMode(aec_mode_ == kAecOff ? kListeningModeAutoStop : kListeningModeRealtime); #else + // Set flag to play popup sound after state changes to listening + // (PlaySound here would be cleared by ResetDecoder in EnableVoiceProcessing) + play_popup_on_listening_ = true; SetListeningMode(aec_mode_ == kAecOff ? kListeningModeAutoStop : kListeningModeRealtime); - // Play the pop up sound to indicate the wake word is detected - audio_service_.PlaySound(Lang::Sounds::OGG_POPUP); #endif } else if (state == kDeviceStateSpeaking) { AbortSpeaking(kAbortReasonWakeWordDetected); @@ -825,6 +826,12 @@ void Application::HandleStateChangedEvent() { audio_service_.EnableVoiceProcessing(true); audio_service_.EnableWakeWordDetection(false); } + + // Play popup sound after ResetDecoder (in EnableVoiceProcessing) has been called + if (play_popup_on_listening_) { + play_popup_on_listening_ = false; + audio_service_.PlaySound(Lang::Sounds::OGG_POPUP); + } break; case kDeviceStateSpeaking: display->SetStatus(Lang::Strings::SPEAKING); @@ -846,7 +853,7 @@ void Application::HandleStateChangedEvent() { } } -void Application::Schedule(std::function callback) { +void Application::Schedule(std::function&& callback) { { std::lock_guard lock(mutex_); main_tasks_.push_back(std::move(callback)); @@ -960,9 +967,10 @@ void Application::WakeWordInvoke(const std::string& wake_word) { protocol_->SendWakeWordDetected(wake_word); SetListeningMode(aec_mode_ == kAecOff ? kListeningModeAutoStop : kListeningModeRealtime); #else + // Set flag to play popup sound after state changes to listening + // (PlaySound here would be cleared by ResetDecoder in EnableVoiceProcessing) + play_popup_on_listening_ = true; SetListeningMode(aec_mode_ == kAecOff ? kListeningModeAutoStop : kListeningModeRealtime); - // Play the pop up sound to indicate the wake word is detected - audio_service_.PlaySound(Lang::Sounds::OGG_POPUP); #endif } else if (state == kDeviceStateSpeaking) { Schedule([this]() { diff --git a/main/application.h b/main/application.h index 212eaf68..33bda4cf 100644 --- a/main/application.h +++ b/main/application.h @@ -75,7 +75,7 @@ public: /** * Schedule a callback to be executed in the main task */ - void Schedule(std::function callback); + void Schedule(std::function&& callback); /** * Alert with status, message, emotion and optional sound @@ -139,6 +139,7 @@ private: bool has_server_time_ = false; bool aborted_ = false; bool assets_version_checked_ = false; + bool play_popup_on_listening_ = false; // Flag to play popup sound after state changes to listening int clock_ticks_ = 0; TaskHandle_t activation_task_handle_ = nullptr; diff --git a/main/boards/common/ml307_board.cc b/main/boards/common/ml307_board.cc index 2db9695d..fc551841 100644 --- a/main/boards/common/ml307_board.cc +++ b/main/boards/common/ml307_board.cc @@ -155,13 +155,13 @@ const char* Ml307Board::GetNetworkStateIcon() { int csq = modem_->GetCsq(); if (csq == -1) { return FONT_AWESOME_SIGNAL_OFF; - } else if (csq >= 0 && csq <= 14) { + } else if (csq >= 0 && csq <= 9) { return FONT_AWESOME_SIGNAL_WEAK; - } else if (csq >= 15 && csq <= 19) { + } else if (csq >= 10 && csq <= 14) { return FONT_AWESOME_SIGNAL_FAIR; - } else if (csq >= 20 && csq <= 24) { + } else if (csq >= 15 && csq <= 19) { return FONT_AWESOME_SIGNAL_GOOD; - } else if (csq >= 25 && csq <= 31) { + } else if (csq >= 20 && csq <= 31) { return FONT_AWESOME_SIGNAL_STRONG; } diff --git a/main/boards/common/wifi_board.cc b/main/boards/common/wifi_board.cc index 062362e5..77aff4fc 100644 --- a/main/boards/common/wifi_board.cc +++ b/main/boards/common/wifi_board.cc @@ -259,9 +259,9 @@ const char* WifiBoard::GetNetworkStateIcon() { } int rssi = wifi.GetRssi(); - if (rssi >= -60) { + if (rssi >= -65) { return FONT_AWESOME_WIFI; - } else if (rssi >= -70) { + } else if (rssi >= -75) { return FONT_AWESOME_WIFI_FAIR; } return FONT_AWESOME_WIFI_WEAK; diff --git a/main/idf_component.yml b/main/idf_component.yml index 863ffe64..290a7112 100644 --- a/main/idf_component.yml +++ b/main/idf_component.yml @@ -18,9 +18,9 @@ dependencies: espressif/esp_io_expander_tca9554: ==2.0.0 espressif/esp_lcd_panel_io_additions: ^1.0.1 78/esp_lcd_nv3023: ~1.0.0 - 78/esp-wifi-connect: ~3.0.1 + 78/esp-wifi-connect: ~3.0.2 78/esp-opus-encoder: ~2.4.1 - 78/esp-ml307: ~3.5.2 + 78/esp-ml307: ~3.5.3 78/xiaozhi-fonts: ~1.5.5 espressif/led_strip: ~3.0.1 espressif/esp_codec_dev: ~1.5