6.1 KiB
6.1 KiB
Day 22 - GLM API 修复 + SenseVoice 语言修复
日期: 2025-12-26
主题: AI 对话链路修复
🔧 GLM API 升级 (10:00)
问题:Day 21 的 GLM API 调用失败 (Error 400/1210)
原因:使用了错误的 SDK 和模型名称
修复:升级到官方 zai-sdk + glm-4.5-flash
修改对比
| 项目 | 修改前 | 修改后 |
|---|---|---|
| SDK | openai |
zai-sdk |
| 模型 | glm-4-flash |
glm-4.5-flash |
| 客户端 | OpenAI(...) |
ZhipuAiClient(...) |
代码变更 (glm_client.py)
# 修改前
from openai import OpenAI
MODEL = "glm-4-flash"
_client = OpenAI(api_key=API_KEY, base_url=API_BASE)
# 修改后
from zai import ZhipuAiClient
MODEL = "glm-4.5-flash"
_client = ZhipuAiClient(api_key=API_KEY)
🔧 SenseVoice 语言修复 (10:08)
问题:Day 21 识别出韩语字符 (그)
原因:language="auto" 自动检测错误
修复:固定为 language="zh" 中文
代码变更 (sensevoice_asr.py)
# 修改前
language="auto"
# 修改后
language="zh" # 固定为中文,避免 auto 误判
🔧 扬声器杂声修复 (10:48)
问题:无 TTS 播放时扬声器有杂声
原因:loopback debug 开关将麦克风信号回环到 I2S 输出
修复:在 audio_player.cpp 中禁用 loopback 开关
代码变更 (audio_player.cpp)
// 在 setup_mixer() 中
if (switch_name.find("loopback") != std::string::npos) {
snd_mixer_selem_set_playback_switch_all(elem, 0); // 禁用
LOG_INFO("DISABLED playback switch for '%s' (noise reduction)", name);
}
注意事项
- 不能禁用 MIC playback switch:Day 12 发现禁用会导致麦克风无数据(硬件限制)
- 如果此修复不彻底,可能需要硬件层面改进(加磁环、屏蔽线)
📁 修改文件汇总
| 文件 | 修改内容 |
|---|---|
glm_client.py |
升级到 zai-sdk + glm-4.5-flash |
sensevoice_asr.py |
语言设置从 auto 改为 zh |
test_glm.py |
新增 GLM API 测试脚本 |
🧪 验证说明
服务器测试步骤
cd ~/ProgramFiles/OpenAIglasses_for_Navigation
# 1. 同步代码(从本地推送或 git pull)
# 2. 启动服务器(主程序已集成修复)
python app_main.py
验证点
- 语音识别结果为中文(不再出现韩语字符)
- AI 回答与问题相关 (GLM-4.6v-flash)
- VAD 响应灵敏,无首字丢失
- 导航语音播报正常 (Chipmunk effect 确认为正常现象)
🔧 VAD 语音截断修复 (14:30)
问题:语音指令首字经常丢失(如"开始导航"识别为"导航")
原因:VAD 触发后才开始录制,错过了触发前的几百毫秒关键音节
修复:在 server_vad.py 中引入 pre_speech_buffer 环形缓冲区 (300ms)
效果:检测到语音时,自动回溯并拼接前 300ms 音频,首字识别率显著提升
代码原理
# 环形缓冲队列
self.pre_speech_buffer = collections.deque(maxlen=PRE_SPEECH_CHUNKS)
# 触发时拼接
packet = b''.join(list(self.pre_speech_buffer)) + chunk
🔧 TTS 语速与音频底噪 (15:50)
1. 导航语音语速过快 ("Chipmunk Effect")
现象:导航提示音(如"远处发现斑马线")语速极快,音调偏高
调查:
- 检查采样率:确认 Client/Server 均为 16kHz,配置无误
- 检查源文件:发现
远处发现斑马线.WAV实际时长仅 1.02s,而map.zh-CN.json预期 1.6s 结论:源文件录制语速本身较快
决策:用户确认偏好此语速,取消修复(保持原样)
2. 音频回环底噪
现象:扬声器有持续静电底噪
分析:
- 此前怀疑硬件接地问题(手触开发板底噪消失)。
- 最终确认:连接电脑 USB/串口导致的共地干扰 (PC 机箱未接地,或 USB 供电干扰)。 解决方案:
- 移除串口,使用电池独立供电 -> 杂音完全消失。
- 软件上仍保持
ADC Playback Volume80% 以防万一,但核心问题已由电源隔离解决。
🛑 踩坑与反思 (Lessons Learned)
今天开发过程中经历了几个关键的“弯路”,值得记录以避免重蹈覆辙:
1. 音频问题的归因偏误
- 弯路:听到 TTS 语速快 ("Chipmunk Effect"),第一反应是代码逻辑错误(认为采样率 8k/16k 不匹配),花费大量时间排查
audio_compressor和audio_player。 - 真相:实际上是源文件本身录制语速就这么快(1.0s vs 预期 1.6s)。
- 教训:遇到音频异常,优先检查源文件 (Source Asset) 的属性,不要预设是代码 BUG。
2. 硬件 Mixer 的隐形耦合
- 弯路:为了消除回环噪音,直接在代码中将
ADC Playback Volume设为 0(静音)。 - 后果:导致麦克风采集数据全为 0,一度以为驱动损坏。
- 真相:该开发板 (V821) 的 Codec 硬件通路上,ADC Playback Volume 同时控制采集增益。
- 教训:嵌入式音频开发中,Mixer 控件往往存在硬件级耦合,调整前需小步验证,不能想当然地“全关”。
3. VAD 的时序陷阱
- 弯路:语音首字识别丢失,一直在调整 VAD 的灵敏度阈值 (threshold)。
- 真相:阈值再低也需要时间触发,触发时说话人已经发出了第一个音节。
- 教训:实时语音交互中,环形缓冲区 (Lookback Buffer) 是必须的,它能“挽回”触发前的那几百毫秒关键信息。
📝 Day 22 总结
| 类别 | 状态 | 说明 |
|---|---|---|
| GLM API 升级 | ✅ | zai-sdk + glm-4.6v-flash |
| SenseVoice 语言修复 | ✅ | language="zh" |
| VAD 截断修复 | ✅ | Ring Buffer (300ms) |
| TTS 语速排查 | ✅ | 确认源文件特性,用户决定保留 |
| 音频底噪优化 | ⚠️ | 软件80%音量,硬件需接地 |
| 待服务器验证 | ⏳ | 需要部署并测试 |