チュートリアル19:
タイミング(時間処理)

イントロダクション

このチュートリアルでは、時間を取り上げます。時間を扱うオブジェクトについて、また、Max に組み込まれたメトリカル・タイミングシステム(拍節的時間システム)を使用するオブジェクトについて説明します。さらに、プログラムの流れを決定する論理演算を使って意思決定を行なうオブジェクトのいくつかを見ていきます。

以前のチュートリアルで見たように、時間の扱いは、Max プログラムを行なう上で重要なことです。時間に基づいて動作するオブジェクトは、生成的な音楽や描画動作を作る手助けをしてくれます。そして、これをユーザのアクションと連動した演奏可能なプログラムを作るために使用することができます。Max 5 で導入されたメトリカル・タイミングシステムは、集中化された「音楽的な」時間システムを提供します。このシステムは、送信のコントロールや、小節(bar)/拍(beat)へのフィードバックを提供することが可能で、さらに、スケジューリングされたイベントを特定の時点で動作させることも可能です。これには、特定の時間やデュレーションを拍節に基づいた方法で決定する機能が含まれます。

訳注:メトリカル・タイミングシステム(拍節的時間システム)は、拍節的に時間を管理するシステムで、小節|拍|ティック(時間分解能の最小単位)という形で時間を管理します。これは、実際に多くのMIDIシーケンサなどでよく用いられるものです。これはMax5 で導入されたものです。

時間の機能に加え、いくつかの論理比較オブジェクトについても説明を加えます。論理比較オブジェクトとは、入力された値の比較とテストに基づき、論理演算の結果を出力するものです。このようなオブジェクトは、時間ベースのオブジェクトを利用する際に特に役に立ちます。その理由は、動作中に、現在時刻と望ましい時刻の比較や、サブタイム機能に基づいた決定を行ないたい場合が数多くあるためです。

新しいオブジェクト

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

チュートリアルの左側には5個の小さなパッチがあります。これは、Max で時間を扱う新しいオブジェクトのいくつかについて、その操作方法を示すものです。パッチ1 では、pipe オブジェクトの例を示しています。このオブジェクトは任意のメッセージやリストを特定の時間だけ遅延させて、そのまま出力します。アーギュメントはデフォルトのディレイタイムを与えるもので、この場合は 1000 ミリ秒(1秒)です。左のナンバーボックスの値を変更すると、1秒後にその変更が出力に反映されるようすを見ることができます。ディレイタイムは右インレットに値を送信して変更することができます。この変更には、整数値が用いられ、ディレイタイムをミリ秒単位の値で設定します。右側のナンバーボックスを2000 に変更し、左側の入力値を変更して下さい。今度は、2秒後に変更が起こることがわかるでしょう。

2 と表示された、次の小さなパッチはdelay オブジェクトの例です。このオブジェクトは pipe オブジェクトと非常によく似ていますが、bang メッセージのディレイのために特に調整されたものです。pipe と同様、ディレイタイムは右インレットに整数値を送ることで変更できます。

パッチ 3 では clocker オブジェクトを紹介しています。このオブジェクトは metro オブジェクトと密接な関係を持っています。clocker と metro の主な違いは、その出力にあります。metro オブジェクトが一定の間隔で bang を出力するのに対し、clocker は bang によって動作をスタートしてから経過した時間を(ミリ秒単位で)出力します。clocker は stop メッセージをクリックすると停止しますが、新しい bang メッセージを送信すると、タイマと経過時間の測定を再スタートさせます。

4 と表示されたパッチは、経過時間をカウントするもう1つのオブジェクトである timerオブジェクトの例を示しています。このオブジェクトは両方のインレットで bang メッセージを受け取ります。左インレットで bang を受信すると時間間隔の測定をスタートさせ、右インレットでbang を受信すると測定をストップさせます。したがって、timer オブジェクトはストップウォッチのような動作を行ないます。左側の button をクリックしてクロックをスタートさせ、2、3秒待ってから右のbutton をクリックして、どのくらいの時間が経過したかを見て下さい。timer は左インレットではなく右インレットがホット(出力をトリガします)であるため、通常のMax オブジェクトとやや異なっている点に注意して下さい。

