チュートリアル 26:
pfft~を使った周波数領域でのシグナルプロセッシング

周波数領域での作業

オーディオのデジタルシグナル処理のほとんどは、時間領域の中で行われます。そのため、他のMSPチュートリアルでは、サンプル(またはサンプルのグループ)の振幅の変更(リングモジュレーション、ウェイブシェイピング、ディストーション)や時間の変更(フィルタ、ディレイ)からなる、多くの、最も一般的なオーディオ処理について述べています。高速フーリエ変換(FFT)では、オーディオデータを時間領域から周波数領域へ変換することができるため、サウンドのスペクトル(スライスされたオーディオの周波数成分)を直接処理することができます。

MSPオブジェクトの fft~ ifft~ では、シグナルを周波数領域に変換したり、逆変換したりすることができます。fft~ オブジェクトはサンプルのグループ(通常フレームと呼ばれます)を、フレームに含まれるサンプル数と同じ数だけの、周波数の振幅と位相を表わす実数と虚数のペアに変換します。これらは、通常「ビン」または「周波数ビン」と呼ばれます。(この実数と虚数の値それ自身は振幅と位相を表すものではありませんが、それらによって振幅と位相を導き出すことができるということを、後ほど説明します)。ifft~ オブジェクトは逆変換を行います。これは、周波数領域のサンプルのフレームを時間領域のオーディオシグナルに再変換し、実際に聞いたり、別の方法で処理したりすることができるようにします。フレームのサンプル数はFFTサイズ(あるいはFFTポイントサイズ)と呼ばれます。このサイズは、512、1024、2048(これらは一般的によく用いられる値です)というような2の累乗(ベキ数)でなければなりません。

fft~ ifft~ オブジェクトの1つの欠点は、サンプルのフレーム間のオーバーラッピングやクロスフェードを行わずに、連続したフレームを処理する点です。これらのオブジェクトを実用的に音楽で使用するためには、ほとんどの場合、常にその前後に、このようなオーバーラップやクロスフェードのシステムを構築する必要があります。サウンドの処理にフーリエ変換を使う場合に、このようなシステムを作る必要があることには、いくつかの理由があります。FFT分析では、必ず周波数解像度と時間解像度の間のトレードオフが生じます。

例えば、FFTサイズが2048サンプルの場合、FFT分析によって0 Hz からサンプリング周波数までの2048の等間隔な周波数ビンを得ることができます(ただし、実際に使用できるのはこれらのビンのうちの1024だけです:詳しくはチュートリアル25を参照して下さい)。しかし、1つのFFTフレーム内の変化は、ひとかたまりにされてしまうため、2048サンプル内での時間解像度は分析によって失われてしまいます。加えて、FFT分析後のスペクトルデータを加工してIFFT再合成を行う場合、IFFTによる時間領域シグナルが、連続するフレーム上で一致するかどうかの保障ができないという点があります。出力される時間領域ベクタが適合しない場合には、出力シグナルにクリックを生じます。MSPで窓関数を設計し(下にしめすように)、連続したフレームがお互いにオーバーラップするようなクロスフェードを行なうことによって、この欠点を補うことができます。これは、時間解像度の補償は行いませんが、分析データをオーバーラップすることにより、再合成の際にIFFTフレームの端点で生じるクリック音やポンというような音を除去することができます。

この分析/再合成のしくみ(FFTとIFFTにオーバーラップと時間のスライスに対する窓関数を使用するもの)は、通常、短期間フーリエ変換(Short Term Fourier Transform)、あるいは短時間フーリエ変換(Short Time Fourier Transform)と呼ばれ、STFTと略されます。MSP でのSTFT の設計は、1つ以上のfft~/ifft~オブジェクトのペアを用いて、周波数領域への変換、逆変換の際にシグナルに「ウィンドウイング(窓掛け):窓関数の適用」を行なうようなパッチを作ることによって可能になります。このアプローチはうまく動作しますが、周波数領域の中で行われるすべての操作に対して各々のfft~/ifft~ペアを正確に複製しなければならない点がプログラム上いくぶん厄介です。次のサブパッチは、この方法で入力されるFFTデータにウィンドウイング(窓掛け)を行なうようすを示しています。


