チュートリアル16

名前を持ったJitterマトリクスを使う


このチュートリアルでは、複数のソースからのデータを同じマトリクスに書き込む場合、jit.matrixオブジェクトのnameアトリビュートをどのように使ったらよいかということについて学びます。さらに、新しいマトリクスへコピーをする際にマトリクスのサイズをどのようにスケール(拡大・縮小)するかについて、また、 より時間のかかるタスクに合わせてMaxイベントの優先順位を下げるために、Maxの低い優先順位のキューを使う方法についても見ていきます。

・Jitter Tutorialフォルダの16jNamedMatrices.patというチュートリアルパッチを開いて下さい。

チュートリアルパッチは5つの色分けされた領域に分かれています。中央(ライトブルー)の領域には2つのjit.qt.movieオブジェクトがあります。パッチが開かれる際、loadbangオブジェクトによって、2つのムービー(rain.movとtraffic.mov)がjit.qt.movieオブジェクトに読込まれます。


ムービーの読込み

これまでに見て来たチュートリアルパッチと異なり、このパッチのjit.qt.movieオブジェクトはsend およびreceiveオブジェクトを使って、パッチの他の部分との通信を行います。m1とm2という名前をm持つreceiveオブジェクトは2つのjit.qt.movieオブジェクトにメッセージを送ります。2つのオブジェクトが出力するマトリクスは(sendオブジェクトを使って)パッチ内にあるmovie1とmovie2という名前のreceiveオブジェクトに送られます。

パッチ上部の黄色の領域には、パッチのJitter処理を駆動するためのmetroオブジェクトがあります。


metro
オブジェクトは2つのメッセージボックスの片方を動作させます。


・トグルボックスをクリックしてmetroをスタートさせて下さい。パッチ内の3つのjit.pwindowオブジェクトでイメージの表示が始まります。


重要な順序

metroオブジェクトはGgateオブジェクト及びjit.qball(これについては後ほど説明します)と呼ばれるオブジェクトを経由してgateオブジェクトに接続されています。metroによって出力されるbangメッセージはgateによって2つのメッセージボックスオブジェクトのうちの1つにルーティングされます。最終的な出力マトリクス(パッチの一番下にあるjit.pwindowオブジェクトに表示されます)はどちらのメッセージボックスがbangメッセージを受け取るかによって変更されます。

gateの左インレット(1と2)に接続されている2つのメッセージボックスをクリックして下さい。一番下のjit.pwindowがどのように変化するかに注意して下さい。


最終的な出力マトリクスはパッチ内のメッセージの順序によって変化します


2つのメッセージボックスオブジェクトは、同じように3つの名前(m1、m2、output)を持った receiveオブジェクトにbangメッセージを送信します。2つのメッセージボックスでは、メッセージを送る順番が違います。左のメッセージボックス(gateが1にセットされた場合にmetroによって動作)は、最初にm2というラベルのreceiveオブジェクトに、その後m1というラベルのreceiveオブジェクトに、そしてoutputというラベルのreceiveオブジェクトにbangメッセージを送信します。これによって、まず右のjit.movieオブジェクト(道路の情景を読込んでいる)がマトリクスを出力し、左のjit.movieオブジェクト(雨の映像を読込んでいる)がそれに続きます。最後にパッチの一番下にあるjit.matrixオブジェクトがbangメッセージを受け取り最終的なマトリクスが出力されます。右のメッセージボックス(gateが2にセットされた場合にmetroによって動作)では、jit.qt.movieオブジェクトを動作させる2つのbangメッセージの順序が逆になっています。(左のjit.qt.movieが最初にマトリクスを出力し、右のjit.qt.movieオブジェクトがそれに続きます。)

これらのメッセージが発生する順序は、2つのjit.qt.movieオブジェクトと最後のjit.pwindowオブジェクトの間で起こることを見る場合にのみ重要になります。

Name(名前)とは?

