チュートリアル38:
expr と if

C言語の表現

Max アプリケーション自体はC言語で書かれています。そして Max の多くの用語やオブジェクト名(例えば論理積 (and) や論理和 (or) を表わす && や || のような名前)はC言語に基づいています。Cや Pacalを扱った経験があったり、伝統的なプログラム言語の構文を使うことになじんでいるプログラマのために、Max はC言語のような方法で数式や条件文を評価するオブジェクトを提供します。

たとえ、プログラミング言語を知らなかったとしても、これらのオブジェクトを理解し、使用することが可能です。多くの場合、いくつかのパッチャーオブジェクトを必要とするような複雑な比較や数学的演算が、1つのフレーズや1つのオブジェクトで表現できます。また、どのような算術演算子を用いてもできなかった演算が、これらのオブジェクトによって可能となる場合もあります。

expr

expr オブジェクトのアーギュメントでは、Cプログラミング言語と同様なフォーマットで数式を組み立てます。例えばC言語では次のように表される式があるとします。

x = 67; y = 96; z = ( x % 12 + 1 ) * abs( y - 127 );

expr オブジェクトでは、これを次のように表わすことができます。

expr オブジェクトを用いない場合、次のように、多くのオブジェクトを使ったパッチによってこの計算を実行することになります。

patcher expr_example オブジェクトをダブルクリックして、プログラミングの問題に対するオブジェクトベースの解決法と、これに相当するexpr を用いた解決法を見て下さい。

この例では、次のような問題を解決しようとしています。問題は「モジュレーション・ホイールを 0 〜127まで動かすにつれて、ピッチベンド値 64〜127を送信し、64に戻りなさい。」というものです。左側のパッチは標準的なパッチャーを使った方法でこれを行なった場合の例を示しています。右側のパッチでは、exprの中で、様々なタスクすべてを1つの数式として結びつけている例を示しています。

expr オブジェクトの中にある可変アーギュメントには、「$i1 」のように文字が含まれている点に注意して下さい。これは、アーギュメントで使用するデータ型を expr に告げるためのものです。

・MIDI キーボードのモジュレーション・ホイールを 0 から 127まで動かして下さい。数式を表現している2つの方法が同じように動作しているのがわかるでしょう。しかし、4つのオブジェクトを使う代わりに、1つのオブジェクトを使う場合、メモリ効率はやや向上します。

if

C プログラミングのもう1つの中心的な要素は、if() ; else ; の組み合わせです。Pascal では、これを「IF 条件 THEN 文 ELSE 文」 という形で表現します。これをわかりやすい言葉に直せば、「もし特定の条件と合致した場合には、ある動作を実行し、そうでなければ他の動作を実行しなさい」という意味です。時として、ものごとについてこのように考えるほうが、数多くのボックスをワイアーで接続するよりもはるかに意味があると思われることがあります。Maxには if と呼ばれるオブジェクトがあり、これによってプログラミング上の問題を
if / then / else 形式で表現することができます。アーギュメント内の比較の結果が真(0 でない)ならば、then という語のあとのメッセージがアウトレットから送信されます。そうでなければ、elseという語(オプション)のあとのメッセージが送信されます。

従って、この条件文は次のようになります。

もし受信した数値が64以上の場合には、

127を送信します。

そうでなければ、受信した数値を送信します。

これは、次のように表現されるでしょう。

同じことをオブジェクト・ベースで行なうと、次のようになります。

if オブジェクトの thenelse 部分には、メッセージボックスに書き込むものと同じようなメッセージが含まれています。if の後のメッセージ部分には、可変アーギュメントを含むことができますが、数式を含むことはできません。

if オブジェクトの then または else 部分 がアーギュメント out2 で始まる場合、オブジェクトは右側に第2アウトレットを持つようになり、メッセージが右アウトレットから送信されます。

また、then 部分と else 部分は、receive オブジェクトの名前を後に続けた send で始めることもできます。この場合、出力はアウトレットの代わりに、同じ名前を持つすべての receive オブジェクトに送信されます。

patcher if_example オブジェクトをダブルクリックして if の実用性を見て下さい。

