プログラミング(2)

pdは基本的に音楽ソフトであるにも関わらず、200種以上のオブジェクトの約半数は、音声を扱わないオブジェクトである。中には一見何に使うんだか不明なものもあるが、アイディアに対して可能な限り自由にパッチを作るために、これらのオブジェクトが用意されている。またこのことは、pdが音楽ソフトである一方で、プログラム言語の一種であることを示す。他の言語に備わっている機能の基本は、概ねpdにも備わっていると考えられる。

以下、音声信号以外のデータ(数値、文字列など)を扱うオブジェクトを簡単に見て、pdでの仕組み作り、仕掛け作りを考える。全てのオブジェクトを記憶する必要は全くないので、まずはパッチを動かして、オブジェクトの挙動を感覚的に知ることにする(これが可能なのもpdの利点である)。尚、各オブジェクトの詳細については
オブジェクト一覧、またはpdのオブジェクトヘルプ(右クリック>Help)。

数値の計算

何と言おうと結局のところコンピュータとは計算機であるので、数値の計算はプログラミングの基本である。このパッチではpdで数値計算を担うオブジェクトを集めている。

#N canvas 0 0 865 685 10; #X obj 263 101 +; #X obj 307 101 -; #X obj 351 101 *; #X obj 395 101 /; #X obj 439 101 %; #X obj 483 101 mod; #X obj 527 101 div; #X obj 693 81 sin; #X obj 724 81 cos; #X obj 755 81 tan; #X obj 693 108 atan; #X obj 731 108 atan2; #X obj 775 108 log; #X obj 807 108 exp; #X obj 91 251 abs; #X obj 456 251 random; #X obj 179 251 max; #X obj 231 251 min; #X obj 267 415 ==; #X obj 311 415 !=; #X obj 355 415 >; #X obj 399 415 <; #X obj 443 415 >=; #X obj 487 415 <=; #X obj 574 415 &; #X obj 618 415 &&; #X obj 662 415 |; #X obj 706 415 ||; #X obj 750 415 <<; #X obj 794 415 >>; #X obj 263 42 r A; #X floatatom 263 135 5 0 0 0 - - -; #X floatatom 307 135 5 0 0 0 - - -; #X floatatom 351 135 5 0 0 0 - - -; #X floatatom 395 135 5 0 0 0 - - -; #X floatatom 439 135 5 0 0 0 - - -; #X floatatom 483 135 5 0 0 0 - - -; #X floatatom 527 135 5 0 0 0 - - -; #X floatatom 571 135 5 0 0 0 - - -; #X obj 584 42 r B; #X obj 571 101 pow; #X obj 36 135 s A; #X obj 165 135 s B; #X obj 140 101 t b f; #X obj 36 48 nbx 5 8 -1e+037 1e+037 0 0 empty empty empty 0 -6 2 24 -262144 -1 -1 0 256; #X obj 140 48 nbx 5 8 -1e+037 1e+037 0 0 empty empty empty 0 -6 2 24 -262144 -1 -1 0 256; #X floatatom 617 135 5 0 0 0 - - -; #X obj 617 101 sqrt; #X floatatom 179 286 5 0 0 0 - - -; #X floatatom 231 286 5 0 0 0 - - -; #X floatatom 91 286 5 0 0 0 - - -; #X floatatom 91 218 5 0 0 0 - - -; #X floatatom 244 218 5 0 0 0 - - -; #X floatatom 179 218 5 0 0 0 - - -; #X obj 329 251 clip -10 10; #X floatatom 329 218 5 0 0 0 - - -; #X floatatom 329 286 5 0 0 0 - - -; #X obj 456 218 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1; #X floatatom 487 218 5 0 0 0 - - -; #X floatatom 456 286 5 0 0 0 - - -; #X msg 546 218 seed \$1; #X floatatom 546 194 5 0 0 0 - - -; #X floatatom 267 452 5 0 0 0 - - -; #X floatatom 311 452 5 0 0 0 - - -; #X floatatom 355 452 5 0 0 0 - - -; #X floatatom 399 452 5 0 0 0 - - -; #X floatatom 443 452 5 0 0 0 - - -; #X floatatom 487 452 5 0 0 0 - - -; #X floatatom 574 452 5 0 0 0 - - -; #X floatatom 618 452 5 0 0 0 - - -; #X floatatom 662 452 5 0 0 0 - - -; #X floatatom 706 452 5 0 0 0 - - -; #X floatatom 750 452 5 0 0 0 - - -; #X floatatom 794 452 5 0 0 0 - - -; #X obj 267 361 r C; #X obj 807 361 r D; #X obj 138 416 t b f; #X obj 34 363 nbx 5 8 -1e+037 1e+037 0 0 empty empty empty 0 -6 2 24 -262144 -1 -1 0 256; #X obj 138 363 nbx 5 8 -1e+037 1e+037 0 0 empty empty empty 0 -6 2 24 -262144 -1 -1 0 256; #X obj 163 450 s D; #X obj 34 450 s C; #X obj 87 557 mtof; #X floatatom 87 580 0 0 0 0 - - -; #X obj 87 603 ftom; #X floatatom 87 626 0 0 0 0 - - -; #X floatatom 229 580 0 0 0 0 - - -; #X floatatom 229 626 0 0 0 0 - - -; #X obj 229 557 dbtorms; #X obj 229 603 rmstodb; #X floatatom 323 580 0 0 0 0 - - -; #X floatatom 323 626 0 0 0 0 - - -; #X obj 323 557 dbtopow; #X obj 323 603 powtodb; #X obj 229 528 nbx 5 8 -1e+037 1e+037 0 0 empty empty empty 0 -6 2 24 -262144 -1 -1 0 256; #X obj 87 528 nbx 5 8 -1e+037 1e+037 0 0 empty empty empty 0 -6 2 24 -262144 -1 -1 0 256; #X obj 540 584 expr; #X obj 586 584 expr~; #X obj 635 584 fexpr~; #X connect 0 0 31 0; #X connect 1 0 32 0; #X connect 2 0 33 0; #X connect 3 0 34 0; #X connect 4 0 35 0; #X connect 5 0 36 0; #X connect 6 0 37 0; #X connect 14 0 50 0; #X connect 15 0 59 0; #X connect 16 0 48 0; #X connect 17 0 49 0; #X connect 18 0 62 0; #X connect 19 0 63 0; #X connect 20 0 64 0; #X connect 21 0 65 0; #X connect 22 0 66 0; #X connect 23 0 67 0; #X connect 24 0 68 0; #X connect 25 0 69 0; #X connect 26 0 70 0; #X connect 27 0 71 0; #X connect 28 0 72 0; #X connect 29 0 73 0; #X connect 30 0 0 0; #X connect 30 0 1 0; #X connect 30 0 2 0; #X connect 30 0 3 0; #X connect 30 0 4 0; #X connect 30 0 5 0; #X connect 30 0 6 0; #X connect 30 0 40 0; #X connect 30 0 47 0; #X connect 39 0 6 1; #X connect 39 0 5 1; #X connect 39 0 4 1; #X connect 39 0 3 1; #X connect 39 0 2 1; #X connect 39 0 1 1; #X connect 39 0 0 1; #X connect 39 0 40 1; #X connect 40 0 38 0; #X connect 43 0 41 0; #X connect 43 1 42 0; #X connect 44 0 41 0; #X connect 45 0 43 0; #X connect 47 0 46 0; #X connect 51 0 14 0; #X connect 52 0 17 1; #X connect 52 0 16 1; #X connect 53 0 16 0; #X connect 53 0 17 0; #X connect 54 0 56 0; #X connect 55 0 54 0; #X connect 57 0 15 0; #X connect 58 0 15 1; #X connect 60 0 15 0; #X connect 61 0 60 0; #X connect 74 0 18 0; #X connect 74 0 19 0; #X connect 74 0 20 0; #X connect 74 0 21 0; #X connect 74 0 22 0; #X connect 74 0 23 0; #X connect 74 0 24 0; #X connect 74 0 25 0; #X connect 74 0 26 0; #X connect 74 0 27 0; #X connect 74 0 28 0; #X connect 74 0 29 0; #X connect 75 0 29 1; #X connect 75 0 28 1; #X connect 75 0 27 1; #X connect 75 0 26 1; #X connect 75 0 25 1; #X connect 75 0 24 1; #X connect 75 0 23 1; #X connect 75 0 22 1; #X connect 75 0 21 1; #X connect 75 0 20 1; #X connect 75 0 19 1; #X connect 75 0 18 1; #X connect 76 0 80 0; #X connect 76 1 79 0; #X connect 77 0 80 0; #X connect 78 0 76 0; #X connect 81 0 82 0; #X connect 82 0 83 0; #X connect 83 0 84 0; #X connect 85 0 88 0; #X connect 87 0 85 0; #X connect 88 0 86 0; #X connect 89 0 92 0; #X connect 91 0 89 0; #X connect 92 0 90 0; #X connect 93 0 87 0; #X connect 93 0 91 0; #X connect 94 0 81 0;

