チュートリアル24

分析:高速フーリエ変換の使用

フーリエの定理

フランスの数学者ジョーゼフ・フーリエは、どんな周期的波動でも、各々別個の振幅と位相をもつ調和関係(整数倍の周波数)にあるサイン波の総和として表されることを証明しました。周期的波動のデジタル的表現を与えられると、離散フーリエ変換(DFT)として知られる公式を用いることによって、波動のサイン波成分の周波数、位相、振幅を計算することができます。本質的に、DFTは音波の時間領域での表現を周波数領域でのスペクトルに変換するものです。

一般的に、フーリエ変換は時間の小さな「スライス」(理想的には分析されている波形の正確な1サイクルに等しいもの)の上で行われます。この操作を「現実的な世界」のサウンド(ほとんどの場合、厳密に一定の周期ではなく、周波数はわかっていません。)に対して実行する場合、スペクトルが時間軸上でどのように変化するかについての認識を得ようとするタイムスライスの連続に対してDFTを実行することが可能です。、

各々のタイムスライスでのディジタルサンプルの数が2のべき(累乗)である場合、高速フーリエ変換(FFT)として知られるDFTのより速いバージョンを使用することができます。FFTの公式は、fft~オブジェクトにカプセル化されています。

フーリエ変換の数学は、このマニュアルの範囲を越えています。そこで、チュートリアルのこの章では、シグナル解析のためのfft~オブジェクトの使用法について説明します。

シグナルのスペクトル:fft~

fft~は、そのインレットでシグナルを受け取ります。fft~は、受け取った各々の時間のスライス(デフォルトでは512サンプルの長さ)に対して、同じ長さの、各周波数領域でのエネルギー量のリストのシグナルを送ります。fft~から出力されるシグナルは、「何かを聞くためのもの」ではありません。むしろ、「異なる512の周波数帯における、受信シグナルの相対振幅のリスト」なのです。この「リスト」は、たまたま各々のタイムスライスで受信されるサンプルと全く同じ長さなので、受信したシグナルと同じレートで出力されます。fft~から出力されるシグナルは、直前のタイムスライスで受け取ったサンプルの周波数領域での解析結果です。

変換はシグナルの形でfft~から出力されますが、それは時間領域シグナルではありません。この特別なシグナルを「理解する」唯一のオブジェクトはifft~オブジェクトです。これはスペクトルに対して逆FFTを実行し、それを時間領域の波形に逆変換します。

fft~から出力されるシグナルは時間領域のシグナルではなく、スペクトル情報です

capture~オブジェクトによって、fft~のアウトプットを捉え、シグナルの周波数分析をすることができます。

* ezdac~オブジェクトの1つをクリックし、オーディオをオンにして下さい。

オーディオがオンにされた時、dspstate~は真中のアウトレットからMSPサンプリングレートを送り出します。この値は、ちょうど512サンプルの周期を持つ周波数を計算するために使用されます。これがFFT自身の基本周波数です。fft~にその周波数の波を送った場合、各々のタイムスライスは波形のちょうど1サイクルを含むことになります。ここでは実際に、その10倍の周波数をもつコサイン波を、分析のためのテストトーンとして使用します。

テストトーンの周波数はFFT自身の基本周波数の10倍です

パッチャーウィンドウの左上では、fft~の非常にシンプルな使用例を示してます。分析結果はcapture~オブジェクトにストアされ、ifft~オブジェクトは分析結果をオーディオ・シグナルに再変換します。

(通常、このように理由もなくオーディオシグナルの変換、逆変換を行うことはないでしょう。このパッチでは、ifft~は単に分析-再合成プロセスの働きを説明するためだけに用いられています。)

* パッチの左上のトグルをクリックして、 再合成されたサウンドを聞いて下さい。トグルをクリックしてgate~をもう一度閉じて下さい。すぐに、パッチのその部分にあるcapture~オブジェクトをダブルクリックして、fft~によって実行された分析結果を見て下さい。

