小智的四段音频队列,先分清 PCM 任务与Opus
🎧 小智能出声,但声音断续:直接把音频缓冲加大,会更稳吗?先看满了以后代码如何取舍。下面是公开源码允许出现的情境,本次没有复现设备故障。
上行经过PCM待编码队列、Opus发送队列;下行经过Opus解码队列、PCM播放队列。PCM是未压缩采样,Opus是压缩音频包;四段不是同一种缓存。
📥 上行的待编码队列满了,会先丢最旧任务,再接新任务。假设已有A、B,C到来后留下B、C。这让输入继续前进,代价是A里的声音丢了;这是规则示意,不是录音测试。发送队列满了也丢最旧包,但这段丢弃没有计入编码丢弃计数,不能只看一个计数就宣布上行没丢包。
下行默认相反:解码队列满时返回false,新包没入队,旧包仍保留。应用来音回调在Speaking状态调用默认wait=false,且这个调用点没有检查返回值。本地PlaySound会用等待模式,但停止或播放代次变化仍可能让它失败;等待不保证全部播完。
🔎 下行积压也不一定是解码器慢。播放队列已有2个PCM任务时,代码暂缓继续取包解码,压缩包更容易堆在前面。音频任务仍可处理编码工作。扩大解码队列能推迟拒新,却不能单靠容量让输出变快。
当前编码、发送、解码、播放容量分别是2个任务、40个包、20个包、2个任务。40和20由默认60ms参与编译期计算,限制的是槽位;运行时下行会按来包时长配置解码器。
⏱ 假设包有效且等时长:20×60ms是1200ms媒体内容,20×20ms是400ms。这不是端到端延迟,更不证明服务端实际发送这两种格式。容量也不是占用,队列只有3包时不能按20包算。
队列空了同样不能直接当作播放完成:AudioService还要确认解码和输出都没有在途工作。这仍是服务层排空,不能当作扬声器最后一个声音已经结束的证据。
📝 改缓冲前,在同一段音频里记下:哪段队列积压、当前媒体量、最老数据等待多久、哪种入队失败或丢弃发生,以及解码和输出耗时。这是待实现的采集建议。短暂突发后能追上,才有依据试验适量加缓冲;长期消费跟不上,就继续查消费瓶颈。用同条件下的丢弃、等待和实际音频结果一起判断,别只看满队列次数。
小智AI ESP32 音频开发 Opus 语音交互 AI进化生活howto AIAgent AI新手村





