问题(上次提交 d5239cf 之后实测):
1. EnterIdleHibernate 触发的 LeaveRoom() 顺手关闭了 codec output:
LeaveRoom → on_audio_channel_closed_ → player_pipeline_close → EnableOutput(false)
导致后续 PlaySound(P3_KAKA_DAIMING) 入队后 AudioLoop 写不出声音,
WaitForAudioPlayback 3 秒超时退出, 用户听不到待命音。
2. LeaveRoom 调用 volc_rtc_destroy 后 rtc_handle_ = nullptr,
WakeFromHibernate → ToggleChatState → OpenAudioChannel 直接返回 false,
触发 2 秒重试循环, 同时每次失败回退 idle 都重新 PlaySound,
codec 状态震荡产生杂音, 服务端 AI 任务也无法重新加入房间。
方案 C+ 修复:
- Protocol::LeaveRoom() 新增 bool notify_closed=true 参数 (默认行为不变)。
- VolcRtcProtocol::LeaveRoom(notify_closed):
* 只 volc_rtc_stop, 不 volc_rtc_destroy, 保留 rtc_handle_ 供唤醒复用。
* notify_closed=false 时跳过 on_audio_channel_closed_, 不连带关 codec。
- EnterIdleHibernate:
* 调用 LeaveRoom(false) → codec output 保留。
* 手动 background_task_->WaitForCompletion + 清空队列 + 关麦克风。
* SetDeviceState(idle) 后 PlaySound 真正能播出来。
* WaitForAudioPlayback 完才 player_pipeline_close (这里再正常关 output)。
- WakeFromHibernate:
* 先放下 hibernating_ 让 AudioLoop guard 通过, 再 ToggleChatState。
* 因 rtc_handle_ 仍有效, OpenAudioChannel 走 volc_rtc_start 重启路径,
on_audio_channel_opened_ 回调重开 player_pipeline + 灌 200ms silence。
编译: kapi.bin 0x2e6330 (3.04MB), 分区 42% 空闲。
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
编译配置命令
配置编译目标为 ESP32S3:
idf.py set-target esp32s3
打开 menuconfig:
idf.py menuconfig
选择板子:
Xiaozhi Assistant -> Board Type -> Movecall Moji 小智AI衍生版
编译:
idf.py build