チュートリアル18:
データコレクション

イントロダクション

このチュートリアルでは、Max の中でも非常に役に立つ2つのオブジェクト、coll と route について説明します。coll オブジェクトによって、データをインデックス付きのコレクションとして扱うことが可能になります。これは、メッセージデータのための小さくて実行速度の速いデータベースであると考えることができます。route オブジェクトも、インデックス付けの概念と結びついたものです。これは、リストのインデックス(最初のエントリ(項目))に基づいて、特定のアウトレットからデータを送信します。

インデックス付きのデータは情報の複雑なルーティングを行なう場合に、非常に役に立ちます。データを使いやすくするために、あらかじめインデックス付けされていることもよくあります。MIDI コントローラは通常コントロールナンバでインデックス付けされます。これに対し、ノート情報はMIDI チャンネルによってインデックス付けされます。データにインデックス付けを行なうことは、複雑なパッチの中でのメッセージ送信の手助けとなります。インデックス付けのシステムを作ることにより、データを無差別に送信しながら、route オブジェクトを使ってこのインデックスを検索し、これを解釈して、必要な場所にデータを送信することができます。

coll の基本的な操作

チュートリアルを開いて下さい。

このチュートリアルには、小さいサイズから中くらいのサイズまでのいくつかのパッチがあり、チュートリアルのインターフェイス全体に散在しています。まず、左上のパッチから見ていきましょう。

最初のパッチ(1 と表示されています)は、coll オブジェクトを紹介するものです。coll オブジェクトには3つのメッセージボックスが接続されています。3つともクリックすると、coll オブジェクトは3組の値を読み込みます。coll に格納されている値を見るための最も簡単な方法は、coll をダブルクリックすることです。ダブルクリックすると、編集ウィンドウが開き、最初の数値がインデックスとして、2番目の数値が値として格納されているのを見ることができます。プログラムでこの値を取り出すためには、coll のインレットにインデックスの値を送信します。すると、そのインデックスの場所に格納されていた値(または複数の値)が出力されます。ナンバーボックスを使って coll オブジェクトに 0 を送信すると、coll オブジェクトから 20(インデックス位置 0 に格納されている値)が出力されます。1 と 2 では、それぞれ -50 と 33 が出力されます。これが、最も基本的で、最も一般的な、coll オブジェクトの使い方で、インデックス付きの値の組を格納するメカニズムとして使用するというものです。

2 と表示されたパッチは、少しだけ異なっています。ここでは、インデックスの値として数値ではなくシンボルを使っています。3つのstore メッセージボックスをクリックし、再び coll をダブクrクリックして、格納されているデータを見て下さい。データは最初の coll と同じですが、インデックスは数値ではなくシンボル(語)になっています。この後、左側のメッセージボックス(foo、bar、biz)をクリックすると、coll オブジェクトはシンボルそれぞれに対応した正しい値を出力します。

3番目のパッチで(3 と表示されています)では、すでにデータが格納されています。0 から 3 の間の任意の数を選ぶと、coll はそのインデックスに対応したデータを出力します。この例では、coll に格納されているデータは1つの数値ではなく、シンボルの文字列で(シェークスピアの「リチャード3世」の冒頭のセリフから引用しています)、これらはすべてリストとして出力されます。リストの先頭に set メッセージを付け加えると、その値をメッセージボックスで見ることができるようになります。

パッチャーの中にこのデータを保存しておきたい場合、coll オブジェクトのインスペクタでアトリビュートを設定しなければなりません(この例では、あらかじめ設定してあります)。パッチャーをアンロックし、パッチ 3 の coll のインスペクタを開いて下さい。"Save Data With Patcher's Inspector" と表示されたアトリビュートが選択されていることに気がつくと思います。このアトリビュートがセットされていると、パッチを保存する際に、coll に格納された情報はすべてパッチファイルの中に書き込まれます。そして、パッチを再び開いたとき、すぐにこのデータにアクセスことができます。

coll を使った描画と演奏

パッチの中央の部分(セクション 4)では、coll を使って 描画と MIDI 演奏機能をコントロールしています。ここでは、coll は定義済みのデータと共にロードされています。しかし、このデータはパッチに保存されていたものではなく、データが保存されている外部ファイル EEG から読み出して、ロードされたものです。このファイル名は "eeg.txt" で、これが coll のアーギュメントとして使われています。このようにすると、coll が初期化される際に、このファイルのデータが読み込まれます。

パッチの上部には、シンプルで小さな「自動的にインクリメント(増加)する」カウンタのシステムがあります。生成される数値は、右上のナンバーボックスで指定された値を増分として、毎回、自動的に増加していきます。デフォルトでは、増分は1 で、これが + オブジェクトに設定されています。データファイルには18,000行以上のデータが保存されているため、この速さですべてのデータを演奏するには、かなりの時間を要します。ナンバーボックスの値を 15 に変える(これは、metro によって出力される1回の bang ごとの増加のステップを 15 にすることを意味します)と、EEG パターンがよりはっきりと認識できるでしょう。この数値ジェネレータの出力は coll からインデックス付きのデータを取り出すために使用され、取り出されたデータは描画用サブパッチと、シンプルなMIDI 演奏部分(makenote/noteout)に送信されます。MIDI 演奏部分では、この値を(MIDI で用いる 0 から 127 の範囲にスケールして)MIDI ノートとして用いているだけです。これに対し、Drawit というサブパッチでは、この値をスクロール表示される小さな円の垂直位置のオフセットとして使っています。(toggle を使って)metro をスタートさせ、様々な「増分(インクリメント)」の値をカウントに適用することによって、展開されるEEG データが変化することに注目して下さい。ファイルの先頭から再スタートしたい場合には、0 と書かれたメッセージボックスをクリックしてナンバーボックスの値を再び 0 にリセットします。

