# Day 21 - 语音系统全面优化 **日期**: 2025-12-25 🎄 **主题**: 语音识别修复 + 音频系统优化 + AI 对话优化 + 轻量级 VAD --- ## 🐛 语音识别停止响应 (09:30) **问题**:停止盲道导航后,语音指令不再被识别 **修复**:热词匹配白名单 + 客户端 RESET 处理 **状态**:✅ 已修复 ### 根因 ```mermaid sequenceDiagram participant U as 用户 participant ASR as ASR回调 participant S as 系统 U->>ASR: 说"停止导航" ASR->>ASR: "停止" in "停止导航" ✓ ASR->>S: full_system_reset() Note over S: ASR会话终止 → 语音不响应! ``` ### 解决方案 **服务器端** (`asr_core.py`) ```python NAV_CONTROL_WHITELIST = ["停止导航", "结束导航", "开始导航", ...] def _has_hotword(self, text): # 先检查白名单,匹配则不触发热词 for nav_cmd in NAV_CONTROL_WHITELIST: if nav_cmd in text: return False # 再检查热词 for w in INTERRUPT_KEYWORDS: if w in text: return True return False ``` **客户端** (`main.cpp`) ```cpp if (msg == "RESTART" || msg == "RESET") { ws_aud.send_text("START"); // 重新启动 ASR } ``` --- ## 🔧 音频系统优化 (10:10) ### 1. 采样率转换简化 ``` 修改前: 24kHz → 8kHz → 16kHz (两次转换) 修改后: 24kHz → 16kHz (一次转换) ``` **效果**:减少 50% 转换开销 ### 2. 减少日志频率 - 音频接收日志:100包 → 500包 ### 3. 指数退避重连 ``` 1s → 2s → 4s → 8s → 16s (max) → 连接成功后重置 ``` --- ## 🔧 视觉优先级中断 (10:35) **问题**:AI 对话时检测到障碍物无法打断 **修复**:障碍物检测优先级高于 AI 对话 **状态**:✅ 已实现 ```python # app_main.py if is_obstacle_warning and is_playing_now(): asyncio.create_task(hard_reset_audio("Obstacle priority")) ``` **触发关键词**: `前方有`, `停一下`, `注意避让`, `左侧有`, `右侧有` --- ## 🔧 AI 对话简洁化 (11:05) **问题**:AI 回答过长 **修复**:添加 system prompt 限制回答长度 **状态**:✅ 已实现 ```python # omni_client.py system_prompt = """你是视障辅助AI助手。 请用极简短语言回答,每次不超过2-3句话。 避免冗长解释,只提供最关键信息。""" ``` --- ## 🔧 轻量级 VAD (11:14) **问题**:静默时仍持续发送音频,浪费带宽 **修复**:客户端能量阈值 VAD,仅语音时发送 **状态**:✅ 已实现 ### 新增文件 `simple_vad.h` - 能量阈值 VAD,header-only ### 参数 | 参数 | 值 | 说明 | |------|-----|------| | threshold | 400 | 能量阈值 | | attack | 2帧 | 40ms确认语音开始 | | hangover | 15帧 | 300ms避免截断 | **效果**:静默时减少 70-80% 带宽 --- ## 📁 修改文件汇总 ### 服务器端 | 文件 | 修改内容 | |------|----------| | `asr_core.py` | 导航命令白名单,热词匹配修复 | | `app_main.py` | 采样率优化 + 日志频率 + 视觉中断 + **新AI管道集成** | | `audio_stream.py` | 移除多余 8k→16k 转换 | | `omni_client.py` | AI 简洁回复 system prompt | | `sensevoice_asr.py` | **新增** 本地 ASR (非流式) | | `glm_client.py` | **新增** GLM-4.5-Flash 客户端 | | `edge_tts_client.py` | **新增** EdgeTTS 流式合成 | | `ai_voice_pipeline.py` | **新增** 统一 AI 管道 | ### 客户端 (Avaota F1) | 文件 | 修改内容 | |------|----------| | `main.cpp` | RESET处理 + 指数退避 + VAD集成 + **RECOGNIZE命令** | | `simple_vad.h` | **新增** 轻量级 VAD + 边沿检测 --- ## 🚀 新 AI 管道 (13:50) **目标**:替换付费 API 为免费方案 **状态**:✅ 已实现并测试通过 ### 新架构 ``` 语音 → [SenseVoice] → 文本 → [GLM-4.5-Flash] → [EdgeTTS] → 播放 本地ASR 免费LLM 免费TTS ``` ### 新增文件 | 文件 | 功能 | |------|------| | `sensevoice_asr.py` | 本地 ASR (非流式) | | `glm_client.py` | GLM-4.5-Flash 客户端 | | `edge_tts_client.py` | EdgeTTS 流式合成 | | `ai_voice_pipeline.py` | 统一管道 | ### 工作流程 ```mermaid sequenceDiagram participant C as 客户端 participant S as 服务器 participant ASR as SenseVoice participant LLM as GLM-4.5 participant TTS as EdgeTTS C->>S: START S-->>C: OK:STARTED loop 有语音时 C->>S: 音频数据 (binary) S->>S: 收集到 audio_buffer end Note over C: VAD 检测到语音结束 C->>S: RECOGNIZE S->>ASR: 一次性识别 ASR-->>S: 用户文本 S->>LLM: 调用 GLM LLM-->>S: AI 回复 S->>TTS: 流式合成 TTS-->>S: PCM 音频块 S-->>C: 音频播放 ``` ### 本地测试结果 | 组件 | 状态 | 结果 | |------|------|------| | GLM-4.5-Flash | ✅ | "你好👋!需要帮助吗?" | | EdgeTTS (MP3) | ✅ | 7200 bytes | | EdgeTTS (PCM) | ✅ | 38400 bytes | | SenseVoice 路径 | ✅ | 自动检测成功 | ### 控制开关 ```bash # 启用新管道(默认) export USE_NEW_AI_PIPELINE=1 # 回退到旧管道 export USE_NEW_AI_PIPELINE=0 ``` --- ## ⏳ 待验证 ### 语音修复 & 优化 - [ ] 部署服务器端修复 - [ ] 编译并部署客户端(含 VAD) - [ ] 测试语音识别恢复 - [ ] 测试 VAD 带宽节省效果 - [ ] 测试 AI 回答简洁度 ### 新 AI 管道 - [x] GLM-4.5-Flash 调用测试 - [x] EdgeTTS 语音合成测试 - [ ] 部署到服务器完整测试 - [ ] SenseVoice ASR 实际语音测试 --- ## 🔴 GLM API 调用问题 (17:30) ### 问题1:API 调用失败 (Error 400/1210) **日志**: ``` [GLM] 调用失败: Error code: 400, with error text {"error":{"code":"1210","message":"API 调用参数有误,请检查文档。"}} ``` **尝试的修复**: 1. 模型名称从 `glm-4-flash` 改为 `glm-4.5-flash`(根据官方文档) 2. 尝试安装 `zai-sdk`(官方推荐的 SDK) **结论**:由于 zai-sdk 未成功安装/配置,回退到稳定版本: - 模型:`glm-4-flash` - SDK:纯 OpenAI SDK **状态**:🔴 API 仍报错 ### 问题2:AI 回答与问题不相关 **症状**: | 用户说 | AI 回答 | |--------|---------| | "吧" | "天气:晴朗,温度适宜" | | "前方是什么" | "位置:现在在市中心广场" | | "现在看我情况是什么" | "时间:晚上7点整" | **分析**: - 语音识别结果不准确("工"、"吧" 等) - AI 回答像是预设的状态查询模板 ### 问题3:语音识别不准确 **日志**: ``` [SenseVoice] 识别耗时: 0.490s | 结果: 그. # 韩语字符 [SenseVoice] 识别耗时: 0.492s | 结果: 그. ``` **问题**:识别出韩语字符表明模型语言配置可能有问题 --- ## 🔴 未解决问题清单 ### 1. GLM API 调用失败 - **错误码**:400 / 1210 - **待办**: - 确认 API Key 有效性 - 检查 messages 格式 - 尝试正确安装配置 zai-sdk ### 2. AI 回答模式异常 - **症状**:回答与问题无关,像是固定模板 - **待办**: - 检查 system prompt 是否导致问题 - 验证对话历史是否正确传递 ### 3. 语音识别出韩语字符 - **症状**:SenseVoice 输出韩语字符 - **待办**:检查模型语言配置 ### 4. VAD 延迟过长 - **症状**:语音结束后 2-3 秒才触发识别 - **待办**:调整 `min_silence_duration_ms` 参数 --- ## 📝 Day 21 总结 | 类别 | 状态 | 说明 | |------|------|------| | 语音识别停止响应修复 | ✅ | 热词白名单 + RESET 处理 | | 新 AI 管道框架 | ✅ | SenseVoice + GLM + EdgeTTS | | GLM API 调用 | 🔴 | 参数错误,需进一步调试 | | 语音识别准确性 | 🔴 | 出现韩语字符,需检查配置 | | VAD 延迟 | 🔴 | 2-3 秒延迟,需优化参数 | **Day 21 状态**:⚠️ 部分完成,核心 AI 对话问题待 Day 22 继续调试