2つのjit.qt.movieオブジェクトは、bangメッセージを受信するとそれぞれ下にあるsendオブジェクトにマトリクスを出力しますが、これらは順番にmovie1とmovie2という名前のreceiveオブジェクトへマトリクスを送信します。2つのreceiveオブジェクト(パッチの右側にある同じような2つの領域にあります)は2つの名前付きのjit.matrixと同様、jit.pwindowにも接続されています。


名前を持ったjit.matrixオブジェクト

パッチの右側にある2つのjit.matrixオブジェクトは(パッチの下部の最終的なjit.pwindowの上にあるjit.matrixオブジェクトと同じ)名前(name)を持っています。この3つのオブジェクトにつけられた名前はcompositeです。その結果、3つのjit.matirixオブジェクトはcompositeという名前のJitter マトリクスを中身とする同じマトリクスデータを共有します。

2つのjit.qt.movieオブジェクトが(同じ名前を共有する別々のjit.matrixオブジェクトを経由して)同じJitterマトリクスにデータを書き込んでいるということが判ってしまえば、bangメッセージの順序が重要である理由は理解できると思います。左のjit.qt.movieが最初にマトリクスを出力する場合、この jit.qt.movieがcompositeマトリクスにデータを書き込み、その後右のjit.qt.movieが同じマトリクスに書き込みます。もし、この2つのマトリクスが共通するセルに書き込みを行ったとすると(下記参照)、最後に到着したマトリクスがすでにセルが持っているデータを上書きします。

重要な注記:Maxパッチの中で起こっていることの順序について確信が持てない場合、パッチの処理がどのように実行されているかを見るために「トレース」を行うことができます。TraceメニューのEnableコマンドを選択し、metroオブジェクトをオンにすると、ステップコマンド(command + [t])によるステップスルー(訳注:段階ごとに処理を見ていくこと)によってパッチがどのように処理をしていくかを見ることができます。(トレース機能を使ったMaxメッセージのトレースに関する詳細は、Max Tutorials and Topicsマニュアルの「Debugging」の章を参照して下さい。)



ディスティネーション(送り先)の大きさ

チュートリアルパッチの右側にある2つのjit.matrixオブジェクトは、usedstdimアトリビュートが1に設定されています。これによって、jit.qt.movieオブジェクトから送られて来るマトリクスをスケールしcomposite Jitterマトリクスの特定の領域だけに書き込むことができます。

p coords と表示された2つのサブパッチに接続されているx origin、y origin、scaleというナンバーボックスオブジェクトをいろいろ試してみて下さい。compositeマトリクスの中に表示されている jit.qt.movieからの2つのイメージのサイズ変更や移動がどのようにしたらできるのかという点に注意して下さい。


画像の中の画像

サブパッチp coordsには、jit.matrixオブジェクトに送るdstdimstartおよびdstdimendアトリビュートをフォーマット(形式化)するための同じヘルパー・パッチが含まれています。これらのアトリビュートはそれぞれ、composite Jitterマトリクスにデータをコピーする際に使う範囲の左上隅と右下隅の座標値を指定します。usedstdimアトリビュートは単に、jit.matrixがデータをコピーする際にこれらのアトリビュートを使うよう指示しているだけです。usedstdimが0に設定されていると、入力されたマトリクスは jit.matrixオブジェクトが参照するマトリクス全体を満たすようにスケールされます。


入力されるマトリクスは共有マトリクスに書き込まれる前にスケーリングされます

サブパッチに送信した3つの数値はMaxオブジェクト内部でフォーマットされ、入力マトリクスを置こうとする出力マトリクス中の領域の左上と右下が書かれたリストが生成されます。アウトレットの前のメッセージボックスは$による代入を使って、リスト中の数値でアトリビュートに関連するアーギュメントを置き換えています。

2つのマトリクスがcompositeマトリクスに書き込まれた後、最後にbangメッセージがoutputという名前の receiveオブジェクトに送られます。


最終的な結果