上から一段目は初歩的と思われる「+」「-」「*」「/」「%」「mod」「div」「pow」「sqrt」の検証を行なう。左上の、大きくしたナンバーボックスを操作すると、これらのオブジェクトの挙動が見られる。まず「+」「-」「*」「/」は「加減乗除」「和差積商」の四則演算である。かけ算記号を「*」割り算記号を「/」と書くのはコンピュータに一般的な表記である(キーボードに「×」「÷」というキーはない)。

「%」は割り算の余り、「mod」はモデュロ(法)と呼ばれる計算だが、どちらも右入力(または引数)で指定した値を範囲として数を繰り返す(左入力が負数となった場合に両者の差が現れることを確認)。これらは音楽に重要な、反復する構造を作るのに役立ちそうである。このように、初めて知るような計算でも、その仕組みはともかく、まずオブジェクトの挙動から、何に使えるかを考えるのは重要と思われる。

次に「div」は、端数を省いた商だが、数の増減を緩やかにするもの、と捉えられる。「pow」「sqrt」は累乗と平方根である。他にも「sin」「cos」「tan」「atan」「atan2」「log」「exp」といった高等数学のオブジェクトがあるが、ここではその存在のみ確認する。

二段目、「abs」は絶対値、つまり数から正負の符号を取り去る。「max」「min」「clip」は数の出力に上限や下限を設けるもので、過剰な数値が生じるのを防ぐ上で使い出があるだろう。「random」は右入力や引数で指定された数マイナス1から、0までの乱数(不規則な数)をbangを受けて出力するもので、意外性や飽きの来なさ、といった面から非常に多用され得る。

ちなみに「random」に対するメッセージ「seed」は乱数の系列を変える。ここでseedの数をひとつ決めて、四五回乱数を出して、それを覚えた上で、seedの数を一旦変え、また戻し、再度四五回乱数を出してみる。二度の結果は全く同じである。

乱数とはいえ、コンピュータの処理とは常に確定的なので、実は乱数の不確定性とは込み入った計算によって見せかけられたものに過ぎない。この「擬似乱数」を作る仕組みはプログラムによって様々だが、pdではこのように大雑把である。

例えば「random」を多用したパッチを開いて実行すると、毎度同じ結果になる。これを避けるとすれば、人間の操作や、外部音声(後述の通り、音声信号も数値なので、ノイズは加工によって理想的な乱数となる)などの「介入」が検討される。

「==」「!=」「>」「<」「>=」「<=」は、左右が「等しい」「等しくない」、左が右「より大きい」「未満」「以上」「以下」という比較を行い、結果の真偽を0と1で出力する。条件処理に用いることができるだろう。

「&」「&&」「|」「||」「<<」「>>」とは面妖な記号である。このうち「&&」はAND、論理積と呼ばれ、「||」はOR、論理和と呼ばれる。これら論理学の記号を日常言語に直すとそれぞれ「かつ」「または」である。どういうことなのか。こればかりは一言で説明し難いので、少し詳しくしてみたい。

ANDについては「Aである、かつ、Bである」という話(命題)を考える。例えば「彼は酒もやるしタバコも呑む」と第三者から聞いたとする。この場合、後で「彼」自身に確認したら実はこうだったという真相の4種が考えられる。「彼は酒もタバコもやらない」「彼は酒はやるがタバコはやらない」「彼は酒はやらないがタバコはやる」「彼は酒もタバコもやる」。このうち最初に第三者から聞いた話が正しくなる(真である)のは無論、最後の場合のみである。この真偽の組み合わせを0と1で表すと以下のようになる。

0 && 0 = 0
0 && 1 = 0
1 && 0 = 0
1 && 1 = 1

要するにANDは「二条件とも真(1)である」場合に真(1)となる計算である。「&&」を乗算に置き換えても同じなので論理積と呼ばれる。ところで「&&」では0以外の数は全て真(1)として扱うことをパッチで確認する。

同様にして、ORについては「Aである、または、Bである」という話(命題)を考える。例えば「今日の昼飯はうどんかそば」である。この場合、うどんもそばも食わずにいきなり寿司を食いに行きました、と言うのであれば無論、先の話は偽となる。では何を思ったか、うどんもそばも両方平らげてしまった場合はどうか。

