小嶋秀樹 | 授業情報 | 研究室
日本語 | English
はじめに
【Pd (Pure Data) とは】

Pd (Pure Data)Miller Puckette が開発したデータフロー型プログラミングによるマルチメディア制作環境です.演算機能をもった「オブジェクト」を相互に接続することで,さまざまなデータ(数値・音・映像など)に対する処理の流れ(フロー)を「パッチ」とよばれる図式として視覚的・対話的に構成していきます.

たとえば,下のパッチはランダムな音楽(らしきもの)を生成するものです.上側に置かれたメトロノームから 100ms ごとにタイミング信号が下に流れていき,それに合わせてランダムな音階(鍵盤の番号)が生成され,その音階にあたる周波数の正弦波(の波形データ)に変換された後,下側に置かれた音声アウトプット(左右のスピーカ)に流れていきます.(細かい部分はまだ分からなくて結構です.)

Pd のパッチは,フローチャート(仕事の手順を図示したもの)に似ていますが,むしろ工場の生産ライン(パインプラインなど)のようなものと考えるべきでしょう.つねに材料(気体や液体など)が流れ続け,流れの中でさまざまな加工(変換)が行なわれます.

Pd 本体は,音メディア制作(シンセサイザ・シーケンサを含めた音信号処理システムの開発)に関するさまざまな機能をもっています.また,OpenGL ベースの映像メディア制作パッケージ GEM など,さまざまなパッケージが用意されていて,自由に組み込むことができます.よく使うパッケージ(GEM など)をあらかじめ Pd に組み込んだものが,Pd-extended として用意されています.

このページでは,Pd-extended の基本的な使い方を解説し,その原理と簡単なプログラミングを学んでいきます.続編では,それを踏まえて,音メディア・映像メディアを自在に操るための基礎を学びます.以下では説明を分かりやすくするため,"Pd" で "Pd-extended" を意味するものとします.

【インストール】

Pd は Mac・Linux・Windows などで動作するオープンソースのソフトウェアです.

ダウンロードしてインストーラを起動し,選択肢にはデフォルト項目を選ぶだけで,問題なくインストールできると思います.下図は,それぞれ Mac OS X・Ubuntu Linux・Windows XP で Pd を起動したときのメインウィンドウです.

【例題パッチ】

このページで例題として扱うパッチは,下の pack1.zip にまとめてあります.適当な場所に展開して,読み進めながら試してみてください.

まずは動かしてみる
【Hello world】

Pd を起動すると,つぎのような Pd ウィンドウが現われます.これは Pd 全体の機能設定をしたり,動作ログやエラーメッセージを表示するためのウィンドウです.これを閉じると Pd は終了してしまいますので注意してください.

Pd のプログラムは,キャンバス (canvas) とよばれる白地のウィンドウ上に,パッチ (patch) とよばれる図式として作成していきます.まず空のキャンバスを作成してみましょう.File メニューから,New を選択してください.つぎのような新しいキャンバスが現われます.このキャンバスに,さまざまなボックス(データの処理単位)を配置し,それらを接続線 (connection) でつなぐことで,データの流れをプログラムしていきます.

図:Pdの空パッチ

