以前の記事 で、音の正体は1秒に44100個の数の列だと書きました。そのとき、こんな宿題も残していました。人間に聞こえるいちばん高い音はおよそ2万Hzなのに、なぜその2倍あまりの44100個で足りるのか。今回はその答え合わせです。

答えを先に言ってしまうと、サンプリング周波数44100Hzで表せる音の高さには天井があって、それはちょうど半分の22050Hzです。この天井をナイキスト周波数と呼びます。可聴域の上限2万Hzより少し上に天井が来るように、44100という数字が選ばれているわけです。

ここまでなら「へえ、上限があるのか」で終わる話です。面白いのはここからで、では天井より高い音を無理やり作ったらどうなるのか。エラーになるわけでも、無音になるわけでもありません。天井を超えた音は、壁に当たったボールのように折り返して、聞こえる音域に降りてきます。22050Hzの壁に向かって音をどんどん高くしていくと、ある瞬間から音は裏返って、上げているのに下がって聞こえはじめる。プログラムで高い音を作ろうとした人が最初に出会う、いちばん有名な化け物です。この現象をエイリアシング(折り返し雑音)と呼びます。

記録に残るのは点だけ

なぜそんな奇妙なことが起きるのか。種明かしは、サンプリングという記録方法そのものにあります。コンピューターは音の波を連続のまま持てないので、一定間隔のスナップショット、つまり点の列として記録するのでした。問題は、波が速すぎて点の間隔が追いつかなくなったときに起きます。

高すぎる7000Hzの波を1秒8000回のペースで記録すると、点の列は1000Hzの低い波の上にも完璧に乗ってしまう図

図は話を分かりやすくするために、サンプリング周波数を8000Hzに下げた世界です。壁は半分の4000Hz。そこへ7000Hzの波を作って記録したとします。波は1回の記録の間にほぼ1周も進んでしまうので、記録された点の列を眺めると、ゆっくりした波にしか見えません。実際、この点の列は1000Hzの波の上にも一分の隙もなく乗っています。そして記録に残っているのは点だけです。元の波が7000Hzだったという情報はどこにも残っていないので、再生側は点に合う波のうち低いほう、つまり1000Hzを鳴らします。7000Hzを作ったつもりが、1000Hzの偽物(エイリアス)が鳴る。これがエイリアシングの正体のすべてです。

同じことは目でもよく起きています。映画で車のホイールが逆回転して見える、あの現象です。カメラは1秒24コマのスナップショットしか撮らないので、コマの間にホイールがほぼ1回転してしまうと、少しだけ戻ったようにしか写らない。速すぎる回転が「ゆっくり逆回る」偽物に化けるのは、速すぎる波が低い音に化けるのとまったく同じ理屈です。

波を点で記録するとき、1周期あたり最低2点は打てないと波の上下すら描き取れません。だからサンプリング周波数の半分が天井になります。逆に言えば、半分より下の成分は完全に記録できる、というのが標本化定理(サンプリング定理)と呼ばれる有名な定理で、ナイキスト周波数の名は、この理論の礎を築いた通信技術者ハリー・ナイキストにちなんでいます。

消えるのではなく、折り返す

天井を超えた成分がどこへ行くかは、きれいな規則になっています。作ろうとした周波数を横軸、実際に聞こえる周波数を縦軸に取ると、グラフはナイキスト周波数を頂点にしたジグザグを描きます。

作ろうとした周波数と実際に聞こえる周波数の関係。ナイキスト周波数22050Hzを頂点に折り返すジグザグのグラフ

壁の内側では、作ったとおりの高さが聞こえます。壁を越えると、超過ぶんがそのまま鏡写しに引き返してきて、たとえば44100Hzサンプリングで30000Hzを作れば、44100 − 30000 = 14100Hzが鳴ります。さらに上げて44100Hzに達すると聞こえる高さは0Hz、つまりほぼ無音まで下がり、そこから先はまた上がりはじめる。周波数をどれだけ上げ続けても、聞こえる高さは0Hzと壁のあいだを往復するだけで、決して壁の外へは出られません。

数式で書けば、作った周波数$f$に対して聞こえる周波数は

$$f_{\text{alias}} = \left| f - f_s \cdot \mathrm{round}\left(\frac{f}{f_s}\right) \right|$$

です($f_s$はサンプリング周波数)。いちばん近い$f_s$の整数倍からの距離、と読めます。壁の内側なら$f_{\text{alias}} = f$となって元のまま、壁の外なら別の場所に化けて出ます。

触ってみる

この「音が裏返る瞬間」は、耳で聴くのがいちばんです。デモを用意しました。高い音を扱うので、再生の前に音量をかなり下げておいてください。

うまく表示されないときは、デモを別タブで開く

上のパネルは、折り返しを聴きやすくするためにサンプリング周波数8000Hzの世界をシミュレートしています(8000Hzでサンプリングした波を理想的に再生した音、つまり折り返し後の正確な周波数を鳴らしています)。「自動で上げ続ける」を押すと、音は素直に高くなっていき、4000Hzの壁に当たった瞬間に裏返って下がりはじめます。さらに続けると8000Hz地点で音がすっと消え、また上がってくる。スライダーを手で動かして、壁の前後を行き来してみるのも面白いはずです。