日常的な「または」の感覚は主に「どちらか一方」であるので、偽であるように思える(排他的OR)。ところが論理学で言うORは、この場合も真とする(非排他的OR)。実は日常言語において排他的ORと非排他的ORは混在している。例えば「受験資格、普通免許または大型特殊免許を持つ者」は、両方の免許を持っているからと言って受験できないことはない。論理学では数学的な収まりの良さと寛容の原則から、非排他的ORを採用している。

0 || 0 = 0
0 || 1 = 1
1 || 0 = 1
1 || 1 = 1

要するにORは「二条件とも偽(0)である」場合に偽(0)となる計算である。加算とも、まあまあ似ている(最後だけ違う)ので論理和と呼ばれる。また「||」でも、0以外の数は全て真(1)として扱うことをパッチで確認する。

以下さらなる余談なので興味がなければ飛ばして欲しい。このANDやORのようなものを論理関数と呼ぶ。二変数の論理関数は「0,0」「0,1」「1,0」「1,1」の四種の入力について0か1かの出力を行なうものであるから、出力の種類は24種、つまり16種の二変数論理関数がある。また全ての論理関数はNOT、AND、ORの3種の論理演算子のみ用いた論理式で表現できる。NOT(否)は入力を反転させる演算子であり、pdでは「== 0」「!= 1」などと書ける。以下に全ての二変数論理関数を示すが、当然別の書き方も可能である(NOTを「-」とする)。

(A = 0011, B = 0101)

0000 (f0) = 0
0001 (f1) = A && B [AND]
0010 (f2) = A && -B
0011 (f3) = A
0100 (f4) = -A && B
0101 (f5) = B
0110 (f6) = -A && B || A && -B [XOR]
0111 (f7) = A || B [OR]
1000 (f8) = -(A || B) [NOR]
1001 (f9) = (-A || B) && (A || -B) [XNOR]
1010 (f10) = -B
1011 (f11) = A || -B
1100 (f12) = -A
1101 (f13) = -A || B
1110 (f14) = -(A && B) [NAND]
1111 (f15) = 1

「&」「|」はAND/ORの計算を二進数の各桁(ビット)毎に行う(入出力は十進数である)。人間の日常的な数え方は10で繰り上がる十進法だが、コンピュータの中身は2で繰り上がる二進法(つまり数字が0と1しかない)が用いられている。そのためこのようなオブジェクトがあるらしい。「<<」「>>」は左に入力した数の二進数を、右に入力した桁数ずらず計算である。一桁の移動は「2をかける」「2で割る」に相当する。

最後は単位の変換である。「mtof」はMIDIノートナンバーを周波数に変換する計算であり「ftom」はその逆である。(平均律の)音階を用いる際には非常に重宝する。「dbtorms」「rmstodb」「dbtopow」「powtodb」は音量の単位の変換だが、dbはデシベル値、powは振幅、rmsはRMSレベルの意味である(
fig.2)。

exprグループのオブジェクト

より自由度の高い演算オブジェクトとして「expr」「expr~」「fexpr~」も存在する。これらexprグループのオブジェクトでは、引数部分に数式を書き込むことで計算が可能となる。「;」で区切って複数の数式を書くことも出来る。演算子や書式などの詳細はhttp://crca.ucsd.edu/~syadegar/expr.htmlまたはオブジェクトのヘルプで見られるが、ここでは各オブジェクトについて簡単にまとめる。

「expr」は数式計算、「expr~」は音声信号における数式計算を行う。「fexpr~」はサンプル毎の音声信号の数式計算を行い、高負荷だが、後述するフィルタなどの作成も可能である。

「expr」では$i#(整数)$f#(数値)$s#(文字列。配列参照に用いる)の三種の変数を扱う。ここで「#」とは変数の数に応じて作成されるインレットの順位であり、1から始まる。

配列参照は「expr $s2[$f1]」などと行う。この場合、左入力すなわち$f1は配列アドレス、右入力$s2はメッセージ「symbol[配列名]」で配列を指定する。

「expr~」では$i#、$f#、$s#に加え、$v#(音声信号または数値)を使用。$i1、$f1は不可(今後のバージョンアップで変更予定)。

fexpr~ では$i#、$f#、$s#に加え、$x#[n](入力音声)$y#[n](出力音声)を使用。[n]はnサンプル前の参照を意味する。nを変数や式で表記することもできる。

$xでは0≧n≧[-ブロックサイズ]、$yでは0>n≧[-ブロックサイズ]である。ブロックサイズとはpdでの音声計算の単位であり、デフォルトでは64サンプルを一単位として計算を行っている。ブロックサイズの変更は「block~」オブジェクト。$x、$yと略記可能であり、それぞれ$x1[0]、$y1[-1]と解釈する。メッセージ「set」「clear」により変数への一括代入、クリアなどが可能。

データの制御

以下の例では数値や文字列といったデータの、格納や伝達、加工などを行うオブジェクトを集めている。

