アルゴリズム作曲

1997年4月 長嶋洋一


1. アルゴリズム作曲環境 "MAX"

本項では、コンピュータ音楽の専門家の間では古典的となった(しかし一般にはあまり 馴染みがない)「アルゴリズム作曲」の概念について、作曲環境"MAX"での実例と ともに紹介する。作曲には、音響レベルから演奏情報、そして大きな構造まで色々な 階層があるが、ここではMIDIに代表される音楽演奏情報のレベルを具体的な対象と する。(なお、本項では「MAXを知らない人」を対象としているので、既に知っている 人は軽く読み流して、あとは参考文献[1][2]等を参照されたい。)

1.1 MIDI環境 "MAX" とは

MIDIはポピュラー音楽の世界では空気のような標準インターフェースである。 ステージ上でショルダーキーボードやMIDIギターやウインドMIDI楽器を演奏する ミュージシャンの演奏情報は、MIDIケーブルによって接続された、「MIDI音源」と 総称されるシンセサイザによって具体的な楽音信号となる。

そこで、このMIDI楽器とMIDI音源との間に、Macintoshを仲間入りさせる。 具体的には、MIDIケーブルをまずMacintoshのMIDIアダプタの入力側に接続し、 MIDIアダプタの出力側からMIDI音源へとさらにケーブルを接続する。 そして、パソコンショップならどこでも取り寄せてくれる "MAX" という Macintosh専用のソフトを入手して、MAX上で

というようなアイコンで表されたデータ(MAXではこれをパッチと呼ぶ) をダブルクリックする。そしてMAXが立ち上がり、画面にはこのデータに対応した 図1 のような「MAXパッチ」が走る。すると、何事もなかったようにその演奏 は同じように続けられる。つまりこのMAXパッチの走るMacintoshは、入力 されたMIDI情報をそのままMIDI出力として「スルー」している。

MAXのパッチを通常デフォルトで保存すると、

というようなバイナリデータとなるが、MAXのパッチを電子メイルで やりとりする時などは、プレインテキスト形式がより便利である。 その場合、「ファイル保存」の時に「テキスト形式」と指定すれば よい。たとえば図1のパッチは、

max v2;
#N vpatcher 166 163 494 436;
#P user hslider 93 166 18 128 128 1 0 0;
#P user kslider 19 203 35 1 36 48 19 7;
#P number 95 68 35 9 0 0 0 3;
#P number 125 102 35 9 0 0 0 3;
#P number 156 133 35 9 0 0 0 3;
#P newex 236 108 41 9 noteout;
#P newex 172 23 40 9 notein;
#P connect 0 0 4 0;
#P connect 0 1 3 0;
#P connect 0 2 2 0;
#P connect 0 0 1 0;
#P connect 0 1 1 1;
#P connect 0 2 1 2;
#P connect 3 0 6 0;
#P connect 4 0 5 0;
#P pop;

のようになる。このプレインテキストファイルをMAXから読み出せば、再び

のような画面でパッチが起動できる。 本項では、以降も同様に、紹介するMAXパッチは全てテキストファイル として付記することにする。

このパッチ "fig1" には、7個の「箱」の部品があり、それぞれが線で 繋がれている。これはグラフィカルなプログラミング環境であり、MAX以前の 時代にはC言語などで記述していた音楽演奏情報の処理アルゴリズムを、 直感的に、かつ効率的に実現できるようになったものである。

図1のパッチ例では、「notein」という箱(オブジェクトと言う)によって MIDI入力が得られると、この情報はとりあえずそのまま「noteout」と いうオブジェクトに直結されているので、入力情報は出力へとスルー される。 これと同時に、「notein」の左端の出力からはMIDIノートナンバ情報が抽出 されるために、これが変数ボックスで「60」と表示され、さらにこの情報は 鍵盤状のオブジェクトでグラフィカルにも表示されている。 また、「notein」の中央の出力からはMIDIノートイベントのベロシティ情報が 抽出されるために、これが変数ボックスで「100」と表示され、さらにこの 情報はスライダー状のオブジェクトでグラフィカルに表示されている。 「notein」の右端の出力からはMIDIチャンネル情報が抽出され、これが変数 ボックスで「1」と表示されている。この画面は、MIDIピアノで中央Cの鍵盤 を「100」のベロシティで打鍵した、というMIDI情報を入力した瞬間の 状態なのである。

このMAXパッチと同様の動作をするソフトウェアをパソコン上で作ってみる、 というのはなかなか重要なプログラミング演習の課題である。数値形式による MIDI情報の表示だけでなく、グラフィカルなパーツがリアルタイムに動く ところまで作れれば、なかなか凄いレベルである。腕に自信のある読者の チャレンジを期待しておこう。

1.2 ノンプログラミング環境 "MAX"

C言語にせよLISPにせよJavaにせよ、図1のアルゴリズムを実現する ソフトウェアの開発には、かなりの手間が必要となる。ところが筆者が図1の パッチを作るのに要した時間は30秒ほどである。この間、ほとんど何も余計な ことを考えることなく、アルゴリズムで実現したい音楽情報処理の中身だけを 頭に描いていられる。この意味は、アート的な要素だけでなく テクニカルな要素の大きなコンピュータ音楽においては、非常に重要である。

MAXのグラフィカルなオブジェクトは、ディスプレイ手段としてだけ使える ものではない。図1に少しだけ手を加えた、 図2 を見てみよう。筆者のパッチ開発期間は、これまた1分以下である。 このパッチには、直接MIDIに関係するオブジェクトは 「midiout」しかないので、これは全体としてはMIDI演奏情報を出す、 いわば一種の「楽器」として機能する。 実際、この手のMAXパッチを使って、ステージ上でマウスぐりぐりして ニヤニヤする、という「音楽パフォーマンス」活動をしている 人たちもいる。

このパッチ "fig2"

max v2;
#N vpatcher 335 74 656 350;
#P newex 100 231 50 9 noteout 1;
#P newex 88 193 50 9 makenote;
#P number 207 168 35 9 0 0 0 3;
#P user uslider 266 7 18 128 96 10 50 0;
#P number 129 125 35 9 0 0 0 3;
#P user dial 119 68 40 40 128 1 0 0;
#P number 37 121 35 9 0 0 0 3;
#P user kslider 25 20 35 1 36 48 19 7;
#P connect 2 0 3 0;
#P connect 1 0 6 0;
#P connect 3 0 6 1;
#P connect 5 0 6 2;
#P connect 0 0 1 0;
#P connect 6 0 7 0;
#P connect 6 1 7 1;
#P connect 4 0 5 0;
#P pop;

には、8個のオブジェクトがある。図1の例では ディスプレイとして使用された、鍵盤、スライダー、そして丸いダイヤル は、ここではマウスでクリックしたりドラッグすると任意の整数値を出力 する、人間からの入力インターフェースとして機能する。そして 「makenote」オブジェクトでは、左端の入力をMIDIノートナンバ、中央の 入力をMIDIベロシティ、そして右端の入力はノートオンとノートオフの時間差、 つまりdurationとして計算して、一つのノートナンバごとにちゃんとON/OFF の二つのMIDIイベントを自動生成してくれる。

グラフィカルな、あるいはインタラクティブなソフトウェアのプログラミング 経験を持つ読者であれば、このMAXパッチに相当するソフトをC言語などで開発 する苦労が予想できるだろう。ところがMAXでは、何もないキャンバスに箱を 並べてきて線で結ぶ、あるいは既存のパッチを呼び出してきて必要な部分 だけ変更することで、このような音楽情報処理をいとも簡単に実現できて しまうのである。これがMAXである。このアイデアを生み、そして実際に 開発して世界に提供したIRCAMの研究者には、限りない賛辞を送りたい。

百聞は一見に 如かず、ということで、興味のある読者はまずMacintoshとMAXを用意して、 実際に自分で体験してみることをお奨めする。コンピュータ音楽の世界の 大海に漕ぎ出す、最初の驚くべき一歩を経験することになるだろう。

1.3 シーケンサ

上記のようなMIDI情報の表示や入力だったら、楽器メーカの製品で色々と 出ているぞ、パソコンのMIDIソフトといえば、なんといってもシーケンサ だぞ、というDTMホビイストも多いことだろう。そこで、 図3 を見て欲しい。全てのMIDI入力を表す「midiin」を受けて、全てのMIDI 出力「midiout」に情報を与える「seq」というオブジェクトが中心に あるだけである。実はこれが、MAXに標準のMIDIシーケンサ処理を実現する オブジェクトである。MAXにはこのようなソフトウェア部品が数百個、 世界中の専門家からフリーで提供されている。

前述のセッティングでこのパッチ "fig3"

max v2;
#N vpatcher 108 92 444 296;
#P newex 110 160 50 196617 midiout;
#P message 244 68 52 196617 write;
#P message 243 37 52 196617 read;
#P message 22 17 31 196617 start;
#P message 73 17 30 196617 stop;
#P message 184 17 52 196617 start 512;
#P message 122 17 40 196617 record;
#P newex 19 84 50 196617 midiin;
#P newex 120 120 27 9 seq;
#P connect 0 0 8 0;
#P connect 7 0 0 0;
#P connect 4 0 0 0;
#P connect 3 0 0 0;
#P connect 2 0 0 0;
#P connect 5 0 0 0;
#P connect 6 0 0 0;
#P connect 1 0 0 0;
#P pop;

を走らせておいて、まずは マウスで「record」ボタンをクリックしよう。すると、その瞬間から入力MIDI イベントのリアルタイムレコーディングが開始されている。これは「stop」 ボタンを押すまで続く。 レコーディング後は「start」ボタンにより、記録された MIDI演奏情報がそのままMIDI出力される。「start 512」というボタンを 押せば、デフォルト値の1024の半分なので、半分のスローテンポで演奏情報 が再生される。シーケンサをプログラミングする時に煩雑なデータの バッファリングや時間管理は、まったく不要なブラックボックスなのである。

そしてこのパッチの「write」ボタンを押すと、この記録したMIDI演奏情報 をファイルとして保存するためのメニューが出てくる。もちろん、既存の MIDI演奏情報ファイルの読み込みは、「read」ボタンである。 readボックスに明示的にファイル名を指定することもできるので、 あらかじめ用意したシーケンスフレーズを次々に読み込んで再生演奏 する、などというのも簡単である。 この「seq」オブジェクトによって、MAX上では、どんな市販シーケンス ソフトのような動作も、自在にカスタマイズしてプログラミングできる のである。

このようにMIDIシーケンサとは、要するにMIDIイベントの記録できる テープレコーダのようなものである。いったん記録された音楽演奏情報 は、当然ながら何度「再生」しても、ハンで押したように同じである。 サカモトでもコムロでも、ポピュラー音楽やカラオケ音楽はこのシーケンサ が支えているが、本誌が対象としているコンピュータ音楽の世界では、 こんな「seq」オブジェクト1個で実現できるものは、ほとんど相手にして いない。もちろん、音楽の要素として必要に応じて利用するのであるが、 作曲のコンセプトの本質はもっと遠いところを指向している。 従って、本項でシーケンサについて述べるのは、これで終わりである。

1.4 ドラムマシン

本項の主眼である「アルゴリズム作曲」の検討に入る前に、もう一つだけ MAXのパッチ例として、「ドラムマシン」を構成した例を紹介しておこう。 図4 は、もっとも簡単な「8ビートのロックドラム」のパターンを生成する MAXパッチ "fig4"

max v2;
#N vpatcher 40 84 421 453;
#P number 64 42 35 9 0 0 0 3;
#P toggle 5 42 15 0;
#P user hslider 59 13 18 128 128 5 100 0;
#P newex 21 66 42 196617 metro;
#P newex 101 138 39 196617 % 16;
#P newex 32 137 30 196617 +;
#P message 24 113 20 196617 1;
#P button 22 89 15 0;
#P number 45 164 35 9 0 0 0 3;
#P newex 59 190 121 196617 select 1 2 3 4 5 6 7 8;
#P newex 196 190 156 196617 select 9 10 11 12 13 14 15 16;
#P newex 154 299 93 196617 makenote 100 50;
#P newex 167 326 63 196617 noteout 10;
#P message 274 259 26 196617 38;
#P message 227 260 26 196617 35;
#P message 172 261 26 196617 44;
#P message 124 260 26 196617 42;
#P message 74 261 26 196617 57;
#P message 319 260 26 196617 46;
#P connect 15 0 11 0;
#P connect 12 0 13 0;
#P connect 14 0 13 1;
#P connect 11 0 12 0;
#P connect 10 0 9 0;
#P connect 10 0 14 0;
#P connect 13 0 10 0;
#P connect 9 0 1 0;
#P connect 9 6 2 0;
#P connect 9 2 2 0;
#P connect 9 0 2 0;
#P connect 9 5 3 0;
#P connect 9 3 3 0;
#P connect 9 4 2 0;
#P connect 9 7 3 0;
#P connect 9 8 8 0;
#P connect 9 1 3 0;
#P connect 9 5 4 0;
#P connect 9 0 4 0;
#P connect 9 6 5 0;
#P connect 9 2 5 0;
#P connect 8 6 2 0;
#P connect 8 2 2 0;
#P connect 8 0 2 0;
#P connect 8 5 3 0;
#P connect 8 4 2 0;
#P connect 8 1 3 0;
#P connect 8 3 3 0;
#P connect 8 5 4 0;
#P connect 8 4 4 0;
#P connect 8 1 4 0;
#P connect 8 6 5 0;
#P connect 8 2 5 0;
#P connect 0 0 7 0;
#P connect 17 0 15 0;
#P connect 16 0 18 0;
#P connect 7 0 6 0;
#P connect 8 7 0 0;
#P connect 7 1 6 1;
#P connect 3 0 7 0;
#P connect 2 0 7 0;
#P connect 1 0 7 0;
#P connect 4 0 7 0;
#P connect 5 0 7 0;
#P connect 18 0 15 1;
#P pop;

である。 ここでは、「metro」オブジェクトがその中枢である。 このオブジェクトは、左端の入力が「1」となるとスタートし、「0」が 与えられるとストップする、文字通りのメトロノームである。右端の入力 で与えられる時間(単位はmsec)ごとに出力トリガを発生する。

そして、この「metro」のトリガによって「1」という定数が、加算の 「+」オブジェクトに与えられる。毎回の加算結果は変数ボックスから 後述のドラムキットに行くとともに、「% 16」というオブジェクトに 与えられ、16で割った剰余が加算の「+」のもう一つの入力となる。 この一連の処理によって、変数ボックスの値は1から16までの整数を インクリメントしつつ無限に繰り返す。このあたりで、少し「アルゴリズム」 らしい雰囲気が出てくる。

この1から16までの値を受けるのが、「select」というオブジェクトである。 このオブジェクトは、入力が箱の中に記述した数値と一致すると、対応した 場所のトリガ出力が発生して、線でつながれた数値ボックスの値をさらに 下流に送り出す機能を持つ。いずれにもヒットしない時には右端の出力から 次段に入力情報を転送する。これによって、この二つの「select」から、 16種類の全てのタイミング状態のトリガを引き出すことができる。

ここから後段は、MIDIについて知っている人ならお馴染みのものである。 57、42、...という数値は、MIDIの10チャンネルで指定されたそれぞれの 打楽器に対応したノートナンバであり、この箱をマウスで直接クリックして ドラム演奏を行うこともできる。この情報をMIDI出力すれば、標準的なGM 音源ではドラムセットが演奏されるのである。

MAXでは、図4のようなパッチを組まないとシンプルな8ビートもできないのか、 とがっかりする必要はない。MAXは無地のキャンバスであり、何でもできる のである。たとえば、市販のドラムマシンで、この8ビートから突然に 7ビートや9ビートに変拍子できるだろうか。MAXなら簡単である。周期を 8から7にすればいいのである。「% 16」を「% 14」にしてみよう。この 数値は、定数としてだけでなく変数としても与えられる。 また、さらにカスタマイズしたドラムマシンにしたければ、たとえば 図5 というのはどうだろう。 かなり複雑になっているように見えるが、実は同じパターンをコピー&ペイスト しているだけなので、このパッチ "fig5"

