朋友聚会 新生活 语音实验室如何合成 8 位 Mii 语音
语音实验室的 8 位 Mii 语音由一条三节点的 Web Audio API 音频图构建而成:一个 OscillatorNode 生成音调,一个 BiquadFilterNode 负责柔化,一个 GainNode 塑造音量包络。本指南将按照这条管线在 语音实验室 中的实际运行方式逐层解剖——每一个常量、每一个预设、每一项调度决策——让你能够理解、复现或扩展这种令人联想到《朋友聚会 新生活:Living the Dream》的蜂鸣语音美学。下文的每一个数字都引自本站源代码;凡是社区估算值而非 Nintendo 官方文档记载的数值,文中都会明确说明。
为什么《朋友聚会 新生活》的角色用蜂鸣声说话
《朋友聚会 新生活》音频最具标志性的特征就是蜂鸣语音:游戏不使用录制的台词,而是让每个 Mii 用短促的合成音发声——这些音跟随句子的节奏,却从不构成真正的词语。这一做法可以追溯到系列的掌机起源:卡带容量和声音硬件让完整配音并不现实;而它一路延续到 Switch 上的《朋友聚会 新生活:Living the Dream》,是因为蜂鸣声已经成为系列身份的一部分。这种效果听起来像说话,因为它复刻了语音的韵律——音高起伏、音节节拍、停顿——同时又刻意保持非词汇化。
Nintendo 从未公开过这款游戏的真实合成方法,因此任何浏览器端的复现按定义来说都是社区估算。实验室瞄准的是美学神似而非逐位精确的复刻,其中三个特性承担了大部分工作。第一,音是短促的:包络在数十毫秒内开启和关闭,每个音节都干净利落地起止。第二,波形谐波丰富:带毛刺感的音色远比纯音更容易被听成「芯片音乐」。第三,音高从不静止:每个音节的小幅频率偏移模拟了自然语音的语调轮廓。本指南余下的部分将展示这三个特性各自如何对应到具体的 Web Audio API 机制。
逐节点解析合成管线
实验室发出的每个声音,在振荡器与你的扬声器之间都恰好经过三个处理节点。每次播放都会新建一个 AudioContext——实验室从不维持全局常驻的音频图——每个音节都在其中调度自己的一组节点:
OscillatorNode ──▶ BiquadFilterNode (lowpass) ──▶ GainNode ──▶ AudioContext.destination
elder preset only:
LFO OscillatorNode (5 Hz) ──▶ GainNode (depth 15) ──▶ main osc.frequencyOscillatorNode 是声音的源头。它的 type 取自所选预设(五个预设中有四个用 sawtooth,机器人用 square),frequency 则由音高滑杆设定。振荡器只是一台纯粹的波形发生器,自身没有任何音色控制——让一个预设听起来不同于另一个预设的全部原因,都在下游的参数调度里。
BiquadFilterNode 始终配置为 lowpass(低通)滤波器,截止频率取自预设的 filterFreq 值(视预设而定,为 900 – 2500 Hz)。低通滤波器会衰减截止频率以上的谐波,正是这一步把原生锯齿波的全频毛刺变成了接近人声的东西:偏暗的预设(长者为 900 Hz)只保留低次谐波,偏亮的预设(儿童为 2500 Hz)则放过那些让声音听起来娇小年轻的高频光泽。
包络就住在 GainNode 里,靠四个自动化点调度。增益在音节起点为 0,在攻击时间内线性爬升到预设的目标值(0.2 – 0.3),保持到结束前一个释放时长,再线性回落到 0。锚点调用 setValueAtTime(),斜坡调用 linearRampToValueAtTime()——这是一个没有任何指数曲线的朴素攻击/保持/释放包络,让声音始终带着标志性的干脆突兀,正合 8 位风格的味道。
管线中还有一组可选的第四对节点:颤音。当某个预设启用它时,第二个充当 LFO(低频振荡器)的 OscillatorNode 按预设的 vibratoRate 运行,喂给一个 GainNode(设为 vibratoDepth),后者再接到主振荡器的 frequency 参数上。这是经典的频率调制——在长者预设中,一个 5 Hz 的 LFO 让音高产生 ±15 Hz 的摆动,营造出与苍老人声相伴的颤抖质感。只有长者预设开启了它,其余四个预设完全禁用颤音。
每种波形听感如何(以及何时选用)
波形选择是整条管线中最大的单项音色决策,因为它决定了滤波器和包络随后要塑造的谐波内容。Web Audio API 的 OscillatorNode 提供四种标准类型,每一种都有鲜明的个性:
| 波形 | 谐波构成 | 听感特征 | 使用的预设 |
|---|---|---|---|
sine | 仅基波 | 纯净、如长笛、零毛刺 | 无(可通过 OscillatorType 启用) |
square | 奇次谐波,强 | 空洞,经典 NES 主音通道 | 机器人 |
sawtooth | 全部谐波,逐级衰减 | 毛刺感、簧片感,最接近人声的饱满度 | 成年男性、成年女性、长者、儿童 |
triangle | 少量奇次谐波,弱 | 柔和、圆润、略显暗哑 | 无(可通过 OscillatorType 启用) |
实验室的预设只用到四种中的两种:sawtooth 承担四个有机人声,square 承担机器人。这一分工是有意为之。锯齿波在每一个谐波上都有能量,经低通滤波后留下一团厚实的类人声内核——这正是它比其他任何基础波形都更像歌唱或说话音色的原因。方波只保留奇次谐波,且高频能量更多,带来机器人预设想要的空洞、带鼻音感、一听便知是电子音的特质。Sine 和 triangle 目前没有被任何预设使用,但通过同一个 OscillatorType 字段改一行即可启用:正弦波适合风铃这类纯净音效,三角波适合柔和的背景提示音——在这两种场合,锯齿波都会显得太凶。
解码五种语音预设
这五个预设是同一条三节点图上的五组参数包,它们之间的差异完全可以逐项枚举。下面是完整的参数表,直接引用自源代码中的 VOICE_PRESETS 常量:
| 预设 | 波形 | 基频 | 低通截止 | 增益 | 颤音 | 攻击 | 释放 |
|---|---|---|---|---|---|---|---|
| 成年男性 | sawtooth | 180 Hz | 1200 Hz | 0.30 | 关闭 | 0.02 s | 0.05 s |
| 成年女性 | sawtooth | 350 Hz | 1800 Hz | 0.25 | 关闭 | 0.02 s | 0.04 s |
| 长者 | sawtooth | 120 Hz | 900 Hz | 0.30 | 5 Hz、±15 Hz | 0.04 s | 0.08 s |
| 儿童 | sawtooth | 600 Hz | 2500 Hz | 0.20 | 关闭 | 0.01 s | 0.03 s |
| 机器人 | square | 250 Hz | 1500 Hz | 0.25 | 关闭 | 0 s | 0 s |
成年男性以 180 Hz 基频为整套预设定下锚点,落在典型成年男性说话音域的低端,1200 Hz 低通滤波把锯齿波的毛刺驯化得更为圆润。成年女性把基频几乎翻倍到 350 Hz,滤波器开到 1800 Hz 换来更明亮的音色,同时收紧增益(0.25)和释放(0.04 s),让咬字略微更脆。
长者是处理最重的预设:最低的音域(120 Hz)、最暗的滤波(900 Hz)、唯一的颤音(5 Hz LFO、±15 Hz 深度),以及最慢的包络(0.04 s 攻击、0.08 s 释放)。后两个数值与音高同样重要——迟缓的攻击柔化了每个音节的起音,较长的释放让音与音之间轻微地相互渗透,唤起这个预设所追求的那种不够精准的咬字感。
儿童几乎把长者的每一项决策都反过来:最高的基频(600 Hz)、最亮的滤波(2500 Hz)、最低的增益(0.20)、最快的包络(0.01 s 攻击、0.03 s 释放)。高音配快包络是小型生物配音的经典配方——每个音节都像一声短促的啁啾落地。机器人在两个维度上独树一帜:它是唯一的 square 波形,也是唯一零攻击、零释放的预设,也就是说增益会瞬间开启和关闭。这种硬切的边缘制造出该预设想要的生硬、门控式的机械质感——没有斜坡就没有柔和,这是结构使然。
音高与速度如何真正驱动振荡器
两个滑杆实时控制着这条音频图:音高的范围是 100 – 800 Hz,默认 300 Hz;速度的范围是 0.5x – 2.0x,默认 1.0x。每个预设还声明了自己的基准 baseFreq(即上表列出的参考中心),用来标注该声音类型被设计所在的音高位置。
音高直接设定振荡器频率,但有一道护栏:儿童预设实际播放的频率是 Math.max(pitch, 500),所以在儿童模式下把滑杆拖到 500 Hz 以下不会有任何效果——振荡器永远不会跌破这条下限。这个钳制保护了预设的特征,因为 150 Hz 的「儿童声」听起来只会像一个安静的成年男性。
速度控制的是时间,不是频率。按一次播放按钮会发出一声持续 0.5 / speed 秒的蜂鸣——0.5x 时为 1.0 s,1.0x 时为 0.5 s,2.0x 时为 0.25 s。同一个除数也作用于文字模式中的每一个时间常量,所以 2.0x 的语音是端到端货真价实地快一倍,而不是重采样——重采样会让音高发生偏移。播放结束后,界面在 500 / speed + 50 毫秒后重置播放状态,即蜂鸣时长加上 50 ms 的保护余量。
从文字到语音:每个字符一声蜂鸣
实验室的朗读文字模式并不是一个语音引擎——它就是同一条三节点振荡器管线,只是按字符逐个调度。当你输入最多 100 个字符并点击朗读时,输入会被拆成单个字符,每个非空格字符都会变成一次被调度的音节蜂鸣,并附带一个由其字符编码推导出的音高偏移。相关时间常量(均已除以速度)如下:
- 字符音 —— 每个字符
0.08 / speed秒(1.0x时为0.08 s)。 - 字符间隔 —— 相邻字符之间
0.03 / speed秒。 - 词间隔 —— 一个空格字符插入
0.12 / speed秒静音,约为 1.5 个字符音的长度。 - 短语停顿 —— 每第 5 个字符(
i % 5 === 4)额外加一个gap × 2的停顿,让输出有抑扬顿挫,而不是一条平直的音流。 - 前置时间 —— 调度从
currentTime + 0.05秒开始,确保音频图在第一个音之前准备就绪。
音高变化是其中最巧妙的部分。每个字符的频率偏移按 ((charCode % 20) - 10) × 3 计算,在基础音高上下产生介于 -30 Hz 与 +27 Hz 之间的确定性散布。确定性很重要:同一个词永远产生同一条旋律轮廓,于是一句特定的短语会像 Mii 的嗓音那样变得可以辨认。由于偏移量来自字符编码而非语音学,输出紧贴文字的节奏,却始终是无意义的非词汇音——这恰恰就是实验室想要逼近的蜂鸣语音效果。
为每个性格分组设计语音
一个有说服力的性格语音,说到底主要是一次音域决策:先按本站参考表为你的 Mii 的性格分组选定预设,再把音高滑杆停进推荐范围。以下是 语音实验室参考表 使用的完整映射:
| 性格分组 | 示例类型 | MBTI | 推荐预设 | 音高范围 |
|---|---|---|---|---|
| 外向型 | 领袖型 | ESTJ | 成年男性 | 180 – 250 Hz |
| 自信型 | 设计师型 | INTJ | 成年男性 | 150 – 200 Hz |
| 独立型 | 艺术家型 | INFP | 成年女性 | 280 – 380 Hz |
| 随和型 | 梦想家型 | INFJ | 长者 | 120 – 180 Hz |
| 儿童角色 | Any | Any | 儿童 | 500 – 700 Hz |
| 机器人/AI 角色 | Any | Any | 机器人 | 200 – 300 Hz |
请注意,这张表映射的是分组,而不是全部 16 种性格——我们 MBTI 映射 中的四个性格分组各对应一种代表性声音轮廓,具体性格则由你把滑杆停在范围内的哪个位置、以及速度开多快来表达。下面是分步配方:
- 1按分组选定预设。外向型和自信型 Mii 用成年男性;独立型 Mii 用成年女性;随和型 Mii 用长者,它的
5 Hz颤音为这个组增添了标志性的松弛从容。Mii 的分组来自它的四个性格滑杆——如果你还不知道分组,请先查看 性格一览表。 - 2把音高滑杆设进分组范围。对自信型设计师来说就是
150 – 200 Hz;滑向150 Hz听起来更有气势,滑向200 Hz更有活力。儿童预设的500 Hz下限意味着500 – 700 Hz的范围会自动守住。 - 3选一个与说话风格相称的速度。语速飞快的艺人用
1.4x – 2.0x名正言顺;睡眼惺忪的梦想家自然落在0.5x – 0.8x。速度只改变时长,绝不会让第 2 步选定的声音走调。 - 4用短句测试。在文字框里输入
20 – 30个字符,留意每第 5 个字符一次的短语停顿——如果节奏感跟性格不搭,先调速度,再动音高。 - 5对照历史记录迭代。每一次播放——预设、音高、速度,以及最多
100个字符的文本——都会保存到工具内置的本地IndexedDB历史面板,你可以直接 A/B 对比两组设置,不必手抄记录。任何数据都不会离开浏览器。
儿童和机器人两行被有意放在性格体系之外:任何 Mii 都可以配这两种声音,所以它们的 MBTI 栏写的是 Any。机器人零时长的包络让它对语速免疫——无论速度如何,它都保持着同样的门控式生硬感,因此它是唯一一种速度纯粹用来制造喜剧效果的声音。
为什么没有 Web Speech API 备用方案
实验室刻意避开了浏览器的 Web Speech API——代码库中任何地方都找不到 speechSynthesis 调用,朗读文字模式是纯粹的振荡器调度。这是一个理由充分、代价也真实存在的设计决策,两面都值得说清楚。
理由是:speechSynthesis 产生自然的人声,而这恰恰是 8 位语音实验室不想要的东西。它还把声音选择权交给操作系统,于是同一段文字在不同浏览器和设备上听起来可能不一样;一些浏览器还会懒加载声音库,第一次发声时有可感知的延迟。逐字符蜂鸣的方案让每一个声音都留在单蜂鸣模式所用的同一条三节点图里,保证只要 Web Audio API 可用,音色就处处一致,而且因为无需加载任何内容而即点即响。
代价是:输出不是能听懂的话。它跟随文字的节奏和轮廓,却不产生任何可辨认的词语,所以它唤起的是《朋友聚会 新生活》蜂鸣语音的韵律感,而非可懂度——何况游戏里的咿呀声本身也听不懂,而这可以说正是精髓所在。停止播放同样简单粗暴而有效:实验室通过 close() 关闭整个 AudioContext,立即终止所有已调度的节点,而不是淡出。
如实说明局限
有三条局限划定了这台合成器能够诚实宣称的边界。第一,它近似的是一种美学,而不是游戏的引擎:Nintendo 从未记载《朋友聚会 新生活》如何生成语音,因此这里的预设值是为唤起系列之声而调校的社区估算,不是提取出来的常量。这些声音让人想起游戏里的声音,却不是它的复制品。
第二,合成是单声部、无共振峰的。每个音节只是一个由单个低通滤波器整形的振荡器,而自然语音——想必还有游戏那台更精巧的引擎——携带来自声道共鸣的共振峰结构。这就是输出听起来像芯片音乐配音而非采样语音的原因;如果你要扩展这段代码,这也是最值得探索的缺口:高一个八度的第二个振荡器,或一个频率按调度移动的滤波器,都能把结果进一步推向人声的领地。
第三,一切取决于浏览器支持。这里使用的 Web Audio API——AudioContext、OscillatorNode、BiquadFilterNode、GainNode——在当前所有主流浏览器中都受支持,但 Web Audio API 的输出特质仍会随设备音频栈略有差异;而在用户操作之前封锁自动播放的浏览器,也正好需要实验室本来就提供的那次播放按钮点击。在隐私方面,本工具完全在客户端运行:合成在浏览器中执行,唯一的持久化是本地的 IndexedDB 历史记录——任何音频或文本都不会被上传到任何地方。
亲自试一试这条管线
把这套模型装进脑袋的最快方式,就是拖动那两个滑杆,听音频图实时回应:
- 语音实验室 —— 合成器本体:五种预设、
100 – 800 Hz音高滑杆、速度控制,以及逐字符蜂鸣的文字模式。 - MBTI 对照表 —— Mii 的四个性格滑杆如何决定它的分组,而这个分组又决定它在上面表格中的预设。
- 性格一览表 —— 完整的 16 型参考表,用于挑选要配音的示例性格。
- Mii QR 解锁器 —— 把设计好的语音与编辑过的 Mii 角色配成一对,凑齐一位完整的岛屿居民。