09 — TTS 模块

源码目录:src/vocal10n/tts/

Vocal10n 支持两个可互换 TTS 后端,均以独立子进程运行并通过本地 HTTP 访问:

  • GPT-SoVITS(默认、成熟):vendor/GPT-SoVITS/api_v2.py
  • Qwen3-TTS:较新的模型,支持 clone、speaker、design 三种语音模式。

任意时刻仅激活一个后端。UI 的 tts_container_tab 负责切换;状态分别在 SystemState.tts_statusSystemState.tts_qwen3_status

通用流水线

flowchart LR
    Ev{{"TRANSLATION_CONFIRMED"}} --> Q["TTSQueue"]
    Q --> HTTP["HTTP request"]
    HTTP --> Bytes["audio bytes"]
    Bytes --> Player["AudioPlayer<br/>(sounddevice)"]
    Player --> Spk(["speakers"])
    Player --> Timeline["PlaybackTimeline<br/>(reference for AEC)"]

TTSQueuequeue.py)控制:

  • tts_queue_max_size:硬上限;超过会阻塞入队。
  • tts_queue_max_pending:丢弃最旧阈值,优先保留新文本以维持延迟预算。

提交 e9d4556 引入两级播放:

  1. 后端音频块到达即播,降低 TTFA(首音时间)。
  2. 块与块之间按 audio_output.crossfade_ms 交叉淡化,减少拼接突变。

GPT-SoVITS 后端

  • server_manager.pyvenv_ttsvendor/GPT-SoVITS/api_v2.py(通常由启动脚本完成,管理器负责重启健康)。
  • client.py 负责 HTTP 调用。参考音频路径会先转绝对路径(4a19037 修复相对路径导致的冷启动问题)。
  • 预热:服务就绪后,controller 发起一次极小合成请求把图加载进 GPU,且在后台线程执行(142f915)。
  • 该路径只读取 tts.* 配置,忽略 tts_qwen3.*

Qwen3-TTS 后端

  • qwen3_server.py 在独立子进程运行,stdout 专用于行分隔二进制协议,stderr 单独排空,防止日志污染协议流(2311042)。
  • qwen3_client.py 实现对应协议。
  • qwen3_controller.py 提供与 GPT-SoVITS 同构的控制接口,保证队列、播放、延迟追踪逻辑无需改动。

voice_mode 可选 clonespeakerdesign。UI 会同步更新 tts_qwen3.voice_mode 与对应子参数。Simple 模式会强制 clonefdf978c)。

音频输出

audio_output.py 在每个激活设备上维护一个 sounddevice.OutputStream,支持:

  • 选择任意 PortAudio 输出设备(UI 会去重多 host API 下的同名设备,见 74be837)。
  • tts_source_enabledtts_target_enabled 同时开启时,可把 source/target 路由到不同设备。
  • 将真实 TTFA 回传给延迟追踪器。

Source 与 Target TTS

由独立开关控制两路播报:

  • Target TTS(默认开):朗读翻译文本。STT 开启时用于同传;STT 关闭时可作手动输入朗读。
  • Source TTS(默认关):朗读修正后的源文本。STT 开启时近似“变声器”;STT 关闭时是普通 TTS 朗读。

两路同时开启时,建议路由到不同输出设备。UI 在 TTS 页提供提示。