前回までのところでタイマーに対し演奏されるべき時間にトリガーをかけてもらう予約を行うところまで来ていた。あとはトリガーに対して演奏データを処理する、つまりは最終的にsclangのランドから、scsynthに対してコマンドを発行することになる。
ようやくUGenからみていったSuperColliderの処理の流れも、一周してきたというわけだ。
前回までのところでタイマーに対し演奏されるべき時間にトリガーをかけてもらう予約を行うところまで来ていた。あとはトリガーに対して演奏データを処理する、つまりは最終的にsclangのランドから、scsynthに対してコマンドを発行することになる。
ようやくUGenからみていったSuperColliderの処理の流れも、一周してきたというわけだ。
前回までにClock(TempoClock)によってトリガーを発生させ、そのタイミングでコマンドをシンセサイザノードに送信することによって演奏を行うことが可能だと言うことを見てきた。
ただ、その操作はローレベル過ぎて、確かに可能なのだけど、毎回このような基礎の部分から行わないといけないとなると面倒だ。おそらく、プログラムをかける人なら必ずなんらかの手間の簡略化(クラス化なり)を行うだろう。そしてSuperColliderにもそういった上位のラッパークラスが用意されていて、演奏をさせたいのに、それまでのことに煩わせらるといったことがないようになっている。
今回見ていくのはPatternクラスだ。Patternクラスは豊富な派生クラスが存在していて、名前が示すとおりパターンとして登録しておけばそれを演奏してくれるというものだ。必ずしも最初に決められたものだけではなく、ジェネレーティブなものもある、そしてそれらを複雑に組み合わせることも出来る。
パターンクラスを使うと、例えばこんなコードで演奏をさせることが出来る。
Pbind(\degree, Pseq(#[0,1,2],2)).play
さて、これを見ていると、ふと疑問がわいてくる。魔法というものが存在しないように、前々回見たような処理を誰かが行ってくれているわけだ。それは誰がどのようにして行っているのだろうか。どうやってコマンドは手元からシンセサイザノードに届くのだろうか。
その点に注目してPatternクラスを見ていこう。
前回は実際にサウンドの生成を行っているサーバscsynthを離れて、クライアントであるsclang側でのシンセサイザコントロールのさわりの部分を見てみた。
SuperColliderにはClockというクラスがあり、その機能はトリガーをかけて欲しい時間を登録しておき、トリガーのタイミングで行いたい処理を実行すれば良いという仕組みになっていた。トリガーは一度かかると解除されるので、繰り返し行いたい場合は処理の終了時に再度トリガーを登録しておく必要がある。
そのClockクラスの主要な派生クラスの一つがTempoClockであり、名前の通りテンポによる時間管理を行うクラスになっている。主要というのは、このクラスにはdefaultというクラス変数があり、クラスがロードされたときに暗黙にそこにインスタンスが生成される。そして、いろんな演奏に関するクラスがClockに関するパラメータのデフォルト引数(引数が明示的に指定された無かった場合も)としてTempoClock.defaultを使用しているからだ。
TempoClockにはプロパティtempoがあるのだけど、ではこのtempoのパラメータの単位はなんだろうか。メトロノームと同じくBPMでいいのか、はたまた違うのか。初期的に設定されているテンポはどれぐらいの速さなのだろうか。
今回はTempoClockに注目してみようと思う。
前回までのところで、シンセサイザを作り(SynthDef、Synth)、そのラッパクラス(Synth)を使いクライアント(sclang)からサーバ(scsynth)を操作できるというところまでたどり着いた。
SynthDefのコンストラクタの2つめの引数ugenGraphFuncで渡される関数オブジェクトの引数が、すなわちそのシンセサイザのコントローラとなり、Synthクラスのsetメソッドを使って値をセットすることが出来る。
とりあえず演奏すべきシンセサイザを作るところまでは来たので、次はそれを演奏させたい。手動で値をセットするのも良いのだけど、ある程度は自動演奏させたい。
SuperColliderには演奏させるための仕組みが色々と用意されている。今回ピックアップしたのはRoutineクラスだ。流れ的には、必要なコントロールパラメータを設定し、必要なだけスリープする(次のタイミングを待つ)、その繰り返しが単純明快なので、サーバ側でのUGenの時のようにクライアント側のSuperCollider探求のとっかかりとして最適なのではないかと思ったのだ。
話の舞台はサーバからクライアントに移る。
前回、前々回でUGenという出口から始まり、ようやくクライアント側からサーバ側への橋がみつかった。いままでの道のりを図示すると左図のようになるだろうか。
今回見ていくのはもう一つの橋、Synthクラスだ。
前回はUGenを中心としてSuperColliderの世界への探求を試みてみた。今回はその上位構造となるSynthDefを見ていこうと思う。
SuperColliderはクライアントサーバ型アーキテクチャであることは既出のことなのだけど、SynthDef、そしてSynthがこの二つの間にかかった橋だと言えるだろう。UGenは確実に向こう側の世界だ。
お約束だけど、まだSuperColliderへの冒険の道半ばなので、間違っていることが含まれているかもしれないということは注記しておこうと思う。
少々前よりSuperColliderをいじっている。SuperColliderというのは、あえて説明することもないぐらいの有名どころなのだけど、主に音楽・音響記述に長けたプログラミング言語環境だ。音響系といってもDSPなどのストリームプロセスを書くというよりは、むしろ、ノードの接続を記述してシンセサイザーをつくり、それをコントロールするロジックを記述して動かすというのがコアな部分のようだ(もちろんそれ以外が出来ないというわけではない)。
Maxなどともコンセプトでは似ているところもあるのだけど、決定的に違うのはそれがビジュアルプログラムではなくテキストコーディングで行うものという点ではないかと思う。
わたしがSuperColliderに興味を持ったそもそものきっかけは、SC140というTwitterに書けるだけの分量でSuperColliderで音楽を作ろうという試みがあるということを知ったときだった。そのミニマムな魅力にくらくらっときて自分でもやってみたいと思ったのだった。
SuperColliderは少々取っつきにくいところがあるのだけど、コミュニティのパワーが補って余る。わたしもとても助けられている。特に、@umbrellaprocess氏(on twitter)にはわたしの初歩の初歩な質問にもきちんとレスポンスをいただき、大変感謝している。
SuperColliderのTutorialは、公式のIntroductory Tutorialがよくまとまっていると思う。今見返してみると、よく読めばちゃんと書いてあるということも多い・・・。
わたしはSuperColliderを学ぶ上でまずターゲットに決めたのはUGenというクラスだった。その部分がSuperColliderでシンセサイザ(音響処理も含む)を扱うクラスの基底クラスだったというのがその理由だった。
今回、とりあえず今までに分かったことをまとめてみた。しかし、まだSuperColliderへの冒険の道半ばなので、間違っていることが含まれているかもしれないということは注記しておこうと思う。