5 番目のパッチでは、最も一般的なブーリアンオブジェクト(論理オブジェクト)の一部の動作を示すものです。>(より大きい)オブジェクトは比較関数を実装しています。このオブジェクトは入力された値はアーギュメントに使われている値より大きい場合には1を、そうでない場合には 0 を出力します。したがって、このオブジェクトはテストを行ない、真(1)または偽(0)を出力するものです。>(より小さい)オブジェクトはその逆の動作を行ないます。入力された値がオブジェクトのアーギュメントより小さいかどうかによって真または偽(1 または 0)を出力します。これらのシンボルは数学で一般的に使われているものです。その他の論理オブジェクトは、おそらくプログラマにはより見慣れたものでしょう。==(イコール)オブジェクトは、入力された数値がアーギュメントと等しい場合にのみ 1 を出力します。これに対し != (イコールでない)オブジェクトはこの逆の動作を行ないます。このオブジェクトは入力された数値がアーギュメントと等しくない場合に 1 を出力します。多くの Max オブジェクトと同様に、新しい比較演算子はオブジェクトの右インレットで値を受け取ることができます。

最後の2つの論理演算子は &&(論理 AND)と || (論理 OR)です。最初の && オブジェクトは、左インレットと右インレットに送信された数値が両方とも 0 でない場合にのみ 1 を出力します。そうでない場合には 0 を出力します。2番目の || オブジェクトは、左インレットまたは右インレットのどちらかに 0 でない値が送信された場合に 1 を出力します。それ以外の場合、このオブジェクトは0 を出力します。

これらのオブジェクトがあるパッチの最も上のナンバーボックスを変更して、オブジェクトがどのような動作を行なうかを見て下さい。入力する値が 10 の場合にのみ、すべての演算子が 1 を出力する点に注目して下さい。

メトリカル・タイミング、パート1

右側の大きなパッチ(6 と表示されています)はパフォーマンス用パッチです。ここでは、メトリカル・タイミングシステム(拍節的時間システム)の中で、先ほどの新しいオブジェクトのすべて(および、若干の古いオブジェクト)を使用しています。パッチを(上部にある大きな黄色の toggleを使って)スタートさせて下さい。デフォルトの MIDI シンセサイザから安定したビートと、パフォーマンスの間に様々なタイミングで生じるバリエーションを聴くことができます。このパフォーマンスはループされ、16小節ごとに再び実行されます。このかなり複雑なパッチを理解するためには、まず最初にメトリカル・タイミングシステムについて学んでおく必要があります。

メトリカル・タイミングは、時間管理の中心となるtransport オブジェクトと、このオブジェクトの機能に基づいています。その機能とは、時間情報を待ち受けている他のオブジェクトに対して、時間情報をブロードキャストするものです。この、時間情報を待ち受けている「リスニング」オブジェクトの多くは、すでに見慣れたもの(metro)や、このチュートリアルで紹介したもの(clocker)です。今まで、これらのオブジェクトはセルフクロッキング・モードで使用してきました。このモードでは、一定の時間で出力を行なうために、ミリ秒で表されるタイムベース(時間軸)を使用します。しかし、transport オブジェクトと共に使用される場合、時間はメトリカルな表記法(拍節的な表記法)で表されます。この表記法では、ミリ秒による時間表記の代わりに、4n(4分音符を表します)というような値を使用することができます。

transport オブジェクトは、時間管理の中心となるオブジェクトです。このオブジェクトは時間を、bar(小節)/ beat(拍)/ tick(ティック) というフォーマットで提供します。そして、これをテンポと拍子記号によって進めていきます。したがって、transport が拍子記号 4/4、テンポ 120 B.P.M. で動作するように設定されている場合、それぞれの拍(beat)は500 ミリ秒、1小節は 2秒(2000 ミリ秒)になります。transport がこのパッチをコントロールしている方法を理解するためには、それぞれのセクションごとに見ていく必要があります。