fft~ オブジェクトと共に使用するための、適切なオーディオのウィンドウイングの方法

このアプローチがプログラムにあたっての難題であることに加え、複数のFFTサイズやオーバーラップの組み合わせを用いたパッチの一般化が困難であるという問題点があります。フレームサイズやオーバーラップを定義する fft~/ifft~ のアーギュメントは変更ができないため、異なった状況では、各々のサブパッチのために数多くのバージョンを作る必要が生じてしまいます。例えば、パーカッシブなサウンドは少なくとも4つのオーバーラップが必要であるのに対し、適度に静的で、ハーモニックな豊かなサウンドは非常に大きいFFTサイズを要求します。

技術的な詳細:時間解像度 vs. 周波数解像度

FFT サイズは次のようなトレードオフをもたらします。フーリエ変換は小さな時間のスライスを固定された「スナップショット」に数学的に変換するものであるため、印象として、時間的な変化が1つの分析されたスペクトルに平均化されてしまうのを避けるために、小さいFFT サイズを選ぶ方がより有効であると考えるかも知れません。しかし、実際には、よりサンプル数が小さいFFT サイズは、より少ない周波数ビンによるスペクトルしか持ち得ません。これは、周波数解像度が低くなってしまうということを意味します。より小さい FFT サイズは、結果としてより良い時間解像度を持ちますが、その代わりにサウンドの周波数領域での変更や再合成を行なう場合に、より低い周波数解像度で実行されます。逆に言えば、より大きなFFT サイズでは、周波数に関しては細部までより良い情報を与えてくれますが、サウンドの時間的な変化がわかりにくくなる傾向を持ちます。従って、実際には処理しようとするサウンドの種類に基づいて、適切な FFT サイズを選択する必要があります。

pfft~ オブジェクトは、以前からの fft~ifft~ オブジェクトが持つ多くの弱点を解決し、ウィンドウイング、オーバーラップ、FFTサイズに左右されない、周波数領域シグナルデータを扱う特別な「スペクトル・サプパッチ」を作成し、ロードすることを可能にします。したがって、1つのサブパッチで複数のアプリケーションに対応することが可能です。さらに、pfft~ オブジェクトはFFTフレームのオーバーラップを管理し、窓関数を取り扱ってくれます。また、冗長なスペクトルの鏡像状のデータを取り除き、従来の fft~ifft~ に比べて、よりデータを使いやすく、効率的なものにします。

pfft~ オブジェクトは、アーギュメントとして、fftin~ fftout~ オブジェクト(後述)を含む、特別に設計されたサブパッチの名前と、FFTサイズのサンプル数、オーバーラップの係数(2の累乗でなければなりません)を取ります。


pfft~の簡単な使用法

上の例で参照されている pfft~ のサブパッチ fftbasic~ は次のようなものになるでしょう。


fftbasic~ サブパッチ

fftbasic~ はシグナル入力を受け取り、このシグナルをハニング窓(後述)を使ってFFTを実行します。そして、FFT を実行されたシグナルに対し、同じハニング窓を使ってIFFTを実行します。pfft~ オブジェクトはインレットとアウトレットに特別なオブジェクトを用いたサブパッチと通信を行ないます。fftin~ オブジェクトは時間領域シグナル入力を親パッチから受け取り、FFTを使って周波数領域に変換します。この時間領域シグナルは、pfft~ オブジェクトによって、前もって時間軸上でオーバーラップしたフレームのシーケンスに変換されたもので、fftin~ がスペクトル・サブパッチに出力するシグナルは、これらの入力されたフレーム個々のスペクトルを表しています。