capture~テキストウィンドウの最初の512の数は、全部0.0000になっています。これは、fft~が最初のタイムスライスを分析している間の出力です。送り出される分析結果が1つ前のタイムスライスのものであることはぜひ覚えておいて下さい。最初にオーディオがオンになった時点で、それ以前にはオーディオが存在しないため、fft~の分析結果はシグナルが無いことを示しています。

* 最初の512個の数をスクロールさせて下さい。(capture~のテキストウィンドウはブロックごとに分かれているので、シグナルのベクタサイズが256ならば2つの数値のグループはすべて0.0000になるはずです。)2番目のタイムスライスの512個の数を見て下さい。

512個の数値の各々は、FFT自身の周波数の高調波(第0次高調波(0Hz)から開始されます)を表しています。分析結果は第11番目の数でエネルギーを示していますが、これはFFTの第10次高調波を表し、サンプリングレートの10/512(まさに、テストトーンの周波数)です。(分析結果はまた、最後から第10番目の数でエネルギーを示していますが、これはサンプリングレートの502/512を表しています。この周波数は、ナイキスト・レートを上回っていて、サンプリングレートの-10/512と同じです。)

技術的な詳細: FFTは、得られる周波数領域の全体を各々のタイムスライスのサンプル数と同じ数の帯域に分割します。従って、fft~から出力される512の数値の集合の1つ1つは、0からサンプリングレートまでの周波数範囲を512分割したものを表しています。最初の数は、0Hzでのエネルギーを、第2の数は、サンプリングレートの1/512の周波数帯でのエネルギーを、第3の数は、サンプリングレートの2/512の周波数帯でのエネルギーを、・・・(以下同様)、という形で表しています。

第257番目の数値(サンプリングレートの256/512)でナイキスト・レートに達してしまうと、それ以降のすべての数値は、ナイキスト・レートで「折り返され」てしまう点に注意しなければなりません。これについてのもう一つの考え方は、これらの数値が負のナイキストレートから上昇してくる負の周波数を表すと考えることです。こう考えると、第258番目の数値は、ナイキスト・レートからサンプリングレートの1/512の値を引いたものになります。(これはまた、サンプリングレートの-255/512と考えることもできます。)この例では、第11番目(サンプリングレートの10/512)と第503番目(サンプリングレートの -256/512 - -246/512) = -10/512)の周波数領域でエネルギーを見ることができます。

このようにして、fft~が正確にシグナルを分析していることがわかります。しかし1つだけ問題があります・・。

FFTの実際的な問題

FFTは分析されているサンプルが周期的波動の1サイクルを含んでいるとみなします。実例では、コサイン波はFFTの基本周波数の第10高調波だったので、FFTはうまく機能しました。しかし、ほとんどの場合、FFTの512のサンプルは波の正確な1サイクルではありません。このような場合でもなお、FFTは512のサンプルを波の1サイクルとして分析し、その波のスペクトルを出力しようとします。この分析結果には、実際のシグナルでは存在しないような多くの偽の周波数が含まれてしまいます。

* capture~のテキストウィンドウを閉じて下さい。オーディオをオンにしたままで、"Test Frequency"ナンバーボックスを1000にセットして下さい。これはまた、capture~オブジェクトの前の内容を消去するために、パッチの左上のclearメッセージをトリガします。もう一度capture~をダブルクリックして、新しい内容を見るためにテキストウィンドウをスクロールして下さい。

1000Hzの音の分析結果は1000Hz(MSPサンプリングレートが44,100Hzならば、第12番目と第13番目の周波数領域)で実際より大きなエネルギーを示しますが、同時に他のすべての領域でも仮想的なエネルギーを示します。この分析結果は、もはやサイン波ではありません。(正確なサイクル数が512サンプルと正確に一致していません。)このFFTで示されるすべての他のエネルギーは、これらの512サンプルを波の正しい1サイクルとする「不正確」な解釈によって生じた人為的なものです。

この問題を解決するために、我々は振幅エンベロープを適用して各々のタイムスライスの末端を「先細り」にし、さらにエンベロープの使用を補正するためにタイムスライスのオーバーラップ(重ね合わせ)を試みてみましょう。

FFTのオーバーラップ