#N canvas 0 0 870 619 12; #X obj 167 121 float; #X obj 535 123 symbol; #X obj 538 475 key; #X obj 42 448 trigger; #X obj 722 125 print; #X obj 747 311 swap; #X floatatom 90 49 5 0 0 0 - - -; #X obj 90 160 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1; #X obj 90 121 b; #X obj 35 121 bang; #X floatatom 236 49 5 0 0 0 - - -; #X floatatom 263 76 5 0 0 0 - - -; #X obj 214 89 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1; #X floatatom 236 160 5 0 0 0 - - -; #X msg 535 52 ?; #X msg 548 80 !; #X msg 587 34 symbol ?; #X msg 598 60 symbol !; #X obj 507 89 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1; #X symbolatom 535 162 10 0 0 0 - - -; #X obj 394 286 v zzz; #X floatatom 394 323 5 0 0 0 - - -; #X floatatom 305 236 5 0 0 0 - - -; #X obj 394 251 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1; #X floatatom 170 236 5 0 0 0 - - -; #X floatatom 170 323 5 0 0 0 - - -; #X obj 170 263 s wo; #X obj 170 293 r wo; #X floatatom 305 323 5 0 0 0 - - -; #X obj 236 121 f 42; #X floatatom 376 50 5 0 0 0 - - -; #X floatatom 427 77 5 0 0 0 - - -; #X obj 354 90 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1; #X floatatom 376 161 5 0 0 0 - - -; #X obj 376 122 int 6.6; #X floatatom 518 239 5 0 0 0 - - -; #X floatatom 555 261 5 0 0 0 - - -; #X floatatom 593 281 5 0 0 0 - - -; #X obj 518 311 pack 0 0 0; #X floatatom 518 384 5 0 0 0 - - -; #X floatatom 563 409 5 0 0 0 - - -; #X floatatom 609 384 5 0 0 0 - - -; #X obj 518 352 unpack f f f; #X obj 488 276 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1; #X floatatom 747 260 5 0 0 0 - - -; #X floatatom 774 283 5 0 0 0 - - -; #X msg 710 236 3 2; #X floatatom 747 369 5 0 0 0 - - -; #X floatatom 774 345 5 0 0 0 - - -; #X obj 700 279 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1; #X obj 538 542 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1; #X floatatom 538 510 5 0 0 0 - - -; #X obj 594 542 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1; #X floatatom 594 510 5 0 0 0 - - -; #X obj 594 475 keyup; #X obj 656 542 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1; #X floatatom 656 510 5 0 0 0 - - -; #X obj 656 475 keyname; #X symbolatom 707 510 10 0 0 0 - - -; #X floatatom 722 57 5 0 0 0 - - -; #X obj 298 476 makefilename %d.wav; #X symbolatom 298 511 10 0 0 0 - - -; #X floatatom 298 443 5 0 0 0 - - -; #X floatatom 176 421 5 0 0 0 - - -; #X obj 121 488 +; #X floatatom 121 525 5 0 0 0 - - -; #X obj 176 448 t b f; #X floatatom 121 421 5 0 0 0 - - -; #X floatatom 72 236 5 0 0 0 - - -; #X obj 72 263 send wo; #X floatatom 72 323 5 0 0 0 - - -; #X obj 72 293 receive wo; #X obj 305 286 value zzz; #X obj 707 542 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1; #X connect 1 0 19 0; #X connect 2 0 51 0; #X connect 5 0 47 0; #X connect 5 1 48 0; #X connect 6 0 8 0; #X connect 8 0 7 0; #X connect 10 0 29 0; #X connect 11 0 29 1; #X connect 12 0 29 0; #X connect 14 0 1 0; #X connect 15 0 1 0; #X connect 16 0 1 1; #X connect 17 0 1 1; #X connect 18 0 1 0; #X connect 20 0 21 0; #X connect 22 0 72 0; #X connect 23 0 20 0; #X connect 23 0 72 0; #X connect 24 0 26 0; #X connect 27 0 25 0; #X connect 29 0 13 0; #X connect 30 0 34 0; #X connect 31 0 34 1; #X connect 32 0 34 0; #X connect 34 0 33 0; #X connect 35 0 38 0; #X connect 36 0 38 1; #X connect 37 0 38 2; #X connect 38 0 42 0; #X connect 42 0 39 0; #X connect 42 1 40 0; #X connect 42 2 41 0; #X connect 43 0 38 0; #X connect 44 0 5 0; #X connect 45 0 5 1; #X connect 46 0 5 0; #X connect 49 0 5 0; #X connect 51 0 50 0; #X connect 53 0 52 0; #X connect 54 0 53 0; #X connect 56 0 55 0; #X connect 57 0 56 0; #X connect 57 1 58 0; #X connect 58 0 73 0; #X connect 59 0 4 0; #X connect 60 0 61 0; #X connect 62 0 60 0; #X connect 63 0 66 0; #X connect 64 0 65 0; #X connect 66 0 64 0; #X connect 66 1 64 1; #X connect 67 0 64 0; #X connect 68 0 69 0; #X connect 71 0 70 0; #X connect 72 0 28 0;

「bang」は入力に応じてメッセージ「bang」を出力する(ナンバーをドラッグして確認)。「b」は「bang」の省略形であり、同様に動作するが、pdでは他にも省略形を持つオブジェクトがある。「bang」とは文字通り「ヨーイドン」の「ドン」であって、他のオブジェクトを動かすきっかけであり、pdでは頻繁に用いられるメッセージである(だがクリック可能なことから「b」の下にあるGUIオブジェクトのbangの方が多用されるだろう)。

「float」(f)は小数を含む数値を格納し出力する。まずbangすると、引数にある初期値42が出る。次にhot側(左入力)に結線されたナンバーを動かすと直ちに数値が出力される。cold側(右入力)に結線されたナンバーの数値はbangによって吐かれる。

「int」はほとんど「float」と同じだが整数のみを扱い、入力の端数は切り捨てられる。ナンバーのShift+ドラッグで確認する。

「symbol」も同様に文字列の格納と出力を行う。

「print」は入力された数値や文字列をDOS窓に出力する。これはナンバーボックスやシンボルボックスで表示できないリスト(半角空白で区切られた複数の数値や文字列)などを確認する際に役立つ。

「send」「receive」(s、r)は結線なしでのデータの伝達を可能にし、例えば結線が混乱するのを防ぎ、あるいはパッチを小さい単位で区切る役に立つ。引数は伝達経路の名前と考えられる。尚、伝達はサブパッチや別のパッチウィンドウにも及ぶ。

「value」(v)は「s」「r」同様の遠隔伝達を行い、bangに応じた出力をする。名称から察するに変数としての役割を持つ。

「pack」は複数の数値や文字列をまとめてリストにし、「unpack」はこれを分解する。引数を増やせば、より長いリストも作成できる。引数の種類によって、扱えるデータ形式の順序が決定される。fまたは数値なら数値、sは文字列となる。

「swap」は二個の数値からなるリストの左右を交換する。

「trigger」(t)は入力されたデータの形式を変換して、右から左の順で出力する。順序と言ってもコンピュータの処理速度なので出力はほぼ同時である。例えば「t b f」は、bang(b)と数値(f)の出力の指定だが、数値、bangの順で出力される。例のようにオブジェクトのhot、coldの区別を無くす役に立つ。

「makefilename」は文字列に変数を含めるものであり、特にファイル名に限るものではない。%d(数値変数)または%s(文字変数)を一個だけ文字列に含むことが出来る。

「key」「keyup」「keyname」はキーボードでの操作の役に立つ。「key」「keyup」の数値は文字コード、「keyname」の数値はキーの押下状態である。また「keyup」はキーを押して、放した時にのみ出力を行う。

条件処理

プログラムの基本構造とは順次実行、条件分岐、繰り返しの三種であって、この三種の構造でどのようなプログラムも可能であるという。条件分岐について、一般のプログラム言語ではif文などが用いられるが、pdでは主にオブジェクトの接続によって実現される(順次実行、繰り返しも同様であり、順次実行とは、単に直列に接続されたオブジェクトである。繰り返しについては後述)。

条件分岐とはいえ、難しく考える必要はない。例えばピアノの鍵盤の、どのキーを弾くかということが、既に条件付けである。条件ごとに結果が異なれば、分岐が生じていると言える。