技術的な詳細:スペクトル・サブパッチの内部のシグナルベクタサイズは、pfft~ のアーギュメントとして指定される FFT サイズの半分に等しくなっています。その理由は、効率化のために、fftin~fftout~ が実数 FFT(実FFT) と呼ばれる処理を実行するためで、fft~ifft~で使用されている従来の複素数 FFTより速く処理されます。これは、私たちが変換しようとする時間領域のシグナルが虚部を持たない(あるいは少なくともそれらの虚部が0 である)ために可能になります。実数FFTは、実数のみを持つ時間領域入力を、実際のFFT の半分のサイズの実部と虚部を持つ複素数FFTに再構成する、賢い数学的なトリックです。このFFT の結果は、その後、オリジナルの実数のみによるシグナルを複素スペクトル表現したものの半分(0 Hz からサンプリンングレートの半分まで)に再構成されます。より小さいFFTサイズは、コンピュータのプロセッサにとって効率的です。また、複素数 FFT が生成する鏡像形のスペクトルの半分だけが実際に役立つものであるため、実数FFT は私たちがシグナルのスペクトルを明確にし、それを操作するために必要なすべてのデータを含んでいます。

fftout~ オブジェクトは逆の事を行います。fftout~ は、周波数領域シグナルを受け取り、それを時間領域シグナルに再変換して、親パッチのアウトレットに送ります。どちらのオブジェクトも、アーギュメントとして数値(インレット、アウトレットのナンバの指定)と使用する窓関数を指定するシンボルを取ります。使用できる窓関数は、ハニング(指定がない場合のデフォルト)、ハミング、プラックマン、トライアングル(三角窓)、スクエア(方形窓)です。fftin~fftout~ nofft というアーギュメントを与えると、コントロールデータのための一般的なシグナルインレットまたはアウトレットを作ります。これらはFFT/IFFT処理やウィンドウイング(窓掛け)を行われません。加えて、シンボルには、カスタムな窓関数を格納した buffer~ オブジェクトの名前を指定することができます。異なったウィンドウ関数は、FFT の個々のチャンネル(またはビンー時としてこう呼ばれることもあります)について、異なるバンド幅やストップバンドデプスを持ちます。FFT分析に対する十分な知識は、分析したり、加工したりしようとするサウンドに基づくウィンドウの選択を助けます。そのために「コンピュータミュージックチュートリアル(Computer Music Tutorial)」-Curtis Roads著(訳注:日本語訳は、東京電気大学出版局「コンピュータ音楽 -歴史・テクノロジ・アート」)、あるいは「Computer Music」-Charles Dodge, Thomas,Jerse著を参考にされることを推奨します。

fftin~fftout~に対する nofft アーギュメントは、テストやデバッグの目的のために便利です。これは、pfft~とサブパッチの間で、窓関数の適用やフーリエ変換を行なわずにオーバーラップした時間領域フレームをやりとりすることを可能にします。この場合(スペクトル・サブパッチのシグナルベクタサイズがFFT サイズの半分であるため)、時間領域シグナルは fftin~ および fftout~ オブジェクトの実数と虚数のアウトレットに分割されます。これは、4 つ以上のオーバーラップを使用する場合にはむしろ都合が悪いでしょう。nofft オプションは親パッチからスペクトル・サブパッチにシグナルを送るために使用でき、サプパッチのデバッグに役立つものですが、ほとんどの場合、pfft~ の実用的な使用には推奨できません。

より複雑なpfft~サブパッチは次のようなものです。


シンプルなスペクトルのコンボリューション(畳込み)

このサブパッチは2つのシグナル入力(親の pfft~ オブジェクトではインレットとして現れます)を持ち、それらを周波数領域に変換し、一方の実数シグナルを他方の実数シグナルと、また、一方の虚数シグナルを他方の虚数シグナルと掛け合わせ、その結果を fftout~ オブジェクトに出力して、周波数領域のデータを時間領域のシグナルに変換します。周波数領域での掛け合わせはコンボリューション(畳込み)と呼ばれ、クロスシンセシス(1つのサウンドからもう1つのサウンドへモーフィングすること)で使われる基本的なシグナル処理方法(プロシージャ)です。このアルゴリズムによる結果、2つの分析結果が大きい値を持つ周波数ではお互いが補強されるのに対し、一方の分析結果が弱い値を持つ周波数では、他方の値は、それが強いか弱いかに関わらず、弱められたり、キャンセルされたりすることになります。したがって、2つの入力されるシグナルに含まれる周波数のうち、共通に含まれる周波数は強化され、共通しない周波数(片方のシグナルにあって、片方にはないピッチ)は弱められるか、除去されます。しかし、複素数の乗算(下記参照)は、この例で実行されているような直接的なものではないため、これは「本当の」コンボリューションではありません。このチュートリアルでは、後ほど、「正しい」コンボリューションを生成する 2つの方法について学びます。

