音频输入与缓冲
1. 职责与边界
本模块将网络输入转换为固定时长的推理块,负责 PCM 数据累计、Opus 解码、静音预填充、尾块补齐及输入重采样。它不维护模型的历史上下文,也不执行换声和输出拼接。
主要源码:buffer.py 中的 AudioStreamBuffer 与 OpusAudioStreamBuffer。何时取块由接入层决定,取得音频后的处理见转换流水线。
2. 输入输出与音频约定
2.1 数据表示
| 边界 | 表示 |
|---|---|
| PCM 网络输入 | 单声道有符号整数 PCM 字节,解码支持 16 / 24 / 32 位;示例使用 16 位、小端格式 |
| Opus 网络输入 | 每条二进制消息为一个原始 Opus 包,解码为单声道 16-bit PCM 后进入公共缓冲 |
| Buffer 输出 | 归一化浮点 NumPy 数组,使用模型前端采样率;重采样发生在取块时 |
| 流水线输出 | session.out_data 浮点数组,使用协议输出采样率 |
| WebSocket 返回 | 路由将浮点输出转换为单声道 int16 PCM 字节,无 WAV 头 |
不要将 WAV 文件头或浮点 PCM 当作整数 PCM 发送。Buffer 的 output_bit_depth 参数不表示返回整数数组;get_next_chunk() 返回浮点样本。Opus 输入也不会使服务输出变成 Opus。
2.2 四个采样率环节
| 环节 | 参数 | 当前约定 |
|---|---|---|
| 客户端输入 | 请求 sample_rate | 表示 PCM 输入或 Opus 解码采样率,协议缺省为 16000 Hz |
| 模型前端 | SAMPLERATE_IN | Buffer 输出所用采样率;prod.yaml 为 16000 Hz,供 VAD、内容编码与音高处理 |
| 模型与后处理 | SAMPLERATE_OUT | 与加载模型采样率一致;prod.yaml 的 tiny 路径为 22050 Hz |
| WebSocket 输出 | 请求 sample_rate_out | 协议缺省为 16000 Hz;tiny 可显式请求 22050 Hz,在模型后处理之后按需要重采样 |
模型输出采样率与协议输出采样率独立,客户端应按请求输出格式解释返回字节。字段约束由 语音转换 API 维护,模型兼容要求见模型与参考音色。
3. 关键流程
3.1 累计、取块与解码
PCM Buffer 按输入采样率、位深和 block_time 计算一块所需的字节数,并对齐到完整样本。add_chunk() 将字节追加到缓冲;has_complete_chunk() 判断是否已达到一块。
get_next_chunk() 先取一块输入字节,按位深解码并归一化;需要时用 resampy 重采样到模型前端采样率,再交给转换流程。因此客户端发送包与推理块不是一一对应关系。
Buffer 的块长单位为毫秒,转换配置的 block_time 单位为秒,路由创建 Buffer 时乘以 1000。模型窗口另有帧对齐规则,修改块长需同时核对流水线长度约束。
3.2 预填充与尾块
当 prefill_time < block_time 时,Buffer 创建时先加入 prefill_time 毫秒静音。prod.yaml 使用 500 ms 推理块和 375 ms 静音预填充,因此首块理论上再累计 125 ms 输入即可处理。该值不包含模型执行、网络及播放等待,也不是首包实测结果。
正常结束时,路由持续消费剩余缓冲;不足一块由 get_next_chunk() 补静音。超时和异常断联不走该尾块流程,未处理的输入随 Buffer 清空。
尾块处理只消费当前输入缓冲,路由没有额外循环排出模型右侧上下文或 SOLA 保留区。实际输出区域由流水线裁取,输入时长与最终输出时长可能不同。
3.3 Opus 路径
Opus Buffer 将输入采样率限制为 8000 / 12000 / 16000 / 24000 / 48000 Hz,根据帧长计算解码器的 frame_size。帧长优先使用请求值,未提供时使用服务缓冲配置;路由另有 20 ms 兜底值。
解码成功后复用 PCM 的累计、取块和重采样逻辑。解码异常时记录日志,并加入配置帧长对应的静音;因此连接继续并不代表每个 Opus 包均成功解码。
4. 约束与关联文档
预填充、尾块补齐和上下文裁取均会影响时间轴,采样率变化也会改变样本数。调用方应保持完整 PCM 样本和正确的格式声明,不能通过更改采样率字段替代实际重采样。
Buffer 在追加 PCM 字节时通过 Session 记录输入事件,Opus 在解码后记录。输入录音则在推理入口记录已取出的浮点块,两者位于不同阶段;具体数据含义见数据记录与可观测性,测量步骤见评测指南。