チュートリアル27:
パッチ・オブジェクトの作成

作成したパッチをオブジェクトとして使用する

パッチの作成に関わるようになると、オブジェクトの特定の組み合わせを繰り返し使用することや、頻繁に必要となる特定のコンピュータのタスクがあることに気づくと思います。このようなタスクを実行するオブジェクトを作り、必要なときにそのオブジェクトに接続することができれば素晴らしいことでしょう。

実際に、すでに作成され、保存されているパッチは、他のパッチのオブジェクトとして使用することができます。そのためには、オブジェクトボックスにオブジェクト名を書き込むのと全く同じ要領で、オブジェクトボックスに、使用したいパッチのファイル名を書き込むだけです。

訳注:オブジェクトのように使用されるパッチのことを、原書では「アブストラクション - Abstraction」と呼んでいます。「抽象化パッチ」というようなニュアンスではないかと思います。
日本では、「パッチ・オブジェクト」という言い方が一般的に使用されているようですので、この訳では原則として「パッチ・オブジェクト」を使用します。

patcher オブジェクトで見たように、パッチの中でパッチを使用する場合には、通常、そのサブパッチと通信を行なうことができるようにしておく必要があります。したがって、他のパッチの中でオブジェクトとして使用する計画のあるパッチを作成する場合には、inlet オブジェクトと outlet オブジェクト(あるいは send オブジェクトと receive オブジェクト)を使う必要があります。これにより、オブジェクトへのメッセージの送信や、オブジェクトからのメッセージの出力が可能になります。

notetransposer オブジェクト

このパッチでは notetransposer オブジェクトを使用します。これは、入力されるピッチをトランスポーズして送信するためのものです。トランスポーズの音程(半音単位で上下させる数値)は右インレットで与えられます。

notetransposer オブジェクトは Max に組み込まれているオブジェクトではありません。これは notetransposer というファイル名で作成し、保存されているパッチです。

notetransposerオブジェクトをダブルクリックして、その内容を見て下さい。

以前のパッチでは、ノートのトランスポーズを行なう際には、単にピッチを + オブジェクトあるいは - オブジェクトに送信するだけでした。このようなノートのトランスポーズを行なうためだけのサブパッチを必要とするのはなぜでしょうか? notetransposer オブジェクトが + 演算子より優れているのは、たとえノートがオンになっている間にトランスポーズの音程が変更された場合でも、対応するノートオフ・メッセージをノートオン・メッセージと同じ音程で確実にトランスポーズするという点です。

ノートオフ・メッセージがノートオン・メッセージと違う音程でトランスポーズされてしまった場合、ノートオン・メッセージをオフにすることができなくなり、シンセサイザの音は鳴ったままになってしまいます。notetransposer オブジェクトは funbuff というオブジェクトの内部に、ノートオンのピッチ値、およびそのノートをトランスポーズした結果のピッチ値を組み合わせたリストを保存し、ノートオフを受信した場合にはトランスポーズした結果のピッチ値を参照するという方法によって、この問題を解決しています。

funbuff オブジェクト

配列( array )はインデックス付けされた数値のリストです。リスト内のそれぞれの数値は固有のインデックス値、または「アドレス」を持ちます。ここではアドレスを x、及びそのアドレスに格納された値を y と呼ぶことにしましょう。funbuff オブジェクトは x, y のペアの配列を格納します。

右インレットで数値を受信し、続いて左インレットで数値を受信すると、右インレットの数値( y )は左インレットで指定されたアドレス( x )に格納されます。その後、funbuffの左インレットでアドレスナンバー( x )を受信すると、funbuffは対応する y の値を左アウトレットから送信します。

数値は、アドレスxと値yのリストとしてfunbuff オブジェクトに格納することもできます。より詳しい情報は、Max リファレンスマニュアル の funbuffを参照して下さい。

トランスポーズした値の格納と呼び戻し

notetransposer オブジェクトの中の gate オブジェクトは、ノートオン・メッセージのピッチだけを通過させるために使われています。gate オブジェクトの右インレットにピッチが到着する前に、ベロシティ値が gate オブジェクトのコントロール・インレットに送られ、gate の開閉が行なわれます。ベロシティが 0(ノートオフ・メッセージ)の場合、gate は閉じられ、ピッチは通過できません。

ノートオンのピッチは最初に + オブジェクトへ行き、トランスポーズされてから funbuff オブジェクトの右インレットに送られます。トランスポーズされていないピッチは funbuff オブジェクトの左インレットへ送られるため、トランスポーズされていないピッチがアドレス( x )となり、トランスポーズされたピッチが y 値として共に格納されます。

x, y のペアが格納されるとすぐに、トランスポーズされていないピッチ( x )自体が送信され、それによってトランスポーズされたピッチ( y )が送り出されます。

その後、ノートオフ・メッセージを受信したときには、何も gate オブジェクトを通過しません。そして、トランスポーズされていないピッチそれ自体が funbuff オブジェクトに送信され、トランスポーズされたピッチを再び送信させます。ノートオフ・メッセージは、トランスポーズされた値を、 + オブジェクトではなく funbuff オブジェクトから取得するため、+ オブジェクトの中の値は、ノートオフのトランスポーズ値に影響を与えることなく変更できます。