max v2;
#N vpatcher 40 119 638 505;
#P newex 19 75 42 196617 metro;
#P number 65 76 35 9 0 0 0 3;
#P hidden button 19 95 15 0;
#P message 35 95 20 196617 1;
#P newex 89 94 30 196617 %;
#P newex 57 94 30 196617 +;
#P user hslider 102 76 15 56 200 2 20 0;
#P number 122 95 29 9 0 0 0 3;
#P user IncDec 153 95 15 15 0 0;
#P number 171 95 29 9 0 0 0 3;
#P message 176 76 26 196617 16;
#P button 389 37 15 0;
#P button 373 37 15 0;
#P button 357 37 15 0;
#P button 341 37 15 0;
#P button 325 37 15 0;
#P button 309 37 15 0;
#P button 293 37 15 0;
#P button 277 37 15 0;
#P newex 277 16 139 196617 select 0 1 2 3 4 5 6 7;
#P newex 418 16 144 196617 select 8 9 10 11 12 13 14 15;
#P button 418 37 15 0;
#P button 434 37 15 0;
#P button 450 37 15 0;
#P button 466 37 15 0;
#P button 482 37 15 0;
#P button 498 37 15 0;
#P button 514 37 15 0;
#P button 530 37 15 0;
#P button 547 37 15 0;
#P newex 307 204 93 196617 makenote 100 30;
#P number 371 186 35 9 0 0 0 3;
#P number 338 186 29 9 0 0 0 3;
#P user IncDec 322 186 15 15 0 0;
#P button 306 186 15 0;
#P newex 310 229 63 196617 noteout 10;
#P toggle 301 144 15 0;
#P toggle 317 144 15 0;
#P toggle 333 144 15 0;
#P toggle 349 144 15 0;
#P toggle 365 144 15 0;
#P toggle 381 144 15 0;
#P toggle 397 144 15 0;
#P toggle 413 144 15 0;
#N vpatcher 144 76 544 305;
#P outlet 71 254 15 0;
#P button 70 226 15 0;
#N vpatcher 145 71 545 300;
#P inlet 78 78 15 0;
#P inlet 113 77 15 0;
#P user GSwitch 84 110 40 32 1 0;
#P outlet 82 169 15 0;
#P connect 3 0 1 0;
#P connect 2 0 1 2;
#P connect 1 0 0 0;
#P pop;
#P newobj 36 190 18 196617 p p;
#N vpatcher 145 71 545 300;
#P inlet 92 96 15 0;
#P inlet 127 95 15 0;
#P user GSwitch 98 128 40 32 0 0;
#P outlet 96 187 15 0;
#P connect 3 0 1 0;
#P connect 2 0 1 2;
#P connect 1 0 0 0;
#P pop;
#P newobj 55 190 18 196617 p p;
#N vpatcher 145 71 545 300;
#P inlet 117 78 15 0;
#P inlet 152 77 15 0;
#P user GSwitch 123 110 40 32 0 0;
#P outlet 121 169 15 0;
#P connect 3 0 1 0;
#P connect 2 0 1 2;
#P connect 1 0 0 0;
#P pop;
#P newobj 74 190 18 196617 p p;
#N vpatcher 145 71 545 300;
#P inlet 142 78 15 0;
#P inlet 177 77 15 0;
#P user GSwitch 148 110 40 32 1 0;
#P outlet 146 169 15 0;
#P connect 3 0 1 0;
#P connect 2 0 1 2;
#P connect 1 0 0 0;
#P pop;
#P newobj 94 190 18 196617 p p;
#N vpatcher 145 71 545 300;
#P inlet 167 78 15 0;
#P inlet 202 77 15 0;
#P user GSwitch 173 110 40 32 0 0;
#P outlet 171 169 15 0;
#P connect 3 0 1 0;
#P connect 2 0 1 2;
#P connect 1 0 0 0;
#P pop;
#P newobj 113 190 18 196617 p p;
#N vpatcher 145 71 545 300;
#P inlet 192 78 15 0;
#P inlet 227 77 15 0;
#P user GSwitch 198 110 40 32 0 0;
#P outlet 196 169 15 0;
#P connect 3 0 1 0;
#P connect 2 0 1 2;
#P connect 1 0 0 0;
#P pop;
#P newobj 133 190 18 196617 p p;
#N vpatcher 145 71 545 300;
#P inlet 217 78 15 0;
#P inlet 252 77 15 0;
#P user GSwitch 223 110 40 32 0 0;
#P outlet 221 169 15 0;
#P connect 3 0 1 0;
#P connect 2 0 1 2;
#P connect 1 0 0 0;
#P pop;
#P newobj 152 190 18 196617 p p;
#N vpatcher 145 71 545 300;
#P inlet 231 96 15 0;
#P inlet 266 95 15 0;
#P user GSwitch 237 128 40 32 1 0;
#P outlet 235 187 15 0;
#P connect 3 0 1 0;
#P connect 2 0 1 2;
#P connect 1 0 0 0;
#P pop;
#P newobj 171 190 18 196617 p p;
#P inlet 260 55 15 0;
#P inlet 166 56 15 0;
#P inlet 147 56 15 0;
#P inlet 128 56 15 0;
#P inlet 109 56 15 0;
#P inlet 90 56 15 0;
#P inlet 71 56 15 0;
#P inlet 52 56 15 0;
#P inlet 33 56 15 0;
#P newex 137 87 150 196617 select 8 9 10 11 12 13 14 15;
#P message 248 140 20 196617 0;
#P newex 254 119 53 196617 loadbang;
#P connect 17 0 20 0;
#P connect 16 0 20 0;
#P connect 15 0 20 0;
#P connect 13 0 20 0;
#P connect 12 0 20 0;
#P connect 2 0 19 1;
#P connect 2 1 18 1;
#P connect 2 2 17 1;
#P connect 2 3 16 1;
#P connect 2 4 15 1;
#P connect 2 5 14 1;
#P connect 2 6 13 1;
#P connect 2 7 12 1;
#P connect 0 0 1 0;
#P connect 1 0 19 0;
#P connect 1 0 18 0;
#P connect 1 0 17 0;
#P connect 1 0 16 0;
#P connect 1 0 15 0;
#P connect 1 0 14 0;
#P connect 1 0 13 0;
#P connect 1 0 12 0;
#P connect 20 0 21 0;
#P connect 19 0 20 0;
#P connect 11 0 2 0;
#P connect 10 0 12 0;
#P connect 9 0 13 0;
#P connect 8 0 14 0;
#P connect 7 0 15 0;
#P connect 6 0 16 0;
#P connect 5 0 17 0;
#P connect 4 0 18 0;
#P connect 3 0 19 0;
#P connect 18 0 20 0;
#P connect 14 0 20 0;
#P pop;
#P newobj 430 163 142 196617 p select9-16;
#P toggle 430 144 15 0;
#P toggle 446 144 15 0;
#P toggle 462 144 15 0;
#P toggle 478 144 15 0;
#P toggle 494 144 15 0;
#P toggle 510 144 15 0;
#P toggle 526 144 15 0;
#P toggle 542 144 15 0;
#P newex 22 204 93 196617 makenote 100 30;
#P number 86 186 35 9 0 0 0 3;
#P number 53 186 29 9 0 0 0 3;
#P user IncDec 37 186 15 15 0 0;
#P button 21 186 15 0;
#P newex 27 228 63 196617 noteout 10;
#N vpatcher 113 46 443 311;
#P inlet 12 31 15 0;
#P inlet 31 31 15 0;
#P inlet 50 31 15 0;
#P inlet 69 31 15 0;
#P inlet 88 31 15 0;
#P inlet 107 31 15 0;
#P inlet 126 31 15 0;
#P inlet 145 31 15 0;
#P inlet 239 30 15 0;
#N vpatcher 145 71 545 300;
#P inlet 210 71 15 0;
#P inlet 245 70 15 0;
#P user GSwitch 216 103 40 32 1 0;
#P outlet 214 162 15 0;
#P connect 3 0 1 0;
#P connect 2 0 1 2;
#P connect 1 0 0 0;
#P pop;
#P newobj 150 165 18 196617 p p;
#N vpatcher 145 71 545 300;
#P inlet 196 53 15 0;
#P inlet 231 52 15 0;
#P user GSwitch 202 85 40 32 1 0;
#P outlet 200 144 15 0;
#P connect 3 0 1 0;
#P connect 2 0 1 2;
#P connect 1 0 0 0;
#P pop;
#P newobj 131 165 18 196617 p p;
#N vpatcher 145 71 545 300;
#P inlet 171 53 15 0;
#P inlet 206 52 15 0;
#P user GSwitch 177 85 40 32 0 0;
#P outlet 175 144 15 0;
#P connect 3 0 1 0;
#P connect 2 0 1 2;
#P connect 1 0 0 0;
#P pop;
#P newobj 112 165 18 196617 p p;
#N vpatcher 145 71 545 300;
#P inlet 146 53 15 0;
#P inlet 181 52 15 0;
#P user GSwitch 152 85 40 32 1 0;
#P outlet 150 144 15 0;
#P connect 3 0 1 0;
#P connect 2 0 1 2;
#P connect 1 0 0 0;
#P pop;
#P newobj 92 165 18 196617 p p;
#N vpatcher 145 71 545 300;
#P inlet 121 53 15 0;
#P inlet 156 52 15 0;
#P user GSwitch 127 85 40 32 1 0;
#P outlet 125 144 15 0;
#P connect 3 0 1 0;
#P connect 2 0 1 2;
#P connect 1 0 0 0;
#P pop;
#P newobj 73 165 18 196617 p p;
#N vpatcher 145 71 545 300;
#P inlet 96 53 15 0;
#P inlet 131 52 15 0;
#P user GSwitch 102 85 40 32 1 0;
#P outlet 100 144 15 0;
#P connect 3 0 1 0;
#P connect 2 0 1 2;
#P connect 1 0 0 0;
#P pop;
#P newobj 53 165 18 196617 p p;
#N vpatcher 145 71 545 300;
#P inlet 71 71 15 0;
#P inlet 106 70 15 0;
#P user GSwitch 77 103 40 32 1 0;
#P outlet 75 162 15 0;
#P connect 3 0 1 0;
#P connect 2 0 1 2;
#P connect 1 0 0 0;
#P pop;
#P newobj 34 165 18 196617 p p;
#N vpatcher 145 71 545 300;
#P inlet 57 53 15 0;
#P inlet 92 52 15 0;
#P user GSwitch 63 85 40 32 1 0;
#P outlet 61 144 15 0;
#P connect 3 0 1 0;
#P connect 2 0 1 2;
#P connect 1 0 0 0;
#P pop;
#P newobj 15 165 18 196617 p p;
#P button 49 201 15 0;
#P outlet 50 229 15 0;
#P newex 104 63 139 196617 select 0 1 2 3 4 5 6 7;
#P newex 232 99 53 196617 loadbang;
#P message 231 122 20 196617 0;
#P connect 0 0 5 0;
#P connect 0 0 6 0;
#P connect 0 0 7 0;
#P connect 0 0 8 0;
#P connect 0 0 9 0;
#P connect 0 0 10 0;
#P connect 0 0 11 0;
#P connect 0 0 12 0;
#P connect 20 0 6 0;
#P connect 21 0 5 0;
#P connect 19 0 7 0;
#P connect 18 0 8 0;
#P connect 17 0 9 0;
#P connect 16 0 10 0;
#P connect 15 0 11 0;
#P connect 14 0 12 0;
#P connect 13 0 2 0;
#P connect 10 0 4 0;
#P connect 11 0 4 0;
#P connect 9 0 4 0;
#P connect 8 0 4 0;
#P connect 7 0 4 0;
#P connect 6 0 4 0;
#P connect 5 0 4 0;
#P connect 4 0 3 0;
#P connect 2 1 6 1;
#P connect 2 0 5 1;
#P connect 2 2 7 1;
#P connect 2 3 8 1;
#P connect 2 4 9 1;
#P connect 2 5 10 1;
#P connect 2 6 11 1;
#P connect 2 7 12 1;
#P connect 12 0 4 0;
#P connect 1 0 0 0;
#P pop;
#P newobj 14 162 145 196617 p select1-8;
#P toggle 14 143 15 0;
#P toggle 30 143 15 0;
#P toggle 46 143 15 0;
#P toggle 62 143 15 0;
#P toggle 78 143 15 0;
#P toggle 94 143 15 0;
#P toggle 110 143 15 0;
#P toggle 126 143 15 0;
#N vpatcher 144 76 544 305;
#P outlet 57 236 15 0;
#P button 56 208 15 0;
#N vpatcher 145 71 545 300;
#P inlet 64 60 15 0;
#P inlet 99 59 15 0;
#P user GSwitch 70 92 40 32 1 0;
#P outlet 68 151 15 0;
#P connect 2 0 1 2;
#P connect 3 0 1 0;
#P connect 1 0 0 0;
#P pop;
#P newobj 22 172 18 196617 p p;
#N vpatcher 145 71 545 300;
#P inlet 78 78 15 0;
#P inlet 113 77 15 0;
#P user GSwitch 84 110 40 32 1 0;
#P outlet 82 169 15 0;
#P connect 2 0 1 2;
#P connect 3 0 1 0;
#P connect 1 0 0 0;
#P pop;
#P newobj 41 172 18 196617 p p;
#N vpatcher 145 71 545 300;
#P inlet 103 60 15 0;
#P inlet 138 59 15 0;
#P user GSwitch 109 92 40 32 1 0;
#P outlet 107 151 15 0;
#P connect 2 0 1 2;
#P connect 3 0 1 0;
#P connect 1 0 0 0;
#P pop;
#P newobj 60 172 18 196617 p p;
#N vpatcher 145 71 545 300;
#P inlet 128 60 15 0;
#P inlet 163 59 15 0;
#P user GSwitch 134 92 40 32 1 0;
#P outlet 132 151 15 0;
#P connect 2 0 1 2;
#P connect 3 0 1 0;
#P connect 1 0 0 0;
#P pop;
#P newobj 80 172 18 196617 p p;
#N vpatcher 145 71 545 300;
#P inlet 153 60 15 0;
#P inlet 188 59 15 0;
#P user GSwitch 159 92 40 32 1 0;
#P outlet 157 151 15 0;
#P connect 2 0 1 2;
#P connect 3 0 1 0;
#P connect 1 0 0 0;
#P pop;
#P newobj 99 172 18 196617 p p;
#N vpatcher 145 71 545 300;
#P inlet 178 60 15 0;
#P inlet 213 59 15 0;
#P user GSwitch 184 92 40 32 1 0;
#P outlet 182 151 15 0;
#P connect 2 0 1 2;
#P connect 3 0 1 0;
#P connect 1 0 0 0;
#P pop;
#P newobj 119 172 18 196617 p p;
#N vpatcher 145 71 545 300;
#P inlet 203 60 15 0;
#P inlet 238 59 15 0;
#P user GSwitch 209 92 40 32 0 0;
#P outlet 207 151 15 0;
#P connect 2 0 1 2;
#P connect 3 0 1 0;
#P connect 1 0 0 0;
#P pop;
#P newobj 138 172 18 196617 p p;
#N vpatcher 145 71 545 300;
#P inlet 217 78 15 0;
#P inlet 252 77 15 0;
#P user GSwitch 223 110 40 32 0 0;
#P outlet 221 169 15 0;
#P connect 2 0 1 2;
#P connect 3 0 1 0;
#P connect 1 0 0 0;
#P pop;
#P newobj 157 172 18 196617 p p;
#P inlet 246 37 15 0;
#P inlet 152 38 15 0;
#P inlet 133 38 15 0;
#P inlet 114 38 15 0;
#P inlet 95 38 15 0;
#P inlet 76 38 15 0;
#P inlet 57 38 15 0;
#P inlet 38 38 15 0;
#P inlet 19 38 15 0;
#P newex 123 69 150 196617 select 8 9 10 11 12 13 14 15;
#P message 234 122 20 196617 0;
#P newex 240 101 53 196617 loadbang;
#P connect 1 0 19 0;
#P connect 1 0 18 0;
#P connect 1 0 17 0;
#P connect 1 0 16 0;
#P connect 1 0 15 0;
#P connect 1 0 14 0;
#P connect 1 0 13 0;
#P connect 1 0 12 0;
#P connect 18 0 20 0;
#P connect 17 0 20 0;
#P connect 20 0 21 0;
#P connect 15 0 20 0;
#P connect 16 0 20 0;
#P connect 14 0 20 0;
#P connect 13 0 20 0;
#P connect 11 0 2 0;
#P connect 9 0 13 0;
#P connect 10 0 12 0;
#P connect 8 0 14 0;
#P connect 7 0 15 0;
#P connect 6 0 16 0;
#P connect 5 0 17 0;
#P connect 4 0 18 0;
#P connect 3 0 19 0;
#P connect 12 0 20 0;
#P connect 2 0 19 1;
#P connect 2 1 18 1;
#P connect 2 2 17 1;
#P connect 2 3 16 1;
#P connect 2 4 15 1;
#P connect 2 5 14 1;
#P connect 2 6 13 1;
#P connect 2 7 12 1;
#P connect 0 0 1 0;
#P connect 19 0 20 0;
#P pop;
#P newobj 143 162 142 196617 p select9-16;
#P toggle 143 143 15 0;
#P toggle 159 143 15 0;
#P toggle 175 143 15 0;
#P toggle 191 143 15 0;
#P toggle 207 143 15 0;
#P toggle 223 143 15 0;
#P toggle 239 143 15 0;
#P toggle 255 143 15 0;
#P newex 305 318 93 196617 makenote 100 30;
#P number 369 300 35 9 0 0 0 3;
#P number 336 300 29 9 0 0 0 3;
#P user IncDec 320 300 15 15 0 0;
#P button 304 300 15 0;
#P newex 307 341 63 196617 noteout 10;
#P toggle 303 256 15 0;
#P toggle 319 256 15 0;
#P toggle 335 256 15 0;
#P toggle 351 256 15 0;
#P toggle 367 256 15 0;
#P toggle 383 256 15 0;
#P toggle 399 256 15 0;
#P toggle 415 256 15 0;
#N vpatcher 144 76 544 305;
#P outlet 85 272 15 0;
#P button 84 244 15 0;
#N vpatcher 145 71 545 300;
#P inlet 92 96 15 0;
#P inlet 127 95 15 0;
#P user GSwitch 98 128 40 32 0 0;
#P outlet 96 187 15 0;
#P connect 3 0 1 0;
#P connect 2 0 1 2;
#P connect 1 0 0 0;
#P pop;
#P newobj 50 208 18 196617 p p;
#N vpatcher 145 71 545 300;
#P inlet 106 114 15 0;
#P inlet 141 113 15 0;
#P user GSwitch 112 146 40 32 0 0;
#P outlet 110 205 15 0;
#P connect 3 0 1 0;
#P connect 2 0 1 2;
#P connect 1 0 0 0;
#P pop;
#P newobj 69 208 18 196617 p p;
#N vpatcher 145 71 545 300;
#P inlet 131 96 15 0;
#P inlet 166 95 15 0;
#P user GSwitch 137 128 40 32 0 0;
#P outlet 135 187 15 0;
#P connect 3 0 1 0;
#P connect 2 0 1 2;
#P connect 1 0 0 0;
#P pop;
#P newobj 88 208 18 196617 p p;
#N vpatcher 145 71 545 300;
#P inlet 156 96 15 0;
#P inlet 191 95 15 0;
#P user GSwitch 162 128 40 32 0 0;
#P outlet 160 187 15 0;
#P connect 3 0 1 0;
#P connect 2 0 1 2;
#P connect 1 0 0 0;
#P pop;
#P newobj 108 208 18 196617 p p;
#N vpatcher 145 71 545 300;
#P inlet 181 96 15 0;
#P inlet 216 95 15 0;
#P user GSwitch 187 128 40 32 0 0;
#P outlet 185 187 15 0;
#P connect 3 0 1 0;
#P connect 2 0 1 2;
#P connect 1 0 0 0;
#P pop;
#P newobj 127 208 18 196617 p p;
#N vpatcher 145 71 545 300;
#P inlet 206 96 15 0;
#P inlet 241 95 15 0;
#P user GSwitch 212 128 40 32 0 0;
#P outlet 210 187 15 0;
#P connect 3 0 1 0;
#P connect 2 0 1 2;
#P connect 1 0 0 0;
#P pop;
#P newobj 147 208 18 196617 p p;
#N vpatcher 145 71 545 300;
#P inlet 231 96 15 0;
#P inlet 266 95 15 0;
#P user GSwitch 237 128 40 32 1 0;
#P outlet 235 187 15 0;
#P connect 3 0 1 0;
#P connect 2 0 1 2;
#P connect 1 0 0 0;
#P pop;
#P newobj 166 208 18 196617 p p;
#N vpatcher 145 71 545 300;
#P inlet 245 114 15 0;
#P inlet 280 113 15 0;
#P user GSwitch 251 146 40 32 0 0;
#P outlet 249 205 15 0;
#P connect 3 0 1 0;
#P connect 2 0 1 2;
#P connect 1 0 0 0;
#P pop;
#P newobj 185 208 18 196617 p p;
#P inlet 274 73 15 0;
#P inlet 180 74 15 0;
#P inlet 161 74 15 0;
#P inlet 142 74 15 0;
#P inlet 123 74 15 0;
#P inlet 104 74 15 0;
#P inlet 85 74 15 0;
#P inlet 66 74 15 0;
#P inlet 47 74 15 0;
#P newex 151 105 150 196617 select 8 9 10 11 12 13 14 15;
#P message 262 158 20 196617 0;
#P newex 268 137 53 196617 loadbang;
#P connect 1 0 19 0;
#P connect 1 0 18 0;
#P connect 1 0 17 0;
#P connect 1 0 16 0;
#P connect 1 0 15 0;
#P connect 1 0 14 0;
#P connect 1 0 13 0;
#P connect 1 0 12 0;
#P connect 20 0 21 0;
#P connect 18 0 20 0;
#P connect 17 0 20 0;
#P connect 16 0 20 0;
#P connect 15 0 20 0;
#P connect 14 0 20 0;
#P connect 13 0 20 0;
#P connect 11 0 2 0;
#P connect 10 0 12 0;
#P connect 9 0 13 0;
#P connect 8 0 14 0;
#P connect 7 0 15 0;
#P connect 6 0 16 0;
#P connect 5 0 17 0;
#P connect 4 0 18 0;
#P connect 3 0 19 0;
#P connect 12 0 20 0;
#P connect 2 0 19 1;
#P connect 2 1 18 1;
#P connect 2 2 17 1;
#P connect 2 3 16 1;
#P connect 2 4 15 1;
#P connect 2 5 14 1;
#P connect 2 6 13 1;
#P connect 2 7 12 1;
#P connect 0 0 1 0;
#P connect 19 0 20 0;
#P pop;
#P newobj 432 275 142 196617 p select9-16;
#P toggle 432 256 15 0;
#P toggle 448 256 15 0;
#P toggle 464 256 15 0;
#P toggle 480 256 15 0;
#P toggle 496 256 15 0;
#P toggle 512 256 15 0;
#P toggle 528 256 15 0;
#P toggle 544 256 15 0;
#P newex 16 315 93 196617 makenote 100 30;
#P number 80 297 35 9 0 0 0 3;
#P number 47 297 29 9 0 0 0 3;
#P user IncDec 31 297 15 15 0 0;
#P button 15 297 15 0;
#P newex 18 336 63 196617 noteout 10;
#P toggle 13 256 15 0;
#P toggle 29 256 15 0;
#P toggle 45 256 15 0;
#P toggle 61 256 15 0;
#P toggle 77 256 15 0;
#P toggle 93 256 15 0;
#P toggle 109 256 15 0;
#P toggle 125 256 15 0;
#N vpatcher 144 76 544 305;
#P outlet 71 254 15 0;
#P button 70 226 15 0;
#N vpatcher 145 71 545 300;
#P inlet 78 78 15 0;
#P inlet 113 77 15 0;
#P user GSwitch 84 110 40 32 0 0;
#P outlet 82 169 15 0;
#P connect 3 0 1 0;
#P connect 2 0 1 2;
#P connect 1 0 0 0;
#P pop;
#P newobj 36 190 18 196617 p p;
#N vpatcher 145 71 545 300;
#P inlet 92 96 15 0;
#P inlet 127 95 15 0;
#P user GSwitch 98 128 40 32 0 0;
#P outlet 96 187 15 0;
#P connect 3 0 1 0;
#P connect 2 0 1 2;
#P connect 1 0 0 0;
#P pop;
#P newobj 55 190 18 196617 p p;
#N vpatcher 145 71 545 300;
#P inlet 117 78 15 0;
#P inlet 152 77 15 0;
#P user GSwitch 123 110 40 32 0 0;
#P outlet 121 169 15 0;
#P connect 3 0 1 0;
#P connect 2 0 1 2;
#P connect 1 0 0 0;
#P pop;
#P newobj 74 190 18 196617 p p;
#N vpatcher 145 71 545 300;
#P inlet 142 78 15 0;
#P inlet 177 77 15 0;
#P user GSwitch 148 110 40 32 0 0;
#P outlet 146 169 15 0;
#P connect 3 0 1 0;
#P connect 2 0 1 2;
#P connect 1 0 0 0;
#P pop;
#P newobj 94 190 18 196617 p p;
#N vpatcher 145 71 545 300;
#P inlet 167 78 15 0;
#P inlet 202 77 15 0;
#P user GSwitch 173 110 40 32 1 0;
#P outlet 171 169 15 0;
#P connect 3 0 1 0;
#P connect 2 0 1 2;
#P connect 1 0 0 0;
#P pop;
#P newobj 113 190 18 196617 p p;
#N vpatcher 145 71 545 300;
#P inlet 192 78 15 0;
#P inlet 227 77 15 0;
#P user GSwitch 198 110 40 32 0 0;
#P outlet 196 169 15 0;
#P connect 3 0 1 0;
#P connect 2 0 1 2;
#P connect 1 0 0 0;
#P pop;
#P newobj 133 190 18 196617 p p;
#N vpatcher 145 71 545 300;
#P inlet 217 78 15 0;
#P inlet 252 77 15 0;
#P user GSwitch 223 110 40 32 0 0;
#P outlet 221 169 15 0;
#P connect 3 0 1 0;
#P connect 2 0 1 2;
#P connect 1 0 0 0;
#P pop;
#P newobj 152 190 18 196617 p p;
#N vpatcher 145 71 545 300;
#P inlet 231 96 15 0;
#P inlet 266 95 15 0;
#P user GSwitch 237 128 40 32 0 0;
#P outlet 235 187 15 0;
#P connect 3 0 1 0;
#P connect 2 0 1 2;
#P connect 1 0 0 0;
#P pop;
#P newobj 171 190 18 196617 p p;
#P inlet 260 55 15 0;
#P inlet 166 56 15 0;
#P inlet 147 56 15 0;
#P inlet 128 56 15 0;
#P inlet 109 56 15 0;
#P inlet 90 56 15 0;
#P inlet 71 56 15 0;
#P inlet 52 56 15 0;
#P inlet 33 56 15 0;
#P newex 137 87 150 196617 select 8 9 10 11 12 13 14 15;
#P message 248 140 20 196617 0;
#P newex 254 119 53 196617 loadbang;
#P connect 1 0 19 0;
#P connect 1 0 18 0;
#P connect 1 0 17 0;
#P connect 1 0 16 0;
#P connect 1 0 15 0;
#P connect 1 0 14 0;
#P connect 1 0 13 0;
#P connect 1 0 12 0;
#P connect 20 0 21 0;
#P connect 18 0 20 0;
#P connect 17 0 20 0;
#P connect 15 0 20 0;
#P connect 16 0 20 0;
#P connect 14 0 20 0;
#P connect 12 0 20 0;
#P connect 11 0 2 0;
#P connect 10 0 12 0;
#P connect 9 0 13 0;
#P connect 8 0 14 0;
#P connect 7 0 15 0;
#P connect 6 0 16 0;
#P connect 5 0 17 0;
#P connect 4 0 18 0;
#P connect 3 0 19 0;
#P connect 13 0 20 0;
#P connect 2 0 19 1;
#P connect 2 1 18 1;
#P connect 2 2 17 1;
#P connect 2 3 16 1;
#P connect 2 4 15 1;
#P connect 2 5 14 1;
#P connect 2 6 13 1;
#P connect 2 7 12 1;
#P connect 0 0 1 0;
#P connect 19 0 20 0;
#P pop;
#P newobj 142 275 142 196617 p select9-16;
#P toggle 142 256 15 0;
#P toggle 158 256 15 0;
#P toggle 174 256 15 0;
#P toggle 190 256 15 0;
#P toggle 206 256 15 0;
#P toggle 222 256 15 0;
#P toggle 238 256 15 0;
#P toggle 254 256 15 0;
#P newex 279 85 93 196617 makenote 100 30;
#P number 352 67 35 9 0 0 0 3;
#P number 319 67 29 9 0 0 0 3;
#P user IncDec 297 67 15 15 0 0;
#P button 278 67 15 0;
#P newex 281 106 63 196617 noteout 10;
#P newex 433 87 93 196617 makenote 100 30;
#P number 511 68 35 9 0 0 0 3;
#P number 478 68 29 9 0 0 0 3;
#P user IncDec 456 67 15 15 0 0;
#P button 435 67 15 0;
#P newex 435 107 63 196617 noteout 10;
#P newex 122 55 53 196617 loadbang;
#P button 180 57 15 0;
#N vpatcher 113 46 443 311;
#P inlet 26 49 15 0;
#P inlet 45 49 15 0;
#P inlet 64 49 15 0;
#P inlet 83 49 15 0;
#P inlet 102 49 15 0;
#P inlet 121 49 15 0;
#P inlet 140 49 15 0;
#P inlet 159 49 15 0;
#P inlet 253 48 15 0;
#N vpatcher 145 71 545 300;
#P inlet 224 89 15 0;
#P inlet 259 88 15 0;
#P user GSwitch 230 121 40 32 0 0;
#P outlet 228 180 15 0;
#P connect 3 0 1 0;
#P connect 2 0 1 2;
#P connect 1 0 0 0;
#P pop;
#P newobj 164 183 18 196617 p p;
#N vpatcher 145 71 545 300;
#P inlet 210 71 15 0;
#P inlet 245 70 15 0;
#P user GSwitch 216 103 40 32 0 0;
#P outlet 214 162 15 0;
#P connect 3 0 1 0;
#P connect 2 0 1 2;
#P connect 1 0 0 0;
#P pop;
#P newobj 145 183 18 196617 p p;
#N vpatcher 145 71 545 300;
#P inlet 185 71 15 0;
#P inlet 220 70 15 0;
#P user GSwitch 191 103 40 32 0 0;
#P outlet 189 162 15 0;
#P connect 3 0 1 0;
#P connect 2 0 1 2;
#P connect 1 0 0 0;
#P pop;
#P newobj 126 183 18 196617 p p;
#N vpatcher 145 71 545 300;
#P inlet 160 71 15 0;
#P inlet 195 70 15 0;
#P user GSwitch 166 103 40 32 0 0;
#P outlet 164 162 15 0;
#P connect 3 0 1 0;
#P connect 2 0 1 2;
#P connect 1 0 0 0;
#P pop;
#P newobj 106 183 18 196617 p p;
#N vpatcher 145 71 545 300;
#P inlet 135 71 15 0;
#P inlet 170 70 15 0;
#P user GSwitch 141 103 40 32 0 0;
#P outlet 139 162 15 0;
#P connect 3 0 1 0;
#P connect 2 0 1 2;
#P connect 1 0 0 0;
#P pop;
#P newobj 87 183 18 196617 p p;
#N vpatcher 145 71 545 300;
#P inlet 110 71 15 0;
#P inlet 145 70 15 0;
#P user GSwitch 116 103 40 32 0 0;
#P outlet 114 162 15 0;
#P connect 3 0 1 0;
#P connect 2 0 1 2;
#P connect 1 0 0 0;
#P pop;
#P newobj 67 183 18 196617 p p;
#N vpatcher 145 71 545 300;
#P inlet 85 89 15 0;
#P inlet 120 88 15 0;
#P user GSwitch 91 121 40 32 1 0;
#P outlet 89 180 15 0;
#P connect 3 0 1 0;
#P connect 2 0 1 2;
#P connect 1 0 0 0;
#P pop;
#P newobj 48 183 18 196617 p p;
#N vpatcher 145 71 545 300;
#P inlet 71 71 15 0;
#P inlet 106 70 15 0;
#P user GSwitch 77 103 40 32 1 0;
#P outlet 75 162 15 0;
#P connect 3 0 1 0;
#P connect 2 0 1 2;
#P connect 1 0 0 0;
#P pop;
#P newobj 29 183 18 196617 p p;
#P button 63 219 15 0;
#P outlet 64 247 15 0;
#P newex 118 81 139 196617 select 0 1 2 3 4 5 6 7;
#P newex 246 117 53 196617 loadbang;
#P message 245 140 20 196617 0;
#P connect 0 0 5 0;
#P connect 0 0 6 0;
#P connect 0 0 7 0;
#P connect 0 0 8 0;
#P connect 0 0 9 0;
#P connect 0 0 10 0;
#P connect 0 0 11 0;
#P connect 0 0 12 0;
#P connect 20 0 6 0;
#P connect 21 0 5 0;
#P connect 19 0 7 0;
#P connect 18 0 8 0;
#P connect 17 0 9 0;
#P connect 16 0 10 0;
#P connect 15 0 11 0;
#P connect 14 0 12 0;
#P connect 13 0 2 0;
#P connect 10 0 4 0;
#P connect 11 0 4 0;
#P connect 9 0 4 0;
#P connect 8 0 4 0;
#P connect 7 0 4 0;
#P connect 6 0 4 0;
#P connect 4 0 3 0;
#P connect 5 0 4 0;
#P connect 2 0 5 1;
#P connect 2 1 6 1;
#P connect 2 2 7 1;
#P connect 2 3 8 1;
#P connect 2 4 9 1;
#P connect 2 5 10 1;
#P connect 2 6 11 1;
#P connect 2 7 12 1;
#P connect 1 0 0 0;
#P connect 12 0 4 0;
#P pop;
#P newobj 301 163 145 196617 p select1-8;
#N vpatcher 113 46 443 311;
#P inlet 26 49 15 0;
#P inlet 45 49 15 0;
#P inlet 64 49 15 0;
#P inlet 83 49 15 0;
#P inlet 102 49 15 0;
#P inlet 121 49 15 0;
#P inlet 140 49 15 0;
#P inlet 159 49 15 0;
#P inlet 253 48 15 0;
#N vpatcher 145 71 545 300;
#P inlet 224 89 15 0;
#P inlet 259 88 15 0;
#P user GSwitch 230 121 40 32 0 0;
#P outlet 228 180 15 0;
#P connect 3 0 1 0;
#P connect 2 0 1 2;
#P connect 1 0 0 0;
#P pop;
#P newobj 164 183 18 196617 p p;
#N vpatcher 145 71 545 300;
#P inlet 210 71 15 0;
#P inlet 245 70 15 0;
#P user GSwitch 216 103 40 32 0 0;
#P outlet 214 162 15 0;
#P connect 3 0 1 0;
#P connect 2 0 1 2;
#P connect 1 0 0 0;
#P pop;
#P newobj 145 183 18 196617 p p;
#N vpatcher 145 71 545 300;
#P inlet 185 71 15 0;
#P inlet 220 70 15 0;
#P user GSwitch 191 103 40 32 0 0;
#P outlet 189 162 15 0;
#P connect 3 0 1 0;
#P connect 2 0 1 2;
#P connect 1 0 0 0;
#P pop;
#P newobj 126 183 18 196617 p p;
#N vpatcher 145 71 545 300;
#P inlet 160 71 15 0;
#P inlet 195 70 15 0;
#P user GSwitch 166 103 40 32 1 0;
#P outlet 164 162 15 0;
#P connect 3 0 1 0;
#P connect 2 0 1 2;
#P connect 1 0 0 0;
#P pop;
#P newobj 106 183 18 196617 p p;
#N vpatcher 145 71 545 300;
#P inlet 135 71 15 0;
#P inlet 170 70 15 0;
#P user GSwitch 141 103 40 32 0 0;
#P outlet 139 162 15 0;
#P connect 3 0 1 0;
#P connect 2 0 1 2;
#P connect 1 0 0 0;
#P pop;
#P newobj 87 183 18 196617 p p;
#N vpatcher 145 71 545 300;
#P inlet 110 71 15 0;
#P inlet 145 70 15 0;
#P user GSwitch 116 103 40 32 0 0;
#P outlet 114 162 15 0;
#P connect 3 0 1 0;
#P connect 2 0 1 2;
#P connect 1 0 0 0;
#P pop;
#P newobj 67 183 18 196617 p p;
#N vpatcher 145 71 545 300;
#P inlet 85 89 15 0;
#P inlet 120 88 15 0;
#P user GSwitch 91 121 40 32 0 0;
#P outlet 89 180 15 0;
#P connect 3 0 1 0;
#P connect 2 0 1 2;
#P connect 1 0 0 0;
#P pop;
#P newobj 48 183 18 196617 p p;
#N vpatcher 145 71 545 300;
#P inlet 71 71 15 0;
#P inlet 106 70 15 0;
#P user GSwitch 77 103 40 32 0 0;
#P outlet 75 162 15 0;
#P connect 3 0 1 0;
#P connect 2 0 1 2;
#P connect 1 0 0 0;
#P pop;
#P newobj 29 183 18 196617 p p;
#P button 63 219 15 0;
#P outlet 64 247 15 0;
#P newex 118 81 139 196617 select 0 1 2 3 4 5 6 7;
#P newex 246 117 53 196617 loadbang;
#P message 245 140 20 196617 0;
#P connect 0 0 5 0;
#P connect 0 0 6 0;
#P connect 0 0 7 0;
#P connect 0 0 8 0;
#P connect 0 0 9 0;
#P connect 0 0 10 0;
#P connect 0 0 11 0;
#P connect 0 0 12 0;
#P connect 21 0 5 0;
#P connect 20 0 6 0;
#P connect 19 0 7 0;
#P connect 18 0 8 0;
#P connect 17 0 9 0;
#P connect 16 0 10 0;
#P connect 15 0 11 0;
#P connect 14 0 12 0;
#P connect 13 0 2 0;
#P connect 10 0 4 0;
#P connect 11 0 4 0;
#P connect 9 0 4 0;
#P connect 8 0 4 0;
#P connect 7 0 4 0;
#P connect 6 0 4 0;
#P connect 4 0 3 0;
#P connect 5 0 4 0;
#P connect 2 0 5 1;
#P connect 2 1 6 1;
#P connect 2 2 7 1;
#P connect 2 3 8 1;
#P connect 2 4 9 1;
#P connect 2 5 10 1;
#P connect 2 6 11 1;
#P connect 2 7 12 1;
#P connect 12 0 4 0;
#P connect 1 0 0 0;
#P pop;
#P newobj 13 275 145 196617 p select1-8;
#N vpatcher 113 46 443 311;
#P inlet 40 67 15 0;
#P inlet 59 67 15 0;
#P inlet 78 67 15 0;
#P inlet 97 67 15 0;
#P inlet 116 67 15 0;
#P inlet 135 67 15 0;
#P inlet 154 67 15 0;
#P inlet 173 67 15 0;
#P inlet 267 66 15 0;
#N vpatcher 145 71 545 300;
#P inlet 238 107 15 0;
#P inlet 273 106 15 0;
#P user GSwitch 244 139 40 32 0 0;
#P outlet 242 198 15 0;
#P connect 3 0 1 0;
#P connect 2 0 1 2;
#P connect 1 0 0 0;
#P pop;
#P newobj 178 201 18 196617 p p;
#N vpatcher 145 71 545 300;
#P inlet 224 89 15 0;
#P inlet 259 88 15 0;
#P user GSwitch 230 121 40 32 0 0;
#P outlet 228 180 15 0;
#P connect 3 0 1 0;
#P connect 2 0 1 2;
#P connect 1 0 0 0;
#P pop;
#P newobj 159 201 18 196617 p p;
#N vpatcher 145 71 545 300;
#P inlet 199 89 15 0;
#P inlet 234 88 15 0;
#P user GSwitch 205 121 40 32 1 0;
#P outlet 203 180 15 0;
#P connect 3 0 1 0;
#P connect 2 0 1 2;
#P connect 1 0 0 0;
#P pop;
#P newobj 140 201 18 196617 p p;
#N vpatcher 145 71 545 300;
#P inlet 174 89 15 0;
#P inlet 209 88 15 0;
#P user GSwitch 180 121 40 32 0 0;
#P outlet 178 180 15 0;
#P connect 3 0 1 0;
#P connect 2 0 1 2;
#P connect 1 0 0 0;
#P pop;
#P newobj 120 201 18 196617 p p;
#N vpatcher 145 71 545 300;
#P inlet 149 89 15 0;
#P inlet 184 88 15 0;
#P user GSwitch 155 121 40 32 0 0;
#P outlet 153 180 15 0;
#P connect 3 0 1 0;
#P connect 2 0 1 2;
#P connect 1 0 0 0;
#P pop;
#P newobj 101 201 18 196617 p p;
#N vpatcher 145 71 545 300;
#P inlet 124 89 15 0;
#P inlet 159 88 15 0;
#P user GSwitch 130 121 40 32 0 0;
#P outlet 128 180 15 0;
#P connect 3 0 1 0;
#P connect 2 0 1 2;
#P connect 1 0 0 0;
#P pop;
#P newobj 81 201 18 196617 p p;
#N vpatcher 145 71 545 300;
#P inlet 99 107 15 0;
#P inlet 134 106 15 0;
#P user GSwitch 105 139 40 32 0 0;
#P outlet 103 198 15 0;
#P connect 3 0 1 0;
#P connect 2 0 1 2;
#P connect 1 0 0 0;
#P pop;
#P newobj 62 201 18 196617 p p;
#N vpatcher 145 71 545 300;
#P inlet 85 89 15 0;
#P inlet 120 88 15 0;
#P user GSwitch 91 121 40 32 0 0;
#P outlet 89 180 15 0;
#P connect 3 0 1 0;
#P connect 2 0 1 2;
#P connect 1 0 0 0;
#P pop;
#P newobj 43 201 18 196617 p p;
#P button 77 237 15 0;
#P outlet 78 265 15 0;
#P newex 132 99 139 196617 select 0 1 2 3 4 5 6 7;
#P newex 260 135 53 196617 loadbang;
#P message 259 158 20 196617 0;
#P connect 0 0 5 0;
#P connect 0 0 6 0;
#P connect 0 0 7 0;
#P connect 0 0 8 0;
#P connect 0 0 9 0;
#P connect 0 0 10 0;
#P connect 0 0 11 0;
#P connect 0 0 12 0;
#P connect 21 0 5 0;
#P connect 20 0 6 0;
#P connect 19 0 7 0;
#P connect 18 0 8 0;
#P connect 17 0 9 0;
#P connect 16 0 10 0;
#P connect 15 0 11 0;
#P connect 14 0 12 0;
#P connect 13 0 2 0;
#P connect 10 0 4 0;
#P connect 11 0 4 0;
#P connect 9 0 4 0;
#P connect 8 0 4 0;
#P connect 7 0 4 0;
#P connect 6 0 4 0;
#P connect 4 0 3 0;
#P connect 5 0 4 0;
#P connect 2 0 5 1;
#P connect 2 1 6 1;
#P connect 2 2 7 1;
#P connect 2 3 8 1;
#P connect 2 4 9 1;
#P connect 2 5 10 1;
#P connect 2 6 11 1;
#P connect 2 7 12 1;
#P connect 1 0 0 0;
#P connect 12 0 4 0;
#P pop;
#P newobj 303 275 145 196617 p select1-8;
#N vpreset 1;
#X append 1 2 9 67 456 IncDec int 51 \; 10 68 478 number int 51 \;
 11 68 511 number int 85 \; 15 67 297 IncDec int 49 \;
 16 67 319 number int 49 \; 17 67 352 number int;
