/**/

チュートリアル 48:
MSP シグナルのフレーム

チュートリアル27:「JitterマトリックスでのMSPオーディオの使用」では、jit.poke~ オブジェクトを使ってMSP オーディオシグナルをサンプル単位で Jitter マトリックスにコピーする方法について学びました。このチュートリアルでは、データをシグナルからマトリックス領域に移すもう1つのオブジェクトとして、jit.catch~ を紹介します。ここでは、jit.graph オブジェクトを使ってオーディオや、他の1次元データをビジュアライズする方法について、そして、一連のフレームベースの分析の中での jit.catch~ の使い方の可能性について示してみたいと思います。さらに、データをマトリックスからシグナル領域に移す jit.release~ オブジェクトについても触れ、サウンドの処理や合成に Jitter オブジェクトを使用する可能性についても見て行きます。

・Jitter Tutorialsフォルダの中のチュートリアルパッチ、48jSignals.pat を開いて下さい。

このパッチは、いくつかの小さなサブパッチにわかれています。左上の audio パッチャーには、Sine wave madness と表示されたネットワークがあり、いくつかの cycle~ オブジェクトがお互いをモジュレートしています。サブパッチの右上隅 のsfplay~ オブジェクトによって、オーディオファイルのプレイバックも可能になっています。


Sine wave madness の内部

基本的なビジュアライゼーション

dsp startと書かれたメッセージボックスをクリックして、オーディオベクタの処理を開始して下さい。

basic visualization という名前のパッチャーを開いて下さい。qmetro オブジェクトに接続された toggle ボックスをクリックして下さい。


オーディオシグナルを Jitter マトリックスとしてキャプチャし、出力する

basic visualization パッチャーでは、audio パッチャーからの2つのシグナルが、jit.catch~ オブジェクトに入力されています。jit.catch~ オブジェクトの基本的な機能は、シグナルデータを Jitter マトリックス領域に移すことです。このオブジェクトは複数のシグナルの同期キャプチャをサポートします。オブジェクトの第1のアーギュメントはシグナルインプットの数を設定し、それぞれ別のインレットが作られます。異なるシグナルからのデータは、float32型の Jitter マトリックスの別々のプレーンに多重送信されます。このサブパッチの例では、2つのシグナルがキャプチャされています。結果として、出力されるマトリックスは2つのプレーンを持ちます。

jit.catch~ オブジェクトは、mode アトリビュートによって、いくつかの異なった方法で操作することができます。mode アトリビュートが 0 にセットされている場合、jit.catch~ は単に、前の bang を受け取ってから集められた全てのシグナルデータを出力します。例えば、オブジェクトが 最後に bang を受信してから1024 サンプルが受け取られた場合、1次元の、1024 のセルを持つ float32型のマトリックスが出力されます。

mode 1の場合、jit.catch~ は固定フレームサイズのちょうど倍数にあたる数を出力します。この固定フレームサイズの長さは、framesize アトリビュートによってセットすることができます。データはフレームサイズと同じ幅を持つ2次元のマトリックスに並べられます。例えば、フレームサイズが100 で、同じ 1024 サンプルが内部的に蓄えられ(キャッシュされ)、出力を待っている状態だとすると、mode 1 では、bang によって 100×10 のマトリックスが出力され、残りの 24 サンプルは次の bang までキャッシュに留まります。この 24 サンプルは次の出力フレームの最初に置かれ、それ以降に受け取ったシグナルデータがその後に続きます。

mode 2 の場合の動作では、オブジェクトはフレームサイズの長さ分の、最も最後のデータを出力します。上の例の場合(フレームサイズが 100 で、最後の出力以降に1024サンプルがキャプチャされている場合)、jit.catch~ オブジェクトの mode 2 では最後に受信した 100 サンプルが出力されます。

