チュートリアル11

リストとマトリクス


このチュートリアルでは、Maxのリストを使ってマトリクスの全部、または一部にデータを書き込む方法について、また、マトリクスの全部、または一部の内容をリストとして取り出す方法についてご説明します。さらに、マトリクスの名前を使って、その内容にリモート(遠隔的)にアクセスする方法についても御紹介します。このコンセプトについては、さらにチュートリアル12、16、17においても御紹介します。


マトリクスの名前

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

パッチの左上隅の黄色の領域に、青いjit.matrixオブジェクトがあるのがわかると思います。最初のアーギュメントはマトリクスにsmallboxという個別の名前を与えるものです。他のアーギュメントは、マトリクスが、1つのプレーンを持つcharデータ型で、1つの次元しか持たずセルの数が12であることを表わしています。


このマトリクスは固有な名前-smallbox-を持っています

チュートリアル2で全てのマトリクスには名前を持っているということをご説明しました。マトリクスに対して明示的に名前を与えない場合、Jitterは任意に名前を選びます(通常は、名前が固有のものになるようにするために、"u040000114"といったような奇妙なものになります)。この名前は、マトリクスの中身が格納されている、コンピュータ内のメモリの場所を参照するために利用されます。それでは、なぜマトリクスに私たちが選んだ名前をつけるのでしょうか?こうすると私たちはその名前をよく知っているわけですから、他のオブジェクトに対してマトリクスの中身の見つけ方を容易に指示することができます。マトリクスの名前を参照することによって、オブジェクトはデータを共有することができ、実際にjit_matrixメッセージを受信しなくても、マトリクスの中身にリモートでアクセスすることができます。

Jitterの、メモリ位置を参照するためのマトリクス名の使い方は、Maxのvalueオブジェクトの働きと類似しています。同じ名前をもつvalueオブジェクトをたくさん作ることができ、そのうちのどれか1つのに数値を格納して、同じ値を他のどれからでも取り出すことができます。しかし、実際には、その名前のついたメモリの場所が1か所あるだけなので、多くのvalueが同じデータを共有できるのです。同様な方法によって、同じ名前を持つ複数のjit.matrixを作ることができ、それらすべては同じデータを共有します。
jit.fillのような、いくつかの他のオブジェクトはマトリクスの名前を知るだけで、その中身にアクセスできます。


jit.fillオブジェクト

チュートリアル2では、setcellメッセージを使ってマトリクスの特定の場所に数値を置く方法や、getcell メッセージによって特定の場所の中身を取り出す方法を見てきました。ここでは、jit.fillオブジェクトを使って値のリストをまるごとマトリクスに置く方法を見ていきます(この章の後の方では、マトリクスから一度に多くの値を取り出す方法についても見ていきます)。

パッチの左上隅に12の数値によるリストを持ったメッセージボックスがあり、jit.fill smallbox オブジェクトに接続されています。このsmallboxアーギュメントはマトリクスの名前を指しています。


jit.fillは、名前を持ったマトリクスに値のリストを入力します。

・メッセージボックスをクリックして、値のリストをjit.fill smallboxオブジェクトに送って下さい。 jit.fill smallboxオブジェクトはこれらの値を"smallbox"と名付けられたマトリクスに置きます。本当かどうか確かめるために、jit.matrix smallboxオブジェクトの上にあるbuttonをクリックして、 "smallbox" マトリクスの内容を表示させて下さい。jit.printによって値がMaxウィンドウに表示され、 jit.pwindowにグレーレベルとして表示されます。

この例では、リストはマトリクス全体を満たすことができるように、マトリクスと全く同じ長さを持っています。しかし実際には、そうである必要はありません。、1Dまたは2Dのマトリクスの中の隣接したどのような部分に、どのような長さのリストを置くことも可能です。

offsetアトリビュート

jit.fillは、デフォルトの設定では、値のリストをマトリクスの最も最初の位置に置きます。しかし、 jit.fillのoffsetアトリビュートを設定することによって、リストをマトリクスのどの位置にでも送ることができます。パッチの2.の部分ではoffset機能の使い方を紹介しています。


まず、offsetを指定し、それからリストを与えます

この例では、jit.fill grayboxオブジェクトへ送るoffsetメッセージのアーギュメントとして乱数を用いることによって、セルのインデックスをランダムに選んでいます。そして、grayboxマトリクスのそのインデックスの所から格納するための16個の要素から成るリストを送っています。