簡単なパッチを作ってみましょう.キャンバスのウィンドウがアクティブになっている状態で,Put メニューから Message(メッセージボックス)を選択し(または Ctrl+2 を押し),キャンバスの適当な位置をクリックして配置します.するとメッセージボックス内部でカーソルが点滅しますから,たとえば Hello world と(カンマを入れずに)タイプし,Pd にタイプ終了を知らせるためにキャンバスの白地の部分をクリックします.こうして生成されたメッセージボックスを,以下では [Hello world[ と表記します.

図:Pdでのメッセージボックス作成

もう1つボックスを置きます.Put メニューから Object(オブジェクト)を選択し(または Ctrl+1 を押し),先ほど作成した [Hello world[ の下あたりをクリックして配置します.やはりオブジェクト内部でカーソルが点滅していますから,print とタイプし,キャンバスの白地の部分をクリックします.こうして生成されたオブジェクトを,以下では [print] と表記します.

図:Pdでのオブジェクト作成

最後に,マウスポインタを [Hello world[ の左下にある小さな四角に合わせ(マウスポインタが変化します),マウスボタンを押し下げて,そのまま [print] の左上にある小さな四角まで(マウスポインタが変化します)ドラッグします.そこでマウスボタンを離せば,[Hello world[ から [print] への接続線が生成されます.

図:Pdでのリンク作成

ボックスや接続線を消すには,マウスドラッグして消したいボックスを含んだ長方形領域を選択して delete キーを押すと,ボックスとそれに出入りする接続線が削除されます.コピー(Ctrl+C)やペースト(Ctrl+Y)も可能です.接続線を1本だけ消したいときは,消したい接続線をマウスクリックして選択したのち,delete キーを押してください.

ボックスに書き込んだ文字列を修正したいときは,ボックスをマウスクリックすると内部の文字列が選択状態になりますので,キー入力した文字列に入れ替えることができます.あるいはカーソルキーを動かして一部分だけを修正することできます.ボックスを移動するには,そのボックスをマウスドラッグ(クリックではない)してください.

これでプログラミング終了です.実行するには,Edit メニューの下端にある Edit mode を選択するか,あるいは Ctrl+E を押してください.これで実行モードに入ります.もう一度 Edit mode を選択するか Ctrl+E を押せば編集モードに戻ります.では,実行モードで [Hello world[ をマウスクリックしてみてください.Pd ウィンドウのコンソール(文字表示領域)に print: Hello world という行が追加されるはずです.

編集モードと実行モードでマウスポインタの形状が変わります.指型であれば編集モード,矢印であれば実行モードです.

ちなみに,2つのモードの違いは,マウスやキーボードの入力を編集作業に使うか,実行時のボックス操作(メッセージボックスからの送信など)に使うかの区別しかありません.編集モードでもパッチは動いているのです.

Pd の原理を理解する(1)
【オブジェクトとメッセージ】

ボックスの上側にみえる小さな四角が入力端子 (inlet),下側にあるのが出力端子 (outlet) です.複数の入力端子が並ぶことや,複数の出力端子が並ぶことがあります.また,入力端子あるいは出力端子のないボックスもあります.すべての接続線はボックスの出力端子から別のボックスの入力端子へという方向性をもっていて,接続線を作成するにはこの方向にマウスドラッグします.

先ほどの例では,メッセージボックス [Hello world[ をクリックすると,メッセージ Hello world がその出力端子から出力されます.メッセージは,このような単語の列=リスト (list) になる場合もあれば,1つの単語になる場合もあります.もちろん,ふつうのプログラミング言語と同じように数値をとることもあります.たとえば [123[ を押せば 123 という数値メッセージが出力されます.

オブジェクト [print] は,入力されたメッセージをコンソールに表示するという機能をもったボックスです.[print] は入力端子のみをもつオブジェクトですが,一般にオブジェクトは入力端子からメッセージを受け取り,何らかの変換を行ない,その結果をメッセージとして出力端子から送り出します.オブジェクトは入力を変換して出力する「関数」と考えてよいでしょう.

たとえば,つぎのパッチは2つの数値の和を計算するものです.[+] は2つの入力端子から入力された数値を加算し,その結果を出力します.同様に,[-] は減算, [/] は除算, [*] は乗算です.すべて実数(float 型)演算となります.[div] は割り算の商(整数部分)を,[mod] はその余りを出力しますが,結果はやはり実数(float 型)となります.

図:pd-sum1.pd

まず右側の [234[ を押してから,左側の [123[ を押してみてください.[+] によってそれらの和が計算され,その結果が [print] に送られ,コンソールに 357 が表示されます.

【ホットとコールド】

上のパッチで,[234[ だけを押しても.[+] は何も出力しません.[123[ を押すことで,[+] は2つの数値を加算し,その結果 357 を出力します.[234[ を何度押しても何も出力されませんが,[123[ を押すと,何度でも押すたびに,計算結果が出力されます.では,つぎのパッチはどうでしょう.

右側の入力端子につながった [234[[23[ をいくら押しても何も出力されません.一方,左側の入力端子につながった [123[ を押すと,その直前に右側の入力端子に入れた数値との和が出力されます.[12[ を押しても同様に,その直前に右側に入れた数値との和が出力されます.この動作は,やや直観に反するのではないでしょうか?

これを説明するのがホットとコールドの区別です.一番左側にある入力端子がホット入力端子 (hot inlet) で,それ以外はコールド入力端子 (cold inlet) となります.コールド入力端子に入力されたメッセージは内部に一時的に格納(上書き)されますが,実際の処理は行なわれません.一方,ホット入力端子に何らかのメッセージが入力されると,そのとき各コールド端子について格納されていた(つまり最新の)メッセージと合わせて処理され,結果が出力されます.この原理は,若干の例外はありますが,ほとんどのオブジェクトについて当てはまります.

上のパッチを作成した(あるいはファイルに保存してから再び開いた)直後,まだコールド入力端子に何もメッセージを入力していない状態で,ホット入力端子に 123 を入力すると,[+]123 を出力します.これは,[+] が生成された時点で,コールド入力端子に対応する内部変数が 0 に初期化されているためです.

他の演算オブジェクトについても,内部変数の 0 に初期値は 0 となります.減算をする [-] は「ホット − コールド」を計算します.除算をする [/] は「ホット / コールド」の実数演算を行ないますが,少しクセがあります.通常 0 で割り算をするとエラーとなるところ,Pd では 0 を出力します.

【オブジェクトの引数】

オブジェクトに引数 (creation argument) を与えることができます.引数とはオブジェクト名の後ろに与えられた文字列や数値のことです.たとえば,[* 2]2 が引数です.左下のパッチにある [* 2] は,ホット入力端子に 123 が入力されると,それを2倍した 246 を出力します.

図:pd-witharg.pd 図:pd-witharg2.pd

つぎに右上のパッチを見てみましょう.[* 2] のコールド入力端子に何も入力していなければ,左側のパッチと同じように,[123[ を押すたびに 246 が出力されます.コールド入力端子に 3 あるいは 4 を入力しても何も出力されませんが,そのあとでホット入力端子に 123 を入力すると3倍の 369 あるいは4倍の 492 が出力されるはずです.

このように,引数は内部変数の初期値を明示的に与えるためのものです.コールド入力端子への入力は,内部変数を上書きします.内部変数が上書きされても,パッチ上に見える引数(上の例では 2)は更新されません.

パッチをファイルに保存するには File メニューから Save(または Save as...)を選択し,適当なファイル名を与えます.このとき,パッチ上で目に見える引数は保存されますが,目に見えない内部変数の状態は保存されません.

保存したパッチを開くには File メニューから Open を選びます.開いた時点で,各オブジェクトの内部変数は,規定の初期値あるいは明示された引数によって初期化されます.

注意:Pd は非アスキー文字を扱えないようです.たとえばファイルのパス名に(「デスクトップ」のような)日本文字が入っているとうまく保存できないことがあるようです.パッチ内部やパス名にはアスキー文字だけを使うようにしてください.

Pd の原理を理解する(2)

オブジェクトやメッセージボックスを接続線でつなぎ,メッセージが流れる回路をつくることが,Pd におけるプログラミングとなります.

【メッセージの流れ】

複数の接続線が1つの入力端子に入ることがあります.下のパッチで,[Hello world[ を押せば,そのメッセージがコンソールに表示され,[Yes we can[ を押せば,そのメッセージがコンソールに表示されます.どんなに素早く操作しても,メッセージが衝突することはありません.

図:Pdでの多対1のリンク接続

1つの出力から複数の接続線が出ることもあります.下の2つのパッチは,いずれも,[we can[ を押せば,コンソールには Yes we canMaybe we can が表示されます.ここで登場した [prepend] は,入力メッセージの先頭に引数を追加したメッセージを出力するオブジェクトです.

図:Pdでの1対多のリンク接続 図:Pdでの多対1と1対多のリンク接続

上の2つのパッチで,メッセージがコンソールに表示される順序には注意が必要です.[we can[ からのメッセージは,[prepend Yes] への接続線に出力されるのが先か,あるいは [prepend Maybe] への接続線に出力されるのが先か,その出力順序は未知となります.正確には,接続線が作られた順序で(古い順に)メッセージが出力されますが,パッチを見ただけではわかりません.このような性質は,メッセージボックスだけでなく,すべてのボックスの出力端子についても言えます.

メッセージの出力順序を明示的に扱うには [trigger] を使います.たとえば [trigger a a] は,入力されたメッセージを,まず右の出力端子から出力し,つぎに同じメッセージを左の出力端子から出力します.引数 a は anything の意味で,入力されたメッセージをそのまま出力にコピーすることを意味します.[trigger a a a] のように引数を増やせば,出力端子の数をいくつでも増やすことができ,右から左へと順番に出力されます.([trigger ...] はよく使うので [t ...] と略記することができます.)

つぎのパッチでは,[prize[ をクリックすると,1st prize5th prize の順にコンソールに表示されます.ボックスの位置関係や接続線の向きは関係ないことに注意してください.

メッセージの流れ方は深さ優先 (depth-first) となることに注意してください.つまり,メッセージが分岐点に来ると,ただちに出力順序1番の接続線に流れていきます.この流れに対する処理(オブジェクトによるデータ処理,さらなる分岐など)がすべて終了すると,つぎに出力順序2番の接続線に同じメッセージが流れていきます.これを繰り返すことで,メッセージがパッチ上を伝搬し,処理されていくわけです.

Pd の商用版である Max では,[trigger] によって出力順序が明示されていない分岐について,接続先のオブジェクトが右にあるものほど先(横位置が同じであれば下にあるものほど先)に出力されるようになっています.Max 経験者は,この規則が Pd には適用されないことに注意してください.

【メッセージの種類】

いままでに,数値(float:実数値)・シンボル(symbol:数値でない文字列)・リスト(list:シンボルや数値の並び)という3種類のメッセージを扱いました.まとめると,つぎのようになります.

数値として解釈できない文字列(ただし空白・セミコロン・カンマを含まないもの)はすべてシンボルとなります.したがって 1+2 もひとつのシンボルで, 2*2+2/2 もひとつのシンボルです.

残された第4のメッセージは bang(バン)というもので,Pd ではさまざまな場面で「合図」として使われます.bang メッセージを発生させるには [bng] オブジェクトが使えます.Put メニューから Bang を選択する(あるいは Ctrl+Shift+B を押す)ことで生成できます.丸が入った正方形のボックスが [bng] オブジェクトです.これを押すと,出力端子から bang が出力されます.たとえば,つぎのパッチをみてください.

図:pd-bang.pd

[bng] を押すと Pi: 3.14159 とコンソールに表示されます.([print] に与えた引数は,コンソール表示の行頭に表示されます.) メッセージボックスは bang を受け取ると,マウスクリック時と同じように,その内容を出力するわけです.では,つぎのパッチはいかがでしょうか.

このパッチは独立した2つの部分からなります.左側の [bng] を押すと,[trigger] から3つの bang が(右から左へと順番に)出力されます.まず 123 の二乗が計算され,つぎに 3.14 との乗算が行なわれ,コンソールに表示されます.右側の [bng] を押しても,やはり 123 の二乗が計算され,さらに 3.14 と掛け合わされて,同じ結果がコンソールに表示されます.

メッセージボックスは bang を受け取るとその内容を出力しますが,基本的にはどんなメッセージを受け取っても自分の保持する内容を出力します.

ただし,メッセージボックスの内容に $1, $2 などの特殊シンボルが入っている場合,受け取ったメッセージのn 要素で $n を置換したメッセージを出力します.下のパッチで,[11 24[ を押すとコンソールには month day と表示されますが,[2 25[ を押すと month 2 day 25 と表示されます.(文字列レベルで置換されるので [$1/$2[ であれば 2/25 が得られます.)

図:pd-message.pd

一方,[3 12[ を押すと month 3 がコンソールに表示され,つぎの行に day 11 が表示されます.このようにメッセージボックスの内容がカンマで区切られている場合,先頭からのカンマ区切りごとに別々のメッセージとして出力されます.

メッセージボックスの内容をそっくり置換するには [set ...[ を送ります.下のパッチで,[bng] を押せば original が出力されますが,[set update[ を押すと,何も出力されませんが,パッチ上に見える [original[[update[ に変化します.[set brand new[ を押せば,こんどは [brand new[ に変化します.その内容を出力するには bang を入力します.

図:pd-messageset.pd
【数値ボックス】

ここまで数値計算をするパッチでは,メッセージボックスに数値を入れ,計算結果を [print] によってコンソールに表示していましたが,数値ボックス (number box) を使うことで,数値(float 型データ)の入力・保持・表示などがより柔軟に行なえます.数値ボックスは,Put メニューから Number を選ぶ(あるいは Ctrl-3 を押す)ことで生成される,右上に切り欠きのある灰色のボックスです.初期値は 0 です.

図:pd-number.pd

このパッチ(実行モード)で [123[ を押すと,数値ボックスの内容が 123 に変わり,[print] に出力されます.マウスクリックして,キーボードから 4 5 <enter> と押すと,内容も表示も 45 に変わり,やはり [print] に出力されます.マウスで上下にドラッグすると数値が連続的に増減し,変化する度に [print] へ出力されます.一方,[set 123[ を押すと,数値ボックスの内容が 123 に変わりますが,出力はされません.bang を送ることで,現在の内容が出力されます.(メッセージボックスと異なり,クリックしただけでは内容は出力されません.)

数値ボックスをふつうにドラッグすると 1 単位にその値が増減しますが,Shift を押しながらドラッグすることで 0.01 単位に増減させることができます.

数値ボックスの幅(字数)は,マウスで右クリックして Property を選ぶことで変更することができます.初期状態では幅 5 です.幅を 1 にした場合は特別で,数値ボックスはマウスクリックによって 0, 1 を交互に出力するスイッチとして機能します.

数値ボックスは,数値の入力や表示だけでなく,一時的に数値を保持するためにも使います.下のパッチで,[bng] を押すたびに何が起こるのかを想像してみてください.

図:pd-count.pd

[+] のコールド入力端子の内部変数は初期値 0 です.したがって,最初に [1[ から送られてきた 1 はこの 0 と加算され,その結果である 1 が数値ボックスに送られます.数値ボックスはその内容を 1 に更新するとともに,それを [+] のコールド入力端子にも送り,その内部変数を 1 で上書きします.これに付随して,[+] の加算結果は [print] にも送られています.2回目に [1[ が押されたときは,[+] のコールド入力端子の内部変数は 1 ですから,加算結果 2 が伝わっていきます.こうして,[1[ を押すたびに,数値ボックスの内容が1つずつ増えていくわけです.このようなカウンタ機能は,Pd のプログラミングでよく使われます.

このカウンタのパッチは,[+] の出力が 同じ [+] の入力に戻っていくようで,奇妙に見えるかもしれませんが,正しく動作します.一方,ホット入力端子だけを通って元のボックスのホット入力端子に戻るようなパッチは正しく動作しません.メッセージが無限に回り続け,エラー (stack overflow) となります.

Pd プログラミングの初歩

Pd では,演算オブジェクトで回路をつくり,そこにメッセージを流すことで,さまざまな情報処理を行ないます.ここからは,この原理を踏まえて,いくつかの基本的な回路をつくり,Pd プログラミングを理解していきます.

【繰り返し】

たとえば1分間に 100 回のテンポで音や光を出すといった,実時間を扱う処理を Pd は得意としています.これには,一定の時間間隔で bang を出力する [metro] を使います.引数は周期(ミリ秒)です.

図:pd-metro.pd

まず,左側の回路で [1[ を押してみてください.コンソールに bang が 600ms(ミリ秒)ごとに表示されるはずです.これを止めるには [0[ を押します.[1[ を押せば再開します.

右側の2つの回路は全く同じものです.上にある正方形は [toggle] というオブジェクト(Put メニューの Toggle)で,クリックするごとにオン(× 印)とオフ(無印)が切り替わります.オンに切り替わるときに 1 が,オフに切り替わるときに 0 が出力されます.一方,下にあるのは [bng] ですが,ここではインジケータとして使っています.何らかのメッセージを受け取ると, [bng] は一瞬だけ点灯(黒く変化)し,bang を出力します.

では,この [metro] の応用として,つぎのパッチを見てみましょう.まずは左側の回路の [toggle] をオン(×)にしてみてください.

600ms ごとに左端にある [bng] が点滅し,それに 100ms だけ遅れて右隣りの [bng] が点滅します.[delay] は,メッセージを遅らせる機能をもったオブジェクトです.bang を受け取ると,与えられた時間(ミリ秒)だけ遅延して,bang を送り出します.右側の回路も原理は同じです.100ms ずつ遅れて点滅パターンが流れていきます.

この [delay] は,Pd 全体の動作を止めるものではありません.あくまで bang を遅延させるだけです.[metro] から出力された bang は,[delay 100] に入力されると,100ms 後の出力をスケジューリングされて,ひとまず流れは止まります.[metro] からのもう一方の出力は,直下の [bng] に入力されます.[metro] からの出力順序は任意でよいので,この分岐に [trigger] を使う必要はありません.

[delay] は Pd プログラミングで最もよく使うオブジェクトのひとつです.遅延時間は引数によって設定することもできますし,右側のコールド入力端子から設定することもできます.また,左側のホット入力端子に遅延時間を入力すると,その時間だけ遅延した後に bang を出力します.

[delay]bang や数値を入力し,その遅延出力が出る前に,新しい bang や数値を入力すると,それまでスケジューリングされていた遅延出力はキャンセルされ,新しい遅延出力がスケジューリングされます.

ここで [metro][delay] にミリ秒という時間が出てきましたので,時刻を出力する [time] と経過時間を計測する [timer] を紹介しておきましょう.

図:pd-time.pd

[time] は現在時刻を出力するオブジェクトです.bang を与えると,4つの出力端子の左から,時・分・秒・ミリ秒が出力されます.一方,ストップウォッチのように経過時間を計測するには [timer] を使います.左側の入力端子に bang を与えるとタイマが 0 秒からスタートします.右側の入力端子に bang を入力するたびにスタートからの経過時間をミリ秒で出力します.

【条件分岐】

条件によってメッセージを分岐させることも必要になるでしょう.ある条件が成り立つかどうかをテストするために [==], [!=], [<], [>], [<=], [>=] といった関係演算子が用意されいてます.たとえば [>= 3] であれば,3 以上の数値が入力されると 1 を出力し,それ以外の数値の場合 0 を出力します.

下のパッチは,600ms 周期のメトロノームをカウンタにつなげ,得られた数値から [mod] によって 4 で割った余りを求め,その結果を 0, 1, 2, 3 と比較しています.比較した結果は,下に並んだ数値ボックスに入力・表示されます.1 の表示が左から右へ流れていくのがわかります.

つぎのパッチでは,[==] で比較した結果(0 または 1)から,1 のみを抽出するために [select] を使った例です.[select] は受け取った数値を引数と比較し,一致すれば左端の出力端子から bang を出力し,そうでなければその数値を右端の出力端子から出力します.([select ...] はよく使うので [sel ...] と略記することができます.)

[select] に複数の引数を書くと,それぞれに対応して(bang が出る)出力端子がつくられます.右端に追加された出力端子は,どの引数とも一致しなかった場合にその入力数値が出力される端子です.したがって,上のパッチは,左下にあるようなシンプルなパッチに書き換えることができます.

図:pd-branch3.pd 図:pd-branch4.pd

これとよく似た機能をもつオブジェクトに [route] があります.右上のパッチにあるように,selectroute と書き換えても同じように動作します.ですが [route] が力を発揮するのはリストの分類です.

[route] は入力されたリストの先頭要素によって,それが流れる出る先を選択します.先頭要素と一致した引数がある場合,対応する出力端子から先頭要素を除いたメッセージが出力されます.結果が空リストとなる場合は bang が出力されます.どの引数とも一致しない場合は,入力されたメッセージがそのまま右端の出力端子から出力されます.上のパッチを操作して,どの [print] から何が表示されるかを確認してみてください.

【流れの切替え】

メッセージの流れをバルブのように開閉したい場合があるでしょう.そのためのオブジェクトが [spigot] です.右側の入力端子に 1 を入れると,左側の入力端子に入ったメッセージが出力端子に流れ,右側の入力端子に 0 を入れると,その流れが止まります.

図:pd-spigot.pd

あるメッセージが流れる方向を,別のメッセージによって制御したい場合もあるでしょう.そのために用意されているのが [gate] というオブジェクトです.引数として分岐の本数を与えます.左側の入力端子には,メッセージを流したい出力端子の番号(左端が第1出力端子)を入力します.初期値は 0 で,どこにも出力されないことを意味します.右側の入力端子には,分岐先に流したいメッセージを入力します.(左右の入力端子の違いに注意してください.)

上のパッチでは,600ms ごとにカウントアップされる数値が [gate] に流れてきます.初期状態では [gate] の先には流れていきません.[1[ を押すと,[gate] は左端の第1出力端子から,この数値を出力するようになります.[2[ を押せば第2出力端子から,[3[ を押せば第3出力端子から出力するようになります.[0[ を押すと,どこにも出力しなくなります.

【パッチを整理するには】

パッチが複雑になってくると,接続線が込み入ってきて,全体的な構造がわかりづらくなってきます.ここで紹介する [send][receive] は,あたかも電波のようにメッセージを送受信することができます.引数として与えた名前は,いわば通信ポート名のようなもので,この名前を共有する [send](送信側:ひとつ)から [receive](受信側:複数あってもよい)への見えない接続線がつくられます.なお受信側が複数ある場合,メッセージの伝達順序は不定となります.

[send], [receive] の引数に与える名前は,グローバルなスコープをもちます.ゆえに異なるパッチの間での通信も可能です.ただし意図しない「混線」には注意してください.パッチの内部に閉じたローカルな名前をつけたい場合は,[send $0-beat] のように "$0-" を名前の先頭につけるとよいでしょう.$0 はパッチごとに異なる番号(1007 など)に置き換えられます.

パッチを整理するもうひとつの方法は,サブパッチをつくることです.パッチの中に [pd] というオブジェクトをつくります.[pd subpatch] のように,引数に適当な名前を与えるとわかりやすいでしょう.すると新しいキャンバスが開きます.(ただし,同じ名前でもうひとつ [pd subpatch] を生成しても別個のキャンバスとなります.) ここに [inlet] を入力とし,[outlet] を出力とするようなサブパッチをつくります.元のパッチ(メインパッチ)に生成した [pd subpatch] に入力端子と出力端子が現われるので,このサブパッチをひとつのオブジェクトとして扱うことができます.サブパッチが複数の [inlet] をもつ場合,その水平方向の位置が,オブジェクトボックスに現われる入力端子の順序に反映されます.複数の [outlet] をもつ場合も同様です.

図:pd-subpatch.pd 図:subpatch-sub

サブパッチのウィンドウを閉じてもその内容はメインパッチに記録されています.サブパッチを展開するには [pd] を右クリックして Open を選ぶか,あるいは実行モードであればクリックしてください.いつでも編集できます.メインパッチを保存すれば,サブパッチの内容もいっしょに保存されます.

このほかに,サブパッチを別のファイル(somepatch.pd のような名前をもつファイル)に保存して,それをメインパッチから [somepatch] のように1つのオブジェクト([somepatch] のインスタンス)として利用することができます.このためには,サブパッチのファイルが探し出せるように Pd のサーチパスを設定しておく必要があります.Windows 版・Linux 版では,File メニューから Path... を選び,Mac OS X 版では Pd-extended メニューから Preferences > Path... を選び,該当するフォルダを登録してください.

別ファイルにするか,サブパッチにするかは,つぎにあげる違いを参考にして決めるとよいでしょう.

  • 機能の再利用:ある機能をもったパッチを独立したファイルとすることで,どこからでもその機能をインスタンス化して利用することができます.ただしサーチパスの設定が必要です.一方,再利用の必要がない場合は,サブパッチとする方が手軽です.
  • $0 の有効範囲:[send][table](後述)にローカルな名前を与えるために $0-name のように $0 を使うことがありますが,この $0 は,ファイルごとに異なる番号と置き換えられます.したがって,サブパッチはメインパッチと同じ $0 をもつことになります.
メッセージとリスト

ここはやや高度な内容を含んでいるので,とにかく Pd で音や画像を出したい人は,ここを飛ばして先に進んでもよいでしょう.(リストを扱う必要がでてきたら,ここに戻ってきてください.)

ここまで「リスト」を要素(シンボルや数値など)の並びとして扱ってきました.各要素の位置(先頭から何番目か)によって,たとえば piano 60 42violin 64 75 のように,意味づけして使うと便利です.そのための手段のひとつが前出の [route] です.つぎのパッチは,リストの第1要素で分類して,第2要素の数値を加算しています.確認してください.

【メッセージの正体】

接続線を流れるメッセージは,実際には下記のような構造をもつ要素列({...} と表記)です.先頭の第1要素をセレクタ (selector) とよびます.セレクタに bang, float, symbol, list が現われたとき,メッセージは特別な意味をもつようになります.

このように,メッセージとリストの関係はやや複雑になっていますが,これをしっかり理解することで,メッセージやリストの適切な操作ができるようになります.注意すべき点をまとめると,つぎのようになります.

【リストの操作】

リストを操作するにはオブジェクト [list] が便利です.引数として操作の種類を与えることでさまざまなリスト操作が可能です.よく使うのは,2つのリストをつなげる [list append][list prepend],リストからセレクタを取り除く [list trim],そしてリストの要素数を求める [list length] などです.また,[+] などの二項演算オブジェクトは,第1入力端子に2要素のリストを与えることで,それらの二項演算を実行します.メッセージボックスに $n のような引数を与えることで,リストの要素を抽出したり,順番を変えたりすることができます.

要素からリストを合成したり,リストを要素に分解することも必要になるでしょう.そのためのオブジェクトが [pack][unpack] です.どちらも引数に fs を並べ,要素の種類(float か symbol か)を明示して使います.

図:pd-packunpack.pd

上のパッチで,[2011[({float 2011} を出力)と [symbol MYU[ をこの順序で押すと,[pack s f] によってそれらを要素とするリスト {list MYU 2011} が合成され,コンソールには P: list MYU 2011 と表示されます.このリストメッセージがこんどは [unpack s f] に入力されると,その要素列がシンボル {symbol MYU} と数値 {float 2011} に分解され,コンソールに F: 2011S: symbol MYU の順序で表示されます.

次のステップへ

ここまで,Pd の原理と簡単なプログラミングについて説明してきましたが,まだ Pd の入り口を覗いただけです.Pd には他にもたくさんのオブジェクトがあります.キャンバスの白地のところを右クリックして Help を選んでください.オブジェクトの一覧が出ます.そこから気になるオブジェクトをさらに右クリックして Help を選ぶことで,より詳しい解説を見ることができます.すべての解説は生きたパッチなので,実際に動作を確かめることができます.

それでは「Pure Data 音処理」に進んでください.音声信号処理の基礎を学びながら,Pd プログラミングの理解を深めていきましょう.