3.9 KiB
3.9 KiB
Day 12: 音频回环与静音问题攻坚
日期:2025-12-10 目标:解决音频底噪问题,恢复音频采集功能的稳定性,并排查 TTS 无声问题。
📅 工作摘要
今日重点攻克了音频子系统的两个棘手问题:采集端的静态底噪/回环 和 播放端的完全静音。同时修复了遗留的链接器错误和运行时崩溃问题。
1. 编译与链接修复 ✅
- 符号定义冲突:修复了
log_set_level等符号的多重定义错误,清理了src/utils/logger.cpp中的冗余实现。 - C++ 标准库链接:通过
-static-libstdc++和移除glog依赖,彻底解决了libstdc++相关的链接问题,确保了在musl环境下的稳定性。 - 动态链接器:再次确认并修复了板端的
/lib/ld-musl-riscv32.so.1符号链接,解决了 "not found" 启动错误。
2. 运行时稳定性修复 ✅
- WebSocket 重连崩溃:修复了
WSClient在重连时可能抛出std::terminate的问题。- 原因:在析构或重置旧连接时,未正确等待
m_recv_thread退出。 - 修复:在创建新线程前,确保先
join()旧线程。
- 原因:在析构或重置旧连接时,未正确等待
3. 音频采集 (Audio Capture) 调试与决策 ⚠️
- 问题现象:麦克风采集伴随强烈的静态底噪(自激啸叫/回环)。
- 尝试方案:
- 方案 A (禁用回环):关闭
Playback Switch。- 结果:底噪消失,但麦克风数据也彻底消失 (
sent=0, ALSA EAGAIN)。说明硬件上 Switch 控制了整个通路电源。
- 结果:底噪消失,但麦克风数据也彻底消失 (
- 方案 B (静音回环):开启
Playback Switch但将Playback Volume设为 0。- 结果:同样导致无数据,可能是前置放大器被连带静音。
- 方案 C (当前方案):开启
Playback Switch并将Playback Volume设为最大。- 结果:优先保证功能可用性。确保麦克风能采集到数据,即便可能带回部分底噪。
- 方案 A (禁用回环):关闭
4. 音频播放 (Audio Player) 修复 ✅
- 问题现象:服务器日志显示已发送音频数据,但扬声器无声。
- 原因分析:
AudioPlayer类初始化时只打开了 PCM 设备,但未配置混音器 (Mixer)。默认情况下,硬件的Master或LINEOUT音量可能是静音或 0。 - 修复实现:
- 在
AudioPlayer中新增setup_mixer()方法。 - 初始化时自动扫描
hw:1(I2S) 和hw:0(Codec) 的所有混音器控件。 - 强制将所有 Playback 相关的 Switch 设为 On,Volume 设为 Max。
- 在
5. 系统集成与验证
- 隔离调试:调试期间暂时禁用了 摄像头 和 IMU 线程,排除干扰。
- 全功能恢复:在确认音频配置后,恢复了所有线程(Camera, IMU, Audio Capture)。
- 当前状态:系统已重新编译并部署,等待最终的板端“有声”验证。
📝 关键代码变更
src/audio/audio_capture.cpp
// 强制开启 Switch 并最大化音量,优先保证采集信号
if (snd_mixer_selem_has_playback_volume(elem)) {
snd_mixer_selem_set_playback_volume_all(elem, max); // Maximize
}
if (snd_mixer_selem_has_playback_switch(elem)) {
snd_mixer_selem_set_playback_switch_all(elem, 1); // Enable
}
src/audio/audio_player.cpp
// 新增混音器配置,确保扬声器未被静音
bool AudioPlayer::setup_mixer(const char* card_name) {
// ... 打开 Mixer ...
// 遍历所有控件,取消静音并设为最大音量
snd_mixer_selem_set_playback_volume_all(elem, max);
snd_mixer_selem_set_playback_switch_all(elem, 1);
}
🔜 下一步计划 (Day 13)
- 板端验证:确认修改后的音频配置能否听到 TTS 语音,并评估底噪水平。
- 摄像头优化:继续解决 VBV 缓存溢出导致的花屏/卡顿问题。
- 长稳测试:进行 1 小时以上的全负载稳定性测试。