チュートリアル21:
数値の格納

変数

従来からのプログラミング言語では、変数はメモリ上に置かれます。プログラムはこの変数を使って数値を格納し、後でその数値を呼び戻すことができます。

Max の多くのオブジェクトは数値を格納し、後で呼び戻すことができます。例えば、ナンバーボックスは bang メッセージを受け取ったときに、格納している数値を送信します。

このチュートリアルでは、数値を格納する動作しか行なわず、左インレットで bang を受信したときにその数値を送信するオブジェクトを使います。そのオブジェクトとは、整数を格納する int と 小数を格納する float です。

int と float

int あるいは float オブジェクトの左インレットで数値が受信された場合、その数値は格納され、アウトレットから送信されます。オブジェクトの 左インレットでbang が受信された場合には、常に格納されている数値が再び送信されます。

右インレットで数値が受信された場合、その数値は出力をトリガせずに格納されます(それまで格納されていた数値を置き換えます)。

int オブジェクトと float オブジェクトは全く同様に機能します。唯一異なる点は、格納する数値の型だけです。 小数( float )が int オブジェクトで受信された場合、その数値はint に変換されてから格納されます。その逆もまた同様です。

int オブジェクトあるいは float オブジェクトに格納する初期値はアーギュメントとして書き込むことができます。アーギュメントがない場合、オブジェクトは初期値として数値 0 を格納します。

float の使用

パッチャーウィンドウ の左側にあるパッチでは、 intfloat の両方を使用しています。パッチの動作が理解できれば、これらのオブジェクトの必要性が明らかになるでしょう。

noteinstripnote の組み合わせはすでにおなじみでしょう。これは MIDI キーボードから(ノートオフ・データを取得せずに)ノートオン・データを取得する簡単な方法です。

ベロシティは ttrigger )オブジェクトによって、floatbang、もう1つの float という3つの別々なメッセージに変換されます。( t オブジェクトの右アウトレットから送信される)最初の float メッセージは / オブジェクトの右インレットに送信され、そこに格納されます。bangfloat オブジェクトに格納されている数値を送信させます。

これは一連の計算をトリガし、最終的に、その結果の数値は makenote オブジェクトと metro オブジェクトの右インレットに送信されます。その後( t オブジェクトの左アウトレットから送信される)最後の floatfloat オブジェクトに格納されます。

このことは、新しいベロシティが受信されるごとに、1つ前のベロシティが新しいベロシティによって割られ、新しいベロシティが次の処理のための「1つ前のベロシティ」として格納されることを意味します。この結果は、古いベロシティと新しいベロシティの比になります。

注:ベロシティは int オブジェクトにも同様に格納できますが、いずれにせよ / オブジェクトによって float に変換されます。int から float への変換はどこかで行なわなければならないため、この変換を t オブジェクトで行っておくようにしています。

2つのベロシティを float として割る必要があるのはなぜでしょうか?可能な限りのケースを考えて下さい。2つのノートオンのベロシティの間で可能な比の範囲は 1/127から 127/1まで(言い換えれば、0.007874 から 127.0 まで)です。1つ前のベロシティが新しいベロシティよりも小さい場合、比率は 0から 1 の間の小数になります。しかし整数による割り算を行なった場合、ベロシティが増加するケースでは、結果は常に0 になってしまいます。


2つのベロシティの正確な比率を得るためには、float による除算が必要です。

この比の値は250 を掛けられ(1 より小さい比の値が乗算を行なう前に 0 に変換されないように、ここでも数値は float として計算されています)、その結果が makenote の新しいデュレーションとmetro の新しいテンポとして使用されます。

しかし、この方法で得たすべての数値が、実際に音楽的な値として適切であるとは限りません。ベロシティの極端な変化は、非常に小さい数値、あるいは非常に大きい数値を結果としてもたらします。この計算結果における可能な数値の範囲は、およそ、最小で 1.9685( int に変換された場合、切り捨てられて 1 になります)から、最大で 31750 までです。そのため、 split オブジェクトを使用して、値を40ミリ秒(1秒間に 25音)から 2000ミリ秒(2 秒間に 1 音)までに制限しています。この制限を超える数値は無視されます。split オブジェクトは自動的に float を int に再変換しています。

・MIDI キーボードでいくつかのノートを演奏し、ベロシティの変化が splitから送信される数値にどのような影響を与えているかを観察して下さい。ベロシティが増加すると、数値は 250より小さくなります。ベロシティが減少すると数値は 250より大きくなります。ベロシティの極端な変化は非常に大きい、あるいは非常に小さい数値をもたらし、それらは split オブジェクトによって無視されることになります。

int の使用

このパッチでは、次に何が起きているのでしょうか?ベロシティは makenote オブジェクトの中央インレットに送信され、格納されます。ピッチ値は int オブジェクトに格納されます。

今まで、シンセサイザの演奏によって多くの数値が格納され、計算され、変化させられるのを見てきました。しかし、ここでは metro をオンにするまで何も起こりません。metro からの bang メッセージは int オブジェクトをトリガし 、int が格納している数値(最も新しく演奏されたピッチ値)を makenote に送信します。metro の速さは、シンセサイザで連続して演奏されたノート間のベロシティの変化によって決まります。

metro オブジェクトをオンにして MIDI キーボードを演奏して下さい。演奏によるベロシティの変化が、速さ、ベロシティ、デュレーションにどのような影響を与えているかに注目して下さい。

accum

