Files
Docs/DevLogs/Day22.md
2025-12-31 16:18:28 +08:00

6.1 KiB
Raw Blame History

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 switchDay 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 Volume 80% 以防万一,但核心问题已由电源隔离解决。

🛑 踩坑与反思 (Lessons Learned)

今天开发过程中经历了几个关键的“弯路”,值得记录以避免重蹈覆辙:

1. 音频问题的归因偏误

  • 弯路:听到 TTS 语速快 ("Chipmunk Effect"),第一反应是代码逻辑错误(认为采样率 8k/16k 不匹配),花费大量时间排查 audio_compressoraudio_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%音量,硬件需接地
待服务器验证 需要部署并测试