以下の例では「==」「*」を用いて、数値の流れを変える仕掛けを簡単に作っている。分配された数値に対してさらに処理を加えれば、それぞれ別様の4種の処理を行なえるだろう。このように信号の流れを変えることによって、パッチの動作に大きな変化を与えることができる。

#N canvas 0 0 454 304 12; #X obj 107 119 == 0; #X obj 88 152 *; #X obj 151 152 *; #X obj 170 119 == 1; #X obj 214 152 *; #X obj 277 152 *; #X obj 233 119 == 2; #X obj 296 119 == 3; #X obj 296 33 hradio 15 1 0 4 empty empty selector 0 -6 0 8 -262144 -1 -1 3; #X floatatom 88 29 5 0 0 0 - - -; #X floatatom 88 245 5 0 0 0 - - -; #X floatatom 151 245 5 0 0 0 - - -; #X floatatom 214 245 5 0 0 0 - - -; #X floatatom 277 245 5 0 0 0 - - -; #X connect 0 0 1 1; #X connect 1 0 10 0; #X connect 2 0 11 0; #X connect 3 0 2 1; #X connect 4 0 12 0; #X connect 5 0 13 0; #X connect 6 0 4 1; #X connect 7 0 5 1; #X connect 8 0 0 0; #X connect 8 0 3 0; #X connect 8 0 6 0; #X connect 8 0 7 0; #X connect 9 0 1 0; #X connect 9 0 2 0; #X connect 9 0 4 0; #X connect 9 0 5 0;

また以下の例では、単体のオブジェクトにより条件処理を行うものを集めている。

#N canvas 0 0 749 368 12; #X obj 44 62 select; #X obj 46 238 spigot; #X obj 307 242 change; #X obj 425 299 bag; #X obj 136 62 sel 1 2 3 5 7; #X floatatom 136 31 5 0 0 0 - - -; #X floatatom 235 97 5 0 0 0 - - -; #X obj 136 97 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1; #X obj 155 97 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1; #X obj 175 97 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1; #X obj 195 97 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1; #X obj 215 97 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1; #X obj 299 97 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1; #X obj 318 97 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1; #X obj 338 97 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1; #X obj 358 97 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1; #X obj 378 97 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1; #X obj 299 31 keyname; #X obj 299 62 sel a b c d e; #X symbolatom 398 97 10 0 0 0 - - -; #X obj 575 153 route 1 2 3; #X floatatom 575 247 5 0 0 0 - - -; #X floatatom 602 226 5 0 0 0 - - -; #X floatatom 630 205 5 0 0 0 - - -; #X floatatom 658 184 5 0 0 0 - - -; #X msg 575 30 1 23; #X msg 587 57 2 34; #X msg 597 85 3 45; #X msg 610 114 4 56; #X msg 630 30 1 0; #X msg 642 57 2 0; #X msg 652 85 3 0; #X msg 665 114 56; #X obj 89 211 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1; #X floatatom 46 189 5 0 0 0 - - -; #X floatatom 46 270 5 0 0 0 - - -; #X obj 156 241 moses 0; #X floatatom 156 214 5 0 0 0 - - -; #X floatatom 207 214 5 0 0 0 - - -; #X floatatom 156 273 5 0 0 0 - - -; #X floatatom 207 273 5 0 0 0 - - -; #X floatatom 307 272 5 0 0 0 - - -; #X obj 307 301 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1; #X msg 307 208 1; #X msg 344 208 2; #X msg 383 208 3; #X obj 471 299 poly; #X connect 1 0 35 0; #X connect 2 0 41 0; #X connect 4 0 7 0; #X connect 4 1 8 0; #X connect 4 2 9 0; #X connect 4 3 10 0; #X connect 4 4 11 0; #X connect 4 5 6 0; #X connect 5 0 4 0; #X connect 17 1 18 0; #X connect 18 0 12 0; #X connect 18 1 13 0; #X connect 18 2 14 0; #X connect 18 3 15 0; #X connect 18 4 16 0; #X connect 18 5 19 0; #X connect 20 0 21 0; #X connect 20 1 22 0; #X connect 20 2 23 0; #X connect 20 3 24 0; #X connect 25 0 20 0; #X connect 26 0 20 0; #X connect 27 0 20 0; #X connect 28 0 20 0; #X connect 29 0 20 0; #X connect 30 0 20 0; #X connect 31 0 20 0; #X connect 32 0 20 0; #X connect 33 0 1 1; #X connect 34 0 1 0; #X connect 36 0 39 0; #X connect 36 1 40 0; #X connect 37 0 36 0; #X connect 38 0 36 1; #X connect 41 0 42 0; #X connect 43 0 2 0; #X connect 44 0 2 0; #X connect 45 0 2 0;

「select」(sel)は引数で指定された値が入力された時にbangを出力し、引数と一致しなかった値は右端から出力する。

「route」はリストの先頭の値が引数と一致した時に、リストの先頭値を除いてデータの振り分けを行う。引数と一致しなかった値は右端から出力する。

「spigot」は右入力が1であればデータを通過させ、0であればデータを遮断する。

「moses」は引数または右入力で指定した数値の、未満と以上で数値を振り分ける。

「change」は数値の入力から同じ数値の連続を削除する。

「bag」「poly」は、例えばMIDIキーボードでの入力に役立ちそうな数値処理を行う。ここではその存在のみ確認する。

時間に応じた処理

遅延(ディレイ)などの時間に応じた処理は、音楽ソフトに特徴的なものであると考えられる。他のプログラムでは何事も最速が是だろうが、音楽ではリズム、節回しなど、時間ないしタイミングの管理が内容の質に関わることは言うまでもない。以下の例で、時間に応じた処理を行うオブジェクトを示す。