この basic visualization サブパッチでは、jit.catch~オ ブジェクトは mode 3 にセットされていて、トリガモードのオシロスコープと同様な動作をします。オブジェクトは、trigthresh アトリビュートでセットされたスレッシュホルド値を横切る値の入力データをモニタします。このモードは、ここでの例のような周期的な波形を見る場合に最も役に立ちます。

jit.catch~ mode 0mode 1では、一度受信した全てのシグナル値を正確に出力しようとするのに対し、mode 2mode 3はそうではないという点に注意して下さい。

さらに、mode 0mode 1 で出力されるマトリックスのサイズは変わることがあるのに対し、mode 2mode 3 で出力されるマトリックスは常に同じ大きさになります。全てのモードで、jit.catch~ オブジェクトは出力を待っている間に受信したシグナル値を保持するメモリのプールを維持しなければなりません。デフォルトでは、このオブジェクトは 100 ミリ秒のデータをキャッシュします。しかし、このサイズは、オブジェクトに対して、必要とするミリ秒単位の時間の値をアーギュメントとして続けた bufsize メッセージを送ることによって増やすことができます。mode 0mode 1 では内部で格納できる値より多くのデータが入力された場合、次の bang ではマトリックスは出力されず、その代わりに、オブジェクトのダンプ(右側の)アウトレットから「バッファ・オーバーラン(buffer overarun)」メッセージが出力されます。


オーディオデータの基本的なビジュアライゼーション

2つのシグナルは出力マトリックスの異なったプレーンに多重送信されるため、jit.unpack オブジェクトを使って、Jitter 領域のシグナルに別々にアクセスしています。この例では、結果として出力されたマトリックスの単独のプレーンが jit.graph オブジェクトに送られています。jit.graphオブジェクトは1次元のマトリックスデータを取り、それを拡大してビジュアライゼーションに適した2次元領域にプロットします。プロットの最小と最大の範囲は、rangehi および rangelo アトリビュートによって、それぞれ設定できます。デフォルトではグラフの範囲は -1.0 〜 1.0 になっています。

これら2つの jit.graph オブジェクトはいくつかのアトリビュート・アーギュメントと共にインスタンス化されています。第1に、out_name アトリビュートが指定されているため、両方のオブジェクトは jane という名前のマトリックスに描画されます。第2に、右側の jit.graphオブジェクト(最初に実行されます)は、clearit アトリビュートが 1 にセットされていますが、左側の jit.graphclearit アトリビュートが 0 に設定されています。想像できるように、 clearit アトリビュートが 1 にセットされている場合、マトリックスはその中にグラフが描かれる前にクリアされます。そうでない場合は、jit.graphオブジェクトは単にマトリックスにすでにあるデータの最初からグラフを描きます。単一のマトリックスの2つ以上のチャンネルをビジュアライズする場合には、最初の jit.graphオブジェクトにマトリックスをクリアさせ(clearit 1)、残りの jit.graph オブジェクトは、clearit アトリビュートを 0 にしておく必要があります。

jit.graphオブジェクトの height アトリビュートは描かれたマトリックスをどのくらいの高さにするかをピクセル数で指定します。出力マトリックスは入力マトリックスと同じ幅になるため、width アトリビュートは必要ありません。frgb アトリビュートは、描かれる線の色を4つの整数値でコントロールします。これは、指定される色のアルファ、赤、緑、青の値を表します。最後に、jit.graphmodeアトリビュートによって、4つの異なる描画システムを使うことができます。mode 0 は各セルを点で表します。mode 1は点をつないで線にします。mode 2 は個々の点とゼロ軸の間に影をつけます。そして、双極形の mode 3 では影のエリアをゼロ軸に対する鏡像として描画します。

フレーム

qmetro をオフにして(toggle ボックスのチェックを外して)、basic visualization サブパッチを閉じて下さい。frame-based analysis という名前のパッチャーを開いて、中の toggle ボックスをクリックし、qmetro オブジェクトを始動させて下さい。


オーディオのフレームベースの分析を行ないます

