Pocket TTS音频输出格式详解:24kHz采样率与PCM数据怎么处理
【免费下载链接】pocket-ttsA TTS that fits in your CPU (and pocket)项目地址: https://gitcode.com/GitHub_Trending/po/pocket-tts
Pocket TTS(Kyutai 开源的轻量级 TTS 文本转语音系统)是一个完全运行在 CPU 上的语音生成工具:1 亿参数、支持音频流式输出、首块延迟约 200ms,生成的是24kHz 采样率、16 位 PCM 编码的单声道 WAV音频。本文带你从零理解这套音频格式是怎么产生的——24kHz 采样率从何而来、浮点波形如何变成 PCM 字节、以及输入音频如何被重采样到 24kHz,帮你彻底搞懂 Pocket TTS 音频输出的每一个环节。
24kHz 采样率从哪里来?
Pocket TTS 的音频"标准"由底层的Mimi 音频编解码器决定。在所有语言配置(如 pocket_tts/config/english.yaml)中都有这样一段:
sample_rate: 24000—— 输出 24kHz 采样率channels: 1—— 单声道frame_rate: 12.5—— 编解码器每秒只产生 12.5 个音频帧
也就是说,每个音频 token(latent)对应 1/12.5 = 80ms 的语音。语言模型每生成一个 token,Mimi 解码器就吐出 80ms 的 24kHz 波形,这也正是"流式输出"能低延迟工作的原因:不用等整段语音生成完,每攒够一小段就能立刻播放。
为什么选 24kHz 而不是 44.1kHz?两个理由:
- 音质足够:人声有效频率集中在 4kHz 以下,24kHz 采样率(奈奎斯特频率 12kHz)完全覆盖语音频段;
- 算力友好:Pocket TTS 的目标是"装进口袋的 TTS",更低的采样率意味着更少的样本数和更快的 CPU 推理,正好匹配它 2 核 CPU 就能跑的定位。
PCM 数据怎么处理:从浮点波形到 16 位 WAV
模型内部运算用的是float32 浮点波形(取值范围 -1 到 1),而写入文件的 PCM 是int16 整型。转换发生在 pocket_tts/data/audio.py 的StreamingWAVWriter中,核心逻辑只有两步:
- 写文件头:声明单声道、16 位采样宽度(
setsampwidth(2))、24kHz 采样率; - 逐块转换:每收到一段浮点音频,先
clamp(-1, 1)削顶防溢出,再乘以 32767 转成 int16 字节流写入文件。
这里有 3 个新手容易忽略的细节:
- 🎵 结尾补 200ms 静音:
finalize()会往文件末尾追加 0.2 秒的静音,让句尾收尾更自然,避免播放器截断尾音; - 📡 支持不可寻流的 stdout:当输出目标是管道(
--output-path -)而非普通文件时,无法回头修改 WAV 头部的帧数,代码会把帧数先写成占位值 10 亿并跳过头部回填(pocket_tts/data/audio.py); - ⚡ 首块缓冲:可通过环境变量
FIRST_CHUNK_LENGTH_SECONDS控制"攒够多少秒再落盘",用于调低首次写盘延迟。
整个流式写入的调度入口是 pocket_tts/data/audio.py 的stream_audio_chunks():它支持把音频块写入文件、写入 stdout,或仅打印(path=None),三种模式共用同一套 PCM 转换逻辑。
输入音频怎么办:重采样与单声道化
声音克隆时你提供的参考音频往往是 44.1kHz 的立体声 MP3,Pocket TTS 会把它"翻译"成模型能吃的 24kHz 单声道格式:
| 处理环节 | 做了什么 | 位置 |
|---|---|---|
| 读取 | 16 位 WAV 用内置wave模块读为 float32(除以 32768 归一化);其他格式走 soundfile | audio.py |
| 降混 | 多声道取平均,得到单声道 | 同上 |
| 重采样 | 用scipy.resample_poly按最大公约数精确换算到 24kHz(如 44100→24000) | audio_utils.py |
重采样用resample_poly而不是简单抽点,是为了避免频谱混叠——这也是官方建议克隆前先清理参考音频的原因之一:输入质量会直接影响输出。
三种方式拿到 24kHz PCM 音频
1. CLI 命令行:pocket-tts generate默认输出到./tts_output.wav(pocket_tts/main.py)。加-可把 WAV 流直接打到终端管道:
pocket-tts generate --output-path - | aplay2. 本地服务:pocket-tts serve启动 FastAPI 服务(pocket_tts/main.py),/tts接口以audio/wav+ chunked 编码边生成边推送,浏览器端可以实现边下载边播放的流式体验。
3. Python API:TTSModel 提供两种方法——generate_audio()返回完整张量(形状[channels, samples],采样率从model.sample_rate属性读取,即 24000);generate_audio_stream()则逐块 yield 音频张量,适合做实时播放器集成。
关键文件路径速查
| 文件 | 作用 |
|---|---|
| pocket_tts/data/audio.py | 音频读写、流式 WAV 写入与 PCM 转换 |
| pocket_tts/data/audio_utils.py | 重采样与声道转换工具 |
| pocket_tts/models/tts_model.py | TTS 主模型,流式生成入口 |
| pocket_tts/config/english.yaml | 24kHz/12.5fps 等音频参数配置 |
| pocket_tts/main.py | CLI 与 HTTP 服务实现 |
| docs/API Reference/python-api.md | Python API 完整参考 |
一句话总结:Pocket TTS 的音频世界非常简单统一——24kHz、16 位、单声道 PCM,模型内部是 float32 波形,落盘时乘以 32767 变成 int16,流式逐块写入 WAV;输入音频则通过resample_poly重采样到这个标准。搞懂这一点,你就能放心地把它的输出接进任何播放器、剪辑软件或你自己的实时语音管道里。
【免费下载链接】pocket-ttsA TTS that fits in your CPU (and pocket)项目地址: https://gitcode.com/GitHub_Trending/po/pocket-tts
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考