・トグルをクリックしてmetroオブジェクトをスタートさせて下さい。0.5秒ごとに、"graybox"マトリクスの新しい場所に16要素のリストが書き込まれます。ウィンドウの中央にあるjit.matrix graybox 1 char 256 オブジェトを見つけて下さい。その上のbuttonをクリックしてマトリクスの中身をjit.pwindowに表示させて下さい。


"graybox"マトリクスの4つの場所にリストが書き込まれています。

・clearメッセージによって"graybox"マトリクスの内容をゼロにすることができます。その後、再び表示をさせると、metroオブジェクトによってリストが新しいランダムな場所に書き込まれているのを見ることができます。終わりましたら、metroオブジェクトをオフにして下さい。

multiSliderオブジェクトを使う

これまでは、値があらかじめ決められているリストをマトリクスに置く方法を見て来ました。このようなリストの数値をMaxでインタラクティブ(対話的)に生成し、それらをマトリクスにリアルタイムで書き込みたい場合には、リストを組み立てるために設計されたMaxオブジェクトを使う必要があります。このような2つのオブジェクト、multiSliderzlについて見てみましょう。

multiSliderオブジェクトは個別なスライダのセットを表示し、すべてのスライダの位置をリストとして一度に出力します。全体のリストは、スライダのどれかを動かすためにウィンドウ内でクリックを行った時に出力され、さらにマウスボタンから手を離した時にも再度出力されます。このパッチのパート3では、 multiSliderが256個のスライダを持ち、それぞれが0〜255の値を出力するように設定してあります。そのため、256個のcharの値からなるリストをjit.fill grayboxオブジェクトに正しく送信できるようになっています。

multiSliderの中をマウスでドラッグし、256個のスライダをセットして下さい。マウスボタンを離す時に、256個の値からなるリストがjit.fill grayboxオブジェクトに送信されます。マトリクスセルの輝度がスライダの高さとどのように対応しているかをよく見て下さい。

jit.fillはインレットにリストを受け取るとすぐに、名前で指定されたマトリクスのoffsetアトリビュートで指定された位置にその値を書き込みます。この書き込みが終わると、jit.fillは即座に左アウトレットからbangメッセージを出力します。このbangメッセージは、他のアクションのトリガとして使用することができます。マトリクスを表示させることなどもその一例です。

最初の2つの例では、あえてjit.fillの左アウトレットからのbangを使うことを避けました。それは、 jit.fillが、jit.matrixオブジェクトとの物理的な(パッチコードによる)接続をすることなく、名前で指定されたマトリクスに書き込みを行うことを、確実に明白なものにするためでした。けれども、この jit.fillの左アウトレットからのbangは、マトリクスが満たされたと同時にそのマトリクスを出力するトリガとして好都合なものです。

zlオブジェクトの使用

ある状況では、パッチのどこかで生じた数値メッセージ(MIDIメッセージやユーザインターフェイスオブジェクトからの数値など)を格納するためにマトリクスを使いたいと思うことがあるかも知れません。 jit.matrixにsetcell、getcellというメッセージを送る方法はそのために役立ちます。しかし、これを行う他の手段として、メッセージをリストとして集めjit.fillによってそれらすべてを一度にマトリクスに置くという方法があります。

zlオブジェクトは、個々の数値をリストとして集める手助けとなる、多機能なリスト処理オブジェクトです。このオブジェクトの動作には多くのモードがあり、最初のアーギュメントによって指定されます。最初のアーギュメントがgroupの場合、zlは左インレットで受け取るメッセージを集めて特定の個数に達するまで貯えておき、それらの数値を1つのリストとして出力します(値は受け取られた順序でグループ化されます)。従って、パッチのパート4にあるzl group 256オブジェクトでは、その左インレットで受け取った256個の値を集め、256個が受信された時点で左アウトレットから1つのリストとして出力される(同時にそれ自身のメモリをクリアする)ようになっています。

usliderを上下に動かして、zlオブジェクトへ送る256個の入力値を作って下さい。zlは256個の数値を受け取るとそれらをリストとしてjit.fill grayboxに送信し(jit.fillはそのリストを"graybox"マトリクスに書き込みます)、それからjit.matrix graybox 1 char 256 オブジェクトにbangを送ってマトリクスを表示させます。


zlは256個の要素を持つリストを"graybox"マトリクスに送り、 それが終わると
jit.matrixオブジェクトにbangメッセージを送って、結果を表示させます。

・コンピュータにOMSがインストールされていて、MIDIキーボードコントローラが接続されている場合には、MIDIキーボードのモデュレーションホイールを使ってusliderを動かすことができます。(MIDIとJitter のインタラクション(相互作用)についてはチュートリアルの後の章で詳しく調べていきます。)