frame-based analysis サブパッチは、最も最後のデータ以外は捨ててしまう jit.catch~ オブジェクトの機能をどのように利用できるかという例を示しています。jit.catch~ のシングルプレーン出力は jit.op オブジェクトに送られてそれ自身を掛けられ、入力される個々の要素は2乗されます。これが jit.3m オブジェクトに送られ、マトリックスの平均値はオブジェクトの中央アウトレットから sqrt オブジェクトへ送られます。この結果は、シグナルの実効値(RMS : 2乗の平均値の平方根)の値を計算したことになります。これはシグナルの強さを測る標準的な方法です。この値を、jit.brcosa オブジェクトの brightness アトリビュートのアーギュメントとして使用することにより、サブパッチはオーディオシグナルの強さをビデオイメージの明るさにマップしています。

このフレームベースの分析テクニックは、jit.catch~ オブジェクトが最後に受信した bang からその直前までの間の、オーディオシグナルの平均振幅の良好な推定値をもたらします。 peakamp~ オブジェクトは bang を受信するとその前の bang からの間に届いたシグナルの最大値を出力するものですが、これは、オーディオシグナルの振幅の推定に使うことができます。しかし、この方法は、ここで紹介した jit.catch~ によるテクニックに比べ、劣っている点が2つあります。第1は、受信される最大値が時間内のデータの1つの点にすぎないということです。この最大値は他のサンプルについての情報は何も提供してくれません。そして、該当の時間内のシグナルの強さをうまく表す値ではないかも知れないのです。一方で、データの全てのサンプルを考慮することは非常に重い処理になる可能性があります。このフレームベース分析サブパッチの qmetro はおよそ33 ミリ秒ごとに bang を出力します CDクォリティのサンプリングレート(44,100 サンプル/秒)では、これはおよそ bang1回ごとに 1455 サンプルになります。しかし、この jit.catch~ を使ってテクニックでは、最後の 512 サンプルだけを調べているため、結果として、正確さと効率のバランスを保っていると言えます。このようなパワーの節約による効果は、分析自体がより重い処理となるような状況では、より大きなものになります。例えば、フレームに対して FFT 分析を行なう場合などはそれにあたるでしょう。

qmetro をオフにして、frame-based analysis サブパッチを閉じて下さい。audio という名前のパッチャーを再び開き、パッチの最下部にある *~ オブジェクトに接続されたナンバーボックスに 0 を入力して下さい。生成されたシグナルは、もはやスピーカには送られなくなります。audio サブパッチを閉じ、processing audio with jitter objects という名前のパッチャーを開いて下さい。


Jitter オブジェクトを使ったオーディオデータ処理、結果はシグナルに再変換されます

jit.release~ オブジェクトは jit.catch~ の反対です。複数のプレーンを持つマトリックスがオブジェクトに入力されると、入力されたマトリックスのプレーンごとに1つずつの、複数のシグナルを出力します。jit.release~ オブジェクトの latency アトリビュートはシグナルとして出力するまえにどのくらいのマトリックスデータをバッファに入れておくかをコントロールします。 Jitter ネットワークが jit.release~ オブジェクトにデータを提供しているケースでは、より長いレイテンシ(latency)の場合、バッファがアンダーフローする可能性はより低くなります。アンダーフローとは、コンスタントな(シグナル駆動の)レートでデータを生成しなければならない jit.release~ オブジェクトに対し、イベント駆動 Jitter ネットワークでシグナルベクタに見合うだけのデータを供給できない状態を言います。

・サブパッチの中の toggle ボックスをクリックして、qmetro オブジェクトを始動させて下さい。サインウェーブにホワイトノイズ(noise~オブジェクトによって供給されています)がミックスされたものが聞こえるはずです。val $1 と書かれたメッセージボックスに接続されたナンバーボックスの値を変更して下さい。パッチからのサウンドの振幅に影響を与えている点に注目して下さい。

