ESP32小智-语音活动(VAD)检测流程
1、启动流程
启动流程可以参考:ESP32唤醒流程-CSDN博客
Application::Start()->AudioService::Initialize()->AfeAudioProcessor::Initialize()
2、VAD配置
选择VADNet模型:
idf.py menuconfig
ESP Speech Recognition -> Select voice activity detection -> voice activity detection (vadnet1 medium).
常用VAD参数配置如下:
afe_config->vad_init = true // 是否在AFE流水线中初始化VAD,默认启用
afe_config->vad_min_noise_ms = 1000; // 噪声/静音段的最短持续时间(毫秒)
afe_config->vad_min_speech_ms = 128; // 语音段的最短持续时间(毫秒)
afe_config->vad_delay_ms = 128; // VAD首帧触发到语音首帧数据的延迟量
afe_config->vad_mode = VAD_MODE_1; // 模式值越大,语音触发概率越高
如需临时启用/禁用/重置VADNet,可使用以下接口:
afe_handle->disable_vad(afe_data); // 禁用VAD
afe_handle->enable_vad(afe_data); // 启用VAD
afe_handle->reset_vad(afe_data); // 重置VAD状态
3、VAD缓存与检测
通过AFE的fetch接口返回检测结果。
VAD配置中的两个特性可能导致语音首帧触发延迟:
-
VAD算法固有延迟:VAD无法在首帧精准触发,可能有1-3帧延迟
-
防误触机制:需持续触发时间达到配置参数`vad_min_speech_ms`才会正式触发
为避免上述原因导致语音首字截断,AFE V2.0新增了VAD缓存机制。可通过检查vad_cache_size判断是否需要保存VAD缓存:
afe_fetch_result_t* result = afe_handle->fetch(afe_data);
if (result->vad_cache_size > 0) {printf("vad cache size: %d\n", result->vad_cache_size);fwrite(result->vad_cache, 1, result->vad_cache_size, fp);
}printf("vad state: %s\n", res->vad_state==VAD_SILENCE ? "noise" : "speech");
ESP32代码AfeAudioProcessor::AudioProcessorTask():
auto res = afe_iface_->fetch_with_delay(afe_data_, portMAX_DELAY);if ((xEventGroupGetBits(event_group_) & PROCESSOR_RUNNING) == 0) {continue;}if (res == nullptr || res->ret_value == ESP_FAIL) {if (res != nullptr) {ESP_LOGI(TAG, "Error code: %d", res->ret_value);}continue;}// VAD state changeif (vad_state_change_callback_) {if (res->vad_state == VAD_SPEECH && !is_speaking_) {is_speaking_ = true;vad_state_change_callback_(true);} else if (res->vad_state == VAD_SILENCE && is_speaking_) {is_speaking_ = false;vad_state_change_callback_(false);}}