fftin~fftout~ を接続する場合、および、その間でスペクトルを処理する場合に、常に2 つのシグナルが接続されることにすでに気づいていることと思います。これは、FFT アルゴリズムが、実部と虚部を持つ「複素数」を生成するためです。実部はfftin~の最も左のアウトレットから出力され、虚部は 2 番目のアウトレットから出力されます。fftout~の 2つのインレットも、それぞれ実部と虚部に対応しています。複素数を理解する最も簡単な方法は、それらを2次元平面の点を表すものと考えることです。この場合、実部は X軸(0 からの水平の距離)を表し、虚部は Y軸(0 からの垂直の距離)を表します。複素数の実部と虚部によってどのようなことができるのかについては、このチュートリアルで後ほど学ぶことにします。

fftin~ オブジェクトは第3のアウトレットを持っています。これは第1,第2アウトレットからデータが出力されているカレントのビンに対応するサンプルのストリームを出力します(これは、チュートリアル 25 で述べた、 fft~ifft~の第3アウトレットと同様なものです)。fftin~では、このアウトレットは 0 から FFTサイズ-1までの値を出力します。この値にFFTの基本周波数または基音のシグナル(シンクシグナルと呼ばれます)をかけ合わせることで、周波数値(各々のビンの「中央」の周波数を表します)に変換することができます。FFTの基音とは、FFTが分析できる最も低い周波数のことで、これはFFTサイズに反比例します(すなわち、大きなFFTサイズでは低い基本周波数になります)。正確なFFTの基本周波数は,FFTのフレームサイズでサンプリングレートを割ることで得られます。fftinfo~ オブジェクトは、pfft~サブパッチの中に置かれたとき、FFTフレームサイズとFFTハーフフレームサイズ(実際にpfft~ サブパッチの中で使用されるビンの数)、FFTホップサイズ(窓掛けされたフレーム間でオーバーラップされるサンプル数)を出力してくれます。これを、dspstate~ オブジェクト、または sr (sampling rate) をアーギュメントに持つ adstatus オブジェクトと共に使うことによって、FFTの基本周波数を得ることができます。


現在分析しているビンの中心周波数を求めます

上の例の number~オブジェクトは、このチュートリアルでは単に説明のために置かれているにすぎないという点に注意して下さい。DSP がオンになったときに、シグナルナンバーボックスに表示される数値は変化しません。シグナルナンバーボックスは、デフォルトではシグナルベクタの最初のサンプルを表示するため、このケースでは常に 0 になります。中央の周波数値をみる場合には、capture~ オブジェクトを使用するか、シグナルを buffer~ の中にレコーディングする必要があります。

fftin から出力されるビンの周波数がわかってしまえば、周波数に基づいたFFTデータの操作を実行することが可能になります。例えば、次はその例です。


簡単なスペクトル交差

上の pfft~ サブパッチは、xover~ と呼ばれています。これは、入力シグナルを分析したデータを、交差周波数(クロスオーバー周波数)に基づいて2つの fftout~ オブジェクトのうちの1つに送ります。交差周波数は in オブジェクトを使って pfft~ サブパッチに送信されます。inオブジェクトは、親パッチを経由して、Max メッセージを pfft~ オブジェクトの右インレットに渡します。カレントのビンの中心周波数(上で述べたように、シンクアウトレットと fftinfo~ およびdspstate~ を組み合わせて決定します)は交差周波数と比較されます。