jit.catch~ jit.release~ の組み合わせによって、Jitter オブジェクトを使ったオーディオの処理を行なうことが可能です。このシンプルな例では、jit.catch~ jit.release~ オブジェクトの間にある jit.op オブジェクトが、オーディオの3つのチャンネル全てに同じゲインを効果的に掛け合わせています。オーディオの処理のために jit.catch~ jit.release~ の使用がより必要とされている例は、jit.forbidden-planet.pat というサンプルパッチで見ることができます。これは、Jitter でフレームベースの FFT 処理を行なっているものです。

速度の変化

qmetro を停止させ、サブパッチを閉じて下さい。interpolation release~ という名前のパッチャーを開いて下さい。

jit.release~ オブジェクトは2つのモードのうちの1つを選んで操作することができます。標準の mode 0 では、サンプルを直接オーディオレートで供給することを期待します。これは、CDクォリティオーディオでは、オブジェクトは平均で 44,100 の float32 の要素を毎秒受け取り、これらのサンプルを直接シグナルに置き換えることを意味します。しかし、mode 1 では、オブジェクトは内部バッファにどのくらいの数のサンプルが格納されているかに基づいて補間を行ないます。格納されているサンプルの再生時間が latency アトリビュートの値より小さい場合、jit.release~ はサンプルをよりゆっくりと再生します。オブジェクトのデータ受信が完全に停止すると、ターンテーブルのストップボタンを押した場合と良く似た方法で、再生が徐々に停止します。一方、内部バッファに必要とするより多いサンプルが存在する場合、jit.release~ はサンプルをより速く再生します。

この機能を、イベント駆動のネットワークから直接サウンドを生成するために使うことができます。interpolating release~ サブパッチは、これを行なう方法を示してくれています。このサブパッチャーの中で、jit.release~ オブジェクトを動かしているデータは、jit.buffer~ からデータを受信します。このオブジェクトは、MSP の buffer オブジェクトへのメッセージを使って、オーディオサンプルからマトリックスのフォームの中へデータを展開することを可能にしてくれます。jit.buffer~ オブジェクトは基本的に標準の buffer~ オブジェクトに対する Jitter のラッパーです。 jit.buffer~buffer~ が受信できるメッセージを受け取ることが、buffer~ データの取得とセッティングをマトリックスの形で行なうことができます。さらに、このパッチの右側の jit.pwindow オブジェクトで使っている、2次元で波形データをビジュアライズする際に効果的ないくつかの機能を提供します。loadbang を受け取った時に、この jit.buffer~ オブジェクトはサウンドファイル talk.aiff からデータをロードします。

・サブパッチの qmetro オブジェクトに接続されている toggle ボックスをオンにして下さい。 period、および length ratio と表示されたナンバーボックスと、start と表示された hslider オブジェクトによって再生をしてみて下さい。


Jitteの中で、サウンドファイルからのオーディオデータを補間して再生します

qmetroの速さは、jit.buffer~ オブジェクトからのデータが、どのくらいの頻度で jit.release~オブジェクトに送られるかを決定します。一番上にある構造によって、jit.buffer~ から出力される周期とサンプル数の比率が維持されます。スタートポイント、長さの比、出力間隔による検証作業は、jit.release~ のこのモードで可能なサウンドのタイプについてのセンスを与えてくれるでしょう。

まとめ

このチュートリアルでは、MSP のシグナルデータを、 Jitter マトリックスとして格納、ビジュアライズ、出力、読み込みを行なうオブジェクトとして、jit.catch~jit.graphjit.release~jit.buffer~ を紹介しました。jit.catch~ および jit.release~ オブジェクトは、イベントレートでMSP シグナルをJitter マトリックスに変換、および逆変換することを可能にします。jit.graph オブジェクトは1次元マトリックスデータを2次元にプロットするために幾つかの方法を提供し、オーディオデータのビジュアライゼーションを理想的なものにしてくれます。jit.buffer~ オブジェクトは、MSP の buffer~ sオブジェクトとお案じ方法で動作し、サウンドファイルから直接オーディオデータをJitter マトリックスにロードすることを可能にしてくれます。