チュートリアル 21: MIDIコントロール
poly~ オブジェクトの使用

異なる方法によるポリフォニーへのアプローチ

これまでの章では、単純にポリフォニックなボイス・アサインメント(ボイス割当て)を行なうための poly オブジェクトの使い方を示してきました。この章では、ポリフォニックなボイス・アサインメントを行う、よりエレガントで効率のよい方法である poly~ オブジェクトについて述べようと思います。

前の章の例では、サンプラのサブパッチのコピーを作り、poly オブジェクトのボイスナンバリング機能を用いてメッセージをそれぞれのサブパッチに振り分けていました。そこでは、どのような種類のサウンド生成サブパッチでも簡単に使用することができました。次の例は、シンプルな4音ポリフォニックシンセサイザを実装するために、littlesynth~というサブパッチを使用しているものです。

しかし、この方法で動作する場合、2つの不都合な点があります。第1に、littlesynth~ の多くのコピーを複製してつなぎ合わせることは、多くの管理を必要とする点です。さらに、CPUの利用に関する問題も生じます。littlesynth~サブパッチャーの4つのコピーすべては常に動作していて、サウンドが作られていない時でも常に処理を行っています。

MSP2.0では、この問題を解決するために異なった方法が導入されています。poly~ オブジェクトは、それ1つで同じMSPサブパッチの複数のコピーを作り管理することができます。またCPUリソースの節約のために、サブパッチの各々のコピーのシグナル処理動作をコントロールすることもできます。

poly~オブジェクト

poly~ オブジェクトはパッチャーファイル名をアーギュメントとして取り、そのコピー(またはインスタンス)が作られる数を指定する値がその後に続きます。これまでの方法では、ポリフォニーを実装するために手動で複製をしていましたが、それを同じ「数」で指定する必要があります。下の図はpoly~オブジェクトの例です。

poly~ オブジェクトをダブルクリックするとサブパッチャーが開き、littlebeep~オブジェクトの内側を見ることができます。

ちょっと、littlebeep~ パッチを見てみましょう。これまでにはなかった inout~thispoly~ というオブジェクトがありますが、それ以外はかなり簡単なものです。ここでは、入力されるMIDIナンバーを取得し、mtof を用いて周波数値に変換して、その周波数のサイン波を140ミリ秒間出力します。140ミリ秒間の振幅エンベロープは line~ オブジェクトによって与えられています。

ところで、inout~ オブジェクトはどんな働きをしているのでしょうか? poly~ オブジェクトによって作られるサブパッチは、インレット、アウトレットとして特別なオブジェクトを使用します。inout オブジェクトはコントロール用のインレット、アウトレットを作り、in~out~ オブジェクトはシグナルインレットとシグナルアウトレットを作ります。どのインレットをどのオブジェクトに割り当てるかは、オブジェクトに数値のアーギュメントを追加することによって指定します。in 1 オブジェクトは poly~ オブジェクトの最も左のインレットに対応します。poly~ オブジェクトは、インレットとアウトレットの数を保持していますが、これは、サブパッチをロードするよう指示した際にインレットとアウトレットを生成するために必要となります。

poly~ オブジェクトに送られるメッセージは、notemidinote メッセージを用いて、サブパッチの別々のインスタンスに動的に振り分けられるか、手動で target メッセージを用いて送信されます。

poly~ は、note メッセージを左インレットで受け取ると、使用されていない(ビジーでない)サブパッチのコピーが見つかるまでメモリ内を探索し、メッセージをそれに送ります。サブパッチのインスタンスは、thispoly~ オブジェクトを使用して、親となる poly~ オブジェクトに、自分自身がビジーであることを知らせることができます。thispoly~ オブジェクトはインレットからシグナルまたは数値を受け取り、ビジーかどうかの状態(ステート)をセットします。0 シグナルまたは数値 0 が thispoly~ のインレットに送られると、親の poly~ に対して、そのインスタンスが、 notemidinote メッセージを受け入れ可能であることを通知します。非0 のシグナルまたは値がインレットで受け取られると、親の poly~ にインスタンスがビジーであることを通知します。これらがビジーでなくなるまで note、midinoteメッセージは送信されません。ビジー状態(ステート)はサブパッチャーのインスタンスによって出力される音のデュレーション(持続)と一致しますが、その他の意味をあらわすものとしても利用できます。上の例では、*~ からのオーディオレベルが0でない時、サブパッチはビジー状態になります。line~ からの振幅エンベロープが 0 になり、サウンドがストップした場合、サブパッチの thispoly~ のコピーは poly~ に対して入力可能であることを通知します。

thispoly~ オブジェクトはまた、サブパッチのコピー各々のシグナル処理の使用をコントロールすることができます。mute メッセージが値1を伴ってthispoly~ に送られると、そのサブパッチのシグナル処理はストップします。mute 0メッセージが受け取られるとシグナル処理は再開します。このことを利用して、littlebeep~ を書き換えることができます。ここでは、音が終えられるとシグナル処理はオフになり、新しいイベントが受け取られるとシグナル処理は再開されます。