下のパネルは、この化け物が実務で顔を出す現場、ノコギリ波の再生です。素朴な作り方と帯域制限した作り方を切り替えて、スペクトラムの違いと音の濁りを聴き比べられます。基音を高くするほど、また「音程スイープ」で音を滑らせると、素朴なほうでは音程と無関係に鳴き声のような成分が横切っていくのが分かります。

ノコギリ波に化け物が住みつく理由

サイン波を1本だけ鳴らしているぶんには、壁の存在はまず問題になりません。可聴域の上限すれすれの音を作る機会など、ほとんどないからです。ところが倍音の回 でやったように、楽器らしい音色は倍音、つまり基音の2倍、3倍、4倍……という高い成分を大量に含んでいます。ノコギリ波にいたっては、すべての整数倍の倍音を無限に含む波形です。基音が可聴域のまん中あたりでも、倍音たちはあっという間に壁を越えます。

基音4200Hzのノコギリ波。素朴に作ると6倍音以降が壁で折り返し、倍音でない半端な場所に成分が立つ。帯域制限版は壁の手前で打ち切るのできれい

そして越えたぶんは消えてくれず、折り返して可聴域に降りてきます。たちが悪いのは、折り返した成分が倍音の位置に着地しないことです。倍音は基音の整数倍という行儀のよい間隔で並んでいて、耳はその並びを「ひとつの音色」として聞きます。ところが折り返し成分は整数倍から外れた半端な周波数に立つので、音色に溶け込まず、調子外れの濁りや金属的なざらつきとして耳につきます。おまけに音程を変えると、正しい倍音は音程と一緒に上がるのに、折り返し成分は壁との鏡写しで逆方向に動く。メロディーを弾くと、音程と無関係な成分がキュルキュルと横切る、なんとも不気味な鳴り方になります。

倍音の回の最後に、倍音は好きなだけ高くまで足せるわけではない、と書き残していました。その答えがこれです。何本まで足してよいかは壁が決めていて、$n$倍音が$f_s/2$を超えない範囲、つまり$n < f_s / (2 f_0)$までは足しても安全。それより上は足した瞬間に化け物に変わります。だから、まともなデジタルシンセサイザーのノコギリ波は、壁の手前で倍音を打ち切った帯域制限(バンドリミット)と呼ばれる波形を使っています。

宣伝を少しだけ。筆者は Harmonize という音感トレーニングアプリを個人開発していて、ピアノやバイオリンなどの音色にノコギリ波を使っています。高い音でも化け物が顔を出さないよう、倍音はナイキストの手前で打ち切る帯域制限にしています。

どう実現するか

帯域制限ノコギリ波の作り方は、倍音の回の加算合成そのままで、違いは足すのをやめる条件が入ることだけです。$n$倍音の周波数$n f_0$がナイキスト周波数に達したら、そこで打ち切ります。

$$x(t) = \frac{2}{\pi} \sum_{n=1}^{N} \frac{1}{n} \sin(2\pi n f_0 t), \qquad N = \left\lfloor \frac{f_s / 2}{f_0} \right\rfloor$$

コードにすると、ループの上限を壁から計算する1行が今回の主役です。

/* ナイキストで打ち切った帯域制限ノコギリ波(C風の擬似コード) */
int N = (int)(fs / 2.0 / f0);            /* 壁を越えない倍音の本数 */
if (N * f0 >= fs / 2.0) N--;             /* 境界ちょうども避ける */

for (i = 0; i < length; i++) {
    double t = (double)i / fs;
    double v = 0;
    for (n = 1; n <= N; n++)             /* 壁の手前までだけ足す */
        v += sin(2.0 * M_PI * n * f0 * t) / n;
    output[i] = (2.0 / M_PI) * v;
}

基音220Hzなら44100Hzサンプリングで100本まで足せますが、基音3520Hzならたった6本。音程が上がるほど許される倍音は減っていくので、実用のシンセサイザーは音程ごとに$N$を計算し直します(音程別に波形を事前計算してテーブルに持っておくのが定番です)。逆に、素朴なノコギリ波──位相をそのまま高さに写す2t - 1のような式──は、この打ち切りを一切していないため、無限の倍音が全部壁に突っ込んで折り返します。デモの聴き比べで濁って聞こえたのは、その折り返したちの合唱です。

なお、マイクで録音する側にも同じ問題があるので、実際のオーディオ機器はサンプリングする前にアナログのフィルタで壁より上の成分を削り落としています(アンチエイリアシングフィルタと呼ばれます)。録音はフィルタで守れますが、プログラムで直接数の列を作る合成では、数を書き出した時点でもう手遅れです。作る側が壁を意識するしかない、というのがサウンドプログラミング固有の事情です。

参考文献

高い音の化け物の正体は、壁で折り返してきた自分自身でした。まずはデモの「自動で上げ続ける」で、音が壁に当たって裏返る瞬間を耳で確かめてみてください。