/**/

チュートリアル 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.filloffset アトリビュートを設定することによって、リストをマトリックスの任意の位置に送ることができます。パッチの2.の部分ではoffset機能の使い方を紹介しています。


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

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

toggle をクリックして 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 オブジェクトは個別なスライダのグループを表示し、すべてのスライダの位置をリストとして一度に出力します。全体のリストは、スライダのどれか1つを動かすためにウィンドウの中でクリックを行ったときに出力され、さらにマウスボタンから手を離した時にも再度出力されます。このパッチのパート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.matrixsetcellgetcell というメッセージを送る方法を使うことができます。しかし、これを行う別の手段として、メッセージをリストとして集め、jit.fillによってそれらすべてを一度にマトリックスに置くという方法があります。

zl オブジェクトは、個々の数値をリストとして集める手助けを行なうことができる、多機能なリスト処理オブジェクトです。このオブジェクトの動作には多くのモードがあり、最初のアーギュメントによって指定されます。最初のアーギュメントが group の場合、zl は左インレットで受信したメッセージを集めて、指定された個数に達するまで貯えておき、それらの数値を1つのリストとして出力します(値は受信した順序でグループ化されます)。したがって、パッチのパート4にある zl group 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 のインタラクション(相互作用)についてはチュートリアルの後の章で詳しく調べていきます。

訳注:現バージョンでは、OMS は必要ありません。システムの標準MIDI機能(Max OSX の Core MIDI、Windows の MMEなど)で使用できます。詳しくは、Maxファンダメンタルの「MIDIの使用」などを参照して下さい。


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

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

zl のリストの長さ(List Length)、および jit.filloffset アトリビュートによる場所の設定(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 個の jit.fill を使用し、それぞれが "colorbox" マトリックスの異なるカラープレーンを扱うように設定しています。


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

・3つの色分けされた multiSlider オブジェクトをドラッグして、3つのカラープレーンのそれぞれに書き込みを行って下さい。

これは、マトリックスのRGBプレーンの強さの様々なカーブを生成するための便利な方法です。マトリックスを表示している jit.pwindow は、実際には256ピクセルの幅を持っていて、マトリックスの64個のセルそれぞれは4ピクセル幅の帯域で表示されています。jit.pwindowinterp アトリビュートをオンにすると、隣り合った帯域の差が補間によってなめらかになります。

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


前の例と同じですが、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 方向のオフセット と y 方向のオフセットを表す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.spilllistlengthoffset というアトリビュートを持っています。これらを使うことによって、何個の値をリストとして取り出すか、マトリックスのどの位置から取り出すかを正確に指定することができます。

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の左アウトレットからもたらされます)の順序を入れ替えています。そして、そのセルの値を y 値として table オブジェクトに格納するために、セルのインデックスを 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つの要素によるリストになります。


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

jit.iterは、1次元マトリックスや小さな2次元マトリックス、あるいはより大きなマトリックスの特定の値やパターンを探す場合など、マトリックス全体をスキャンするために便利なオブジェクトです。

まとめ

個別の値をマトリックスに書き込んだり、マトリックスから取り出したりするためには、 jit.matrix に対してsetcellgetcell メッセージが使用できます(チュートリアル2で示しています)。値のリスト全体をマトリックスに書き込んだり、マトリックスから値のリストを取り出したりするためには、jit.filljit.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 に送ります。