From 659c470eba542383987aad227b7f918100f131fa Mon Sep 17 00:00:00 2001
From: wangzhibo <wangzhibo@shsening.com>
Date: 星期五, 11 九月 2026 15:09:05 +0800
Subject: [PATCH] 小智终端 5种 场景模式 OK

---
 xiaozhi-esp32-2.2.6/main/audio/audio_service.cc |   49 +++++++++++++++++++++++++++++++++++++++++++++++--
 1 files changed, 47 insertions(+), 2 deletions(-)

diff --git a/xiaozhi-esp32-2.2.6/main/audio/audio_service.cc b/xiaozhi-esp32-2.2.6/main/audio/audio_service.cc
index 4489cae..209f7fe 100644
--- a/xiaozhi-esp32-2.2.6/main/audio/audio_service.cc
+++ b/xiaozhi-esp32-2.2.6/main/audio/audio_service.cc
@@ -1,6 +1,7 @@
 #include "audio_service.h"
 #include <esp_log.h>
 #include <cstring>
+#include <chrono>
 
 #define RATE_CVT_CFG(_src_rate, _dest_rate, _channel)        \
     (esp_ae_rate_cvt_cfg_t)                                  \
@@ -554,6 +555,11 @@
         return;
     }
 
+    const bool running = IsWakeWordRunning();
+    if (enable == running && (!enable || wake_word_initialized_)) {
+        return;
+    }
+
     ESP_LOGD(TAG, "%s wake word detection", enable ? "Enabling" : "Disabling");
     if (enable) {
         if (!wake_word_initialized_) {
@@ -577,6 +583,15 @@
         wake_word_->Stop();
         xEventGroupClearBits(event_group_, AS_EVENT_WAKE_WORD_RUNNING);
     }
+}
+
+void AudioService::EnsureVoiceProcessorReady() {
+    if (audio_processor_initialized_ || audio_processor_ == nullptr) {
+        return;
+    }
+    ESP_LOGI(TAG, "Preload voice processor");
+    audio_processor_->Initialize(codec_, OPUS_FRAME_DURATION_MS, models_list_);
+    audio_processor_initialized_ = true;
 }
 
 void AudioService::EnableVoiceProcessing(bool enable) {
@@ -663,9 +678,14 @@
 
 void AudioService::WaitForPlaybackQueueEmpty() {
     std::unique_lock<std::mutex> lock(audio_queue_mutex_);
-    audio_queue_cv_.wait(lock, [this]() { 
-        return service_stopped_ || (audio_decode_queue_.empty() && audio_playback_queue_.empty()); 
+    audio_queue_cv_.wait_for(lock, std::chrono::milliseconds(5000), [this]() {
+        return service_stopped_ || (audio_decode_queue_.empty() && audio_playback_queue_.empty());
     });
+}
+
+bool AudioService::IsPlaybackQueueEmpty() {
+    std::lock_guard<std::mutex> lock(audio_queue_mutex_);
+    return audio_decode_queue_.empty() && audio_playback_queue_.empty();
 }
 
 void AudioService::ResetDecoder() {
@@ -682,7 +702,32 @@
     audio_queue_cv_.notify_all();
 }
 
+void AudioService::KeepCodecReadyForPlayback() {
+    last_output_time_ = std::chrono::steady_clock::now();
+    last_input_time_ = std::chrono::steady_clock::now();
+    if (codec_ == nullptr) {
+        return;
+    }
+    if (!codec_->output_enabled()) {
+        esp_timer_stop(audio_power_timer_);
+        esp_timer_start_periodic(audio_power_timer_, AUDIO_POWER_CHECK_INTERVAL_MS * 1000);
+        codec_->EnableOutput(true);
+    }
+}
+
+void AudioService::SetAudioPowerInhibit(bool inhibit) {
+    audio_power_inhibit_ = inhibit;
+    if (inhibit) {
+        KeepCodecReadyForPlayback();
+    }
+}
+
 void AudioService::CheckAndUpdateAudioPowerState() {
+    if (audio_power_inhibit_) {
+        last_input_time_ = std::chrono::steady_clock::now();
+        last_output_time_ = last_input_time_;
+        return;
+    }
     auto now = std::chrono::steady_clock::now();
     auto input_elapsed = std::chrono::duration_cast<std::chrono::milliseconds>(now - last_input_time_).count();
     auto output_elapsed = std::chrono::duration_cast<std::chrono::milliseconds>(now - last_output_time_).count();

--
Gitblit v1.9.1