#N canvas 0 0 865 391 12; #X obj 568 152 line; #X obj 112 258 timer; #X obj 326 258 cputime; #X obj 211 258 realtime; #X obj 264 47 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1; #X obj 264 143 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1; #X msg 299 46 500; #X obj 54 94 metro 1000; #X obj 54 47 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1; #X obj 54 148 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1; #X msg 641 47 0 5000; #X msg 568 47 10 5000; #X floatatom 568 208 5 0 0 0 - - -; #X msg 706 47 5; #X msg 706 73 0 \, 10 1000; #X msg 706 99 stop; #X obj 420 94 pipe 500; #X floatatom 420 47 5 0 0 0 - - -; #X floatatom 420 143 5 0 0 0 - - -; #X floatatom 112 298 0 0 0 0 - - -; #X obj 112 228 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1; #X obj 147 228 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1; #X obj 211 228 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1; #X obj 270 228 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1; #X floatatom 211 298 0 0 0 0 - - -; #X obj 326 228 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1; #X obj 377 228 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1; #X floatatom 326 298 0 0 0 0 - - -; #X obj 264 94 del 2000; #X obj 201 94 delay; #X floatatom 129 67 5 0 0 0 - - -; #X floatatom 338 67 5 0 0 0 - - -; #X floatatom 479 67 5 0 0 0 - - -; #X connect 0 0 12 0; #X connect 1 0 19 0; #X connect 2 0 27 0; #X connect 3 0 24 0; #X connect 4 0 28 0; #X connect 6 0 28 0; #X connect 7 0 9 0; #X connect 8 0 7 0; #X connect 10 0 0 0; #X connect 11 0 0 0; #X connect 13 0 0 0; #X connect 14 0 0 0; #X connect 15 0 0 0; #X connect 16 0 18 0; #X connect 17 0 16 0; #X connect 20 0 1 0; #X connect 21 0 1 1; #X connect 22 0 3 0; #X connect 23 0 3 1; #X connect 25 0 2 0; #X connect 26 0 2 1; #X connect 28 0 5 0; #X connect 30 0 7 1; #X connect 31 0 28 1; #X connect 32 0 16 1;

「metro」は引数または右入力で指定した時間間隔(ms=ミリ秒、1/1000秒単位)で周期的にbangを出力する。後述する繰り返し処理に用いる事ができる。左入力が1で開始、0で停止する。

「delay」(del)は入力されたbangを、引数または右入力で指定した時間(ms)遅らせて出力する。また左入力への数値の入力で、遅延時間の変更と遅延出力を行う。

「pipe」は入力データを挙動ごと、引数または右入力で指定した時間(ms)遅らせて出力する。

「line」は連続した数値を出力する。例えばメッセージ「10 5000」なら、現在の値から5000ms(5秒)かけて10まで推移する数値の連続を出力する。

「timer」は左右入力のbangの時間間隔をms単位で測定する。「realtime」「cputime」も同様の機能とされるが、それぞれ異なる仕組みで測定を行うようである。

ファイル操作

#N canvas 0 0 408 216 12; #X obj 161 65 openpanel; #X obj 266 65 savepanel; #X obj 43 65 loadbang; #X obj 161 37 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1; #X obj 161 98 print; #X obj 266 98 print; #X obj 266 37 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1; #X obj 43 98 metro 1000; #X obj 43 135 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1; #X connect 0 0 4 0; #X connect 1 0 5 0; #X connect 2 0 7 0; #X connect 3 0 0 0; #X connect 6 0 1 0; #X connect 7 0 8 0;

「loadbang」はpdファイルを開くと同時にbangを発する。これによりパッチ開始時の処理を自動化する事ができる。開始時に自動化させたいパッチ部分は、GUI-bangなどで予め動作を検証しておく必要がある。

「openpanel」「savepanel」はそれぞれ「ファイルを開く」「名前を付けて保存」ダイアログを表示し、ファイルの絶対パス名を出力するが、ファイルの読み込みと保存は「soundfiler」などと組み合わせて行う(後述)。

配列など

数値や文字などのデータを扱いやすく集めたものや、その方法をデータ構造と呼ぶが、配列もこれに含まれる。配列(Array)とはデータを順に並べたもので、順番の数(アドレス、インデクスなどと呼ぶ)を指定する事で格納されているデータを取り出したり書き込んだりする(アクセス)。pdでのArrayは配列のうち最も単純な、数値の一次元配列であり、要するにグラフの形をしている。グラフのx(横軸)の指定でy(縦軸)の数値にアクセスする。

#N canvas 0 0 843 621 12; #X obj 95 525 qlist; #X obj 666 532 textfile; #X floatatom 39 48 5 0 0 2 Y - -; #N canvas 0 0 450 300 graph7 0; #X array aa 100 float 0; #X coords 0 99 99 0 200 140 1; #X restore 430 27 graph; #X obj 39 87 tabwrite aa; #X floatatom 185 48 5 0 0 2 X - -; #X floatatom 185 129 0 0 0 0 Y - -; #X floatatom 281 129 0 0 0 0 Y - -; #X obj 185 87 tabread aa; #X obj 281 87 tabread4 aa; #X obj 55 261 soundfiler; #X msg 55 230 read -resize ../doc/sound/voice.wav bb; #N canvas 0 0 450 300 graph8 0; #X array bb 62079 float 0; #X coords 0 1 62078 -1 200 140 1; #X restore 430 210 graph; #X obj 665 332 tabread4~; #X msg 162 302 add 500 x 1; #X msg 162 330 add 500 x 0; #X msg 162 358 add 500 y 1; #X msg 162 386 add 500 y 0; #X obj 163 421 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1; #X msg 161 453 write q.txt; #X msg 161 481 read q.txt; #X obj 130 557 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1; #X obj 295 525 r x; #X obj 295 557 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -258699 -1 1 1; #X obj 339 557 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -258699 -1 1 1; #X obj 339 525 r y; #X floatatom 122 48 5 0 0 2 X - -; #X connect 0 1 21 0; #X connect 2 0 4 0; #X connect 5 0 8 0; #X connect 5 0 9 0; #X connect 8 0 6 0; #X connect 9 0 7 0; #X connect 11 0 10 0; #X connect 14 0 0 0; #X connect 15 0 0 0; #X connect 16 0 0 0; #X connect 17 0 0 0; #X connect 18 0 0 0; #X connect 19 0 0 0; #X connect 20 0 0 0; #X connect 22 0 23 0; #X connect 25 0 24 0; #X connect 26 0 4 1; #X connect 26 0 2 0;

「tabwrite」は引数で指定した配列に数値を書き込み、「tabread」「tabread4」は配列の読み出しを行う。尚、配列はマウスのドラッグで直接書き込むことも出来る。

「tabread」「tabread4」の違いはナンバーのShift+ドラッグで確認できる。「tabread」が配列のデータをそのまま出力するのに対し、「tabread4」は小数(インデクスの間の数)の入力によっても配列のデータを補間して出力する。

「soundfiler」によって配列への音声ファイルの読み込みと書き出しができる。配列に読み込んだ音声ファイルは「tabread4~」などで再生できる。詳しくはサンプル再生に関する項にて後述。

配列に関しては次の項でさらに詳しくする。

「qlist」はテキストファイルを用いてシーケンスデータ(順に読まれるデータ)を作成できる。だがシーケンスの書式は「時間間隔(ms)、送信先receiveの引数、内容」というごく単純なものであり、「receive」によって内容を受信する。この例では、まず「add」で始まる4つのメッセージを適当に叩く。次にその下のbangを叩くと「r」につながれたトグルが点滅する。シーケンスの終了時に「qlist」の右出力がbangを発する。

