トモダチボイスラボの8-bit音声合成の仕組みを完全解説
トモダチボイスラボは、3つのノードで構成された Web Audio API グラフを使って 8-bit の Mii ボイスを作り出しています。1つの OscillatorNode が音を生成し、1つの BiquadFilterNode がそれを柔らかくし、1つの GainNode が音量エンベロープを形作ります。本ガイドでは、トモダチボイスラボで実際に動作しているパイプラインを——すべての定数、すべてのプリセット、すべてのスケジューリング判断まで——徹底解剖します。『トモダチコレクション 新生活:Living the Dream』を想起させるビープ音声の美学を、理解し、再現し、さらに拡張できるようになるためです。以下の数値はすべて本サイトのソースコードから引用したものであり、Nintendo が公式に文書化した値ではなくコミュニティの推定である場合は、その旨を明記します。
なぜトモダチのキャラクターはビープ音で話すのか
トモダチコレクション 新生活のサウンドを特徴づけるのが、ビープ音声(beep-speech)です。録音された台詞の代わりに、各 Mii が短い合成音で発声し、文のリズムに従いながら、実際の単語を形成することは決してありません。この手法は、カートリッジ容量とサウンドハードウェアの制約でフルボイスが非現実的だった、シリーズの携帯機時代にさかのぼります。そして、ビープ音がすでにシリーズのアイデンティティの一部になっていたため、Switch 版『トモダチコレクション 新生活:Living the Dream』にもそのまま受け継がれました。この効果が話し言葉として聞こえるのは、音高の動き、音節のタイミング、休止といった話声の韻律をコピーしながら、意図的に非語彙的な性質を保っているからです。
Nintendo はゲームで実際に使われている合成方式を一度も公開していないため、ブラウザでの再現は定義上、すべてコミュニティによる推定になります。ボイスラボが目指すのはビット単位の正確な再現ではなく美学の再現であり、その仕事の大部分は3つの特性が担っています。第一に、音が短いこと。エンベロープは数十ミリ秒で開閉するため、すべての音節が明瞭に始まり、明瞭に止まります。第二に、波形の倍音が豊かなこと。バズみのある音色は、純音よりもはるかに容易に「チップチューン」として聞こえます。第三に、音高が決して静止しないこと。音節ごとの微小な周波数オフセットが、自然な話し言葉の輪郭を模倣します。本ガイドの残りの部分では、これらの特性がそれぞれどう具体的な Web Audio API のメカニズムに対応するかを見ていきます。
合成パイプラインをノードごとに解説
ボイスラボが生成するすべての音は、オシレーターからあなたのスピーカーまでの間に、ちょうど3つの処理ノードを通過します。再生のたびに新しい AudioContext が作成され——ボイスラボがグローバルなオーディオグラフを常時保持することはありません——その中で各音節が自分専用のノード一式をスケジューリングします:
OscillatorNode ──▶ BiquadFilterNode (lowpass) ──▶ GainNode ──▶ AudioContext.destination
お年寄りプリセットのみ:
LFO OscillatorNode (5 Hz) ──▶ GainNode (depth 15) ──▶ main osc.frequencyOscillatorNode が音源です。type は選択したプリセットから決まり(5つのプリセットのうち4つは sawtooth、ロボットは square)、frequency はピッチスライダーで設定されます。オシレーターは素の波形ジェネレーターにすぎないため、音色を制御する機能をそれ自体は持ちません。あるプリセットが別のプリセットと違って聞こえる原因は、すべて下流のパラメータスケジューリングにあります。
BiquadFilterNode は常に lowpass フィルターとして設定され、カットオフはプリセットの filterFreq 値から取られます(プリセットに応じて 900 – 2500 Hz)。ローパスフィルターはカットオフより上の倍音を減衰させます。これこそが、生のノコギリ波の強烈なバズを人声に近いものへ変える仕組みです。暗めのプリセット(お年寄りの 900 Hz)は低い倍音だけを残し、明るめのプリセット(子供の 2500 Hz)は、声を小さく若く聞かせる輝きを通します。
エンベロープを司るのが GainNode で、4つのオートメーションポイントでスケジューリングされます。ゲインは音節の開始時刻に 0 から始まり、アタックタイムをかけてプリセットの目標値(0.2 – 0.3)まで線形に上昇し、終端の1リリースタイム分前までその値を保持したあと、0 まで線形に戻ります。アンカーには setValueAtTime() を、ランプには linearRampToValueAtTime() を使います。これは指数曲線を一切含まない素直なアタック/ホールド/リリース包絡線で、8-bit の雰囲気に合う特徴的に歯切れのいい音を保ちます。
さらに、オプションの4組目のノードペアとしてビブラートが存在します。プリセットが有効にすると、LFO(低周波オシレーター)として動作する2つ目の OscillatorNode がプリセットの vibratoRate で動き、vibratoDepth に設定された GainNode へ信号を送ります。この GainNode はメインオシレーターの frequency パラメータに接続されます。これは古典的な周波数変調です。お年寄りプリセットでは 5 Hz の LFO が音高を ±15 Hz 揺らがせ、年老いた声に結びつく震えの質感を生み出します。ビブラートを有効にするのはお年寄りプリセットだけで、他の4つは完全に無効のままです。
各波形の音色と選ぶタイミング
波形の選択は、パイプライン全体の中で最も影響の大きい音色の決定です。フィルターとエンベロープが後から形作る倍音成分を、波形が決めるからです。Web Audio API の OscillatorNode は4つの標準タイプを提供し、それぞれ個性が明確に異なります:
| 波形 | 倍音成分 | 音の個性 | 使用するプリセット |
|---|---|---|---|
sine | 基音のみ | 純粋でフルートに似た、バズのない音 | なし(OscillatorType で選択可能) |
square | 奇数倍音、強い | 空洞感のある、クラシックな NES リード音 | ロボット |
sawtooth | 全倍音、漸減 | バズみがあり葦のようで、人声の豊かさに最も近い | 成人男性、成人女性、お年寄り、子供 |
triangle | 少数の奇数倍音、弱い | 柔らかく丸みがあり、ややこもった響き | なし(OscillatorType で選択可能) |
ボイスラボのプリセットが使うのは4つのうち2つだけです。sawtooth が4つの有機的な声を担い、square がロボットを担います。この分担は意図的なものです。ノコギリ波はすべての倍音にエネルギーを持つため、ローパスフィルター通過後に厚みのある人声らしい核が残ります。歌や話し声を他のどの基本波形よりもうまく近似できるのはこのためです。矩形波は奇数倍音だけを保ち、高域にエネルギーが多いため、ロボットプリセットが求める、空洞のように鼻にかかった、紛れもなく電子的な質感をもたらします。Sine と triangle は現時点でどのプリセットにも使われていませんが、同じ OscillatorType フィールドを1行変えるだけで使えます。サイン波はチャイムのような純粋な効果音に、三角波はノコギリ波では強すぎる柔らかい背景のビープ音に向いています。
5つのボイスプリセットを徹底解説
5つのプリセットは、同じ3ノードグラフの上に成り立つ5つのパラメータの束であり、その違いは完全に列挙できます。以下は、ソースコードの 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)。この最後の2つの値は、音高と同じくらい重要です。緩いアタックが各音節の立ち上がりを柔らかくし、長いリリースが音を次の音へわずかに滲ませることで、このプリセットが目指すやや不明瞭な発話の質感を演出します。
子供はお年寄りの判断をほぼすべて反転させます。最も高い基準周波数(600 Hz)、最も明るいフィルター(2500 Hz)、最も低いゲイン(0.20)、そして最も速いエンベロープ(アタック 0.01 s、リリース 0.03 s)。高いピッチに速いエンベロープは、小さなキャラクターの声付けの定番レシピで、すべての音節が短いさえずりのように着地します。ロボットは2つの軸で異色です。唯一の square 波であり、唯一アタックとリリースがゼロのプリセットでもあります。つまりゲインが瞬時にオン・オフされます。この急峻なエッジが、プリセットの求める硬くゲートされた機械的な質感を生みます。ランプがなければ柔らかさもない——それが構造上の理由です。
ピッチとスピードは実際どうオシレーターを動かすのか
2つのスライダーがグラフをリアルタイムで制御します。ピッチは 100 – 800 Hz の範囲でデフォルトは 300 Hz、スピードは 0.5x – 2.0x の範囲でデフォルトは 1.0x です。また、各プリセットはそれぞれ正規の baseFreq(上の表に記載した基準中心値)を宣言しており、その声タイプがどこに据えられるよう設計されているかを文書化しています。
ピッチはオシレーターの周波数を直接設定しますが、1つのガードレールがあります。子供プリセットでは再生周波数が Math.max(pitch, 500) となるため、子供モードでスライダーを 500 Hz より下へドラッグしても何も起こりません。オシレーターがこの下限を下回ることは決してないのです。このクランプはプリセットの個性を守ります。150 Hz の子供の声は、単に静かな成人男性に聞こえてしまうためです。
スピードが制御するのは時間であって、周波数ではありません。再生ボタンを1回押すと、0.5 / speed 秒続くビープ音が1回鳴ります。0.5x では 1.0 s、1.0x では 0.5 s、2.0x では 0.25 s です。同じ除数がテキストモードのすべてのタイミング定数にも適用されるため、2.0x の声は最初から最後まで本当に2倍速になり、ピッチがずれてしまうリサンプリングとは異なります。再生後、インターフェースは 500 / speed + 50 ミリ秒後——ビープ音の長さに 50 ms のバッファを加えた時間——に再生状態をリセットします。
テキストから音声へ:1文字1ビープ
ボイスラボのテキスト読み上げモードは音声エンジンではありません。同じ3ノードのオシレーターパイプラインを、1文字につき1回スケジューリングしているだけです。最大 100 文字を入力して読み上げを押すと、入力は個々の文字に分割され、空白以外の各文字が、文字コードから導かれるピッチオフセット付きの音節ビープとして1回ずつスケジューリングされます。タイミング定数は次の通りで、すべてスピードで割った値です:
- 文字の音長——1文字あたり
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 マッピングの4つの性格グループには、それぞれ1つの代表的な声のシルエットが割り当てられており、個々の性格は、スライダーを範囲のどこに置くか、そしてスピードをどれだけ速く動かすかで表現されます。手順は以下の通りです:
- 1グループからプリセットを選ぶ。外交的と自信家の Mii には成人男性、独立心の Mii には成人女性、のんびりの Mii にはお年寄りを当てます。お年寄りの
5 Hzビブラートが、このグループで知られるリラックスした慌てない質感を加えます。Mii のグループは4つの性格スライダーから決まります。まだ分からない場合は性格チャートを参照してください。 - 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履歴パネルに保存されるため、書き留めなくても2つの設定を A/B 比較できます。データがブラウザの外へ出ることはありません。
子供とロボットの2行は、意図的に性格システムの外に置かれています。どの Mii にもどちらの声を当てられるため、MBTI 列は Any と表示されるのです。ロボットの長さゼロのエンベロープはテンポへの耐性を持ちます。どのスピードでも同じゲートされた硬さを保つため、スピードが純粋にコミカルな操作になる唯一の声です。
Web Speech API フォールバックがない理由
ボイスラボは、ブラウザの Web Speech API を意図的に避けています。コードベースのどこにも speechSynthesis の呼び出しはなく、テキスト読み上げモードは純粋なオシレーターのスケジューリングです。これは擁護できる根拠と現実的なトレードオフを併せ持つ設計上の決定であり、両面を明示する価値があります。
根拠は次の通りです。speechSynthesis は自然な人間の声を生成しますが、それはまさに 8-bit ボイスラボが望まないものです。さらに声の選択を OS に委譲するため、同じテキストがブラウザやデバイスによって違って聞こえることがあり、いくつかのブラウザは声を遅延ロードするため最初の発声の遅れが顕著です。1文字1ビープの方式は、すべての音を単発ビープモードと同じ3ノードグラフの中に留め、Web Audio API が動作するどこでも同一の音色を保証し、ロードが不要なため瞬時に開始できます。
トレードオフは、出力が理解可能な音声ではないことです。テキストのリズムと輪郭には従いますが、認識可能な単語を一切生成しないため、トモダチコレクション 新生活のビープ音声の理解可能性ではなく、そのリズム感を想起させます。そもそもゲームの意味不明音も理解できるものではありませんが、それこそが狙いと言えるでしょう。再生の停止も同様に力技で効果的です。ボイスラボは close() で AudioContext 全体を閉じ、フェードアウトではなく、スケジューリング済みのすべてのノードを即座に停止します。
限界を正直に述べる
このシンセサイザーが正直に主張できる範囲は、3つの限界によって区切られています。第一に、近似しているのは美学であってゲームのエンジンではありません。Nintendo はトモダチコレクション 新生活がどのように声を生成しているかを文書化したことがなく、ここのプリセット値は、シリーズのサウンドを想起させるよう調整されたコミュニティの推定値であり、抽出された定数ではありません。これらの声はゲームの声を彷彿とさせるものであり、複製ではありません。
第二に、この合成はモノフォニックでフォルマントを持ちません。各音節は1つのローパスフィルターで形作られた単一のオシレーターですが、自然な話し言葉——そしておそらくゲームのより洗練されたエンジン——は、声道に由来するフォルマント構造を持ちます。出力がサンプリング音声ではなくチップチューンの声付けとして聞こえるのはこのためです。コードを拡張するなら、この溝が最も探求する価値があります。1オクターブ上の2つ目のオシレーターも、周波数の動きをスケジューリングするフィルターも、どちらも結果を人声の領域へ一歩近づけます。
第三に、すべてはブラウザのサポートに依存します。ここで使われている Web Audio API——AudioContext、OscillatorNode、BiquadFilterNode、GainNode——は現在のすべての主要ブラウザでサポートされていますが、Web Audio API の出力の性格はデバイスのオーディオスタックによって依然としてわずかに異なります。また、ユーザー操作が行われるまで自動再生をブロックするブラウザでは、ボイスラボが既に用意している再生ボタンの押下が必要になります。プライバシーの面では、このツールは完全にクライアントサイドです。合成はブラウザ内で実行され、唯一の永続化データはローカルの IndexedDB 履歴です。音声もテキストも、どこへもアップロードされません。
パイプラインを自分で試す
このモデルを最も速く身につける方法は、2つのスライダーを動かして、グラフがリアルタイムで応答するのを聴くことです:
- トモダチボイスラボ——シンセサイザー本体。5つのプリセット、
100 – 800 Hzのピッチスライダー、スピード制御、そして1文字1ビープのテキストモードを備えています。 - トモダチ MBTI マッピング——Mii の4つの性格スライダーがグループをどう生み、そのグループが上の表のプリセットをどう決めるかを解説します。
- 性格チャート——声を当てる代表性格を選ぶための、16タイプ完全リファレンスです。
- Mii QRロック解除——デザインした声と編集した Mii キャラクターを組み合わせて、完全な島の住人を完成させます。