チュートリアルパッチの右下の部分は、この「タイムスライスのオーバーラップを使用する」というアプローチをとっており、各々のスライスを分析する前に三角形の振幅エンベロープを適用しています。(振幅エンベロープの他の形がこのプロセスのためによく使用されます。三角形のウィンドウはシンプルで、かつ有効です。)この方法では、fft~オブジェクトは、各々のタイムスライスを、その端を先細りにする三角形のウィンドウを通して見ることになり、波の不連続によって生じる多くの偽の周波数をフィルタにかけています。

100Hzのコサイン波に適用された、オーバーラップする三角形のウィンドウ(エンベロープ)

この「窓関数」の適用とタイムスライスのオーバーラップを達成するためには、どちらが一つがもう一方より256サンプル後ろにオフセットされているような2つのFFTを実行しなければなりません。(fft~はベクタサイズの倍数によってしかオフセットされないので、パッチのこの部分はMSPシグナルベクタサイズが256かそれ以下のときにのみ動作する点に注意して下さい。)FFTのオフセットはfft~の(3番目の)タイプされた引数として与えられ、右側のfft~オブジェクトによって行われます。この結果、タイムスライスのオーバーラップが生じます。

一方のFFTは他のFFTより256サンプル後になっています

窓関数の適用は、FFTと同じ周波数(512サンプルごとに1回)で繰り返される三角形の波形(buffer~オブジェクトにストアされている)をシグナルに乗じることによって行われます。ウィンドウは、2番目のfft~のために1/2サイクル(256サンプル)オフセットされます。

* buffer~オブジェクトをダブルクリックしてその内容を見て下さい。それから、buffer~ウィンドウを閉じて、窓関数を適用されたシグナルのFFTの内容が格納されたcapture~オブジェクトをダブルクリックして下さい。最初のブロックか2つの数値グループをスクロールして、窓関数を適用された1000Hzの音の、FFTの分析結果を見て下さい。

窓関数を用いていないFFTと同様にエネルギーは1000Hzのあたりで最も大きくなっていますが、ここでは、すべての他の周波数領域での(偽の)エネルギーは、窓関数を用いていないバージョンと比べて非常に減少しています。

FFTを用いた信号処理

このパッチで我々は、シグナルを見、分析するために、またシグナルに窓関数を適用してFFTをオーバーラップする効果を説明するために、fft~オブジェクトを用いました。しかしまた、fft~から出力されるシグナルを変換するようなパッチを書くこともできます。そして、再合成のためにifft~に対して変換された分析結果を送ることもできます。このような、周波数領域をフィルタリングする方法の実現は、後のチュートリアルで見ることができます。

まとめ

高速フーリエ変換(FFT)は、時間領域のデジタルシグナルを、周波数領域での表現(シグナルの中の異なる周波数領域間の相対振幅による表現)に変換するためのアルゴリズムです。FFTは、シグナルの比較的小さい「部分」(通常512または1024サンプルの長さの時間のスライス)を使用して計算されます。より長いシグナルを分析するためには、連続した(またはオーバーラップされた)タイムスライスを使用する複合FFTを実行します。

fft~オブジェクトは、受信したシグナルのFFTを実行し、受信シグナルの周波数領域の解析結果を(これもまた、シグナルの形で)送り出します。fft~のアウトプットを理解する唯一のオブジェクトはifft~で、これは周波数領域の情報に基づいて時間領域のシグナルを合成するために逆FFTを実行します。スペクトルを変化させるために、fft~からifft~へ送られる間にシグナルに変化を与えることができます。

ちょうど1サイクル(またはサイクルのちょうど整数倍)の音を分析するときにだけ、FFTは完全に機能します。他の場合に作り出されてしまう人為的な数値を減らすために、各々のタイムスライスの末端を先細りにするような振幅エンベロープを利用して、分析するシグナルに「窓関数」を適用することができます。cycle~オブジェクトを利用して、FFTと同じレート(すなわち、各タイムスライスにつき1回)で繰り返しbuffer~から窓関数を読み、それをシグナルに乗じることで振幅エンベロープを適用することができます。

<-前の章 次の章->