メッセージ「write」「read」はファイルの書き出しと読み込みである。ここで書き出したファイルをテキストエディタで開くと、「;」で区切られたシーケンスを見ることが出来る。pdでテキストファイルの編集を行える「textfile」もあるものの、込み入ったシーケンスを作るなら、当然テキストエディタで直接書く方が合理的だろう。

Arrayの用法

#N canvas 0 0 468 678 12; #X msg 84 442 \; table0 const \$1; #X floatatom 84 383 5 0 0 0 - - -; #X floatatom 83 267 5 0 0 0 - - -; #X msg 83 295 \; table0 resize \$1; #X msg 83 68 \; table0 print; #X msg 82 164 \; table0 0 1 -1 1 -1; #X obj 84 411 / 10; #X floatatom 82 683 5 0 0 0 - - -; #X obj 82 711 / 10; #X msg 82 742 \; table0 cosinesum 100 \$1 1; #X msg 251 835 \; table0 normalize; #X msg 81 835 \; table0 normalize 0.5; #X msg 81 1086 \; table0 write a.txt; #X msg 245 1086 \; table0 read a.txt; #X msg 81 990 \; table0 write \$1; #X obj 81 959 savepanel; #X obj 81 933 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1; #X obj 244 933 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1; #X msg 244 990 \; table0 read \$1; #X obj 244 959 openpanel; #X obj 86 1219 savepanel; #X obj 86 1193 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1; #X obj 236 1193 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1; #X obj 236 1219 openpanel; #X obj 236 1295 soundfiler; #X obj 86 1295 soundfiler; #X msg 86 1258 write \$1 table0; #X msg 236 1258 read -resize \$1 table0; #X msg 83 1383 \; table0 rename boyoyo; #X msg 268 1383 \; boyoyo rename table0; #X msg 83 1661 \; table0 bounds 0 1 100 -1; #X msg 84 540 \; table0 sinesum 64 1; #X msg 84 587 \; table0 sinesum 64 0.3 -0.3 0.3; #X msg 81 1482 \; table0 bounds -10 1 50 -1; #X msg 81 1529 \; table0 bounds 0 1 100 -1; #X msg 83 1614 \; table0 bounds 0 2 100 -2; #X msg 150 2216 \; table0 xticks \$1 \$2 \$3; #X msg 72 2045 0 10 3; #X msg 134 2045 0 10 5; #X msg 190 2083 0 20 1; #X msg 256 2083 0 10 1; #X msg 287 2134 0 10 5; #X msg 354 2134 3 10 5; #X msg 82 1758 \; table0 xlabel -1.1 0 50 100; #X msg 150 2504 \; table0 yticks \$1 \$2 \$3; #X msg 81 1888 \; table0 ylabel -3 -1 0 1; #X msg 81 1935 \; table0 ylabel 0 -0.7 0.7; #X msg 143 2322 0 0.1 5; #X msg 77 2322 0 0.1 3; #X msg 257 2374 0 0.1 1; #X msg 269 2418 0 0.5 1; #X msg 337 2418 0.3 0.5 1; #X msg 191 2374 0 0.5 1; #N canvas 500 0 458 308 /SUBPATCH/ 1; #N canvas 0 0 450 300 graph4 0; #X array table0 100 float 0; #X coords 0 1 99 -1 300 200 1; #X restore 78 43 graph; #X restore 24 26 pd; #X msg 246 164 \; table0 50 1 -1 1 -1; #X text 409 2609 //; #X msg 82 1805 \; table0 xlabel 0 0 33 66 99; #X connect 1 0 6 0; #X connect 2 0 3 0; #X connect 6 0 0 0; #X connect 7 0 8 0; #X connect 8 0 9 0; #X connect 15 0 14 0; #X connect 16 0 15 0; #X connect 17 0 19 0; #X connect 19 0 18 0; #X connect 20 0 26 0; #X connect 21 0 20 0; #X connect 22 0 23 0; #X connect 23 0 27 0; #X connect 26 0 25 0; #X connect 27 0 24 0; #X connect 37 0 36 0; #X connect 38 0 36 0; #X connect 39 0 36 0; #X connect 40 0 36 0; #X connect 41 0 36 0; #X connect 42 0 36 0; #X connect 47 0 44 0; #X connect 48 0 44 0; #X connect 49 0 44 0; #X connect 50 0 44 0; #X connect 51 0 44 0; #X connect 52 0 44 0;

ArrayのPropertiesを開くと、arrayとgraphの二つのプロパティウィンドウが表示される。PutメニューがArrayと呼ぶものは、グラフの枠にあたるgraphと数値の配列(グラフ)にあたるarrayの二つが結びついたものである。

graphのプロパティは、グラフ枠の数値の範囲と枠の大きさを指定する。arrayのプロパティは配列名と配列のサイズ(何個の数値を扱うか)を指定する。またsave contentsにチェックを入れると配列の内容がファイルに記録される(音声ファイルを読み込んだ場合などには配列サイズが膨大になるためリセットされる)。

メッセージを用いてArrayを操作することができるが、これについてパッチの例で検証していく。$記号を用いている例は、無論実際の使用では数値に置き換えられる。尚、配列(グラフ)はドラッグで書き換えることができるので、適宜書き換えつつ検証する。

「;[配列名]print」は配列の形式とサイズをDOS窓に表示する。

「;[配列名][X][Y1][Y2]...」は配列X番目から開始して数値Yを書き込む。

「;[配列名]resize[値]」は配列のサイズを変更する。例えばサイズを10にしてグラフをドラッグする。

「;[配列名]const[値]」は配列全体を一定の数値に書き換える。ところで、グラフ枠を超えても配列は表示されることを確認する。

「;[配列名]sinesum[配列サイズ][A1][A2]...」はサイン波の倍音加算合成を行う。加算合成とは要するに音の波形の足し算だが、この場合は周波数が整数倍のサイン波を順に加算する。数値Aは各サイン波の音量を指定する。また、配列サイズは2の累乗に限られるが、指定した結果はさらに3が加算される。

「;[配列名]cosinesum[配列サイズ][オフセット値][A1][A2]...」はコサイン波の倍音加算合成であり、概ね上に同じだが、オフセット値の指定がある。

「;[配列名]normalize[値]」は指定した数値を上限と下限として、その範囲内に配列の内容を収める(正規化)。数値を省略した場合は-1~1に正規化する。

「;[配列名]write[ファイル名]」は配列をファイルに保存する。ここではダイアログを表示しファイル名を出力するオブジェクト「savepanel」を用いて、ダイアログから保存可能になっている。この場合、拡張子はなくとも問題がない。一定の場所に保存する場合は下の例のようにメッセージを作ると簡単である。尚、ディレクトリ名に半角英数字以外の文字や空白があると、pdが解釈できない原則は変わらないので注意。