値は0〜254の範囲をとるように2倍され、マトリクスのためのcharデータとして実用的なものにされます

List Lengthという表示のあるナンバーボックスからzlの右のインレットへ新しいリストの長さを送信することによって、zlの集めるリストの長さを変更することができます。また、Locationいう表示のあるナンバーボックスからjit.fillにoffsetメッセージを送ることによって、マトリクスのどの部分にデータを書き込むかを指示することができます。リストの長さと場所を変えることで、好きなだけの個数の値を、マトリクスのあらゆる隣接した領域に置くことが可能になります。

・zlのリストの長さ(List Length)、及びjit.fillのoffsetアトリビュートによる場所(Location)の設定を変更(List Lengthを100、Locationを50など)し、再びusliderを動かして値のリストをマトリクスの指定した場所に書き込んで下さい。

・パッチのパート2、3、4を組合わせることによって、様々な方法で"graybox"マトリクスに書き込みを行うことができます。

マルチプレーンマトリクスに対するjit.fillオブジェクトの使用

jit.fillは、マルチプレーン(複数のプレーンを持つ)マトリクスにおいても問題なく動作します。しかし、一度に書き込むことができるのは1つのプレーンだけです。jit.fillがアクセスするプレーンはplaneアトリビュートによって指定されます。パート5では別のマトリクスを用意してありますが、これは4つのプレーンを持つcharデータ型でcolorboxと名付けられています。


個々のプレーンに別々に書き込みを行います

・3つの色分けされたmultiSliderオブジェクトをドラッグして3つのカラープレーンのそれぞれに書き込みを行って下さい。
これは、マトリクスのRGBプレーンの様々な輝度のカーブを生成するための便利な方法です。マトリクスを表示しているjit.pwindowは実際に256ピクセルの幅を持っていて、マトリクスの64個のセルそれぞれは4ピクセル幅の帯域で表示されています。jit.pwindowのinterpアトリビュートをオンにすると、隣り合った帯域の差が補間によってなめらかになります。

・interp $1 というメッセージボックスの上にあるtoggleをクリックして、jit.pwindowにinterp 1というメッセージを送って下さい。(同時に、jit.matrixに対してbangメッセージを送り、中身を再表示させている点に注意して下さい。)


前の例と同じですが、jit.pwindowの補間機能がオンになっています


2Dマトリクスでのjit.fillオブジェクトの使用

これまでの例はすべて、1次元のマトリクスを持つものでした。では、jit.fillによって2次元のマトリクスにリスト(これは1次元の配列です)を書き込もうとした場合、どんなことが起きるでしょうか?jit.fillオブジェクトはリストを使ってできるだけ最初の次元(すなわちできるだけ指定された行)にリストを書き込もうとします、そしてさらに次の行に回り込み、その行の先頭から書き込みを続けます。ここでは、この「ラッピング(回り込み)効果」 の動作を見ることができるようにしてあります。

・2Dというラベルのあるbuttonをクリックして下さい。これによってjit.matrix colorbox オブジェクトは8×8の2次元マトリクスを持つように変えられ、jit.pwindowはよりふさわしい形にサイズを変更されます。マトリクスの次元を変更すると持っていたデータは失われるので、新たにマトリクスに書き込みを行うために再度3つのmultiSliderをもう一度クリックする必要があります。ここでは、依然として64個の要素からなるリストをそれぞれのjit.fillオブジェクトに送信しているのですが、これらのリストはそれぞれ1行に8つの要素を持つ8行のマトリクスを満たしています。

重要:このパッチでは2Dマトリクスに対するoffsetアトリビュートの使用法についてはご説明していませんが、jit.fillのnameアトリビュートが2Dマトリクスを指定している場合、offsetアトリビュートが、x offset と y offset の2つのアーギュメントを要求するということを記憶しておくことは大切です。

Jit.fillは1D及び2Dマトリクスでのみ動作します。



同様な例ですが、個々のリストが8×8のマトリクスを「ラッピング」しています


同様な例で、補間を行って表示しています。


jit.spillオブジェクト

jit.fillと相補的な関係にあるのがjit.spillオブジェクトです。これはインレットにjit_matrixメッセージを受け取り、左アウトレットからMaxのリストとして出力します。パッチのパート5を使っている時にお気付きになったかもしれませんが、パート6にあるjit.spillオブジェクトはプレーン1(赤)の値を左アウトレットから出力し、メッセージボックスの内容をセットしています。


Maxのリストとして表示されている、"colorbox"マトリクスのプレーン1の内容