・サブパッチウィンドウを閉じて下さい。MIDI キーボードを弾きながら、同時に slider オブジェクトをドラッグし、演奏しているノートのトランスポーズを実行して下さい。

ノートがトランスポーズされている間に、トランスポーズの音程が変更されるような場合には、この方法によってトランスポーズされた値を格納することが不可欠です。例えば、トランスポーズの音程が、パッチの他の部分で生成された数値によって自動的に変更される可能性があるからです。

patcherオブジェクトとパッチ・オブジェクトの違い

patcher オブジェクトの中のサブパッチと、別のファイルとして作成され、保存されているサブパッチとの違いは何でしょうか?

1つの違いは、その保存方法です。patcher オブジェクトの中のサブパッチは patcher オブジェクトを含むファイルの一部として保存されます。その結果、patcher オブジェクトをダブルクリックし、サブパッチウィンドウをアンロックすることによって patcher オブジェクトのサブパッチを編集することができます。サブパッチが別のファイルとして保存されている場合、オブジェクトをダブルクリックしてその内容を見ることはできますが、サブパッチウィンドウの内容を編集することはできません( Max はそれをアンロックさせません)。オブジェクトを編集するには、すでに作成されている別のファイルを開かなければなりません。

パッチ・オブジェクを保存した別のファイルは、それを使用するパッチが検索できるフォルダの中に置いておく必要があります。 Max は次の場所でファイルをを検索します。

  • サブパッチを使用しているパッチと同じフォルダ。

  • Max アプリケーションと同じフォルダ。

  • File Preferences ダイアログの Look for files in: で指定されているフォルダ。File Preferences... に関するより詳しい情報は、基礎マニュアルの Menus という章を参照して下さい。

もう1つの大きな違いは、patcher オブジェクトのサブパッチウィンドウを開いた状態でパッチを保存した場合、メインパッチを開くたびにサブパッチウィンドウが自動的に開かれるという点です。別のファイルとして保存されているサブパッチの場合、これはあてはまりません。

再帰に関する注意

他のパッチ内でオブジェクトとして使用されるパッチは、それ自身サブパッチを内部に持つことができます。例えば、このチュートリアルの notetransposer オブジェクトは、ノートオン・メッセージをノートオフ・メッセージから切り分ける spiitnote というオブジェクトをサブパッチとして使用するように設計することも可能です。

しかし、パッチ・オブジェクトが自分自身自身を内部に含めることのないようにして下さい。そうでないと、Maxは自分自身を内部に含むパッチを際限なくロードしようとする無限ループに陥ってしまうことになります。例えば、notetransposer オブジェクトは、それ自身、あるいはnotetransposer オブジェクトを内部に持つサブパッチを notetransposer オブジェクトに含めるべきではありません。

作成したパッチ・オブジェクトのドキュメント化

notetransposer オブジェクトが豊富なコメントを持ち、インレットとアウトレットにはアシスタンスメッセージが設定されていることに気づいたと思います。このように徹底してドキュメントを作っておくことによって、そのパッチを他者が理解したり、利用したりすることがより容易になります。また、パッチの動作を思い出す手助けにもなります。

注:コメントが広範囲にわたり、コメントテキストに改行を含める必要がある場合には、インスペクタを使って、comment ボックスの 2バイト文字互換(two-byte compatibility )モードを設定して下さい。

まとめ

作成し、保存したパッチは、他のパッチの中でオブジェクト(パッチ・オブジェクト)として使用することができます。他のパッチのサブパッチとして使用するパッチを作成する場合、そのオブジェクトに対してメッセージの送信を行なったり、そのオブジェクトからメッセージの送信を行なったりすることができるように、通常 inlet オブジェクトと outlet オブジェクト(あるいは send オブジェクトと receive オブジェクト)を含める必要があります。

funbuff オブジェクトは、「アドレス」と「値」を表す xとy のペアという形で、数値の配列を格納します。アドレスナンバー( x )を左インレットで受信すると、そのアドレスに格納されている値( y )を左アウトレットから送信します。このタイプの配列は、インデックス付けされたリストに値を格納し、後でそれを検索するためのルックアップ・テーブルとして役に立ちます。配列の使い方の1つとして、ノートオンのピッチ値とそれをトランスポーズしたピッチ値をペアにし、対応するノートオフ・メッセージを受信した場合にそのトランスポーズした値を再び探し出すという使用法を挙げることができます。

別のファイルとして保存されているパッチ・オブジェクトのウィンドウは、( patcher オブジェクトとは異なり)それを含むパッチャーウィンドウが開かれた場合に、自動的には開きません。別のファイルとして保存され、サブパッチとして使用されているパッチは、保存されたファイルを開くことによってのみ編集が可能になります。

comment オブジェクトの形式での注釈やアシスタンス・メッセージは、あなた自身や、あなたのパッチを使う他の人たちの手助けとなります。

参照

Encapsulation カプセル化
funbuff 数値を x, y の対にして格納します。