この比較の結果は、2 つの fftout~ オブジェクトのうちの 1 つに FFT データを送信するゲートを切り替えます。スペクトルのうち、交差周波数より低いピッチを持つ部分は pfft~ の左アウトレットから出力され、交差周波数より高い部分は右アウトレットから出力されます。次の例は、このサブパッチが、パッチの中でpfft~によってどのように使われるかを示しています。


xover~ サブパッチの使用の一例

inおよび out オブジェクトを使って、pfft~にロードされたサブパッチと、整数(int)、浮動小数点数(float)、および他の任意の Max メッセージをやり取りすることができるという点に注意して下さい。(詳しくはチュートリアル 21 の「poly~ オブジェクトの使用」を参照して下さい。しかし、現在のところ、シグナルオブジェクト in~out~pfft~の中では動作しないということは記憶に留めておいて下さい。)

すでに学んだように、fftin~ の最初の 2 つのアウトレットは、FFT 分析の個々のサンプルに対応するビンの、実数と虚数のストリームを出力します(同様に、fftout~ はこれらの数値を前提にしています)。これらの値は、個々のビンの振幅と位相ではありませんが、x を実部、y を虚部として2 次元平面上の点を表すデカルト座標の代わりであると考えられます。

個々の周波数ビンの振幅と位相はこの点の極座標で表され、原点からの距離がビンの振幅、原点の周りの角度がビンの位相にあたります。


単位円の図は、FFT の実部、虚部の値と振幅、位相の関係を示しています

cartopol~および poltocar~というオブジェクトを使うと、実数/虚数のペアと振幅/位相のペアの間の変換を容易に行うことができます。


デカルト座標から極座標への変換

技術的な詳細: cartopol~ の左アウトレットから出力される振幅は、pfft~ オブジェクトに送ったシグナルの振幅に依存します。fftin~fftout~ が自動的にウィンドウ関数を(オーバーラップを施した後でも同じ振幅を維持するように)スケールするため、定数シグナル 1.0 の最大の振幅値は次のようになります。