パッチでは示されていませんが、jit.spillはlistlengthとoffsetというアトリビュートを持ってます。これらを使うことによって、何個の値をリストとして取り出すか、マトリクスのどの位置からとりだすか、を正確に指定することができます。

1つのリストメッセージではなく、独立した数値メッセージの流れとして値を即座に取り出す必要がある場合リストをMaxのiterオブジェクトへ送ります。


マトリクスからいくつかの値を取得して、それらを別々のメッセージにしています

jit.iterオブジェクト

マトリクスのすべての値を取り出す必要がある場合のために、jit.iterと呼ばれるオブジェクトがあります。これは、インレットにjit_matrixメッセージを受け取ると、可能な限り素早くメッセージのシーケンスを送りだします。これは、セルインデックス(中央アウトレットから出力)、それからそのセルの値(左アウトレットから出力)という形で、マトリクスの全てのセルごとに順に出力されます。大きなマトリクスでは、これはMaxスケジューラの1つのtickで送りだそうとするには、あまりに凄まじい量のメッセージになってしまう可能性があります。そのためマトリクス内のすべての値の報告が終わった段階で、jit.iterは右アウトレットから終了(done)メッセージを送信します。

パッチのパート7には、jit.iterオブジェクトがあり、jit.matrix graybox 1 char 256 オブジェクトからマトリクス情報を受信しています。ここでは、swapオブジェクトを使ってセルインデックス(jit.iterの中央アウトレットからもたらされます)とセルの値(jit.iterの左アウトレットからもたらされます)の順序を入れ替えています。そして、これをtableオブジェクトに格納したいため、そのセルの値をy値として、セルインデックスをtableのx軸インデックスとして使用しています。

multisSliderオブジェクトをクリックして、その内容をjit.fillに送って下さい。(jit.fillは、書き込みが終わるとjit.matrixオブジェクトにbangを送り、その内容をjit.iterに伝えます。tableオブジェクトをダブルクリックしてグラフィックウィンドウを開き、それが"graybox"マトリクスと同じ値を持っていることを確認して下さい。

この、jit.iterを使ってtableに書き込むというテクニックは、table自身が1次元の配列であるため、あまり大きくない1次元、1プレーンのマトリクスに対してうまく働くものであるという点に注意して下さい。しかし、例えば、jit.qt.movieオブジェクトのマトリクスは2つの次元と4つのプレーンを持っているので、こういった場合、jit.iterの中央アウトレット出力(セルインデックス)は2つの要素によるリストになり、左アウトレット出力(値)は4つの要素によるリストになります。


これらの数値すべてを使って、何をしましょうか?


1次元マトリクスや小さな2次元マトリクス、あるいはより大きなマトリクスの特定の値、またはパターンを探す場合に向いているとはいえ、jit.iterはマトリクス全体をスキャンするために役立つものです。


まとめ

個別の値をマトリクスに書き込んだり、マトリクスから取り出したりするためには、jit.matrixに対してsetcell及びgetcellメッセージが使用できます(チュートリアル2でご覧になったとおりです)。値のリスト全体をマトリクスに書き込んだり、マトリクスから値のリストを取り出したりするためには、jit.fillとjit.spillというオブジェクトを使います。これらのオブジェクトは1Dまたは2Dのどのプレーンに対しても十分に働きます。そして、あらゆる長さのリストを、マトリクスのどのセル位置からスタートするようにでも指定できます。

multiSlider及びzlオブジェクトは、リアルタイムにMaxリストメッセージを組立てる場合に役立ちます。 multiSliderを使うと、マウスでスライダ上をドラッグしてリストを「描く」ことができます。zl group を使うと、多くの個別の数値を1つのリストとして集め、それらすべてを一度にjit.fillへ送ることができます。

マトリクスの中のスタート位置の指定は、jit.fill(またはjit.spill)のoffsetアトリビュートを使用して行います。jit.fillオブジェクトは、書き込む対象となるマトリクスの名前を指定する、nameアトリビュートの設定(name [名前] メッセージとして送るか、初期値のアーギュメントとして[名前]を指定します)を必要とします。jit.fillはこの名前を使ってマトリクスにアクセスし、マトリクスにリストを書き込むとアウトレットからbangメッセージを出力します。このbangメッセージは他のアクションのトリガとして使用することができます。チュートリアル12、16、17では、マトリクスに対する名前でのアクセスの実用的な使用法をいくつか御紹介します。

マトリクス全体の値をすべて個別に出力させたい場合には、マトリクスをjit.iterに送ります。