あらかじめcoll にデータを格納しておき、これを後で使用するというやり方は、大きなデータセットを扱う場合には最善の方法です。18,000以上のデータポイントを持っているこのEEG を保存する場合、これをパッチファイルに保存しようとすると、パッチファイルのサイズが非常に大きくなってしまいます。その代りに、coll に保存したデータをテキストファイルに保存して(write メッセージを使います)、実行時にcollに読み込む(アーギュメントを用いるか、reand メッセージを使います)ことができます。

5 と表示された、パッチの次の部分は、coll で使うことができるいくつかのトリックを示すものです。この coll は cues という名前を持っています。そして、パッチの残りの部分で処理される8個の異なるキューを管理しています(coll オブジェクトをダブルクリックすると、内部に格納されているキューを見ることができます)。接続されたナンバーボックスを使ってメッセージを送信することができますが、もう一つ、3つのメッセージボックスを使って各キューの間を移動し、切り替えることができます。start メッセージを送信すると、coll の最初の項目に移動します。next や prev メッセージを送信すると、次のキュー、または1つ前のキューに移動します。これにより、連続して coll の項目間を移動することができます。これは、エントリが連続した数値でなくても可能です。また、最後の項目に達すると、自動的にループして先頭に戻ります。これは、coll の内容をシーケンシャルに移動していくような処理を実装する簡単な方法です。ここでは、route オブジェクトに関してはまだ考えなくてよいでしょう。start、next、prev メッセージを使ってシーケンス内で移動を行ない、coll オブジェクトの出力によって様々なアクションがトリガされるようすを観察して下さい。

この右側には小さなパッチがあり、"cues" という名前の別の coll があります。この coll をダブルクリックすると、同じ内容が格納されていことがわかるでしょう。実際、この coll は前に取り上げた coll と同じ名前を持っているため、その coll の内容を共有しています。これは value オブジェクトが名前付けという方法でデータを共有することと良く似ています。情報を共有する名前付きの coll により、パッチ内、あるいはサブパッチ内の様々な場所にあるデータセットに、容易にアクセスすることができるようになります。

route によるメッセージのルーティング

右下の小さなパッチでは、route オブジェクトの機能を紹介しています。メッセージボックスをクリックすると、メッセージは識別子(リストの最初の項目)によって照合されます。識別子が route オブジェクトのアーギュメントの1つとマッチすると、そのメッセージは識別子を取り除かれ、残りのデータ(この場合には整数)が対応するアウトレットから出力されます。route オブジェクトはそれぞれのアーギュメントごとに1つのアウトレットを持っていて、最後のアウトレットからは照合できなかったメッセージが出力されます。このパッチでは、認識できないメッセージを受信した場合にどのようなことが起きるかを示しています。zeppo メッセージは、route オブジェクトに列挙されているアーギュメントとは異なるため、ルーティングを行なうことができません。この場合、メッセージを無視するのではなく、そのままの形で右アウトレットから出力されます。これは、場合によっては別の route オブジェクトで使用されたり、あるいはMax ウィンドウに表示するためにprint オブジェクトに(この例では、この方法を取っています)送信されたりします。

パッチの 5 という部分ではまた、route オブジェクトを使って coll からメッセージを取り出し、それを分析してパッチの中にある様々なオブジェクトでのアクションを実行しています。coll の内容を見ると、そのデータの中にはシンボル(m1、m2、m3、pick)とデータ項目(m1 から m3 というシンボルでは0/1、pickというシンボルでは bang)があります。route オブジェクトはこのメッセージを受信すると、最初の要素(シンボル)を使って出力のルートを決定し、メッセージの残りをアウトレットから出力します。従って m1 で始まるメッセージが第1アウトレットへ送られるのに対し、pick で始まるメッセージは第4アウトレットへ送られます。

start や next メッセージを使って、coll のキューを移動していくと、メッセージの最初の部分に基づいてアクションのシーケンスが実行されるようすを見ることができます。metro オブジェクトがスタート、ストップされ、random オブジェクトが 2 回トリガされます。route オブジェクトが、未分化のメッセージの内容を受け取り、それをふさわしい場所にルーティングするという場合に役に立つということが理解できるのではないかと思います。

結び

coll オブジェクトは、インデックス付けされたメッセージとデータを扱うためのパワフルな手段となります。このオブジェクトは、特定のメッセージや、coll の項目間をシーケンシャルに移動するためのメッセージを受け取ります。名前付きのcoll オブジェクトの間では、coll の内容を共有することができます。これを使うと、パッチのあらゆる場所でこのデータにアクセスすることができるようになります。また、coll はデータを外部ファイルから読み込むこともできます。さらに、route オブジェクトによって、メッセージの内容に基づいた、メッセージの追跡と移動を行なうことができます。これは、インデックスに基づいて、様々なオブジェクトに送信しなければならないデータをルーティングするための手助けとなります。

参照

coll データの多くの「かたまり」として格納するコレクション
route メッセージや数値を様々なアウトレットに振り分けます。