三种音色模式:预置、设计、克隆的统一管理
MiMo TTS Studio 支持三种音色来源:预置音色(系统内置)、设计音色(文本描述生成)、克隆音色(参考音频复制)。三种模式的数据结构、API 调用方式完全不同,但需要在同一个角色管理界面中统一操作。
数据模型:Pinia Store 管理音色状态
核心设计是用 ttsStore.js 管理当前音色状态,characterStore.js 管理角色列表。每个角色 = 一个音色配置 + 一组台词:
1 | // ttsStore.js — 简化示意 |
graph TD
A["Character 角色"] --> B["ttsMode: standard"]
A --> C["ttsMode: voicedesign"]
A --> D["ttsMode: voiceclone"]
B --> B1["voiceId → API 音色列表"]
C --> C1["voiceDesignDesc → 文本描述"]
D --> D1["参考音频 base64"]
A --> E["emotion 情感"]
A --> F["speed 语速"]
三种模式的 API 调用差异
预置音色
直接传 voiceId,API 从内置音色库匹配:
1 | // 模式 A:预置音色 |
设计音色
不传 voiceId,改传 styleDescription,API 根据文本描述动态生成音色:
1 | // 模式 B:设计音色 |
克隆音色
传参考音频的 Base64 编码:
1 | // 模式 C:克隆音色 |
统一调用入口
Service 层用一个方法统一处理三种模式(以下为简化示意):
1 | // app/electron/service/tts.js — 实际的 _callApi 参数签名 |
克隆模式需要额外读取本地音频文件并编码为 Base64(通过 readFileAsBase64 工具函数),这是 Electron 的 fs 能力发挥作用的地方——Web 应用无法直接读取本地文件。
持久化:角色配置 JSON
音色配置独立于台词数据,持久化为 JSON 文件:
1 | // characterStore.js — 简化示意 |
保存时序列化为 JSON,加载时反序列化并校验。克隆模式的参考音频路径存绝对路径,意味着项目文件夹复制到另一台机器后,克隆音色需要重新指定音频文件。
情感与风格描述
1 | // ttsStore.js — 实际用 emotion 和 styleDescription 两个独立字段 |
emotion 传给 API 的 emotion 字段,styleDescription 传给 style_description 字段。实际没有 styleTags 数组的实现。
设计取舍
为什么音色配置和台词分开存?
- 同一个音色可能配多组台词(不同场景的配音脚本)
- 台词变化频繁,音色配置相对稳定
- 分开存减少序列化/反序列化的数据量
为什么克隆模式存绝对路径?
- 音频文件可能很大(几 MB ~ 几十 MB),不适合嵌入 JSON
- 用户可能随时修改参考音频,存路径可以实时读取最新版本
- 代价是跨机器迁移需要重新指定
注意:以上代码均为简化示意,实际实现包含完整的错误处理和状态管理逻辑。
统一接口、分支实现。三种模式的差异被封装在 Service 层,前端和 Controller 无需关心音色来源。