Tomodachi 語音實驗室如何合成 8-Bit 語音
Tomodachi 語音實驗室以三節點的 Web Audio API 音訊圖合成 8-bit Mii 語音:一個 OscillatorNode 產生音調,一個 BiquadFilterNode 柔化聲音,一個 GainNode 塑造音量包絡。本指南將逐項剖析這套管線在 Tomodachi 語音實驗室 中的實際運作方式——每個常數、每個預設、每個排程決策——讓你能理解、重現或擴展這種令人聯想到《朋友聚會 新生活:Living the Dream》的嗶聲語音美學。文中的每個數字皆引用自本站原始碼;若某個數值屬於社群推估而非 Nintendo 官方文件記載,內文會明確說明。
為什麼《朋友聚會 新生活》的角色以嗶聲說話
朋友聚會 新生活 音訊的招牌特色就是嗶聲語音:遊戲不使用錄製的台詞,而是讓每個 Mii 以短促的合成音發聲,跟隨句子節奏起伏,卻從不構成真實詞語。這種做法可以回溯到系列在掌機上的起源——卡帶容量與音效硬體的限制使全語音配音不切實際——而它一路延續到 Switch 上的《朋友聚會 新生活:Living the Dream》,因為嗶聲早已成為系列識別性的一部分。這種效果之所以聽起來像說話,是因為它複製了語音的韻律——音高起伏、音節節奏、停頓——同時刻意保持非詞彙化的性質。
Nintendo 從未公開遊戲實際的合成方法,因此任何瀏覽器重現在定義上都屬於社群推估。實驗室追求的是美學上的貼近,而非位元級的精確重現,而其中三項特性承擔了大部分工作。第一,音調短促:包絡在數十毫秒內開啟與關閉,使每個音節都乾淨地起音與停止。第二,波形諧波豐富:帶有嗡鳴感的音色遠比純音更容易被聽成「晶片音樂」。第三,音高從不靜態不變:每個音節的微小頻率偏移模擬了自然語音的輪廓。本指南的其餘部分將說明這些特性各自如何對應到具體的 Web Audio API 機制。
合成管線逐節點解析
實驗室產生的每個聲音,在振盪器與你的喇叭之間都恰好經過三個處理節點。每次播放都會建立全新的 AudioContext——實驗室從不讓全域音訊圖常駐——而每個音節都會在其中排程屬於自己的一組節點:
OscillatorNode ──▶ BiquadFilterNode (lowpass) ──▶ GainNode ──▶ AudioContext.destination
僅長者預設:
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-bit 風格的獨特俐落感。
還有一組可選的第四個節點配對:顫音。當預設啟用它時,第二個擔任 LFO(低頻振盪器)的 OscillatorNode 以預設的 vibratoRate 頻率運行,並將訊號送入設定為 vibratoDepth 的 GainNode,再連接到主振盪器的 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-bit 語音實驗室不想要的。它還把聲音選擇委派給作業系統,因此同一段文字在不同瀏覽器與裝置上的聲音可能不同,而且有些瀏覽器會延遲載入語音,首次發聲的延遲相當明顯。一字元一嗶聲的做法讓每個聲音都留在與單次播放模式相同的三節點音訊圖內,保證在所有支援 Web Audio API 的環境中音色完全一致,並且因為無需載入任何東西而能立即開始。
取捨是:輸出並非可理解的語音。它跟隨文字的節奏與輪廓,但不產生任何可辨識的詞語,因此它重現的是 朋友聚會 新生活 嗶聲語音的韻律感,而非其可懂度——而遊戲裡的嘰咕聲本來也聽不懂,這可以說正是重點所在。停止播放的方式同樣簡單粗暴而有效:實驗室透過 close() 關閉整個 AudioContext,立即終止每個已排程的節點,而不是淡出。
誠實面對限制
有三項限制界定了這個合成器所能誠實宣稱的範圍。第一,它近似的是一種美學,而非遊戲引擎本身:Nintendo 從未公開記載 朋友聚會 新生活 如何產生語音,因此這裡的預設數值是為了喚起系列聲音而調校的社群推估,而非提取出來的常數。這些聲音令人聯想到遊戲,而不是遊戲的複製品。
第二,合成是單音且無共振峰的。每個音節都只是一個由單一低通濾波器塑形的振盪器,而自然語音——以及據推測遊戲中更精密的引擎——帶有來自聲道的共振峰結構。這就是輸出聽起來像晶片音樂配音而非取樣語音的原因,也是你擴充這份程式碼時最值得探索的缺口:再多一個高八度的振盪器,或是一個帶有排程頻率移動的濾波器,都能把結果進一步推向人聲的領域。
第三,一切取決於瀏覽器支援。這裡使用的 Web Audio API——AudioContext、OscillatorNode、BiquadFilterNode、GainNode——在目前所有主流瀏覽器中均受支援,但 Web Audio API 的輸出特質仍會隨裝置音訊堆疊略有差異,而那些在使用者互動前封鎖自動播放的瀏覽器,則需要按下實驗室早已內建的播放按鈕。在隱私方面,此工具完全在客戶端運作:合成在瀏覽器中執行,唯一的持久化資料是本地的 IndexedDB 歷史紀錄——沒有任何音訊或文字被上傳到任何地方。
親自試試這條管線
最快內化這套模型的方法,就是動手移動兩個滑桿,聆聽音訊圖的即時反應:
- Tomodachi 語音實驗室——合成器本體:五種預設、
100 – 800 Hz音高滑桿、語速控制,以及一字元一嗶聲的文字模式。 - 朋友聚會 新生活 MBTI 映射——Mii 的四個性格滑桿如何產生其分組,而分組又如何決定上表中的預設。
- 性格圖表——完整的 16 型參考資料,用於挑選要配音的代表性性格。
- Mii QR 解鎖器——將設計好的聲音與編輯過的 Mii 角色配對,打造完整的島嶼居民。