#X append 1 2 67 \; 19 256 254 toggle int 0 \;
 20 256 238 toggle int 0 \;
 21 256 222 toggle int 0 \; 22 256 206 toggle int 1 \;
 23 256 190 toggle int 0 \; 24 256 174;
#X append 1 2 toggle int 0 \; 25 256 158 toggle int 0 \;
 26 256 142 toggle int 0 \; 28 256 125 toggle int 0 \;
 29 256 109 toggle int 0 \; 30 256 93 toggle int 0 \; 31 256 77;
#X append 1 2 toggle int 1 \; 32 256 61 toggle int 0 \;
 33 256 45 toggle int 0 \; 34 256 29 toggle int 0 \;
 35 256 13 toggle int 0 \; 38 297 31 IncDec int 38 \; 39 297 47;
#X append 1 2 number int 38 \; 40 297 80 number int 90 \;
 42 256 544 toggle int 0 \; 43 256 528 toggle int 1 \;
 44 256 512 toggle int 0 \; 45 256 496 toggle int 0 \; 46 256 480;
#X append 1 2 toggle int 0 \; 47 256 464 toggle int 0 \;
 48 256 448 toggle int 0 \; 49 256 432 toggle int 0 \;
 51 256 415 toggle int 0 \; 52 256 399 toggle int 0 \; 53 256 383;