( FFT サイズ / ( sqrt (ウィンドウ内のポイントの合計/ホップサイズ))

したがって、512 ポイントの FFT を矩形窓、 2 つのオーバーラップで行なった場合、可能な最大の振幅値はおよそ 362、4 つのオーバーラップで行なった場合は 256 になります。ハニング窓、またはハミング窓を使い、2 つのオーバーラップで行なった場合は、それぞれ、およそ 325、341 になり、4 つのオーバーラップで行なった場合は、それぞれ、230、241 になります。しかし、一般的に、非周期または半周期で、-1.0 から 1.0 の間に正規化された「現実音」の場合、スペクトルフレームのピーク振幅は、ほとんどこの値の半分の1/4 くらいにしかなりません。

cartopol~ の右アウトレットから出力される位相は、常に-π と π の間の値になります。

この情報を使って、振幅/位相データに基づくシグナル処理ルーチンを作ることができます。スペクトル・ノイズゲートは次のようになるでしょう。


スペクトル・ノイズゲート

cartopol~ から出力される振幅と pfft~の第2インレットに送られるスレッシュホルドシグナルを比較することで、各々のビンは通過するか *~ オブジェクトによって0にされます。このようにして、一定の振幅を上回る周波数ビンだけが再合成の際に保持されます(スペクトル・サブパッチの中の振幅値に関する情報は、上記のテクニカルノートを参照して下さい)。

コンボリューションやクロス・シンセシス効果では、一般的に振幅と位相のデータを処理に用います。ここで作成した最も基本的なクロス・シンセシス効果の 1 つでは、一方のサウンドの振幅スペクトルと共に、他方のサウンドの位相スペクトルを使っています。位相スペクトルはサウンドの周波数成分についての情報に関連するため、この種のクロス・シンセシスは、他のサウンドのスペクトル・エンベロープによって「演奏」されるサウンドの倍音成分を与えることができます。もちろん、このタイプの効果が成功するかどうかは、使用される 2 つのサウンドの選択に大きく依存します。

次は、cartopol~poltocar~ を使ってこのタイプのクロス・シンセシスを実行するスペクトル・サブパッチの例です。


シンプルなクロス・シンセシス

次のサブパッチの例では、1つの入力の振幅の、他の振幅によるコンボリューション(畳込み)の 2 つの方法が示されています。


振幅だけのコンボリューション

このサブパッチの左側では、入力シグナルの振幅値が掛け合わせられているのが一目でわかります。これにより、両方のサウンドで顕著な振幅は強められ、そうでないものは弱められます。最初のシグナルの位相特性は、複素数と実数の乗算の影響を受けず、2 番目の入力シグナルの位相特性は無視されます。サブパッチの右側は、cartopol~ オブジェクトを 1 つしか使っていないにも関わらず、数学的には左側のものと等しいことにも気がつくでしょう。

このチュートリアルの最初で、コンボリューションを実行するために2つの実数/虚数シグナルの乗算を行なっている例を見ました。その例は説明を行なう目的であえて単純にしていましたが、実際には誤りです。2 つの複素数の「正しい」乗算の意味について知りたいのであれば、その 1 つの方法は次に示すようなものです。


複素数のコンボリューションを行なう正しい方法

次は、第 2 の方法です。これは同じ結果を得られるいくぶん賢いアプローチです。


複素数のコンボリューションを行なう、正しく賢い方法

pfft~ で使用するために作られるサブパッチは、あらゆる MSP オブジェクトを使用することができます。その中には buffer~ オブジェクトにストアされたデータにアクセスするオブジェクトも含まれます(しかし、時間的な問題を扱うために設計されたいくつかのオブジェクトは、pfft~ の中で使用した場合、常に最初に期待したような動作を行なうとは限りません)。

次の例では、スペクトル分析データを、ステレオ buffer~の 2 つのチャンネルにレコーディングし、そのレコーディングデータを違った速さで再合成することが可能です。


pfft~ サブパッチの内部でのレコーディングとプレイバック

このサブパッチャーの例では、スペクトルデータを buffer~ にレコーディングし、さらに、データを buffer~から読み出します。サブパッチのレコーディング部分では、cartopol~ の出力する振幅と位相をそのままレコーディングするのではなく、その代わりに framedelta~ オブジェクトを使って位相差(位相偏移、あるいは位相微分と呼ばれることもあります)を計算している点に注目して下さい。位相差は、ごく単純に、連続したFFT フレームの同じビン位置の位相の差です。framedelta~の出力は、データが正しく -πとπの間に収まることを確実にするために、phasewrap~ オブジェクトに送られます。レコーディングの開始と停止を行なったり、ループをオンにしたりするために、親パッチから、sendオブジェクトによって record~オブジェクトにメッセージを送ることができます。

サブパッチのプレイバック部分では、再合成のためのフレームナンバーを指定するために、非シグナルインレットを使っています。このナンバーは、スペクトルフレームサイズを掛けられ、0 からスペクトルフレームサイズ -1 までをカウントする count~ オブジェクトの出力を加えられます。index~ にこの値を使ってbuffer~ の 2 つのチャンネルを読み出すことにより、与えられたフレームの中の個々の周波数ビンを連続して呼び出すことが可能になります(count~ の代わりに fftin~ のシンク・アウトレットを使うことも可能でしたが、スペクトル・サブパッチのコンテキスト(文脈)の中での count~ の利用方法の例を示すために、そして、サブパッチの中のレコーディング部分とプレイバック部分を視覚的に分けるために、この方法を使っています)。位相を再合成するために frameaccum~ オブジェクトを使っていることに気づくでしょう。このオブジェクトは、framedelta~ の逆の処理を実行することによって「ランニング・フェイズ」の値を加算しています。分析されたフレームは、必ずしもレコーディングされたときの速さで連続して読み出されるわけではありません。そのため、この処理が必要になります。その後、シグナルは poltocar~オブジェクトによって実部と虚部の値に変換され、fftout~ に送られます。

これは「フェイズボコーダ」として知られているものの簡単な例です。フェイズボコーダでは、シグナルのピッチを、時間領域セグメントではなくFFTデータとして処理することによって、シグナルの時間上の圧縮、伸長をピッチとは独立して行うことができます。FFT 分析の個々のフレームをフィルムの 1 フレームと考えると、1回のFFTをフィルムの1つのフレームと考えると、1つ1つのフレームが様々な速さで読まれていくことによって、起きていることの見かけ上のスピードを変化させることができるということが容易に理解できるでしょう。フェイズボコーダの動作はこのようなものです。

pfft~ はウィンドウによるオーバーラップを行うため、buffer~ にストアされるデータ量は pfft~ の設定に依存するという点に注意して下さい。特に、pfft~の中のスペクトルフレームサイズ(すなわち、シグナルベクタサイズ)は、pfft~ の第 2 アーギュメントで示されているFFT サイズの半分であるため、そして、スペクトルサブパッチが、親パッチとは異なるレートでサンプルを処理する(!)ため、バッファサイズを正しく設定するには、やや手の込んだ方法が必要となります。1000 ミリ秒のサンプルメモリを格納するステレオの buffer~ を作ったと仮定しましょう。この buffer~ には44100 サンプルの分析データを格納することができます。FFT サイズが 1024 である場合、個々のスペクトルフレームはバッファのメモリのうち512サンプルを使用します。そのため、バッファには 86 フレーム(44100 / 512 = 86.13)格納することができます。この 86 フレームはサウンドの 1 秒を表すものではありません。しかし、仮に 4 回のオーバーラップを用いている場合、1 つのスペクトルフレームを 256 サンプル毎に処理していることになるため、86 フレームは、親パッチから見た場合、およそ 22050 サンプル、つまり 1/2 秒の時間を表すものとなります。このように、いくぶん複雑なものであることがわかるでしょう。

上記のフェイズボコーダ・サブパッチのための親パッチ(mypvoc~という名前がつけられています)を見てみましょう。


mypvocのラッパー

サブパッチの中の読み込み位置を指定するランプ(傾斜値)を生成するために、phasor~オブジェクトを snapshot~ オブジェクトと共に使用している点に注意して下さい。ここに lineオブジェクトを使うこともできます。また、分析したフレームを手動で「スクラブ」したい場合には slider オブジェクトを使うことも可能です。このメインパッチでは、分析データのループをプレイバックする速さを変更することができます。また、与えられた再生レートで、与えられた分析データの区間をループするために、分析フレームのバッファ内でのループサイズやオフセットを指定することもできます。再生レートの変更が、サウンドのピッチに影響を与えず、スピードだけを変化させるということに気づくでしょう。また、サウンドの特定の場所(通常、音のアタック、言葉の子音、その他のパーカッシブなサウンドなど)に、非常に遅い再生レートを適用することによって、より「汚れた」感じになり、人工的な音質を得ることができるということにも気づくのではないでしょうか。

まとめ

pfft~ を使用してスペクトル領域のシグナル処理を行なうことは、一般的に、従来の fft~ifft~ オブジェクトを使用した場合に比べ、処理をより容易で、視覚的にもわかりやすいものにします。さらに、様々なFFT サイズやオーバーラップで使用できるパッチを設計することを可能にしてくれます。pfft~ による音楽的なシグナル処理のためのアプリケーションは数多くあり、その中には、フィルタ、クロスシンセシス、タイム・ストレッチング(時間伸張)などが含まれます。

参照

adstatus オーディオドライバの出力チャンネルにアクセスします。
cartopol~ シグナルのデカルト座標を極座標に変換します。
dspstate~ 現在のDSP セッティングを報告します。
fftin~ pfft~にロードされたパッチャーへのインプット
fftout~ pfft~にロードされたパッチャーからのアウトプット
framedelta~ 連続した FFT フレーム間で位相偏移を計算
pfft~ パッチのためのスペクトル処理マネージャ
phasewrap~ シグナルを -πとπの間にラッピングします。
poltocar~ シグナルの極座標をデカルト座標に変換します。