チュートリアルパッチの一番下の領域には3番目の名前付きjit.matrixオブジェクトがあります。metro から送信されたbangはtriggerオブジェクトを通りますが、triggerjit.matrixにbangメッセージを送った後、直ちにclearメッセージを送信します。clearメッセージはcompositeという名前のJitterマトリクスの全てのセルを消去(値0)にします。マトリクスのクリアを行わないと、どれかのjit.matrixオブジェクトがdstdimstartおよびdstdimendアトリビュートの変更を行った場合、ムービーがその前に出力された場所がそのまま残される結果になってしまう可能性があります。


キューをジャンプする

パッチの一番上にあるjit.qballオブジェクトは、Maxが私たちの要求について行けないようなイベントにおいて、かけがえのないサービスを提供します。metroオブジェクト(50ミリ秒毎にbangメッセージを送信します)は3つの別々な処理を駆動しています(jit.qt.movieオブジェクトからの2つのマトリクスを名前を指定されたJitterマトリクスに書き込み、同時にデータを表示し、次の処理のためにマトリクスをクリアします)。jit.Matrixオブジェクトは内部のJitterマトリクス(このケースではcompositeという名前のマトリクス)にデータを書き込みますが、書き込みは次のメッセージによって処理が奪い取られる可能性をはらんだ方法で行われます。さらに、タスクが実行されている時に、高い優先順位によってスケジューリングされた他のMaxイベントが生じる可能性もあります。このことから、前の命令(動作)が完了する前にマトリクスの表示(あるいはマトリクスへのデータの書き込み)が行われ、画面のフリッカー(ちらつき)や他の予想外の結果を引き起こす可能性が生じます。jit.qballオブジェクトは、オブジェクトに入力されたメッセージをMax の低い優先順位をもつキューの最後に置きます。ここではこのメッセージ自身もまた他のメッセージによって処理を「奪い取られる」可能性があります。この方法では、jit.qballmetroからbangメッセージを受け取った時点で全てのJitterのタスクが完了していない場合、qballは低い優先順位を持つキューの全ての命令が完了するまで待ち、その後bangを送信することになります。同様に、最初のbangが送信される前に他のbangが到着した(すなわちパッチの他の部分の全ての処理完了するまでに50ミリ秒以上かかってしまった)場合、最初のbangは処理を奪いとられ(捨てられ)」て2番目のbangに処理を譲ります。こうすることによって、イベントの累積が速すぎてオブジェクトの動作が維持できないのではないかという心配をせずに、イベントの最大のレート(速さ)を仮定してMaxパッチの中で設定することができます。

・"jit.qball bypass switch"と表示されたGgateをクリックして、metroオブジェクトの出力が jit.qballオブジェクトをバイパスするようにして下さい。パッチの下部にあるjit.pwindowの中の合成されたイメージがちらつき始めると思いますが、これはメッセージの到着が限度を超えていることを示しています。

通常、Jitterオブジェクトにbangメッセージを送ると、そのオブジェクト内の未了のイベント(例えば、すでの到着しているが、まだオブジェクトによって取り扱われていないbangメッセージ)の処理を「奪い取り」ます。それに対して、jit.qballオブジェクトは、このような制御をJitterオブジェクトの複数のチェーンに関して行い、自動的にイベントを「奪い」(「フレーム落ち」を生じます)メッセージが正しい順序で到着することを保証します。


まとめ

複数のjit.matrixに1つの名前を付けることによって、パッチの異なった部分で共通のJitterマトリクスへの書き込み、読み出しを行うことができます。jit.matrixオブジェクトが内部的に持つマトリクスにコピーを行う際、usedstdimアトリビュートを1に設定し、dstdimstart及びdstdimendアトリビュートを使うことによって、コピーしたいJitterマトリクスのスケーリングを行うことができます。jit.qballオブジェクトは、Maxイベントを低い優先順位のキューに置くことによって、その優先度を低くすることを可能にします。このキューでは、実行できるだけの時間がとれない場合、次のイベントによって処理を「奪われる」(イベントが捨てられる)可能性があります。