#X append 1 2 toggle int 1 \; 54 256 367 toggle int 0 \;
 55 256 351 toggle int 0 \; 56 256 335 toggle int 0 \;
 57 256 319 toggle int 0 \; 58 256 303 toggle int 0 \; 61 300 320;
#X append 1 2 IncDec int 46 \; 62 300 336 number int 46 \;
 63 300 369 number int 87 \; 65 143 255 toggle int 0 \;
 66 143 239 toggle int 0 \; 67 143 223 toggle int 1 \; 68 143 207;
#X append 1 2 toggle int 1 \; 69 143 191 toggle int 1 \;
 70 143 175 toggle int 1 \; 71 143 159 toggle int 1 \;
 72 143 143 toggle int 1 \; 74 143 126 toggle int 1 \; 75 143 110;
#X append 1 2 toggle int 1 \; 76 143 94 toggle int 0 \;
 77 143 78 toggle int 1 \; 78 143 62 toggle int 1 \;
 79 143 46 toggle int 1 \; 80 143 30 toggle int 1 \; 81 143 14;
#X append 1 2 toggle int 1 \; 85 186 37 IncDec int 44 \;
 86 186 53 number int 44 \; 87 186 86 number int 90 \;
 89 144 542 toggle int 1 \; 90 144 526 toggle int 0 \; 91 144 510;
#X append 1 2 toggle int 0 \; 92 144 494 toggle int 0 \;
 93 144 478 toggle int 1 \; 94 144 462 toggle int 0 \;
 95 144 446 toggle int 0 \; 96 144 430 toggle int 1 \; 98 144 413;
#X append 1 2 toggle int 0 \; 99 144 397 toggle int 0 \;
 100 144 381 toggle int 0 \; 101 144 365 toggle int 0 \;
 102 144 349 toggle int 0 \; 103 144 333 toggle int 0 \; 104 144 317;
#X append 1 2 toggle int 1 \; 105 144 301 toggle int 1 \;
 108 186 322 IncDec int 35 \; 109 186 338 number int 35 \;
 110 186 371 number int 110 \; 132 95 171 number int 16 \;
 133 95 153;
#X append 1 2 IncDec int 16 \; 134 95 122 number int 2 \;
 135 76 102 hslider int 54 \; 140 76 65 number int 128 \;
 0 54 20 toggle int 0 \;;
#P preset 24 25 101 17;
#P toggle 20 54 15 0;
#P connect 141 0 139 0;
#P connect 137 0 134 0;
#P connect 138 0 136 0;
#P connect 139 0 138 0;
#P connect 134 0 136 1;
#P hidden connect 134 0 3 8;
#P hidden connect 134 0 82 8;
#P hidden connect 134 0 27 8;
#P hidden connect 134 0 73 8;
#P connect 134 0 122 0;
#P hidden connect 134 0 4 8;
#P hidden connect 134 0 2 8;
#P hidden connect 134 0 97 8;
#P hidden connect 134 0 50 8;
#P connect 122 0 123 0;
#P connect 122 1 124 0;
#P connect 122 2 125 0;
#P connect 122 3 126 0;
#P connect 122 4 127 0;
#P connect 122 5 128 0;
#P connect 122 6 129 0;
#P connect 122 7 130 0;
#P connect 122 8 121 0;
#P hidden connect 97 0 107 0;
#P connect 121 1 119 0;
#P connect 121 0 120 0;
#P connect 121 2 118 0;
#P connect 121 3 117 0;
#P connect 121 4 116 0;
#P connect 121 5 115 0;
#P connect 121 6 114 0;
#P connect 121 7 113 0;
#P connect 133 0 132 0;
#P connect 103 0 4 2;
#P connect 102 0 4 3;
#P connect 104 0 4 1;
#P connect 105 0 4 0;
#P connect 135 0 140 0;
#P connect 136 0 137 0;
#P connect 88 0 83 0;
#P connect 88 1 83 1;
#P connect 111 0 106 0;
#P connect 111 1 106 1;
#P connect 131 0 132 0;
#P connect 108 0 109 0;
#P connect 98 0 4 7;
#P connect 100 0 4 5;
#P connect 101 0 4 4;
#P connect 94 0 97 2;
#P connect 99 0 4 6;
#P connect 93 0 97 3;
#P connect 89 0 97 7;
#P connect 90 0 97 6;
#P connect 91 0 97 5;
#P connect 95 0 97 1;
#P connect 96 0 97 0;
#P connect 92 0 97 4;
#P connect 129 0 8 0;
#P connect 125 0 8 0;
#P connect 123 0 14 0;
#P connect 118 0 8 0;
#P connect 114 0 8 0;
#P connect 140 0 141 1;
#P connect 107 0 109 0;
#P connect 132 0 137 1;
#P connect 132 0 133 0;
#P connect 110 0 111 1;
#P connect 85 0 86 0;
#P connect 84 0 86 0;
#P connect 77 0 82 4;
#P connect 76 0 82 5;
#P connect 78 0 82 3;
#P connect 80 0 82 1;
#P hidden connect 82 0 84 0;
#P connect 79 0 82 2;
#P connect 81 0 82 0;
#P connect 74 0 82 7;
#P connect 75 0 82 6;
#P hidden connect 73 0 84 0;
#P connect 109 0 111 0;
#P connect 109 0 108 0;
#P connect 87 0 88 1;
#P connect 61 0 62 0;
#P connect 72 0 73 0;
#P connect 71 0 73 1;
#P connect 70 0 73 2;
#P connect 69 0 73 3;
#P connect 68 0 73 4;
#P connect 67 0 73 5;
#P connect 65 0 73 7;
#P connect 66 0 73 6;
#P connect 58 0 2 0;
#P connect 60 0 62 0;
#P connect 57 0 2 1;
#P connect 56 0 2 2;
#P connect 55 0 2 3;
#P connect 53 0 2 5;
#P connect 54 0 2 4;
#P connect 52 0 2 6;
#P connect 51 0 2 7;
#P connect 64 0 59 0;
#P connect 64 1 59 1;
#P hidden connect 50 0 60 0;
#P connect 86 0 88 0;
#P connect 86 0 85 0;
#P connect 63 0 64 1;
#P connect 38 0 39 0;
#P connect 37 0 39 0;
#P connect 41 0 36 0;
#P connect 41 1 36 1;
#P connect 48 0 50 1;
#P connect 49 0 50 0;
#P connect 47 0 50 2;
#P connect 46 0 50 3;
#P connect 45 0 50 4;
#P connect 43 0 50 6;
#P connect 44 0 50 5;
#P connect 42 0 50 7;
#P connect 35 0 3 0;
#P connect 34 0 3 1;
#P connect 32 0 3 3;
#P connect 33 0 3 2;
#P connect 31 0 3 4;
#P connect 30 0 3 5;
#P connect 29 0 3 6;
#P connect 62 0 64 0;
#P connect 62 0 61 0;
#P connect 40 0 41 1;
#P connect 15 0 16 0;
#P hidden connect 27 0 37 0;
#P connect 28 0 3 7;
#P connect 18 1 13 1;
#P connect 18 0 13 0;
#P connect 39 0 41 0;
#P connect 39 0 38 0;
#P connect 17 0 18 1;
#P connect 9 0 10 0;
#P connect 12 0 7 0;
#P connect 14 0 16 0;
#P connect 12 1 7 1;
#P connect 5 0 131 0;
#P connect 8 0 10 0;
#P connect 26 0 27 0;
#P connect 25 0 27 1;
#P connect 24 0 27 2;
#P connect 22 0 27 4;
#P connect 23 0 27 3;
#P connect 21 0 27 5;
#P connect 6 0 5 0;
#P connect 20 0 27 6;
#P connect 19 0 27 7;
#P hidden connect 4 0 107 0;
#P hidden connect 3 0 37 0;
#P connect 0 0 141 0;
#P connect 16 0 18 0;
#P connect 16 0 15 0;
#P connect 11 0 12 1;
#P connect 10 0 12 0;
#P connect 10 0 9 0;
#P hidden connect 2 0 60 0;
#P pop;