accum はまた違った記憶用オブジェクトです。これは、内部で加算と乗算を行い、格納されている値を変更します。

accumの左インレットはちょうど int オブジェクトや float オブジェクトのような機能を持っています。左インレットで受信された数値は格納され、アウトレットから送信されます。また、bang は格納した数値を再び送信します。しかし accum オブジェクトの中央インレットと右インレットは格納した数値に対する加算、乗算に使用されます。数値はアウトレットからは送信されずに変更されます。

accum オブジェクトに格納される初期値はアーギュメントとして書き込むことができます。アーギュメントがない場合、初期値として数値 0 が格納されます。通常 accum オブジェクトに格納される値は int ですが、タイプイン・アーギュメントとして小数点を書き込むと、accum は float を格納します。accum で行なわれる乗算は、格納された数値が int であっても常に float として行われます。

accum の使用

accum オブジェクトは、加算や乗算によって頻繁に変化させたい値を格納する場合、非常に役に立ちます。例えば、繰り返しある値を加算して、数値を継続的にインクリメント(増加)させたい場合があるかもしれません。パッチャーウィンドウ の2番目のパッチはインクリメントの例を示しています。

toggle をクリックして metroをスタートさせて下さい。makenote に送信されるピッチ、ベロシティ、デュレーションの値が継続的に変化させられている方法に注目して下さい。変化の量は accum オブジェクトで加算、乗算される数値と直接に関係しています。

accum オブジェクトは、 metro から bangを受信するごとに、格納している数値を makenote オブジェクトに送信します。さらにメッセージボックスをトリガして、格納している値にある値を加算して書き戻したり、ある値を乗算して書き戻したりしています。

注:これまで、常にメッセージボックスを bangでトリガしてきましたが、数値でトリガすることも可能です。

結果として accum オブジェクトは bang を受信するごとに格納する数値を変更していきます。

これらの値は、ある種の制限を設けない場合、適切な範囲をすぐに超過してしまいます。このパッチでは、makenote に送信される数値は、異なる長さのサイクルで繰り返しループされます。ループを実現するための2つの方法が示されています。

makenote にデュレーションを(そしてmetro オブジェクトにテンポを)送信する accumは 1000 からスタートし、数値を送信する毎に、自分自身の持つ値に 0.9 を掛けていきます。最終的に数値は 40 よりも小さい値まで減少します。すると、メッセージ set 1000accum の左インレットに送信され、格納されている値はリセットされます。

すでに、slider の値を、出力をトリガせずに設定する場合に set メッセージが使われているのを見てきました。set メッセージは、accum の左インレットに送られた場合にも同様な効果をもたらします。accum の値が 40 を下回る毎に、値は 1000 にリセットされ、再びサイクルが開始されます。

また、1000 オブジェクトに bang が送信されることによって、同時に metro のテンポも 1000 にセットし直されます。数字のみを持つオブジェクトボックスは、実際には、その数値を初期値としてセットされた int オブジェクト(小数の場合は float オブジェクト)です。

ここではループの基本的な方法を示しています。それは、ある条件(例えば、ある制限を越えるまで)に達するまで絶えず値を変化させ、その後、値をリセットして再び開始するというものです。

他の2つの accum オブジェクトに格納される値は、リセットされずに増加し続けます。しかしモジュロ演算子 % が数値を制限するため、常に制限の範囲内で循環します。% オブジェクトの使用はループを作成するもう1つの方法です。

循環パターンを生成できるループ

プログラム内でのループの使用は周期を作り出す1つの方法です。このパッチでは、デュレーション、ベロシティ、ピッチのパラメータはすべて異なる周期を持っており、常に少しずつ変化しながら繰り返すような音楽を生み出しています。

実際には、デュレーションは 32ノート周期、ベロシティは 118ノート周期、ピッチは 37ノート周期で変化します。従って、すべてのパターンは 69,856ノートごと(およそ6時間ごと)に繰り返されます。頭にこびりついてしまうようなメロディーではないでしょう。

Overdrive

Max は、音楽を演奏したり、メトロノームを動かしたり、演算をしたり、数値を画面上に出力したりと、かなり忙しくなりがちです。 Optionsメニューの Overdrive をチェックすると、Max の音楽生成に関するタスクを優先し、結果としてより正確は音楽上のタイミングが得られます。不適当な音の遅れに気がついたり、動作が不安定になったりした場合にはOverdrive をチェックして下さい。

まとめ

整数は int オブジェクトに格納することができ、その後 intが左インレットへの bang によってトリガされたときに出力されます。小数点をもった数値(小数)も同様に float オブジェクトに格納したり、呼び戻したりすることができます。accum オブジェクトは int あるいは float のどちらも格納、呼び戻しができ、格納された値を送信せずに、その値に対して加算、乗算を行なうことができます。

float は 0から 1 の間の数値を含む計算や、より正確さが求められる計算の場合に役に立ちます。

split オブジェクトは指定した範囲に数値を制限するために役立ちます。受信した数値が指定範囲内であれば左アウトレットから送信され、それ以外は右アウトレットから送信されます。

ループによって、数値のサイクルを生成することができます。ループは、数値を連続的に変化させ、特定の条件に達した場合にリセットすることによって作成されます。accum オブジェクトは、このようなループのしくみに適しています。

参照

accum 数値を格納し、加算、乗算する。
float 小数を格納する。
int 整数を格納する。
Loops ループを使用して操作を繰り返し行う。