大きなチェックボックスをクリックすると、処理が開始されます。このチェックボックスは主として transport をスタートさせるものです。transport は1/0 メッセージを受け取り、動作をスタート/ストップさせます。このコントロールには toggle が最適です。この toggle は同時に、左側にあるmetro (パッチの「赤」セクション)をスタートさせます。このmetro は4n をタイミング・アーギュメントとして使っています。これまでは、metro オブジェクトのタイミングにミリ秒の値を使っていました。しかし、ここでは 4n という表記を用いて、transport のタイミング・ブロードキャストに基づいて4分音符単位で bang を送信するように指定しています。この metro の出力は2つの場所に送信されます。1つはメッセージボックスに送信され、(makenote を介して)MIDI ノート 70 を生成しています。もう1つは、transport に戻されています。なぜ transport に送信されているのでしょうか?その理由は、transport に bang メッセージを受信すると、カレントタイム(現在の時刻)が出力されるためです。この値は transport オブジェクトの最初の3つのアウトレットに接続されている3つのナンバーボックスに表示されます。この時間表記はそれぞれ、bar(小節)、beat(拍)、tick(ティック)を表しています。1拍は 480 ティック(4分音符1つあたり480パルス、ppq と呼ばれることもあります。これはデフォルトの値です)になります。

次に、パッチの「緑」セクションを見てみましょう。ここでは、(transport から出力される)小節数を使い、この値を > オブジェクトと < オブジェクトに送信して、4小節目と8小節目の間(訳注:4小節目と8小節目は含まれません)かどうかを判断しています。この範囲にいる場合、16n(16分音符)の刻みで動作するもう1つのmetro がオンになります。これによって乱数が生成され、この乱数を使って4つの値のうちの1つが選ばれます(random オブジェクトと select オブジェクトを使っています)。選ばれた値は makenote オブジェクトに送信され、これによって MIDI ノートが生成されます。この値は 4nd というアーギュメントを持った pipe オブジェクトにも送信され、付点4分音符(dotted-quarter note)分だけディレイされます。この出力には 7 が加算されていますが、これがMIDI シンセサイザに送信されると、もとの音の完全5度上の音になります。この結果、ループの4小節間に渡って、MIDI ノートによる高速なパッセージが生成されます。

今度は、「青」セクションを調べてみましょう。パッチのこの部分では、シーケンスを強制的にループさせています。パッチのこのセクションの先頭には、timepoint という新しいオブジェクトがあります。timepoint オブジェクトは、アーギュメントとしてメトリカルタイム(拍節的時間)を取ります。このオブジェクトの唯一の目的は、transport が指定されたメトリカルタイムに達したときに bang メッセージを送信することです。この場合、17 小節目(すなわち16小節目の次)の先頭に達すると、4和音を作るための値が makenote に送信され、その後、transport オブジェクトの右インレットに接続されている、ずっと離れたメッセージボックスに bang メッセージが送信されます。このメッセージ(0.)は、transport に対して、直ちにシーケンスのティック 0. 、すなわち1小節目の1拍目のティック 0. にジャンプすることを指示するものです。このように、第17小節に達すると直ちに先頭に戻るという方法で、シーケンスを強制的にループさせています。

メトリカルタイミング、パート2

次に、パッチの「茶色」のセクションを解読する必要があるでしょう。ここでは key オブジェクトと select オブジェクトを使って、スペースバー(ASCII値 32)が押されたかどうかを監視しています。スペースバーが押されると、timer オブジェクトは両方のインレットで bang を受信します。Max オブジェクトは右から左の順でメッセージを送信するため、スペースバーを押すと同時に右インレットへの bang によってtimer が停止し(同時に、それまでの経過時間が出力されます)、左インレットへのbang によって新しい時間計測が再スタートします。timerオブジェクトは経過時間をミリ秒単位で出力するため、この値で60000(1分をミリ秒単位で表した値)を割って、bpm(beat per minute:1分あたりの拍数)の値を得ています。