のプログラミングにしても、 開発の所要時間は1時間程度なのである。 (テキスト表現において、行の先頭に#がついていない場合には、 改行をカットして長くすることに注意)

ここでは、画面左上のプリセットボタンを押すと、全てのセッティングを 瞬時に呼び出してドラムマシンが完成する。それぞれの打楽器に対応して、 全てのビートごとにON/OFFするスイッチを並べているので、新しい ドラムパターンを、パッチの編集モードに入らずに設定できる。そして、 その新しいセッティングを、シフトキーとともにプリセットボタンを クリックすることでどんどん登録していけるのである。まさに、ソフトウェア によるドラムマシンであり、その自由度とカスタマイズも自在である。 このMAXを知ってからは、市販の、機能が固定されてまったく変更できない 機材を倉庫に眠らせたまま、もう使わなくなった人もかなり多いのである。

2. リアルタイム作曲

さて、MAXの実例をちょっと紹介したところで、本題の「アルゴリズム 作曲」について考えてみよう。それには、古典的なスタイルの「作曲」と 比較してみるのが判りやすいだろう。

2.1 古典的作曲とアルゴリズム作曲

あまり美学的に風呂敷を広げない範囲で言えば、MIDIを使った世界での古典的 な「作曲」とは、MIDIで表現される音楽演奏情報をシーケンスデータとして 制作・編集する、というような作業である。ポピュラー音楽、テレビ番組や ゲームやCMのBGM、カラオケの曲データ、などなど、この分野は既に産業 として巨大な存在となっている。その基本はシーケンサの本質である、 「確実に何度でも同じ演奏が再現される」という点にある。クラシック音楽 の世界でも、最近は作曲科の学生がシーケンサでオーケストレーションの 作曲演習を行っているが、このメリットの活用例であろう。

このような音楽は、Computer Musicの分野では「ノンリアルタイム音楽」 あるいは「テープ音楽」と呼ばれている。何度でも完成度の高い同じ演奏を 再現するのなら、わざわざシーケンサでその場で「演奏」することもなく、 DATとかCDとかに、演奏の録音をディジタルの音響データとして固定して しまい、これをHi-Fiのモニタで聴取すればいいのである。 実際、コンピュータ音楽作品の中で、「電子音響 + 生演奏」というスタイル の場合、電子音響の部分はCDとかに固定するという方法が多く用いられる。

ところで「アルゴリズム作曲」という場合には、一般にこれとは発想の異なる アプローチをとる。つまりモチベーションとして「毎回、どこか異なった演奏 となる音楽」「その場の状況に応じて変わる音楽」を、しかし作曲として構築 したい、という姿勢である。生身の人間の演奏であれば、ジャズのアドリブ とかでなくても、クラシック演奏でもその場限りという性格を持つ。しかし ここでは、微妙な演奏表現のレベルよりももっと大きく、音楽演奏情報そのもの が演奏のたびに変わるような「仕組み」、すなわちアルゴリズムを構成する という作業として「作曲」をとらえるのである。

2.2 演奏情報に対する論理的エフェクト

それでは簡単な実例で、この「アルゴリズム作曲」の考え方に触れてみる ことにしよう。 図6 は、図1と図2を合体させて少しだけ手を加えたパッチ "fig6"

max v2;
#N vpatcher 96 113 487 425;
#P newex 175 171 27 9 +;
#P number 293 102 35 9 0 0 0 3;
#P user hslider 293 55 23 45 12 1 0 0;
#P newex 112 171 27 9 +;
#P number 203 102 35 9 0 0 0 3;
#P user hslider 203 55 23 45 12 1 0 0;
#P user hslider 115 55 23 45 12 1 0 0;
#P number 115 102 35 9 0 0 0 3;
#P newex 53 171 27 9 +;
#P newex 31 253 50 9 noteout 1;
#P newex 26 217 92 9 makenote 100 250;
#P number 23 123 35 9 0 0 0 3;
#P newex 29 66 49 9 stripnote;
#P newex 31 26 40 9 notein;
#P connect 3 1 4 1;
#P connect 3 0 4 0;
#P connect 2 0 3 0;
#P connect 2 0 5 0;
#P connect 2 0 10 0;
#P connect 2 0 13 0;
#P connect 1 0 2 0;
#P connect 0 0 1 0;
#P connect 0 1 1 1;
#P connect 6 0 5 1;
#P connect 5 0 3 0;
#P connect 7 0 6 0;
#P connect 10 0 3 0;
#P connect 9 0 10 1;
#P connect 8 0 9 0;
#P connect 13 0 3 0;
#P connect 12 0 13 1;
#P connect 11 0 12 0;
#P pop;

である。 ここではまず、MIDI入力されたノートイベントから「stripnote」というオブジェクト によって、ノートオンのイベントのみ抽出する。そしてそのまま変数ボックスを 経由して「makenote」から「noteout」しているパスは、ベロシティ=100、 デューレーション=250msec、という条件で、そのままMIDI入力情報に対応した 演奏情報を出力していることになる。このパッチ全体の開発期間もまた、1分以内で あることを付記しておこう。

ここでのポイントは、その右側にある3個の「+」オブジェクトである。ここに 入力MIDIノートナンバが入ることで、上のスライダーで設定した値が加算され、 このイベントもMIDI出力される。つまりこのパッチは、入力の1音ごとに設定 された3音のハーモニーが自動的に加わる、「MIDIハーモナイザー」という 機能を実現しているのである。 もちろんこのパッチの機能だけであれば、市販のMIDIイベントプロセッサ製品 でも同等の処理を実現できるが、マニュアルと首っ引きでたくさんのパネル スイッチを操作する労力から解放されるだけでも嬉しい人は少なくない。

そこで図6のパッチに、もう少しだけ実用的な拡張を施してみよう。 図7 のパッチ "fig7"

max v2;
#N vpatcher 59 138 524 504;
#P button 391 50 37 0;
#P message 420 113 20 9 10;
#P message 400 113 14 9 7;
#P message 380 113 14 9 5;
#P comment 392 27 35 9 7sus4;
#P comment 321 27 35 9 mMaj7;
#P message 309 113 14 9 3;
#P message 329 113 14 9 7;
#P message 349 113 20 9 11;
#P button 320 50 37 0;
#P button 249 50 37 0;
#P message 278 113 14 9 9;
#P message 258 113 14 9 6;
#P message 238 113 14 9 3;
#P comment 250 27 30 9 dim7;
#P comment 179 27 30 9 maj7;
#P message 167 113 14 9 4;
#P message 187 113 14 9 7;
#P message 207 113 20 9 11;
#P button 178 50 37 0;
#P button 106 50 37 0;
#P message 135 113 20 9 10;
#P message 115 113 14 9 7;
#P message 95 113 14 9 3;
#P newex 170 234 27 9 +;
#P number 275 187 35 9 0 0 0 3;
#P newex 107 234 27 9 +;
#P number 185 187 35 9 0 0 0 3;
#P number 97 187 35 9 0 0 0 3;
#P newex 48 234 27 9 +;
#P newex 26 316 50 9 noteout 1;
#P newex 21 280 92 9 makenote 100 250;
#P number 18 186 35 9 0 0 0 3;
#P newex 17 66 49 9 stripnote;
#P newex 19 26 40 9 notein;
#P comment 107 27 30 9 min7;
#P connect 4 0 5 0;
#P connect 4 1 5 1;
#P connect 3 0 4 0;
#P connect 3 0 6 0;
#P connect 3 0 9 0;
#P connect 3 0 11 0;
#P connect 2 0 3 0;
#P connect 1 1 2 1;
#P connect 1 0 2 0;
#P connect 7 0 6 1;
#P connect 9 0 4 0;
#P connect 6 0 4 0;
#P connect 8 0 9 1;
#P connect 11 0 4 0;
#P connect 10 0 11 1;
#P connect 13 0 8 0;
#P connect 12 0 7 0;
#P connect 14 0 10 0;
#P connect 15 0 12 0;
#P connect 15 0 13 0;
#P connect 15 0 14 0;
#P connect 19 0 7 0;
#P connect 17 0 10 0;
#P connect 18 0 8 0;
#P connect 16 0 18 0;
#P connect 16 0 17 0;
#P connect 25 0 23 0;
#P connect 16 0 19 0;
#P connect 25 0 24 0;
#P connect 24 0 10 0;
#P connect 23 0 8 0;
#P connect 22 0 7 0;
#P connect 29 0 7 0;
#P connect 27 0 10 0;
#P connect 28 0 8 0;
#P connect 26 0 28 0;
#P connect 25 0 22 0;
#P connect 26 0 27 0;
#P connect 35 0 32 0;
#P connect 35 0 33 0;
#P connect 26 0 29 0;
#P connect 35 0 34 0;
#P connect 34 0 10 0;
#P connect 33 0 8 0;
#P connect 32 0 7 0;
#P pop;

では、図6のパッチの欠点とも言える、いちいち画面の スライダーをマウスでドラッグしてハーモナイズの値を変える操作の代わりに、 いくつかのプリセット値を瞬時に切り換える、という機能を実現してみた。

画面内にある大きなプッシュボタンは、MAXでは「bang」と呼ぶ、値(バリュー) でなく、イベントをトリガするための情報を送り出すためのオブジェクトである。 ここではマウスで操作する入力手段なので大きくしているが、情報が届いた時に表示 するインジケータ(表示出力)として使う場合には小さくしておくのが普通である。 このパッチでは、マウスで瞬時にハーモナイズの設定を変更できるが、この応用 として、設定値をセンサから取り込んだり、後述するようにランダムに刻々と 変化させる、というような発展の可能性がある。

MAXには、ほとんど思いつく全ての種類の論理演算、数値演算のオブジェクトが 標準で用意されている。たとえば、 図8 は、新しいパッチの中で、新しいオブジェクトとして「数値演算/論理演算」の リストから選ぶ、という状態の画面である。しかし、このようなオブジェクトの 機能はいちいち覚える必要はまったくない。 図9 の例では、新しいパッチから累算演算のオブジェクト「accum」を呼び出し、 このオブジェクトを指定して「コマンド + H(ヘルプ)」によってヘルプ画面 を呼び出したところである。ところが、このヘルプ自体が、単なる図ではなくて MAXのパッチなので、実際にこのパッチから必要な部分をコピー&ペイストで 自分のパッチに取り込むことができる。そこで筆者もそうなのだが、 まったく「覚える」ことなく各種のMAXオブジェクトを活用できるのである。

2.3 演奏情報に対する時間的エフェクト

前述の例では、リアルタイムに流れるMIDI情報に対する論理的な操作、という アルゴリズムの例を紹介した。これはいわばエレクトロニクスの「論理回路」 というようなものであり、設定したアルゴリズムに従って入力から瞬時に結果が 得られるものである。エレクトロニクスの論理回路でも半導体チップ上の信号遅延が 問題になるように、MAXの処理は1msecの分解能を単位としているので、処理が多段 になった場合には、多少は遅延の影響を考慮する必要がある。

ところで、ここではコンピュータ音楽を対象としている以上、「時間」の軸という 視点はとても重要である。そこで、エレクトロニクスの世界で論理回路と並んで 重要な「同期回路」に相当する、時間的なオブジェクトを駆使するのが、MAX でのもう一つの重要なアルゴリズム「作曲」となる。 図10 のパッチ "fig10"

max v2;
#N vpatcher 58 113 518 416;
#P newex 324 176 27 9 pipe;
#P number 361 102 35 9 0 0 0 3;
#P user hslider 361 55 23 45 96 10 50 0;
#P user hslider 279 55 23 45 96 10 50 0;
#P number 279 102 35 9 0 0 0 3;
#P newex 242 176 27 9 pipe;
#P newex 160 176 27 9 pipe;
#P number 197 102 35 9 0 0 0 3;
#P user hslider 197 55 23 45 96 10 50 0;
#P user hslider 115 55 23 45 96 10 50 0;
#P number 115 102 35 9 0 0 0 3;
#P newex 78 176 27 9 pipe;
#P newex 31 253 50 9 noteout 1;
#P newex 26 217 92 9 makenote 100 250;
#P number 23 123 35 9 0 0 0 3;
#P newex 29 66 49 9 stripnote;
#P newex 31 26 40 9 notein;
#P connect 8 0 9 0;
#P connect 0 1 1 1;
#P connect 0 0 1 0;
#P connect 16 0 3 0;
#P connect 3 0 4 0;
#P connect 3 1 4 1;
#P connect 2 0 3 0;
#P connect 2 0 5 0;
#P connect 2 0 10 0;
#P connect 2 0 11 0;
#P connect 2 0 16 0;
#P connect 1 0 2 0;
#P connect 6 0 5 1;
#P connect 7 0 6 0;
#P connect 13 0 12 0;
#P connect 9 0 10 1;
#P connect 5 0 3 0;
#P connect 11 0 3 0;
#P connect 10 0 3 0;
#P connect 14 0 15 0;
#P connect 12 0 11 1;
#P connect 15 0 16 1;
#P pop;

は、一見すると図6のパッチに似ているが、オブジェクト が「pipe」という時間要素となっている点が重要である。「pipe」は、右側の入力 で設定される時間(msec)だけ、左側の入力情報を遅延して出力する、という ものである。それぞれのオブジェクトごとに時間管理をするのはとても大変 であるが、MAXではプログラミングをする側では何も考えなくていいのである。 そこで図10の例であれば、MIDI入力がそれぞれの設定値ごとに遅延されてミックス した出力が得られる。つまり、お手軽な「MIDIエコーマシン」なのである。

「演奏」に関わる領域の音楽情報処理の場合、このような「遅延」という要素 は、あらかじめプリセットしておく必要がある。リアルタイム処理のための時間的 パラメータが変動しては動作に問題があるので、これは当然である。ところが MAXの場合、本質的にシステムがリアルタイム動作をするために、その時間的 要素をリアルタイムに変更することもまったく問題とならない。図10をもう一度 眺めてみると、時間的動作のパラメータである「pipe」オブジェクトの右側の 入力には、定数でなく任意の変数を、リアルタイムに与えられるのである。 これは、「MIDIエコーマシンの時間パラメータを刻々と変える」というような フレキシブルな動作を容易に実現できることを意味する。

なお、MAXはプログラミング言語を使わないものの、音楽情報に関するプログラ ミング環境であることを示す例として、 図11 のパッチ "fig11"

max v2;
#N vpatcher 134 127 376 450;
#N vpatcher 364 336 575 503;
#P newex 107 58 49 9 pipe 600;
#P outlet 31 122 15 0;
#P newex 48 58 49 9 pipe 300;
#P inlet 31 16 15 0;
#P comment 107 23 100 9 sub2;
#P connect 4 0 3 0;
#P connect 2 0 3 0;
#P connect 1 0 2 0;
#P connect 1 0 3 0;
#P connect 1 0 4 0;
#P pop 1;
#P newobj 110 154 65 9 patcher sub2;
#N vpatcher 374 110 577 294;
#P newex 108 73 27 9 + 7;
#P newex 64 73 27 9 + 5;
#P outlet 32 134 15 0;
#P inlet 32 17 15 0;
#P comment 92 31 100 9 sub1;
#P connect 3 0 2 0;
#P connect 4 0 2 0;
#P connect 1 0 2 0;
#P connect 1 0 3 0;
#P connect 1 0 4 0;
#P pop 1;
#P newobj 20 155 65 9 patcher sub1;
#P toggle 22 25 29 0;
#P user GSwitch2 55 93 35 32 1 0;
#P newex 49 273 50 9 noteout 1;
#P newex 44 237 92 9 makenote 100 250;
#P number 72 207 35 9 0 0 0 3;
#P newex 126 54 49 9 stripnote;
#P newex 128 14 40 9 notein;
#P connect 8 0 2 0;
#P connect 7 0 2 0;
#P connect 5 0 7 0;
#P connect 5 1 8 0;
#P connect 3 0 4 0;
#P connect 3 1 4 1;
#P connect 6 0 5 0;
#P connect 2 0 3 0;
#P connect 0 0 1 0;
#P connect 1 0 5 1;
#P connect 0 1 1 1;
#P pop;

も紹介しておこう。この中身は、既に述べた「ハーモナイザー」 と「エコーマシン」でしかないが、これをスイッチ状のオブジェクトで切り換える、と いうものである。そして注目して欲しいのは、「patcher」というオブジェクトである。 これは図11のメインパッチの右側にある「sub1」「sub2」という「サブパッチ」を 指定するもので、このようにMAXのパッチは好みに応じて、任意に階層化・構造化を 設定していけるのである。筆者はいつもComputer Musicの作品にMAXを使っているが、 ライブ会場に持ち込むPowerBookの小さなディスプレイでも、このテクニックによって 巨大なアルゴリズムをコンパクトにまとめることで、操作性を確保している。

また、後の例で紹介するように、自分がオリジナルに組んだパッチ、あるいは世界中 の愛好家によってインターネット等で交換されているパッチを、同じディレクトリ内に 置いてそのパッチ名のオブジェクトとして呼び出せば、これまたサブルーチンの ように利用できる。パッチは本書の付録CDROMのように、plain text形式でも保存 できるので、メイルとしてそのまま送れるのも便利である。

なお、MAXのソフトウェア部品である「オブジェクト」そのものを開発するための 環境やドキュメントも、MAXには標準で付いてくる。ただし、これにはMacintosh上 でPASCALやThink Cなどでまともにプログラミングする必要があり、専門家でないと なかなか手が出ない。海外では大学院生の格好の演習課題となっているようである。 国内では、IRCAMのサーバに置かれて世界的に活用されている、千野秀一(ichi)さん の「speak」「aiff」「usnd」等の一連のサウンド関連オブジェクトが有名である。 またイメージラボ(LIST)でも、ピッチトレーサのオブジェクトなどを公開した。

2.4 センサによるリアルタイム作曲

アルゴリズム作曲、あるいはリアルタイム作曲という音楽的な概念は、次項で 述べる「ランダム要素」による偶然性の音楽というアプローチだけではない。 パフォーマー(いわゆる「演奏者」を広義にこう呼ぶことが多い)のあらゆる パフォーマンス情報をセンサによってシステムに取り込み、この情報によって リアルタイムに演奏情報を生成したりアレンジしていく、という手法も、 もう一つの重要な本流である。

ここでは紙面の関係で、一つだけ例を紹介しておこう。 図12 は、筆者が作品の作曲の一部として製作した、「MIDIパワーグローブ」である。 このセンサはパフォーマーの右手の指の曲げ状態を、4本の指(薬指と小指は 共通)のそれぞれのON/OFFという16状態として検出し、ワイヤレスで送信 する。合わせて製作した受信モジュールでは、他のセンサ等からのMIDI入力 情報とマージ(合流)して、MAXでのパターン認識系に出力するようになっている。

そして、このMIDIパワーグローブからの情報を扱うために作ったのが、 図13 の "fig13"

max v2;
#N vpatcher 44 88 499 574;
#P newex 89 6 35 196617 midiin;
#P newex 75 31 90 196617 match 175 127 nn;
#P user uslider 275 141 27 160 2 1 0 0;
#P user uslider 306 125 27 175 2 1 0 0;
#P user uslider 337 139 27 160 2 1 0 0;
#P user uslider 368 158 26 140 2 1 0 0;
#P user uslider 231 207 40 94 2 1 0 0;
#P number 264 105 35 9 0 0 0 3;
#P newex 261 81 27 196617 / 2;
#P newex 261 58 27 196617 % 4;
#P newex 216 61 27 196617 % 2;
#P number 211 88 35 9 0 0 0 3;
#P number 312 104 35 9 0 0 0 3;
#P newex 314 80 27 196617 / 4;
#P newex 309 58 27 196617 % 8;
#P newex 357 52 27 196617 / 8;
#P number 363 74 35 9 0 0 0 3;
#P number 243 25 35 9 0 0 0 3;
#P user GSwitch 88 82 40 32 1 0;
#P toggle 23 18 42 0;
#P message 89 56 20 196617 \$3;
#P button 45 169 34 0;
#P button 121 163 34 0;
#P newex 286 330 40 196617 change;
#P newex 335 330 40 196617 change;
#P newex 384 330 40 196617 change;
#P newex 237 330 40 196617 change;
#P newex 122 388 27 196617 *;
#P newex 160 388 27 196617 *;
#P newex 199 388 27 196617 *;
#P newex 239 389 27 196617 *;
#P newex 147 417 92 196617 makenote 100 500;
#P newex 150 442 50 196617 noteout 1;
#P message 94 333 20 196617 49;
#P message 69 334 20 196617 52;
#P message 43 334 20 196617 56;
#P message 17 334 20 196617 59;
#P message 113 292 20 196617 59;
#P message 140 292 20 196617 55;
#P message 167 292 20 196617 52;
#P message 193 292 20 196617 48;
#P connect 38 0 17 0;
#P connect 39 0 20 0;
#P connect 19 0 5 0;
#P connect 19 0 6 0;
#P connect 19 0 7 0;
#P connect 32 0 33 0;
#P connect 18 0 3 0;
#P connect 18 0 2 0;
#P connect 18 0 1 0;
#P connect 19 0 4 0;
#P connect 18 0 0 0;
#P connect 30 0 29 0;
#P connect 21 0 22 0;
#P connect 40 0 39 0;
#P connect 37 0 16 0;
#P connect 26 0 27 0;
#P connect 25 0 24 0;
#P connect 17 1 12 0;
#P connect 27 0 28 0;
#P connect 16 1 11 0;
#P connect 15 1 10 0;
#P connect 14 1 13 0;
#P connect 33 0 38 0;
#P connect 13 0 9 0;
#P connect 12 0 9 0;
#P connect 22 0 23 0;
#P connect 29 0 34 0;
#P connect 28 0 37 0;
#P connect 24 0 36 0;
#P connect 24 0 35 0;
#P connect 23 0 30 0;
#P connect 23 0 31 0;
#P connect 23 0 26 0;
#P connect 23 0 25 0;
#P connect 20 0 22 2;
#P connect 7 0 10 1;
#P connect 10 0 9 0;
#P connect 11 0 9 0;
#P connect 31 0 32 0;
#P connect 9 0 8 0;
#P connect 9 1 8 1;
#P connect 6 0 11 1;
#P connect 5 0 12 1;
#P connect 4 0 13 1;
#P connect 3 0 13 1;
#P connect 2 0 12 1;
#P connect 1 0 11 1;
#P connect 0 0 10 1;
#P connect 36 0 15 0;
#P connect 34 0 14 0;
#P pop;

というパッチである。ざっとアルゴリズムの流れを説明すると、 まず入力のMIDI情報は全て「midiin」オブジェクトから得られる。そして、 「match」オブジェクトによって、ステータスが175(ポリフォニック プレッシャー16チャンネル)、ノートナンバ127、という特定の情報に ヒットした時だけ、そのバリューが「$3」という指定で出力される。 これをスイッチでON/OFFして、次段の認識系に行く。

パワーグローブの指情報は4ビット2進数としてコーディングされている ので、1の位を親指に、2の位を人差指に、4の位を中指に、8の位を薬指と 小指に、と割り当てている。図13の中のスライダーは、値域としてゼロと 1だけをとるように設定してあるので、グローブの握り状態はそのまま、 このスライダーの動きとして可視化される。このそれぞれの桁の ゼロか1か、という値は、イベントの変化がある時のみ出力する 「change」オブジェクトを通過して、さらに乗算の「*」オブジェクトに 入力される。この乗算のもう一方の値としては、二つのボタンで設定 される和音データが与えられるため、一方ではCmaj7のコード、もう一方 ならC#m7のコードの構成音として、指の動きに対応してアルペジオ 演奏を行えることになる。このパッチにより、パワーグローブが一種の 楽器となったわけである。

この例ではセンサの情報をそのままMIDIノートナンバという音楽演奏情報 にマッピングしたが、MAXパッチ内のあらゆる情報にセンサを作用 させるアルゴリズムが実現可能である。たとえば筆者の例では、BGMパート のテンポを変えたり音量やステレオ定位情報を変化させたり、あるいは音楽の シーンの切り替え、画像系のスイッチング、照明機器の制御などにも利用 している。パフォーマーからの情報によって、リアルタイムに音楽情報 そのものを生成したり変化させる、という「リアルタイム作曲」のため には、センサ情報は格好の題材なのである。最近では秋葉原とか日本橋 でも多種の「センサキット」が安価に出ているので、可能性はまだまだ 広がっている。ICMC(International Computer Music Conference)などの 場で、「世界で最初の***を用いたコンピュータ音楽用センサ」として 発表できる、研究者にとって最短経路の一つかもしれない。

3. 自動作曲アルゴリズム

「アルゴリズム作曲」のもう一つの本流は、シーケンスデータとして固定 されない音楽演奏情報を、「演奏」の際にリアルタイムに自動生成していく、 というタイプである。MAXの時間情報を扱うオブジェクトを活用すれば、 このアルゴリズムはプログラミング言語で開発するよりも、ずっと効率的に 「作曲」できることは容易に想像がつくだろう。

3.1 乱数による音楽生成

自動作曲のもっとも基本となるのは、モーツァルトの「さいころ音楽」と 同じ、乱数を用いたアルゴリズムである。 図14 のパッチ "fig14"

max v2;
#N vpatcher 72 121 291 552;
#P newex 55 378 50 196617 noteout 1;
#P newex 38 337 92 196617 makenote 100 250;
#P user hslider 123 76 18 38 64 1 1 0;
#P number 60 43 35 9 0 0 0 3;
#P user hslider 133 214 18 38 128 1 0 0;
#P number 73 249 27 9 0 0 0 3;
#P number 90 177 35 9 0 0 0 3;
#P user hslider 134 145 18 38 12 1 1 0;
#P number 79 103 31 9 0 0 0 3;
#P user hslider 119 15 18 38 93 10 80 0;
#P number 10 306 29 9 0 0 0 3;
#P newex 21 128 53 196617 random;
#P newex 19 202 18 196617 *;
#P number 11 163 32 9 0 0 0 3;
#P number 11 239 30 9 0 0 0 3;
#P newex 17 270 18 196617 +;
#P button 14 102 13 0;
#P newex 20 69 39 196617 metro;
#P toggle 11 28 26 0;
#P connect 17 0 18 0;
#P connect 17 1 18 1;
#P connect 2 0 7 0;
#P connect 15 0 1 1;
#P connect 13 0 3 1;
#P connect 7 0 5 0;
#P connect 12 0 6 1;
#P connect 10 0 7 1;
#P connect 8 0 17 0;
#P connect 6 0 4 0;
#P connect 5 0 6 0;
#P connect 4 0 3 0;
#P connect 3 0 8 0;
#P connect 1 0 2 0;
#P connect 0 0 1 0;
#P connect 16 0 10 0;
#P connect 14 0 13 0;
#P connect 11 0 12 0;
#P connect 9 0 15 0;
#P pop;

は、まさにこの原型となるシンプルなものだが、 ここをスタートラインとして、思わぬ展開の可能性を秘めている。 情報処理アルゴリズムは上から下に、順に追いかけることで理解できる。

正方形のON/OFFトグルスイッチによって「metro」オブジェクトが スタートされると、右側の入力から設定されたインターバルで 等間隔のトリガが発生される。これが自動演奏のテンポとなる。 これを受けた「random」オブジェクトがこのパッチの中心で、この図 では右側から入力された12という値によって、ゼロから11までの ランダムな整数が得られる。基本的には、これで「さいころ音楽」 はできてしまう。

生成されたランダム値は、乗算オブジェクト「*」に入り、この右側 の設定値と乗算される。たとえば1を設定すれば素通りするが、図14 のように2を設定していると、乱数入力は全て偶数となるので、MIDI ノートナンバとしては「全音音階」が得られることになる。設定値が 3ならdim7の和音を構成し、4ならaugコードとなり、5ならsus4系の スケールとなるわけである。この出力はさらに加算オブジェクト 「+」によって、右側の入力値だけオフセットを加算される。この補正 によって、MIDIノートイベントとして聞きやすい音域に移調する。

このパッチの場合、ランダムに生成された音階の自動演奏は、永遠に 等間隔で続く音の並びとなり、メロディーのように知覚されにくい ものである。そこで、擬似的に「リズム」の要素を盛り込むには どうしたらいいか、これは読者への宿題としておこう。もっとも 簡単には、なんと図14のパッチに、たった一つのオブジェクトを 追加するだけでいいのである。( "fig15")

max v2;
#N vpatcher 72 121 292 551;
#P newex -44 151 40 9 change;
#P newex 58 378 50 196617 noteout 1;
#P newex 41 337 92 196617 makenote 100 250;
#P user hslider 126 76 18 38 64 1 1 0;
#P number 63 43 35 9 0 0 0 3;
#P user hslider 136 214 18 38 128 1 0 0;
#P number 76 249 27 9 0 0 0 3;
#P number 93 177 35 9 0 0 0 3;
#P user hslider 137 145 18 38 12 1 1 0;
#P number 82 103 31 9 0 0 0 3;
#P user hslider 122 15 18 38 93 10 80 0;
#P number 13 306 29 9 0 0 0 3;
#P newex 24 128 53 196617 random;
#P newex 22 202 18 196617 *;
#P number 14 177 32 9 0 0 0 3;
#P number 14 239 30 9 0 0 0 3;
#P newex 20 270 18 196617 +;
#P button 17 102 13 0;
#P newex 23 69 39 196617 metro;
#P toggle 14 28 26 0;
#P connect 17 1 18 1;
#P connect 17 0 18 0;
#P connect 2 0 7 0;
#P connect 15 0 1 1;
#P connect 13 0 3 1;
#P connect 7 0 19 0;
#P connect 10 0 7 1;
#P connect 12 0 6 1;
#P connect 8 0 17 0;
#P connect 6 0 4 0;
#P connect 5 0 6 0;
#P connect 19 0 5 0;
#P connect 3 0 8 0;
#P connect 4 0 3 0;
#P connect 1 0 2 0;
#P connect 0 0 1 0;
#P connect 16 0 10 0;
#P connect 11 0 12 0;
#P connect 14 0 13 0;
#P connect 9 0 15 0;
#P pop;

3.2 カオスによる音楽生成

単なる乱数よりも面白いランダム、として筆者が注目したのが、カオス のアルゴリズムである。ここではもっとも基本的な、「メイの漸化式」 (Logistic Function)を使って、
           X(n+1) = myu * X(n) * ( 1 - X(n) )
という処理を実現する。変数X(n)の変域はゼロから1までの実数であり、 ここに3から4までの実数となるパラメータmyuを作用させることで、 初期値に対して「決定的に」次の値が得られていくが、この演算を 繰り返していくときに、X(n)の値はmyuによってカオス的な振る舞いを する、というものである。

カオス現象をMAXパッチによって実現すると、数学的な振る舞いが 「音」として可聴化され、その挙動が音楽的なフレーズの動きとして かなり系統的に知覚できる、という面白さがある。 図16 のパッチ "fig16"

max v2;
#N vpatcher 44 53 513 390;
#P newex 395 226 27 196617 / 2;
#P number 345 229 31 9 1 127 3 3;
#P hidden newex 254 6 43 196617 loadbang;
#P number 293 231 34 9 0 0 0 3;
#P message 200 43 23 196617 0.5;
#P message 244 45 20 196617 24;
#P message 276 45 20 196617 55;
#P message 312 44 20 196617 90;
#P message 352 41 26 196617 200;
#P number 346 69 34 9 75 2000 3 3;
#P newex 331 262 50 196617 makenote;
#P newex 339 293 50 196617 noteout 1;
#P number 299 176 25 9 0 100 3 3;
#P newex 276 204 27 196617 +;
#P number 259 148 27 9 1 100 3 3;
#P newex 249 177 27 196617 * 0.;
#P flonum 214 148 34 9 0 0 0 3;
#P newex 48 101 35 196617 metro;
#P hidden button 51 131 15 0;
#P flonum 66 157 35 9 0 0 0 3;
#P newex 131 276 27 196617 * 0.;
#P flonum 116 238 34 9 0 0 0 3;
#P newex 116 214 34 196617 + 1.;
#P flonum 59 222 35 9 0 0 0 3;
#P newex 61 190 27 196617 * 0.;
#P newex 116 191 34 196617 * -1.;
#P message 155 44 23 196617 3.8;
#P toggle 33 51 15 0;
#P connect 17 0 16 0;
#P connect 17 1 16 1;
#P connect 7 0 11 0;
#P hidden connect 25 0 1 0;
#P hidden connect 25 0 23 0;
#P hidden connect 25 0 22 0;
#P hidden connect 25 0 21 0;
#P hidden connect 25 0 20 0;
#P hidden connect 25 0 19 0;
#P connect 3 0 4 0;
#P connect 2 0 5 0;
#P connect 5 0 6 0;
#P connect 6 0 7 1;
#P connect 4 0 7 0;
#P connect 23 0 11 0;
#P connect 9 0 8 0;
#P connect 26 0 17 1;
#P connect 24 0 17 0;
#P connect 18 0 10 1;
#P connect 18 0 27 0;
#P connect 15 0 14 1;
#P connect 13 0 12 1;
#P connect 14 0 24 0;
#P connect 11 0 3 1;
#P connect 11 0 2 0;
#P connect 11 0 12 0;
#P connect 8 0 3 0;
#P connect 27 0 17 2;
#P connect 12 0 14 0;
#P connect 10 0 9 0;
#P connect 21 0 15 0;
#P connect 22 0 13 0;
#P connect 20 0 26 0;
#P connect 0 0 10 0;
#P connect 19 0 18 0;
#P connect 1 0 8 0;
#P pop;

は、このアルゴリズムをそのまま記述した ものである。目新しいところは、整数でなく浮動小数点演算をする ために、数値演算オブジェクトに「小数点のついた数値」を指定 するところだけである。図では定数「3.8」が与えられている 変数ボックス内をドラッグしてこの値を変化させると、まさに カオスの教科書に載っている振る舞いを音として聞くことができる。

さらに、図16のパッチの数学的な部分をまったく変えずに、音 とともに視覚的にもカオス現象を体験するために改良したのが、 図17 のパッチ "fig17"

max v2;
#N vpatcher 33 140 636 544;
#P newex 483 299 50 9 noteout 1;
#P newex 484 266 85 9 makenote 100 80;
#P newex 15 76 35 9 metro;
#P toggle 9 16 37 0;
#P hidden newex 400 -3 98 196628 loadbang;
#P number 52 23 71 20 0 0 0 3;
#P message 127 23 49 196628 200;
#P message 496 33 36 196628 45;
#P message 443 35 36 196628 16;
#P message 365 35 70 196628 0.667;
#P message 194 65 44 196622 3.68;
#P message 248 65 44 196622 3.75;
#P message 248 91 44 196622 3.99;
#P message 192 90 44 196622 3.84;
#P message 90 117 44 196622 3.57;
#P message 144 117 44 196622 3.63;
#P message 88 64 44 196622 3.;
#P message 142 91 44 196622 3.54;
#P message 141 64 44 196622 3.43;
#P message 91 91 44 196622 3.45;
#P hidden newex 88 192 27 196617 + 0.;
#P hidden message 83 173 29 196617 0.01;
#P hidden message 81 221 25 196617 0.1;
#P hidden message 80 243 34 196617 -0.01;
#P hidden message 85 262 28 196617 -0.1;
#P button 31 341 31 0;
#P comment 26 322 44 196622 -0.1;
#P button 30 286 31 0;
#P comment 25 267 44 196622 -0.01;
#P button 28 226 31 0;
#P comment 23 206 44 196622 +0.1;
#P comment 22 151 44 196622 +0.01;
#P button 27 171 31 0;
#P number 446 75 45 20 1 100 3 3;
#P number 499 75 45 20 0 100 3 3;
#P flonum 308 104 130 20 0 0 0 3;
#P user multiSlider 271 176 200 201 0. 1. 1 3705 15;
#P newex 197 227 65 196628 * -1.;
#P newex 197 264 55 196628 + 1.;
#P flonum 177 302 61 9 0 0 0 3;
#P flonum 122 160 81 24 0 0 0 3;
#P newex 122 219 57 196628 * 0.;
#P newex 122 325 55 196628 * 0.;
#P hidden button 65 124 14 0;
#P newex 457 138 53 196628 * 0.;
#P newex 509 180 27 196628 +;
#P number 491 223 50 20 0 0 0 3;
#P hidden connect 26 0 6 0;
#P hidden connect 17 0 24 0;
#P hidden connect 42 0 40 0;
#P hidden connect 42 0 30 0;
#P hidden connect 42 0 37 0;
#P hidden connect 42 0 38 0;
#P hidden connect 42 0 39 0;
#P hidden connect 4 0 11 0;
#P connect 2 0 1 0;
#P hidden connect 14 0 25 0;
#P connect 3 0 6 0;
#P connect 8 0 7 0;
#P connect 1 0 0 0;
#P connect 5 0 4 0;
#P connect 45 0 46 0;
#P connect 45 1 46 1;
#P connect 40 0 41 0;
#P hidden connect 19 0 23 0;
#P connect 39 0 12 0;
#P hidden connect 21 0 22 0;
#P connect 41 0 44 1;
#P connect 13 0 2 1;
#P connect 12 0 1 1;
#P connect 11 0 5 1;
#P connect 11 0 10 0;
#P connect 11 0 9 0;
#P connect 11 0 2 0;
#P connect 7 0 4 1;
#P hidden connect 6 0 26 1;
#P connect 6 0 5 0;
#P connect 0 0 45 0;
#P connect 9 0 8 0;
#P connect 44 0 3 0;
#P connect 38 0 13 0;
#P connect 37 0 11 0;
#P connect 43 0 44 0;
#P hidden connect 36 0 6 0;
#P hidden connect 35 0 6 0;
#P hidden connect 34 0 6 0;
#P hidden connect 33 0 6 0;
#P hidden connect 32 0 6 0;
#P hidden connect 30 0 6 0;
#P hidden connect 31 0 6 0;
#P hidden connect 29 0 6 0;
#P hidden connect 28 0 6 0;
#P hidden connect 27 0 6 0;
#P hidden connect 25 0 26 0;
#P hidden connect 23 0 26 0;
#P hidden connect 24 0 26 0;
#P hidden connect 22 0 26 0;
#P pop;

である。ここでは「マルチスライダー」 というオブジェクトを、本来の用途である入力手段としてでなく 視覚的な出力手段として利用している。つまり、刻々と生成される X(n)の値を、時間的にスクロールするグラフのように表示する ことで、myuの値によって次第に倍周期分岐していく状態などが、 容易に把握できるのである。このMAXパッチを走らせたMacを ギャラリーに「展示」して、来場者が任意のmyuの値をマウスで 変化させて音と画面を見る、というようなスタイルにすれば、 これは一種の「インスタレーション」作品ともなるだろう。

カオスには、まだまだ色々な種類のアルゴリズムがある。また、 遺伝アルゴリズムとかライフゲームのような「人工生命」の アルゴリズムもまた、MAXによって容易に音楽に置換できる。 話題の「1/fゆらぎ」を盛り込むのも、まったく簡単である。 これらの数学的なアルゴリズムだけでなく、センサによって 自然界の気温や湿度、風の動きなどをセンシングして音楽に 変換したり、心拍や血圧や脳波、宇宙線や地磁気、街の騒音 や振動などの自然現象(結局はカオスとか1/fゆらぎが多い)、 さらには株価の変動や都市部の大気汚染濃度の状況まで、 音楽に置換している作家もいる。そう、コンピュータ音楽の世界 では「なんでもあり」なのである。ただし、例えばカオスにして も、実際の作品では「どこがカオスか判らなかった」と言われる ことがほとんどである(^_^;)ことを付記しておく。

3.3 スケール感や調性感の織り込み

乱数や自然現象を元にした音楽情報の自動生成アルゴリズムでは、 もっとも基本的には、生成される「でたらめな」音階に対して、 どうやって「音楽らしさ」を盛り込むか、が一種のテクニックと なる。リアルタイム生成でなければ、たとえば和声的なフィルタ をかけて、これをパスしない不協和音を捨て去って再度トライする、 というループを結果が得られるまで回せばいい。ところがここでは 演奏時にその場でリアルタイムに音楽情報を生成するので、 あまり待っていると音楽がコケてしまう。そこで、リアルタイム 処理に適した、二つの簡単なアルゴリズム例を紹介しておこう。

図18 のパッチ "fig18"

max v2;
#N vpatcher 47 120 595 550;
#P newex 122 351 80 9 makenote 50 50;
#P newex 130 380 50 9 noteout 1;
#P newex 31 380 50 9 noteout 2;
#P newex 23 351 92 9 makenote 100 200;
#P newex 24 38 43 196617 loadbang;
#P button 47 71 15 0;
#P number 136 327 34 9 0 0 4096 3;
#P number 105 80 34 9 75 2000 3 3;
#P toggle 147 22 20 0;
#P message 92 53 26 196617 120;
#P newex 362 189 90 196617 if $i1>=$i3 then 0;
#P newex 362 203 147 196617 if $i1<$i2 && $i1>=$i3 then 1;
#P newex 362 217 147 196617 if $i1<$i2 && $i1>=$i3 then 2;
#P newex 362 231 147 196617 if $i1<$i2 && $i1>=$i3 then 3;
#P newex 362 245 147 196617 if $i1<$i2 && $i1>=$i3 then 4;
#P newex 362 259 147 196617 if $i1<$i2 && $i1>=$i3 then 5;
#P newex 362 273 147 196617 if $i1<$i2 && $i1>=$i3 then 6;
#P newex 362 287 147 196617 if $i1<$i2 && $i1>=$i3 then 7;
#P newex 362 301 147 196617 if $i1<$i2 && $i1>=$i3 then 8;
#P newex 362 315 147 196617 if $i1<$i2 && $i1>=$i3 then 9;
#P newex 362 329 153 196617 if $i1<$i2 && $i1>=$i3 then 10;
#P newex 362 343 90 196617 if $i1<$i2 then 11;
#P hidden number 362 177 37 9 0 0 0 3;
#P newex 319 176 41 196617 random;
#P number 362 358 22 9 0 0 0 3;
#P newex 324 154 15 196617 +;
#P newex 341 154 15 196617 +;
#P newex 358 154 15 196617 +;
#P newex 375 154 15 196617 +;
#P newex 392 154 15 196617 +;
#P newex 409 154 15 196617 +;
#P newex 426 154 15 196617 +;
#P newex 443 154 15 196617 +;
#P newex 460 154 15 196617 +;
#P newex 477 154 15 196617 +;
#P newex 494 154 15 196617 +;
#P newex 350 133 164 196617 unpack 1 2 3 4 5 6 7 8 9 10 11 12;
#P user multiSlider 350 43 160 87 0. 99. 12 2921 15;
#P comment 351 31 165 196617 C..C#.D..Eb..E..F..F#.G..G#.A..Bb.B;
#P newex 157 111 35 196617 metro;
#P hidden button 211 151 15 0;
#P newex 220 226 41 196617 random;
#P number 258 193 35 9 0 0 0 3;
#P number 289 224 35 9 0 0 0 3;
#P newex 255 254 27 196617 +;
#P number 155 257 25 9 0 100 3 3;
#P newex 134 278 27 196617 +;
#P newex 207 259 30 196617 * 12;
#P newex 134 302 40 196617 change;
#P number 21 281 33 9 0 0 4096 3;
#P number 18 252 27 9 0 0 0 3;
#P message 18 164 20 196617 36;
#P user kslider 48 134 35 1 24 24 19 7;
#P hidden toggle 159 157 15 0;
#P newex 115 193 96 196617 if $i1==1 then bang;
#N vpreset 8;
#X append 1 2 2 157 159 toggle int 1 \; 3 134 48 kslider int 36 \;
 5 252 18 number int 36 \; 6 281 21 number int 36 \;
 10 257 155 number int 48 \; 12 224 289 number int;
#X append 1 2 4 \; 13 193 258 number int 2 \;
 18 43 350 multiSlider list 99 0 37 0 0 46 0 73 0 0 54 1 \;
 31 358 362 number int 2 \; 33 177 362 number int 189;
#X append 1 2 \; 47 22 147 toggle int 1 \;
 48 80 105 number int 120 \; 49 327 136 number int 50 \;;
#X append 2 2 2 157 159 toggle int 0 \; 3 134 48 kslider int 36 \;
 5 252 18 number int 36 \; 6 281 21 number int 36 \;
 10 257 155 number int 48 \; 12 224 289 number int;
#X append 2 2 4 \; 13 193 258 number int 2 \;
 18 43 350 multiSlider list 99 0 20 50 0 18 8 73 0 23 57 1 \;
 31 358 362 number int 7 \; 33 177 362 number int 107;
#X append 2 2 \; 47 22 147 toggle int 1 \;
 48 80 105 number int 120 \; 49 327 136 number int 67 \;;
#X append 3 2 2 157 159 toggle int 0 \; 3 134 48 kslider int 36 \;
 5 252 18 number int 36 \; 6 281 21 number int 36 \;
 10 257 155 number int 48 \; 12 224 289 number int;
#X append 3 2 4 \; 13 193 258 number int 2 \;
 18 43 350 multiSlider list 99 13 4 50 6 0 16 61 6 23 58 8 \;
 31 358 362 number int 3 \; 33 177 362 number int 201;
#X append 3 2 \; 47 22 147 toggle int 1 \;
 48 80 105 number int 120 \; 49 327 136 number int 63 \;;
#X append 4 2 2 157 159 toggle int 1 \; 3 134 48 kslider int 36 \;
 5 252 18 number int 36 \; 6 281 21 number int 36 \;
 10 257 155 number int 48 \; 12 224 289 number int;
#X append 4 2 4 \; 13 193 258 number int 2 \;
 18 43 350 multiSlider list 99 26 13 50 24 6 27 61 17 31 58 8 \;
 31 358 362 number int 3 \; 33 177 362 number int 261;
#X append 4 2 \; 47 22 147 toggle int 1 \;
 48 80 105 number int 120 \; 49 327 136 number int 51 \;;
#X append 5 2 2 157 159 toggle int 0 \; 3 134 48 kslider int 36 \;
 5 252 18 number int 36 \; 6 281 21 number int 36 \;
 10 257 155 number int 48 \; 12 224 289 number int;
#X append 5 2 4 \; 13 193 258 number int 2 \;
 18 43 350 multiSlider list 82 0 58 0 54 0 54 0 51 0 58 0 \;
 31 358 362 number int 8 \; 33 177 362 number int 102;
#X append 5 2 \; 47 22 147 toggle int 1 \;
 48 80 105 number int 120 \; 49 327 136 number int 68 \;;
#X append 6 2 2 157 159 toggle int 1 \; 3 134 48 kslider int 36 \;
 5 252 18 number int 36 \; 6 281 21 number int 36 \;
 10 257 155 number int 60 \; 12 224 289 number int;
#X append 6 2 4 \; 13 193 258 number int 2 \;
 18 43 350 multiSlider list 71 0 0 55 0 0 51 0 0 51 0 0 \;
 31 358 362 number int 3 \; 33 177 362 number int 121;
#X append 6 2 \; 47 22 147 toggle int 1 \;
 48 80 105 number int 120 \; 49 327 136 number int 63 \;;
#X append 7 2 2 157 159 toggle int 0 \; 3 134 48 kslider int 36 \;
 5 252 18 number int 36 \; 6 281 21 number int 36 \;
 10 257 155 number int 60 \; 12 224 289 number int;
#X append 7 2 4 \; 13 193 258 number int 2 \;
 18 43 350 multiSlider list 97 0 16 0 44 0 0 58 0 17 0 39 \;
 31 358 362 number int 0 \; 33 177 362 number int 238;
#X append 7 2 \; 47 22 147 toggle int 1 \;
 48 80 105 number int 120 \; 49 327 136 number int 60 \;;
#X append 8 2 2 157 159 toggle int 0 \; 3 134 48 kslider int 36 \;
 5 252 18 number int 36 \; 6 281 21 number int 36 \;
 10 257 155 number int 48 \; 12 224 289 number int;
#X append 8 2 4 \; 13 193 258 number int 2 \;
 18 43 350 multiSlider list 97 0 46 0 0 65 0 67 0 8 0 34 \;
 31 358 362 number int 5 \; 33 177 362 number int 149;
#X append 8 2 \; 47 22 147 toggle int 1 \;
 48 80 105 number int 120 \; 49 327 136 number int 65 \;;
#P preset 192 47 47 27;
#P connect 43 0 31 0;
#P connect 44 0 31 0;
#P connect 42 0 31 0;
#P connect 45 0 31 0;
#P connect 6 0 52 0;
#P connect 41 0 31 0;
#P connect 51 0 50 0;
#P connect 40 0 31 0;
#P connect 47 0 16 0;
#P connect 5 0 6 0;
#P connect 15 0 32 0;
#P connect 50 0 4 0;
#P connect 50 0 46 0;
#P connect 33 0 45 0;
#P connect 33 0 44 0;
#P connect 33 0 43 0;
#P connect 33 0 42 0;
#P connect 33 0 41 0;
#P connect 33 0 40 0;
#P connect 33 0 39 0;
#P connect 33 0 38 0;
#P connect 33 0 37 0;
#P connect 33 0 36 0;
#P connect 33 0 35 0;
#P connect 33 0 34 0;
#P connect 31 0 9 0;
#P connect 48 0 16 1;
#P connect 13 0 14 1;
#P connect 12 0 11 1;
#P connect 10 0 9 1;
#P connect 35 0 31 0;
#P connect 39 0 31 0;
#P connect 36 0 31 0;
#P connect 38 0 31 0;
#P connect 37 0 31 0;
#P connect 32 0 33 0;
#P connect 34 0 31 0;
#P connect 29 0 30 1;
#P connect 29 0 44 1;
#P connect 29 0 45 2;
#P connect 28 0 29 1;
#P connect 28 0 43 1;
#P connect 28 0 44 2;
#P connect 27 0 28 1;
#P connect 27 0 42 1;
#P connect 27 0 43 2;
#P connect 26 0 27 1;
#P connect 26 0 41 1;
#P connect 26 0 42 2;
#P connect 25 0 26 1;
#P connect 25 0 40 1;
#P connect 25 0 41 2;
#P connect 24 0 25 1;
#P connect 24 0 39 1;
#P connect 24 0 40 2;
#P connect 23 0 38 1;
#P connect 23 0 24 1;
#P connect 23 0 39 2;
#P connect 22 0 37 1;
#P connect 22 0 23 1;
#P connect 22 0 38 2;
#P connect 21 0 36 1;
#P connect 21 0 22 1;
#P connect 21 0 37 2;
#P connect 20 0 35 1;
#P connect 20 0 21 1;
#P connect 20 0 36 2;
#P connect 19 1 29 0;
#P connect 19 2 28 0;
#P connect 19 0 30 0;
#P connect 19 3 27 0;
#P connect 19 4 26 0;
#P connect 19 5 25 0;
#P connect 19 6 24 0;
#P connect 19 11 34 1;
#P connect 19 7 23 0;
#P connect 19 9 21 0;
#P connect 19 8 22 0;
#P connect 19 10 20 0;
#P connect 19 11 20 1;
#P connect 19 11 35 2;
#P connect 30 0 32 1;
#P connect 2 0 1 0;
#P connect 16 0 2 0;
#P connect 15 0 14 0;
#P connect 16 0 15 0;
#P connect 14 0 11 0;
#P connect 46 0 48 0;
#P connect 11 0 8 0;
#P connect 4 0 5 0;
#P connect 9 0 7 0;
#P connect 18 0 19 0;
#P connect 8 0 10 0;
#P connect 3 0 5 0;
#P connect 1 0 5 0;
#P connect 7 0 49 0;
#P connect 52 0 53 0;
#P connect 52 1 53 1;
#P connect 55 0 54 0;
#P connect 49 0 55 0;
#P connect 55 1 54 1;
#P pop;

は、画面情報にあるプリセットボタンの いずれかをクリックすると、とりあえずスタートする。音源の 音色としては、1チャンネルをエレピに、2チャンネルをベースに でもすると、雰囲気が出るだろう。

このパッチのポイントは、図18の右側にある。左側のMIDI ノートナンバ生成部分は、既に述べたものとまったく同じである。 右側上方にある、マルチスライダーによる「生成音階確率グラフ」 をマウスでいじりながら、生成されるフレーズの変化を確かめて 欲しい。このパッチで、ランダムを基本として生成される音列に、 任意の「さじ加減」でスケールの色合いを加えることができる のである。また、これと合わせて画面内の「鍵盤」オブジェクト をマウスでクリックすると、連打されているベース音を変化 させることができる。このパッチだけで、調性感とスケール感 の独習ができてしまう、という教育的な内容も含まれている。

また、 図19 のパッチ "fig19"

max v2;
#N vpatcher 42 125 356 534;
#P newex 28 333 92 9 makenote 100 200;
#P newex 36 362 50 9 noteout 2;
#P newex 135 362 50 9 noteout 1;
#P newex 127 333 80 9 makenote 50 50;
#P newex 21 35 43 196617 loadbang;
#P number 99 65 34 9 75 2000 3 3;
#P toggle 144 19 20 0;
#P message 91 38 26 196617 120;
#P number 25 305 33 9 0 0 4096 3;
#P number 154 308 34 9 0 0 4096 3;
#P button 25 72 15 0;
#P newex 161 87 35 196617 metro;
#P message 68 111 14 196617 6;
#P number 66 148 35 9 0 0 0 3;
#N vtable 128 379 350 589 517 989701 128 TABLE2.MAX;
#P newobj 79 267 92 196617 table TABLE2.MAX;
#P newex 82 238 56 196617 random 10;
#P newex 73 210 96 196617 if $i1==0 then bang;
#P number 111 181 35 9 0 0 0 3;
#P newex 81 181 27 196617 %;
#P newex 120 158 27 196617 +;
#P message 129 130 14 196617 1;
#P hidden button 170 112 15 0;
#P newex 171 177 56 196617 random 36;
#N vtable 128 379 133 589 300 989701 128 TABLE1.MAX;
#P newobj 193 233 92 196617 table TABLE1.MAX;
#P newex 188 280 40 196617 change;
#P connect 14 0 12 0;
#P connect 14 0 17 0;
#P connect 3 0 4 0;
#P connect 3 0 2 0;
#P connect 13 0 3 0;
#P connect 18 0 13 0;
#P connect 16 0 24 0;
#P connect 15 0 21 0;
#P connect 11 0 6 1;
#P connect 7 0 8 0;
#P connect 7 0 5 1;
#P connect 6 0 7 0;
#P connect 19 0 13 1;
#P connect 10 0 16 0;
#P connect 8 0 9 0;
#P connect 9 0 10 0;
#P connect 5 0 6 0;
#P connect 12 0 11 0;
#P connect 2 0 1 0;
#P connect 0 0 15 0;
#P connect 24 0 23 0;
#P connect 24 1 23 1;
#P connect 21 0 22 0;
#P connect 1 0 0 0;
#P connect 4 0 5 0;
#P connect 21 1 22 1;
#P connect 17 0 19 0;
#P connect 20 0 14 0;
#P pop;

は、同じディレクトリに置かれた "table1"

table 48 48 48 48 48 48 49 50 50 50 51 51 51 51 52 53
 53 53 53 54 54 55 55 55 55 55 57 57 58 58 58 58 58
 60 60 60 41 41 40 40 40 40 40 40 40 62 63 63 63 63
 63 63 63 63 63 63 63 63 63 62 62 62 62 62 61 61 61
 61 61 61 60 60 60 60 60 59 59 59 59 59 59 58 58 58
 58 58 58 57 57 57 58 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

、"table2"

table 32 36 34 34 34 36 36 38 38 36 48 50 50 50 50 50
 50 50 49 49 49 49 49 49 49 49 49 49 49 49 48 48 48
 48 48 48 48 48 48 48 48 48 48 47 47 47 47 47 47 47
 47 47 47 47 47 47 47 47 47 46 46 46 46 46 46 46 46
 46 46 46 45 45 45 45 45 44 44 44 44 44 44 43 43 43
 43 43 43 42 42 42 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

という二つの「テーブル」 オブジェクトを呼び出す構成となっている。このテーブル によって、X軸方向から与えられるランダム入力に対応した MIDIノートナンバをY軸方向に任意に設定できる。横幅の広い ところは、その音階の出現確率がより高くなる、という分かり易さ によって、これまた味付けを色々と楽しむことができるのである。

3.4 秘技「長周期BGM」

自動作曲アルゴリズムの最後の例として、筆者が多くのコンピュータ音楽 作品で何度も愛用しているテクニックをご披露しよう。判ってしまえば なんでもないことなのだが、この単純なアルゴリズムは、うまく使うと 効果テキメンである。正直言えば、あまりこの「技」を広めたくない、という 内心の躊躇もあるのだが、「MAXパッチは皆んなの共有財産」というフリー ウェアの精神に則って、敢えて公開する次第である。味付けをオリジナル化 して、活用していただければ幸いである。

ここで紹介するパッチは、 図20 のパッチ "fig20"

max v2;
#N vpatcher 28 133 709 516;
#P newex 108 476 53 196617 delay 600;
#P newex 89 74 47 196617 delay 20;
#P newex 108 191 53 196617 delay 400;
#P newex 103 335 53 196617 delay 500;
#P comment 579 14 64 196617 Stop !;
#P button 606 29 32 0;
#P button 37 28 32 0;
#P comment 18 12 64 196617 Start !;
#P newex 37 172 49 196617 pgmout 7;
#P newex 37 152 49 196617 pgmout 6;
#P newex 37 132 49 196617 pgmout 5;
#P newex 37 112 49 196617 pgmout 4;
#P number 37 91 35 9 0 0 0 3;
#P message 37 71 20 196617 50;
#P button 209 507 15 0;
#P button 189 507 15 0;
#P message 227 533 20 196617 35;
#P number 226 554 31 9 0 0 0 3;
#P button 189 574 15 0;
#P message 189 533 14 196617 1;
#P newex 189 553 35 196617 metro;
#P message 208 533 14 196617 0;
#P newex 207 594 27 196617 +;
#P number 236 595 25 9 0 30000 2 3;
#P number 321 594 18 9 0 0 0 3;
#P newex 292 593 27 196617 % 4;
#P newex 263 593 27 196617 / 2;
#P number 190 616 35 9 0 0 0 3;
#P newex 228 615 52 196617 ctlout 7 7;
#P message 250 533 41 196617 updown;
#P message 316 533 20 196617 70;
#P message 294 533 20 196617 10;
#P number 278 554 29 9 0 0 0 3;
#P number 310 554 30 9 0 0 0 3;
#P message 190 595 14 196617 1;
#P newex 206 573 66 196617 counter;
#P message 274 574 36 196617 min \$1;
#P message 312 574 39 196617 max \$1;
#P message 402 589 14 196617 0;
#P message 374 589 20 196617 85;
#P message 352 589 20 196617 73;
#P button 392 569 15 0;
#P button 360 569 15 0;
#P message 470 589 14 196617 0;
#P message 442 589 20 196617 90;
#P message 420 589 20 196617 72;
#P button 460 569 15 0;
#P button 428 569 15 0;
#P button 496 569 15 0;
#P button 528 569 15 0;
#P message 488 589 20 196617 75;
#P message 510 589 20 196617 85;
#P message 538 589 14 196617 0;
#P message 606 589 14 196617 0;
#P message 578 589 20 196617 75;
#P message 556 589 20 196617 71;
#P button 596 569 15 0;
#P button 564 569 15 0;
#P newex 352 614 50 196617 noteout 7;
#P newex 356 534 62 196617 select 0 1 2;
#P newex 420 534 59 196617 delay 1000;
#P button 481 535 15 0;
#P button 208 362 15 0;
#P button 188 362 15 0;
#P message 226 388 20 196617 23;
#P number 225 409 31 9 0 0 0 3;
#P button 188 429 15 0;
#P message 188 388 14 196617 1;
#P newex 188 408 35 196617 metro;
#P message 207 388 14 196617 0;
#P newex 206 449 27 196617 +;
#P number 235 450 25 9 0 30000 2 3;
#P number 320 449 18 9 0 0 0 3;
#P newex 291 448 27 196617 % 4;
#P newex 262 448 27 196617 / 2;
#P number 189 471 35 9 0 0 0 3;
#P newex 227 470 52 196617 ctlout 7 6;
#P message 249 388 41 196617 updown;
#P message 315 388 20 196617 75;
#P message 293 388 20 196617 25;
#P number 277 409 29 9 0 0 0 3;
#P number 309 409 30 9 0 0 0 3;
#P message 189 450 14 196617 1;
#P newex 205 428 66 196617 counter;
#P message 273 429 36 196617 min \$1;
#P message 311 429 39 196617 max \$1;
#P message 401 444 14 196617 0;
#P message 373 444 20 196617 85;
#P message 351 444 20 196617 70;
#P button 391 424 15 0;
#P button 359 424 15 0;
#P message 469 444 14 196617 0;
#P message 441 444 20 196617 95;
#P message 419 444 20 196617 53;
#P button 459 424 15 0;
#P button 427 424 15 0;
#P button 495 424 15 0;
#P button 527 424 15 0;
#P message 487 444 20 196617 58;
#P message 509 444 20 196617 95;
#P message 537 444 14 196617 0;
#P message 605 444 14 196617 0;
#P message 577 444 20 196617 90;
#P message 555 444 20 196617 65;
#P button 595 424 15 0;
#P button 563 424 15 0;
#P newex 351 469 50 196617 noteout 6;
#P newex 355 389 62 196617 select 0 1 2;
#P newex 419 389 59 196617 delay 1000;
#P button 480 390 15 0;
#P button 479 247 15 0;
#P newex 418 246 59 196617 delay 1000;
#P newex 354 246 62 196617 select 0 1 2;
#P newex 350 326 50 196617 noteout 5;
#P button 562 281 15 0;
#P button 594 281 15 0;
#P message 554 301 20 196617 55;
#P message 576 301 20 196617 95;
#P message 604 301 14 196617 0;
#P message 536 301 14 196617 0;
#P message 508 301 26 196617 100;
#P message 486 301 20 196617 43;
#P button 526 281 15 0;
#P button 494 281 15 0;
#P button 426 281 15 0;
#P button 458 281 15 0;
#P message 418 301 20 196617 67;
#P message 440 301 20 196617 90;
#P message 468 301 14 196617 0;
#P button 358 281 15 0;
#P button 390 281 15 0;
#P message 350 301 20 196617 43;
#P message 372 301 26 196617 100;
#P message 400 301 14 196617 0;
#P message 310 286 39 196617 max \$1;
#P message 272 286 36 196617 min \$1;
#P newex 204 285 66 196617 counter;
#P message 188 307 14 196617 1;
#P number 308 266 30 9 0 0 0 3;
#P number 276 266 29 9 0 0 0 3;
#P message 292 245 20 196617 30;
#P message 314 245 20 196617 85;
#P message 248 245 41 196617 updown;
#P newex 226 327 52 196617 ctlout 7 5;
#P number 188 328 35 9 0 0 0 3;
#P newex 261 305 27 196617 / 2;
#P newex 290 305 27 196617 % 4;
#P number 319 306 18 9 0 0 0 3;
#P number 234 307 25 9 0 30000 2 3;
#P newex 205 306 27 196617 +;
#P message 206 245 14 196617 0;
#P newex 187 265 35 196617 metro;
#P message 187 245 14 196617 1;
#P button 187 286 15 0;
#P number 224 266 31 9 0 0 0 3;
#P message 225 245 20 196617 31;
#P button 187 219 15 0;
#P button 207 219 15 0;
#P button 478 104 15 0;
#P newex 353 103 62 196617 select 0 1 2;
#P newex 349 183 50 196617 noteout 4;
#P button 561 138 15 0;
#P button 593 138 15 0;
#P message 553 158 20 196617 60;
#P message 575 158 20 196617 90;
#P message 603 158 14 196617 0;
#P message 535 158 14 196617 0;
#P message 507 158 26 196617 100;
#P message 485 158 20 196617 36;
#P button 525 138 15 0;
#P button 493 138 15 0;
#P button 425 138 15 0;
#P button 457 138 15 0;
#P message 417 158 20 196617 48;
#P message 439 158 26 196617 100;
#P message 467 158 14 196617 0;
#P button 357 138 15 0;
#P button 389 138 15 0;
#P message 349 158 20 196617 36;
#P message 371 158 26 196617 100;
#P message 399 158 14 196617 0;
#P message 309 143 39 196617 max \$1;
#P message 271 143 36 196617 min \$1;
#P newex 203 142 66 196617 counter;
#P message 187 164 14 196617 1;
#P number 307 123 30 9 0 0 0 3;
#P number 275 123 29 9 0 0 0 3;
#P message 291 102 20 196617 30;
#P message 313 102 20 196617 90;
#P message 247 102 41 196617 updown;
#P newex 225 184 52 196617 ctlout 7 4;
#P number 187 185 35 9 0 0 0 3;
#P newex 260 162 27 196617 / 2;
#P newex 289 162 27 196617 % 4;
#P number 318 163 18 9 0 0 0 3;
#P number 233 164 25 9 0 30000 2 3;
#P newex 204 163 27 196617 +;
#P message 205 102 14 196617 0;
#P newex 186 122 35 196617 metro;
#P message 186 102 14 196617 1;
#P button 186 143 15 0;
#P number 223 123 31 9 0 0 0 3;
#P message 224 102 20 196617 37;
#P button 186 76 15 0;
#P button 206 76 15 0;
#P newex 417 103 59 196617 delay 1000;
#P connect 205 0 190 0;
#P connect 204 0 203 0;
#P connect 204 0 2 0;
#P connect 203 0 202 0;
#P connect 203 0 49 0;
#P connect 193 0 194 0;
#P connect 193 0 195 0;
#P connect 193 0 196 0;
#P connect 188 0 185 1;
#P connect 182 0 183 1;
#P connect 182 0 179 0;
#P connect 202 0 205 0;
#P connect 202 0 142 0;
#P connect 200 0 1 0;
#P connect 200 0 48 0;
#P connect 200 0 143 0;
#P connect 200 0 191 0;
#P connect 199 0 192 0;
#P connect 199 0 204 0;
#P connect 192 0 193 0;
#P connect 191 0 184 0;
#P connect 191 0 145 0;
#P connect 190 0 186 0;
#P connect 190 0 189 0;
#P connect 190 0 176 0;
#P connect 190 0 174 0;
#P connect 190 0 175 0;
#P connect 189 0 188 0;
#P connect 187 0 170 0;
#P connect 186 0 185 0;
#P connect 186 0 182 0;
#P connect 185 0 187 0;
#P connect 184 0 185 0;
#P connect 183 0 182 0;
#P connect 181 0 146 0;
#P connect 180 0 181 0;
#P connect 179 0 180 0;
#P connect 178 0 177 0;
#P connect 176 0 170 0;
#P connect 175 0 172 0;
#P connect 174 0 173 0;
#P connect 173 0 169 0;
#P connect 172 0 168 0;
#P connect 170 1 171 0;
#P connect 170 0 178 0;
#P connect 169 0 170 0;
#P connect 171 0 183 0;
#P connect 168 0 170 0;
#P connect 167 0 147 1;
#P connect 166 0 147 1;
#P connect 165 0 147 0;
#P connect 164 0 165 0;
#P connect 164 0 167 0;
#P connect 163 0 166 0;
#P connect 163 0 165 0;
#P connect 162 0 147 1;
#P connect 161 0 147 1;
#P connect 160 0 147 0;
#P connect 159 0 160 0;
#P connect 159 0 162 0;
#P connect 158 0 160 0;
#P connect 158 0 161 0;
#P connect 157 0 155 0;
#P connect 157 0 154 0;
#P connect 156 0 155 0;
#P connect 156 0 153 0;
#P connect 154 0 147 1;
#P connect 155 0 147 0;
#P connect 153 0 147 1;
#P connect 152 0 147 1;
#P connect 151 0 147 1;
#P connect 150 0 147 0;
#P connect 149 0 150 0;
#P connect 149 0 152 0;
#P connect 148 0 150 0;
#P connect 146 0 163 0;
#P connect 146 1 158 0;
#P connect 146 1 164 0;
#P connect 146 2 159 0;
#P connect 146 2 157 0;
#P connect 146 3 156 0;
#P connect 146 3 148 0;
#P connect 146 0 149 0;
#P connect 145 0 144 0;
#P connect 144 0 159 0;
#P connect 144 0 156 0;
#P connect 144 0 149 0;
#P connect 143 0 136 0;
#P connect 143 0 97 0;
#P connect 143 0 96 0;
#P connect 142 0 138 0;
#P connect 142 0 141 0;
#P connect 142 0 128 0;
#P connect 142 0 126 0;
#P connect 142 0 127 0;
#P connect 141 0 140 0;
#P connect 140 0 137 1;
#P connect 138 0 137 0;
#P connect 138 0 134 0;
#P connect 137 0 139 0;
#P connect 136 0 137 0;
#P connect 135 0 134 0;
#P connect 134 0 135 1;
#P connect 134 0 131 0;
#P connect 132 0 133 0;
#P connect 133 0 98 0;
#P connect 131 0 132 0;
#P connect 128 0 122 0;
#P connect 127 0 124 0;
#P connect 126 0 125 0;
#P connect 125 0 121 0;
#P connect 124 0 120 0;
#P connect 123 0 135 0;
#P connect 122 1 123 0;
#P connect 122 0 130 0;
#P connect 121 0 122 0;
#P connect 120 0 122 0;
#P connect 119 0 99 1;
#P connect 118 0 99 1;
#P connect 117 0 99 0;
#P connect 116 0 117 0;
#P connect 139 0 122 0;
#P connect 116 0 119 0;
#P connect 115 0 117 0;
#P connect 115 0 118 0;
#P connect 114 0 99 1;
#P connect 113 0 99 1;
#P connect 112 0 99 0;
#P connect 111 0 112 0;
#P connect 111 0 114 0;
#P connect 110 0 112 0;
#P connect 110 0 113 0;
#P connect 109 0 107 0;
#P connect 109 0 106 0;
#P connect 108 0 107 0;
#P connect 108 0 105 0;
#P connect 107 0 99 0;
#P connect 106 0 99 1;
#P connect 105 0 99 1;
#P connect 104 0 99 1;
#P connect 103 0 99 1;
#P connect 102 0 99 0;
#P connect 101 0 102 0;
#P connect 101 0 104 0;
#P connect 100 0 102 0;
#P connect 100 0 103 0;
#P connect 98 0 115 0;
#P connect 98 1 116 0;
#P connect 98 2 111 0;
#P connect 98 1 110 0;
#P connect 98 2 109 0;
#P connect 98 3 108 0;
#P connect 98 3 100 0;
#P connect 98 0 101 0;
#P connect 97 0 96 0;
#P connect 96 0 116 0;
#P connect 96 0 111 0;
#P connect 96 0 108 0;
#P connect 96 0 101 0;
#P connect 95 0 75 0;
#P connect 95 0 80 0;
#P connect 95 0 83 0;
#P connect 95 0 90 0;
#P connect 94 0 95 0;
#P connect 93 0 76 0;
#P connect 93 1 81 0;
#P connect 93 2 80 0;
#P connect 93 1 75 0;
#P connect 93 2 82 0;
#P connect 93 3 83 0;
#P connect 93 3 91 0;
#P connect 93 0 90 0;
#P connect 91 0 89 0;
#P connect 91 0 88 0;
#P connect 90 0 89 0;
#P connect 90 0 87 0;
#P connect 89 0 92 0;
#P connect 88 0 92 1;
#P connect 87 0 92 1;
#P connect 130 0 129 0;
#P connect 86 0 92 1;
#P connect 85 0 92 1;
#P connect 84 0 92 0;
#P connect 83 0 86 0;
#P connect 82 0 84 0;
#P connect 82 0 85 0;
#P connect 81 0 79 0;
#P connect 81 0 78 0;
#P connect 80 0 79 0;
#P connect 80 0 77 0;
#P connect 148 0 151 0;
#P connect 79 0 92 0;
#P connect 78 0 92 1;
#P connect 76 0 74 0;
#P connect 76 0 73 0;
#P connect 75 0 74 0;
#P connect 75 0 72 0;
#P connect 74 0 92 0;
#P connect 73 0 92 1;
#P connect 77 0 92 1;
#P connect 72 0 92 1;
#P connect 71 0 69 0;
#P connect 70 0 69 0;
#P connect 69 1 68 0;
#P connect 69 0 61 0;
#P connect 68 0 56 0;
#P connect 67 0 71 0;
#P connect 66 0 70 0;
#P connect 65 0 66 0;
#P connect 64 0 67 0;
#P connect 63 0 69 0;
#P connect 61 0 62 0;
#P connect 60 0 59 0;
#P connect 59 0 58 0;
#P connect 58 0 93 0;
#P connect 57 0 56 1;
#P connect 57 0 60 0;
#P connect 56 0 57 0;
#P connect 55 0 54 0;
#P connect 54 0 52 0;
#P connect 191 0 144 0;
#P connect 53 0 54 0;
#P connect 53 0 57 0;
#P connect 52 0 69 0;
#P connect 51 0 54 1;
#P connect 50 0 51 0;
#P connect 49 0 53 0;
#P connect 83 0 84 0;
#P connect 49 0 50 0;
#P connect 49 0 63 0;
#P connect 49 0 65 0;
#P connect 49 0 64 0;
#P connect 48 0 55 0;
#P connect 48 0 94 0;
#P connect 48 0 95 0;
#P connect 47 0 28 0;
#P connect 47 0 36 0;
#P connect 47 0 33 0;
#P connect 47 0 43 0;
#P connect 46 0 29 0;
#P connect 46 1 28 0;
#P connect 46 1 34 0;
#P connect 46 2 33 0;
#P connect 46 2 35 0;
#P connect 46 3 36 0;
#P connect 46 3 44 0;
#P connect 46 0 43 0;
#P connect 44 0 42 0;
#P connect 44 0 41 0;
#P connect 43 0 42 0;
#P connect 43 0 40 0;
#P connect 42 0 45 0;
#P connect 41 0 45 1;
#P connect 40 0 45 1;
#P connect 39 0 45 1;
#P connect 38 0 45 1;
#P connect 37 0 45 0;
#P connect 36 0 37 0;
#P connect 144 0 164 0;
#P connect 36 0 39 0;
#P connect 35 0 37 0;
#P connect 35 0 38 0;
#P connect 34 0 31 0;
#P connect 34 0 32 0;
#P connect 33 0 32 0;
#P connect 33 0 30 0;
#P connect 32 0 45 0;
#P connect 31 0 45 1;
#P connect 30 0 45 1;
#P connect 29 0 27 0;
#P connect 29 0 26 0;
#P connect 28 0 27 0;
#P connect 28 0 25 0;
#P connect 27 0 45 0;
#P connect 26 0 45 1;
#P connect 25 0 45 1;
#P connect 24 0 22 0;
#P connect 23 0 22 0;
#P connect 22 1 21 0;
#P connect 22 0 14 0;
#P connect 21 0 9 0;
#P connect 20 0 24 0;
#P connect 19 0 23 0;
#P connect 18 0 19 0;
#P connect 17 0 20 0;
#P connect 16 0 22 0;
#P connect 14 0 15 0;
#P connect 13 0 12 0;
#P connect 12 0 11 0;
#P connect 11 0 46 0;
#P connect 10 0 9 1;
#P connect 10 0 13 0;
#P connect 9 0 10 0;
#P connect 8 0 7 0;
#P connect 7 0 5 0;
#P connect 6 0 7 0;
#P connect 193 0 197 0;
#P connect 6 0 10 0;
#P connect 5 0 22 0;
#P connect 4 0 7 1;
#P connect 2 0 6 0;
#P connect 2 0 16 0;
#P connect 2 0 3 0;
#P connect 2 0 18 0;
#P connect 2 0 17 0;
#P connect 1 0 8 0;
#P connect 3 0 4 0;
#P connect 1 0 0 0;
#P connect 1 0 47 0;
#P connect 0 0 47 0;
#P pop;

である。かなり大きく、図には下半分が入っていない が、同じパターンのブロックが4つ並んでいるだけなので、仕掛けはこれで 十分に判るだろう。図20で上下に2段並んでいるそれぞれのブロックは、 なんとこれでたった1音を刻々と生成する。このパッチにはこのブロックが 4つあるので、いわば「4音ポリフォニック」のパート構成だけである。

このパッチは、サブパッチとして作品のごく一部に使われる、たった4音の BGM生成ブロックである。それで何ができるか、と思ったら、とりあえず スタートボタンを押して、生成される「音楽」を聞いてみて欲しい。これは 一体、どこに「工夫」があるだろうか。ヒントは、無限に繰り返される BGMの周期の「長さ」にある。

各ブロックの右側では、それぞれ設定された4種類のMIDIノートナンバを、ONと OFFとを別々にトリガしているだけである。つまり、1音がONされて、しばらくして OFFされると次の音をONする、という無限ループである。これに対して、各ブロック の左側では、「metro」オブジェクトで「counter」オブジェクト(アップダウン カウンタとして動作指定)を駆動することで、漸増と漸減を繰り返す値を生成 し、これをMIDIのボリュームとして出力している。両方のブロックは同期している ので、結果として、各ブロックでは「小さくONしてクレシェンド、ピーク からデクレシェンドしてOFF」という動作を繰り返していることになる。

そしてポイントは、各ブロックの周期がそれぞれバラバラ、正確には、 「なるべく割り切れないように」設定されている、というところである。 結果として、この4つのブロックの音はそれぞれ別々のタイミングで 登場と退場を繰り返し、このミックスされた音響が全体のハーモニーを 構成する。各パートの4種類の音階は慎重に選ばれており、それぞれの 瞬間に響く「和音」が、ここでの作曲の中心となっている。全体として、 このBGMの周期は非常に大きな最小公倍数となり、なんとも落ちつかない 独特の雰囲気を容易に実現しているのである。

筆者はタイプの異なる多くのコンピュータ音楽作品で、このアルゴリズム を何度も活用している。もちろん、作品ごとに音色も音階の設定もタイミング も新しく検討する。また、固定的パッチとして生成するだけでなく、さらに ここにランダム性やセンサによる即興性を加味することで、音楽は演奏するたびに 異なった新鮮なものとなる。このアルゴリズムは筆者のオリジナルであるが、 しかし考えてみれば、ちっとも目新しいものではない。クラシックの世界にも、 作曲法として似たようなものは昔からある。コンピュータ音楽といっても、 「音楽の本質」という点では、まったく一般の音楽と変わらないのである。

参考文献

[1]YUKO NEXUS6 :
サイバー・キッチン・ミュージック(翔泳社)

[2]ノイマンピアノ :
マジカルMAXツアー((株)ディー・アート)