「;[配列名]read[ファイル名]」はファイルを配列に読み込む。ここではダイアログを表示しファイル名を出力するオブジェクト「openpanel」を用いて、ダイアログから読み込み可能になっている。この場合、拡張子はなくとも問題がない。

オブジェクト「soundfiler」を用いて、配列を音声ファイルとして扱う仕組みを示す。つまり配列を用いる場合に限り、非リアルタイムで音声信号を扱えるのだが、最大でも400万サンプルに限られるので、音声ファイルとしては極めて短いものになる。

「;[配列名]rename[配列名]」は配列名を変える。

「;[配列名]bounds[X下限][Y上限][X上限][Y下限]」は配列の表示範囲を指定する。値の指定が何故このように妙な順番なのかは不明である。

「;[配列名]xlabel(あるいはylabel)[表示位置][A1][A2]...」は数字目盛りを表示する。表示位置の指定はX軸の目盛りならY軸の値、Y軸の目盛りならX軸の値である。Aの値は目盛りを付ける数値を指定する。

「;[配列名]xticks(あるいはyticks)[オフセット値][目盛り間隔][大目盛りの割合]」はグラフ枠に目盛りを表示する。

繰り返し

#N canvas 0 0 905 609 12; #X obj 59 155 until; #X obj 59 189 print; #X obj 59 5 f; #X obj 100 5 + 1; #X obj 59 -26 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1; #X obj 60 399 f; #X obj 102 399 + 1; #X obj 60 335 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1; #X obj 204 399 f; #X obj 246 399 + 1; #X obj 204 335 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1; #X obj 60 367 metro 200; #X obj 204 367 metro 200; #X floatatom 59 41 5 0 0 0 - - -; #X floatatom 60 438 5 0 0 0 - - -; #X floatatom 204 438 5 0 0 0 - - -; #X obj 290 399 mod 10; #X obj 444 399 f; #X obj 486 399 + 1; #X obj 444 367 metro 200; #X floatatom 444 438 5 0 0 0 - - -; #X obj 530 399 sel 10; #X obj 444 335 bng 15 250 50 0 empty empty start 0 -6 0 8 -262144 -1 -1; #X msg 488 332 0; #X msg 391 363 0; #N canvas 0 0 450 300 graph1 0; #X array aa 100 float 0; #X coords 0 100 99 0 200 140 1; #X restore 448 121 graph; #X msg 59 124 100; #X obj 280 153 until; #X msg 280 122 100; #X obj 280 189 f; #X obj 321 189 + 1; #X obj 186 125 bng 15 250 50 0 empty empty reset 0 -6 0 8 -262144 -1 -1; #X msg 230 153 0; #X msg 186 223 \; aa const 0; #X obj 280 254 tabwrite aa; #X text 390 343 reset; #X floatatom 280 220 5 0 0 0 - - -; #X obj 692 348 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1; #X obj 692 381 random 1000; #X obj 692 444 del; #X floatatom 692 414 5 0 0 0 - - -; #X obj 692 477 s FB; #X obj 692 315 r FB; #X connect 0 0 1 0; #X connect 2 0 3 0; #X connect 2 0 13 0; #X connect 3 0 2 1; #X connect 4 0 2 0; #X connect 5 0 6 0; #X connect 5 0 14 0; #X connect 6 0 5 1; #X connect 7 0 11 0; #X connect 8 0 9 0; #X connect 8 0 15 0; #X connect 9 0 16 0; #X connect 10 0 12 0; #X connect 11 0 5 0; #X connect 12 0 8 0; #X connect 16 0 8 1; #X connect 17 0 18 0; #X connect 17 0 20 0; #X connect 18 0 21 0; #X connect 19 0 17 0; #X connect 21 0 23 0; #X connect 21 1 17 1; #X connect 22 0 19 0; #X connect 23 0 19 0; #X connect 24 0 17 0; #X connect 26 0 0 0; #X connect 27 0 29 0; #X connect 28 0 27 0; #X connect 29 0 30 0; #X connect 29 0 36 0; #X connect 30 0 29 1; #X connect 31 0 32 0; #X connect 31 0 33 0; #X connect 32 0 29 0; #X connect 36 0 34 0; #X connect 36 0 34 1; #X connect 37 0 38 0; #X connect 38 0 40 0; #X connect 39 0 41 0; #X connect 40 0 39 0; #X connect 42 0 37 0;

繰り返しもプログラムの基本構造の一つである。繰り返し処理には、予め実行回数を決めて実行される反復型と、一回実行した後で最初からやり直すループ型がある。ループ型は、放置しておけば無限に処理を繰り返すが、コンピュータにおいて、ループ型処理を最速で行なった場合、他の処理が割り込めなくなり操作不能に陥る危険がある。ループ型処理では、他の処理が割り込み可能な適当な時間間隔か、任意に停止可能な仕掛けが必要と思われる。

まずbangに応じて数値を1ずつ増やしていく「カウンタ」をお目にかける。pdにカウンタというオブジェクトはないが、「f」(float)と「+ 1」の結合によって簡単に作ることが出来るので覚えておく。このカウンタは、「+ 1」の出力が「f」に入力されることでループ型の繰り返し処理となっているが、「f」のcold側に入力されているために、実際には毎度bangによって処理が励起される必要がある。もし「f」のhot側に入力された場合には、一度のbangにより、PCは操作不能になるだろう。

「until」は数値の入力に応じて、入力された回数のbangを一挙に出力する。これは反復型の繰り返し処理を一挙に行う役に立つオブジェクトと思われる。例えば「until」とカウンタと「tabwrite」をつなげて、配列を書き込む仕組みを作る。この場合は単純だが、しかし配列に書き込む値の計算が複雑になると「until」が速過ぎて「tabwrite」の書き込みが間に合わない欠点もある。

繰り返し処理にはもうひとつ、「metro」を用いることができる。「metro」を用いたカウンタは、シーケンスパターンの作成などに役立つだろう。またカウンタは「f」と「+ 1」のみならず、様々な拡張が考えられる。例として「mod」を用いた循環カウンタ、「sel」を用いた自動停止カウンタを示す。

最後に「s」「r」で挟まれたパッチがあるが、これは純粋なループ型繰り返し処理の例である。まずbangを叩くと「random 1000」により、0から999までの乱数が生じる。「del」は与えられた数値を時間間隔としてbangを発し、そのbangは「s FB」により「r FB」に送られ、処理の繰り返しとなる。結果は不規則なリズムの発生である。この例では最大999msの間隔があることで、PCが操作不能にならずに済んでいる。