一方で、このbpm の値を適切な範囲に収める必要があります。そのため、split オブジェクトを使って、30. から 200. の間の値だけを使用するようにしています。この範囲の値が得られた場合、split オブジェクトは左アウトレットからこの値を出力します。そして、この値を使ってtempo メッセージを作成し、transport オブジェクトに送信しています。transport オブジェクトは直ちにシーケンスを再生するテンポを変更し、シーケンスを作るために用いられている多くの(しかし、すべてではありません)オブジェクトが動作する相対的な速さを変更します。timer の出力する値が split オブジェクトの範囲外である場合(例えば、スペースキーをすぐに押さなかった場合)、この値はオブジェクトの右アウトレットから送信され、この結果は破棄されます。

シーケンスすべての速度が変更されるわけではないという理由の1つは、パッチ内の関数のいくつかは、メトリカル・タイミングではなく、標準(ミリ秒)のタイミングを使っているためです。パッチの右端(「青紫」)のセクションは、そのよい例です。timepoint オブジェクトは transport の時間が6小節目の3拍目のときにbang を送信します。これによって clocker がスタートし、10 秒(10000 ミリ秒)の間動作し、4分音符ごとに(4n)2音のコードを出力します。timepoint オブジェクトは、delay 3000 オブジェクトにもbang を送信し、メッセージを受信した3000 ミリ秒後にも2音のコードが生成されます。この動作は、非常に遅いテンポの場合、timepoint が bang を出力してから2、3拍後には起きてしまいます。また、速いテンポの場合、何小節にもわたってしまいます。これは、メトリカル(拍節的)な時間と標準の時間を同時に使用し、うまく適合させることによって、面白い生成結果を生み出しているよい例であると言えます。clocker オブジェクトの実行時間が > オブジェクトで比較され、10 秒後には自分自身の状態を切り替えている点に注意して下さい。timer オブジェクトはclocker オブジェクトのスタートとストップの間の時間を追跡し、これを確認できるようになっています。

オーバードライブの重要性

オーバードライブ(Overdrive)がチェックされている(オンになっている)場合、イベントの処理と計算は、スクリーン上の描画やグラフィック処理より高い優先順位を持ちます。オーバードライブがチェックされていない(オフになっている)場合、描画処理は、イベント処理と同じ優先度を持ちます。パッチの性質によっては、タイム・クリティカル(時間優先)なイベント処理タスクで、オーバードライブがより良いパフォーマンスを提供する可能性があります。このチュートリアルパッチは、実際にタイム・クリティカルなため、オーバードライブをオンにしたほうがよいパフォーマンスを得ることができます。最新のコンピュータは信じられないほど速く動作しますが、人間の耳は時間的な不連続には非常に敏感です。したがって、タイム・クリティカルな方法でイベントを連続処理しているパッチを使う場合、通常オーバードライブ(Overdrive)をオンにするほうが賢明でしょう。

結び

このチュートリアルでは、Max の中の大規模な新しいシステム、メトリカル・タイミングシステムについて説明しました。このシステムは、Max パッチの集中化されたタイミングコントロール機能を提供します。これは、イベントの生成を統合し、音楽的シーケンスを生成することを容易にしてくれます。また、ここでは、いくつかの新しい時間を扱うオブジェクトについても学びました。その中には、pipe、delay、clocker、timer が含まれ、これらを使って(メトリカル・タイミングを使用するかどうかに関わらず)アクションのシーケンスを作ることができます。最後に、ブーリアン比較と論理演算しオブジェクトの使い方を見ました。これらは複雑なパッチでの意思決定を助けるオブジェクトです。

参照

pipe 数値のディレイライン
delay bang のディレイを行ないます。
clocker 経過時間を出力するメトロノーム
timer 2つのイベント間の経過時間を出力します。
> 比較演算子(より大きい)
< 比較演算子(より小さい)
== 比較演算子(等しい)
!= 比較演算子(等しくない)
&& 比較演算子(論理 AND)
|| 比較演算子(論理 OR)
transport マスタクロックをコントロールし、時間の値を出力します。
timepoint transport が指定された時刻になると、bang を出力します。
split 範囲内の値を探します。