声学算法调试

更新时间:2026-03-17 08:04:28LLM 副本以 Markdown 格式查看下载 PDF

概述

本文介绍如何调试本示例中的 回声消除(Auto Gain Control,AGC)、残留回声抑制(Acoustic Echo Suppression,AES)语音活动检测(Voice Activity Detection,VAD),二者实现在 src/wukong/audio/wukong_audio_aec_vad.c 中,对外接口见头文件 wukong_audio_aec_vad.h。当前版本使用 Speex AEC + AES + 噪声抑制RNN VAD,无串口在线调参;调试以 初始化参数VAD 灵敏度档位 为主,并结合抓取音频数据进行分析。

测试工具

推荐使用涂鸦官方串口工具 tyuTool 进行联调与数据抓取:

  • 支持 GUICLI,通过串口与设备通信。
  • 可发送控制命令(如开始/停止录音、播放测试音、抓取各通道数据),便于对比 AEC 前后与 VAD 状态。
  • 安装与基本用法见其 GitHub 仓库说明;AI 调试需使用 debug serdebug ser_auto 模式。

测试指令(与声学测试共用)

在 tyuTool 的串口调试模式下,常用指令包括(具体以工具内 help 为准):

命令 说明
start/stop/reset 开始/停止/重置录音与处理
dump 0 抓取麦克风(MIC)原始数据
dump 1 抓取参考 (REF) 回采数据
dump 2 抓取 AEC 输出数据(回声消除后)
dump 4 抓取 VAD 相关数据
volume <0-100> / micgain <0-100> 调节播放音量与麦克风增益

通过 dump 0/1/2 可对比 MIC、REF、AEC 输出,判断回声消除效果;结合日志中的 VAD 起止打印可分析 VAD 行为。

测试步骤建议

  1. 连接设备:用 tyuTool 连接设备串口并进入串口调试模式。
  2. 复位并启动:发送 reset,再发送 start,使设备进入录音与处理状态。
  3. 播放测试音或真人说话:根据需要播放 bg 0/1/… 或直接对话,观察听感与日志。
  4. 停止并抓取:发送 stop,再依次发送 dump 0dump 1dump 2 抓取 MIC、REF、AEC 通道数据。
  5. 离线分析:将抓取的 PCM 导入 Audition/ocenaudio 等工具,对比 AEC 前后波形与频谱,评估回声抑制与 VAD 切音是否合理。

调试前置检查清单(通用)

在排查 AEC/VAD 效果前,建议先固定以下项,避免环境变化干扰判断:

  1. 麦克风型号与增益:固定 MIC 及增益,避免输入幅值变化。
  2. 扬声器型号与增益:固定喇叭与音量,避免回声路径变化。
  3. 产品结构:外壳与音腔固定后再做算法评估。

AEC 与降噪调试说明

残留回声抑制

speex_aes_set_param(handle, value)

  • 含义:value残留回声抑制强弱int 类型。当前源码中为 5
  • 取值建议:
    • 值越大:对残留回声抑制越多,但 打断效果会变差(双讲时近端容易被压掉)。
    • 值越小:对残留回声抑制越少,近端语音保留较多,但残留回声会增多。
  • 可根据听感在源码中调整该值后重编,在 “残留小” 与 “打断好” 之间折中。

降噪

speex_ns_set_param(handle, level1, level2)

  • 含义:level1level2 均为 int,无硬性范围限制。
    • level1:降噪力度,值越大降噪越强。
    • level2:底噪水平,值越小表示底噪越低,可抑制的噪声越多。
  • 调参建议:
    • 高信噪比:选 大 level1、小 level2
    • 低信噪比:选 小 level1、大 level2
  • 当前源码中为 speex_ns_set_param(handle, 8, 10),可按实际环境在源码中修改后重编。

调试建议

  • 先完成调试前置检查清单,再听感评估 + dump 0/1/2 对比。
  • 残留回声偏大:可适当增大 speex_aes_set_param 的数值;若 打断/双讲效果差:可适当减小该值。
  • 噪声抑制不足或过度:按信噪比调整 speex_ns_set_param 的 level1/level2。
  • 同时可配合减小喇叭音量、增大 MIC 与喇叭间距等结构/增益手段。

VAD(语音活动检测)说明

当前实现

  • wukong_aec_vad_init() 中初始化,传入参数为:
    • min_speech_len_ms:最短有效语音时长(ms),过小易误报。
    • max_speech_interval_ms:最大静音间隔(ms),超时认为一句话结束。
  • 通过 wukong_vad_set_threshold(level) 选择灵敏度档位(见下文 API)。内部映射为 RNN 的阈值 dB:
    • WUKONG_AUDIO_VAD_HIGH:- 40 dB(不易误触发)
    • WUKONG_AUDIO_VAD_MID:- 50 dB(默认)
    • WUKONG_AUDIO_VAD_LOW:- 60 dB(更易触发)

调试建议

  • 漏检(该有语音未检测到):可改为 WUKONG_AUDIO_VAD_LOW,或适当增大 max_speech_interval_ms
  • 误触发(静音被判成语音):可改为 WUKONG_AUDIO_VAD_HIGH,或适当增大 min_speech_len_ms
  • 结合串口/日志中的 [vad start]/[vad stop] 与抓取的 dump 4 数据核对边界是否合理。

API 参考(与当前代码一致)

接口定义见 src/wukong/audio/wukong_audio_aec_vad.h,实现见 wukong_audio_aec_vad.c

初始化与反初始化

/**
 * 初始化 AEC 与 VAD 模块(内部创建 Speex AEC 与 RNN VAD)
 * @param min_speech_len_ms   最短有效语音时长(ms)
 * @param max_speech_interval_ms 最大静音间隔(ms),超时则认为一句话结束
 * @param frame_size          帧长(如 16k 下 320 表示 20ms)
 */
OPERATE_RET wukong_aec_vad_init(UINT32_T min_speech_len_ms, UINT32_T max_speech_interval_ms, UINT32_T frame_size);

OPERATE_RET wukong_aec_vad_deinit(VOID);

数据处理(由音频管线每帧调用)

/**
 * 喂入一帧数据进行 AEC 与 VAD 处理
 * @param mic_data  麦克风输入
 * @param ref_data  参考信号(如喇叭回采)
 * @param out_data  AEC 输出(再送 RNN VAD)
 */
OPERATE_RET wukong_aec_vad_process(INT16_T *mic_data, INT16_T *ref_data, INT16_T *out_data);

VAD 灵敏度与控制

typedef enum {
    WUKONG_AUDIO_VAD_HIGH,  // 阈值 -40dB,不易误触发
    WUKONG_AUDIO_VAD_MID,   // 阈值 -50dB,默认
    WUKONG_AUDIO_VAD_LOW,   // 阈值 -60dB,更易触发
} WUKONG_AUDIO_VAD_THRESHOLD_E;

/** 设置 VAD 灵敏度档位,仅此接口可在运行时调节 VAD */
OPERATE_RET wukong_vad_set_threshold(WUKONG_AUDIO_VAD_THRESHOLD_E level);

/** 手动开启/停止 VAD 检测 */
OPERATE_RET wukong_vad_start(VOID);
OPERATE_RET wukong_vad_stop(VOID);

/** 获取当前 VAD 状态:WUKONG_AUDIO_VAD_START 或 WUKONG_AUDIO_VAD_STOP */
INT_T wukong_vad_get_flag(VOID);

支持

在开发过程遇到问题,可以到 TuyaOS 开发者论坛 联网单品开发版块 发帖咨询。