回声消除 (AEC) 配置指南
概述
回声消除(Acoustic Echo Cancellation,AEC)是语音交互中的关键技术,用于消除扬声器播放时产生的回声干扰。当系统播放音频时,麦克风会同时捕获到播放内容,导致语音识别准确性下降,甚至出现"自言自语"(AI 听到自己的声音并回应)。
AEC 的工作原理:
- 捕获麦克风输入的音频信号(包含用户语音 + 回声)
- 获取扬声器播放的参考信号
- 使用算法从麦克风信号中减去预测的回声成分
- 输出干净的用户语音信号
内置 AEC(默认方案,三端开箱即用)
py-xiaozhi 内置 WebRTC APM(libs/webrtc_apm,含 Windows/macOS/Linux 三端动态库),以本应用播放的 TTS/音乐混音作为参考信号(Self far),在应用内完成回声消除,无需任何系统配置。
text
┌─────────────┐ ┌──────────────┐
│ 物理麦克风 │──── 近端(含回声) ────▶│ │
└─────────────┘ │ WebRTC APM │──▶ 干净语音 ──▶ 识别/上行
┌─────────────┐ │ (应用内) │
│ TTS/音乐混音│──── 远端参考 ────────▶│ │
└──────┬──────┘ └──────────────┘
└────────▶ 扬声器播放启用方式
编辑配置文件,或在 GUI 设置页开启:
json
{
"AEC_OPTIONS": {
"ENABLED": true,
"MUSIC_PARALLEL": true,
"FRAME_DELAY": 3,
"ENABLE_PREPROCESS": true
}
}| 配置项 | 说明 |
|---|---|
ENABLED | 启用后进入实时对话模式(REALTIME),可随时打断 AI |
MUSIC_PARALLEL | AEC 在位时 TTS 与音乐并行播放(音乐自动闪避);AEC 旁路时回退为暂停音乐 |
FRAME_DELAY | 延迟补偿帧数,实际补偿 = 40ms + N × 协议帧长 |
ENABLE_PREPROCESS | 噪声抑制/高通预处理 |
配置项完整说明见配置说明。
行为说明
- 自动旁路: AEC 引擎创建失败时自动旁路,不影响正常收发音频;旁路时音乐并行自动回退为"TTS 播放时暂停音乐"
- 设备热切换: 更换输入/输出设备后引擎自动重建,无需重启
- 模式联动:
ENABLED: true时默认实时对话(REALTIME);false时默认回合制对话(AUTO_STOP)
效果验证
text
1. 启用 AEC 后启动,选择自动对话
2. 让 AI 播放音乐或长句 TTS,期间直接说话打断
3. 正常表现:不自言自语、可正常打断、音乐与 TTS 并行时识别不受干扰也可在代码中检查引擎状态:
python
# AEC 引擎是否在位且工作中
codec.aec_active # True = 在位,False = 未启用或已旁路局限
内置 AEC 只以本应用的播放内容为参考信号,因此:
- ✅ 可消除:py-xiaozhi 自己播放的 TTS、音乐
- ❌ 无法消除:其它软件的外放声音(浏览器视频、其它播放器等)
如需消除其它软件的声音,可使用下面的系统级方案作为增强。
系统级 AEC(可选增强)
系统级方案在操作系统层完成回声消除,参考信号覆盖整机所有输出,可消除其它软件的外放声音。配置有一定门槛,按需选用。
🪟 Windows
- 方案: 音频驱动层 AEC(多数设备开箱即用)
- 说明: 部分声卡/耳机驱动自带回声消除,无需配置
🐧 Linux (PulseAudio)
使用 module-echo-cancel 模块在系统层做回声消除:
bash
# 一键配置脚本
git clone https://github.com/W-E-A/PulseAudio-AEC-Script.git
cd PulseAudio-AEC-Script
chmod +x setup_aec.sh uninstall_aec.sh
# 运行安装脚本(不要使用sudo)
./setup_aec.sh配置完成后,在系统"声音"设置中:
- 输入设备: 选择包含
echo cancellation的虚拟麦克风 - 输出设备: 选择包含
echo cancellation的虚拟扬声器
⚠️ 硬件建议: 笔记本内置麦克风+扬声器组合由于物理振动耦合,AEC效果有限,推荐外置USB麦克风 + 独立扬声器
常见问题:
bash
# 找不到 echo cancellation 设备时
pactl list sources short
pactl list sinks short
pulseaudio -k # 重启音频服务
# 检查模块加载状态
pactl list modules | grep echo-cancel卸载:./uninstall_aec.sh
🍎 macOS (BlackHole)
通过 BlackHole 虚拟设备 + 聚合设备把系统输出引回来作参考信号:
bash
# 安装 BlackHole
brew install blackhole-2ch- 打开"音频 MIDI 设置" → "+" → "创建聚合设备"(实测部分机器需创建多输出设备才生效)
- ✅ 内置扬声器(主设备)
- ✅ BlackHole 2ch
- 采样率:48.0 kHz
- 系统"声音"设置:输出选聚合设备,输入保持物理麦克风



⚠️ 音量控制限制: 聚合设备无法直接调节系统音量,可在音频MIDI设置中调整各子设备音量
设备验证:
bash
# 验证 BlackHole 设备
system_profiler SPAudioDataType | grep -i blackhole
# 设备未找到时重装并重启 CoreAudio
brew reinstall blackhole-2ch
sudo launchctl kickstart -kp system/com.apple.audio.coreaudiod故障排除
Q1: 启用后仍然自言自语
- 确认日志中无 "创建 AEC 引擎失败" / "AEC 未启用" 字样
- 降低扬声器音量,或拉开麦克风与扬声器距离
- 适当调大
FRAME_DELAY(蓝牙设备延迟较大时)
Q2: 内置麦克风效果不佳
- 物理振动耦合:扬声器振动直接传导至内置麦克风
- 建议:外置USB麦克风 + 独立扬声器,或使用耳机(物理无回声)
Q3: 别的软件放歌时 AI 听到了
- 内置 AEC 的已知局限(参考信号只有本应用输出)
- 使用上面的系统级方案,或播放时暂停其它软件
参考资源
- WebRTC Audio Processing - 算法实现文档
- PulseAudio AEC Script - Linux 系统级配置脚本
- BlackHole 官方仓库 - macOS 虚拟音频设备