この例で扱っている問題は、「もし、ノートが G1 で、16〜95のべロシティを持っている場合には、シーケンスをスタートさせなさい。そうでなければ、どこかにあるcouter をインクリメントしなさい」というものです。この例では、非常に多くのタスクを1つの if / then / else の表現に結びつけていることがわかります。この場合、1つの if オブジェクトは9つのオブジェクトの役割をこなしています。

C の 数学(Math)関数

C の数学ライブラリは、対数、三角関数、x の y 乗などのような演算に用いられる多くの関数を持っています。Max にはこれらの関数のために特化されたオブジェクトはありませんが、これらの関数を expr オブジェクトのアーギュメントに含めることができます。これが expr の本当の強みです。これによって、Max プログラムでは作れないような計算も実行できます。

この例のメインパッチでは、 sin() pow() という2つの異なった 数学関数を使用して tableに格納するピッチベンド曲線を計算しています。1つの数式は 0〜127までの範囲のサイン波の1サイクルを作ります。もう1つの数式は、64から127までの指数による曲線を描きます。

・All Window Active オプションをチェックし、table オブジェクトをダブルクリックしてグラフィックウィンドウを開いて下さい。パッチの最上部にある button をクリックしてテーブルウィンドウにサイン波の1サイクルを描いて下さい。

expr の中の式では、浮動小数点演算を行うために、 $f1 アーギュメントを( $i1 の代わりに)使用して、入力を float に変換しています。exprは入力を 128 で割り(これによって、入力値が 0 から 127 まで増加すると、 0 からほぼ 1まで増加する数列を生成します)、それに2π(約 6.2832 )を掛け、そのsinの値を計算します。この結果のサイン波の値は 63.5を掛けられ、63.5オフセットされて適切な範囲に拡張された後、最終的に int に変換しなおされて出力されます。

・もう1つの expr の数式はシンプルな指数のマッピングを行なう関数です。Ggate をクリックして矢印を右アウトレットに向けて下さい。ナンバーボックスをドラッグし、expr によって計算される曲線の指数を選択して下さい。指数が 1 の場合は直線、1よりも大きい場合は指数によって急上昇する曲線、 1よりも小さい場合はその逆の曲線を描きます。

button をクリックしてテーブルウィンドウの中に曲線を描き入れて下さい。様々な指数の値で曲線を再描画してみて下さい。

数多くの指数計算(特に大きな指数によるもの)は、コンピュータにかなり集中的な演算処理を要求します。このため、多くの場合、コンピュータが音楽の演奏をしている最中にその場で演算を行なうのではなく、前もって計算した値をtableに格納しておいて後でアクセスする方が良い結果を得られます。

曲線が table の中に格納されると、これはMIDI キーボードでノートを弾くごとに line オブジェクトによって読み通されます。その値はbendout に送信され、ピッチベンドとしてシンセサイザに送信されます。line オブジェクトが table を読み通す速さは、演奏されたべロシティによって決まります。

・キーボード上で、べロシティを幅広く変化させた長いノートを演奏し、様々な速さで linetable の中の曲線を読み通すようすを聴いて下さい。table の中に様々な曲線を描き、その音響的な効果を聴いて下さい。

まとめ

expr オブジェクトは可変アーギュメントを含む、C 言語のような数式をアーギュメントとして取ります。expr は左インレットで数値を受信すると、可変アーギュメントをその値で置き換え、数式を評価して、その結果を送信します。

if オブジェクトは「もし(if) x が真なら、その後(then) y を出力し、そうでない場合は(else) z を出力する」という形式の条件文を評価します。条件文には可変アーギュメントを含むことができます。出力はアウトレットの代わりに recieve オブジェクトに送信することができます。

ifexpr は複数のパッチャーオブジェクトの演算を1つのオブジェクトとして結合する能力を持っています。通常、これによってメモリ効率が向上します。

expr のアーギュメントとなる数式には pow()sin() のような C の数学関数や、関係演算子を含むこともできます。使用することができる演算子や関数についての詳細は Max リファレンスマニュアルの expr を見て下さい。

参照

expr 数式を評価します。
if if/then/else 形式での条件文。