FX INTRODUCTION / 18

音程と母音:別々に操作する

声のような音では、音程と母音の響きは別々の要素です。入力音源の周波数とフォルマントフィルターを分けて操作し、最後に両方を組み合わせます。

1. まず聴いてみる

最初は実験Aです。入力音源は130 Hzに固定し、母音だけを変えます。先頭の設定をBにすると母音を固定して音程を変更、Cにすると両方を変更します。最初から比較したい場合は、実験を変える前にStopしてください。

iframe内のRunで再生、Stopで停止します。再生中にコードを編集したら、もう一度Runすると更新が反映されます。同じliveFx名ならフィルターの状態を保持します。最初から比較したい場合はStopしてからRunしてください。ほかのPlaygroundはStopしてから聴き比べます。

このコードを別タブのPlaygroundで開く ↗

2. 声には「音源」と「共鳴の形」がある

声帯の振動が音源になり、声道が特定の周波数帯を強調します。この幅のある共鳴帯域をフォルマントと呼びます。電子音にもフィルターで似た形を与えられます。ただし、人間の声道そのものを再現しているわけではありません。

倍音を含む入力音
↘ バンドパス F1 ↗
→ バンドパス F2 → 重み付き加算 → 原音/加工音のMix → 出力
↗ バンドパス F3 ↘

3つのフィルターは、同じ入力を並列に受け取ります。その出力を加算します。F1、F2、F3の順に直列で通す処理ではありません。

フォルマント最初の理解の目安
F1母音の開きと関係します。開いた母音ほど高くなる傾向があります。
F2舌の前後位置と関係します。前寄りの母音ほど高くなる傾向があります。
F3母音や声の響きをさらに特徴づけます。独立した身体のつまみに対応するわけではありません。

実際の値は話者や発声で変わります。以下は実験用の目標値で、日本語の母音に共通する唯一の数値ではありません。背景はOxfordの音響音声学入門資料(音源・フィルターと母音、英語)を参照できます。

母音/番号F1(Hz)F2(Hz)F3(Hz)
あ/080012002500
い/130023003000
う/235012002500
え/350019002600
お/45009002400

3. コードの設定を読む

設定意味/単位
vowel0〜4の母音番号。0.5などの小数で隣の母音との中間も指定可能
autoVowelstrueなら母音の目標を自動で切り替える
vowelSeconds次の母音へ進む間隔(実時間の秒)
transitionMsパラメーターの変化をならす時間尺度(ミリ秒)
lfoHz / lfoDepthLFOの周期数/秒と、共鳴周波数を動かす幅(オクターブ)
gain / mix加工音の倍率/加工音を混ぜる割合(0〜1)
formants母音ごとの[F1, F2, F3](Hz)の表
bandwidths / levels3帯域それぞれの幅(Hz)/混ぜる重み

contextは音声処理へ渡す設定、stateは次回の処理へ残す履歴です。これらの母音設定は今回のサンプルが定義する名前で、組み込みFXの追加APIではありません。liveFxのcontextにある数値と、processで入力を加工する箇所を見比べてください。再生中に同名のコードをRunすると、変更した設定が音声処理へ渡されます。

4. 3つの実験

experiment入力音源の音程フォルマント聴く・見るところ
"A"carrierHzに固定5つの母音を巡回音程は同じで、強まる帯域が動く
"B"周波数のパターンを反復fixedVowelに固定音程は変わり、共鳴の目標位置は同じ
"C"同じ周波数パターンを反復5つの母音を巡回両方が一緒に動く

carrierHzの単位はHzです。BとCでは音源用のループがPSGの周波数を変えます。fixedVowelはBのフィルターの目標を選び、PSGの周波数は変えません。入力音源のループとliveFxで役割を分けています。

  1. Aを再生してからexperiment = "B"に変え、編集後にもう一度Runします。何が変わるか聴き比べます。
  2. AでcarrierHz = 110、130、180を試します。フォルマント表は変更しません。
  3. BでfixedVowelを0から1に変えます。同じ音程パターンが別の母音になります。
  4. Cを試します。vowelSeconds: 2.5にすると、2つの操作の重なりをゆっくり確認できます。

「独立」とは、何が独立なのか

Aでは倍音の間隔は同じまま、共鳴する帯域が動きます。Bでは倍音の間隔が変わり、共鳴の目標位置は同じです。どちらでも個々のピークの位置や強さが変わることがあります。フィルターが強調できるのは、入力に含まれる倍音だからです。

音程を変えると、共鳴に近い倍音も変わるため、聞こえる母音の響きが完全に一定になるわけではありません。基音が高いと母音の帯域に入る倍音が少なくなり、違いを聞き分けにくくなります。この例は音源の音程とフィルター制御を分離するもので、任意の録音を加工するピッチシフターではありません。

5. フィルターを途切れずに動かす

process(input, output, state, context)はAudioWorkletの音声スレッドで動きます。input[ch]は左右などの音声チャンネルで、YM2612の演奏チャンネル番号ではありません。左右それぞれの3つのフィルター履歴をstateに保持し、制御位置は共通にして同じタイミングで動かします。

この例では台形積分方式の状態変数バンドパスフィルターを使い、AudioWorkletの実際のsampleRateから係数を計算します。同じ周波数設定を44.1 kHzと48 kHzで使えます。方式の詳細はCytomicの線形台形積分SVFの資料(英語)にあります。

音声ブロックや同名FXの更新をまたいで履歴を保ち、目標周波数・Gain・Mixの変更を平滑化します。transitionMsは移動の時間尺度で、単位はミリ秒です。設定範囲を制限し、有限でない計算結果を防ぎ、出力にも上限を設けます。それでもGainを大きくしすぎると音がつぶれるので、まずは初期値で試してください。

この実験には、加工するための倍音が必要です。サイン波は周波数成分が1つなので、母音の共鳴を十分に作れません。Sega PSGの矩形波には奇数次の倍音があります。標準クロックでの最低音は約109 Hzなので、入力音源は110〜260 Hz程度を目安に試してください。これは小さなチップ音源によるキャリアで、声帯振動の完全なモデルではありません。

6. FX Monitorで加工前後を比べる

RunしたらFX Monitorで対象にformant-pitchを選びます。青が入力、オレンジが出力です。View → Spectrumで強調される周波数帯を、Oscilloscopeで波形の形を比較します。

波形の高さを比較するときはYを固定します。入力と出力は同じ表示スケールです。Spectrumでは倍音ピークの全体の形を見てください。ピークは入力音源の倍音付近に立ち、F1、F2、F3の中心と完全に一致するとは限りません。フィルターは既存の成分を強調するもので、各フォルマントに新しい発振器を追加する処理ではありません。

Monitorは短い時間の観測です。毎フレーム3つの山が独立して見えるとは限らないので、数周期の動きと音を合わせて確認します。音源の後段で動くため、このPlaygroundに追加したほかの音にも同じFXがかかります。

合成した母音の響きを楽しむ実験です。LPCハードウェアの再現、音声認識、子音の生成、自然な話し声の再現を目的にはしていません。聞き取りやすさは音源・音程・再生機器・聴く人でも変わります。無理のない音量で比べてください。

FX入門一覧(作成中)