78 lines
3.9 KiB
Markdown
78 lines
3.9 KiB
Markdown
# 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` 设为最大。**
|
||
- **结果**:优先保证**功能可用性**。确保麦克风能采集到数据,即便可能带回部分底噪。
|
||
|
||
### 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`
|
||
```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`
|
||
```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)
|
||
|
||
1. **板端验证**:确认修改后的音频配置能否听到 TTS 语音,并评估底噪水平。
|
||
2. **摄像头优化**:继续解决 VBV 缓存溢出导致的花屏/卡顿问题。
|
||
3. **长稳测试**:进行 1 小时以上的全负载稳定性测试。
|