wangzhibo
2026-09-11 659c470eba542383987aad227b7f918100f131fa
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();