wangzhibo
10 天以前 220e4fab27b7f419b3e89e2f2d28ae789aac09d7
xiaozhi-esp32-2.2.6/main/audio/audio_service.cc
@@ -1,4 +1,5 @@
#include "audio_service.h"
#include "processors/audio_debugger.h"
#include <esp_log.h>
#include <cstring>
#include <chrono>
@@ -240,6 +241,9 @@
        if (audio_input_need_warmup_) {
            audio_input_need_warmup_ = false;
            vTaskDelay(pdMS_TO_TICKS(120));
            if (xEventGroupGetBits(event_group_) & AS_EVENT_AUDIO_PROCESSOR_RUNNING) {
                audio_processor_->Start();
            }
            continue;
        }
@@ -538,6 +542,12 @@
    }
}
void AudioService::AbortWakeWordEncode() {
    if (wake_word_) {
        wake_word_->AbortWakeWordEncode();
    }
}
const std::string& AudioService::GetLastWakeWord() const {
    return wake_word_->GetLastDetectedWakeWord();
}
@@ -568,6 +578,9 @@
                return;
            }
            wake_word_initialized_ = true;
        } else if (!wake_word_->EnsureRuntime()) {
            ESP_LOGE(TAG, "Failed to restore wake word runtime");
            return;
        }
        // Reset input resampler to clear cached data from previous mode (e.g. AudioProcessor)
        // This prevents buffer overflow when switching between different feed sizes
@@ -585,13 +598,39 @@
    }
}
void AudioService::ClearWakeWordBuffers() {
    if (wake_word_) {
        wake_word_->ClearWakeBuffers();
    }
}
void AudioService::ReleaseAfeRuntime() {
    EnableVoiceProcessing(false);
    EnableWakeWordDetection(false);
    if (wake_word_) {
        wake_word_->ReleaseRuntime();
    }
    ReleaseVoiceProcessorRuntime();
}
void AudioService::ReleaseVoiceProcessorRuntime() {
    EnableVoiceProcessing(false);
    if (audio_processor_initialized_ && audio_processor_) {
        audio_processor_->ReleaseRuntime();
    }
}
void AudioService::EnsureVoiceProcessorReady() {
    if (audio_processor_initialized_ || audio_processor_ == nullptr) {
    if (audio_processor_ == nullptr) {
        return;
    }
    ESP_LOGI(TAG, "Preload voice processor");
    audio_processor_->Initialize(codec_, OPUS_FRAME_DURATION_MS, models_list_);
    audio_processor_initialized_ = true;
    if (!audio_processor_initialized_) {
        ESP_LOGI(TAG, "Preload voice processor");
        audio_processor_->Initialize(codec_, OPUS_FRAME_DURATION_MS, models_list_);
        audio_processor_initialized_ = true;
    } else if (!audio_processor_->EnsureRuntime()) {
        ESP_LOGE(TAG, "Failed to restore voice processor runtime");
    }
}
void AudioService::EnableVoiceProcessing(bool enable) {
@@ -600,6 +639,9 @@
        if (!audio_processor_initialized_) {
            audio_processor_->Initialize(codec_, OPUS_FRAME_DURATION_MS, models_list_);
            audio_processor_initialized_ = true;
        } else if (!audio_processor_->EnsureRuntime()) {
            ESP_LOGE(TAG, "Failed to restore voice processor runtime");
            return;
        }
        /* We should make sure no audio is playing */
@@ -613,8 +655,8 @@
                esp_ae_rate_cvt_reset(input_resampler_);
            }
        }
        audio_processor_->Start();
        xEventGroupSetBits(event_group_, AS_EVENT_AUDIO_PROCESSOR_RUNNING);
        // fetch 等 input warmup 后再 Start,避免刚进聆听就 AFE empty / Error -1
    } else {
        audio_processor_->Stop();
        xEventGroupClearBits(event_group_, AS_EVENT_AUDIO_PROCESSOR_RUNNING);