パッチの機能は同じですが、この方法はより効率的です。それは、CPUの割当て量は常にその時点で出力されている音の数に基づいているからです。

poly~ を利用してイベント割当てを行う他の方法として、target メッセージの使用があります。整数を伴う target メッセージを poly~ サブパッチの左インレットに送ることによって、 poly~ に対し、それに続くメッセージを該当のサブパッチのインスタンスに送るよう要請します。poly~ オブジェクトを、前の章の poly オブジェクトと併用してMIDIシンセサイザを作ることができます。

poly~ サブパッチは次のように target メッセージを使用します。

この例のサブパッチャーでは、入力されるMIDIピッチとベロシティのペアはサイン波によるサウンドをシンセサイズするために使用されています。リストを受信すると、サブパッチャーは thispoly~ bang を送り、インスタンス、あるいはボイスナンバを出力させます。下の例では、ボイスナンバがアウトレットから送信されるのを親パッチ上で見ることができます。

親パッチでは、poly オブジェクトが、makenoteから出力されるMIDIピッチ/ベロシティのペアにボイスナンバを割当てます。poly オブジェクトからのボイスナンバは target メッセージを前に付け加えられて poly~ に送られます。これは、poly~ に対し、target メッセージの次のデータ(リスト)を poly~ によって指定された(訳注参照) targetbeep~ サブパッチャーのインスタンスに送るよう要求します。

訳注:target メッセージの指示によって指定されたインスタンスを表すと思われます。原文は「poly~によって指定された」となっていますが「poly によって指定された」が正しいのかもしれません。

新しいノートが生成されると target は変更されます。poly はノートオフを保持しているので、正しくボイスは循環していくはずです。poly~ の第2アウトレットは最後にメッセージを受け取ったボイスを報告します。ここでは poly を特定のターゲットを指定するために使用しているため、 poly によって出力されたボイスナンバと同じはずです。

thispoly~ オブジェクトは poly~ サブパッチャーの特定のインスタンスに対するパラメータを指定するために利用できます。loadbangオブジェクトを thispoly~ に連結することによって、ボイスナンバを利用して、フィルタの中央周波数をコントロールすることができます。

ここでは、littlefilter~サブパッチャーは thispoly~ からのボイスナンバを使い、それに第2インレットで受け取った基本周波数を掛けています。入力シグナルは、16個すべてのインスタンスによってフィルタリングされますが、各々のインスタンスの振幅出力は第1インレットから入力される int によってコントロールされます。

次はlittlefilter~ を使用したパッチ例です。

metro オブジェクトは counterrandom の両方に接続されています。counter target メッセージを供給しますが、これはpoly~ オブジェクトにロードされた littlefilter~ の16のボイスを循環させ、ボイスの振幅をコントロールするために使われる乱数を各々に提供します。

poly~ のインレットに接続されたシグナルは、すべてのサブパッチャーのインスタンス内の対応するin~オブジェクトに送られます。そのため、上の例のnoise~ オブジェクトはpoly~ 内部のすべてのサブパッチにノイズを供給します。第2インレット(サブパッチャーのin 2ボックスに対応)はフィルタの基本周波数をコントロールします。すべてのpoly~にくり返し送信される周波数が、target 0 メッセージの後にある点に注意して下さい。poly~ サブパッチの特定のインスタンスを見るためには、オブジェクトにopenメッセージを送り、その後に見たいボイスナンバを続けます。ボイスナンバ15に割り当てられたサブパッチは次のようになります。

見てわかる通り、ここでのlittlefilter~ の個別の周波数値は1500Hzです。これはボイスナンバ(15)に、最後に第2インレットに送られた周波数値(100.Hz)を乗じたものです。

まとめ

poly~は、同じサブパッチの複数のコピーを使ったポリフォニックなボイスアロケーション(割り当て)を管理するための強力な手段となります。thispoly~ オブジェクトはサブパッチの中にあって、ビジー・ステート(ビジーかどうかの状態)やシグナルプロセッシングのオン/オフをコントロールします。inin~ outout~ は、コントロール情報やシグナルの特別なインプット、アウトプットを作ります。これらは、poly~ オブジェクトのインレットやアウトレットとして動作します。

参照

in poly~によってロードされたパッチャーのためのメッセージ入力
in~ poly~によってロードされたパッチャーのためのシグナル入力
out poly~によってロードされたパッチャーのためのメッセージ出力
out~ poly~によってロードされたパッチャーのためのシグナル出力
poly~ パッチャーのためのポリフォニー/DSP マネージャ
thispoly~ poly~のボイスアロケーションとミュートをコントロールします