ユニットジェネレータ
SinOscやらdacやらはユニットジェネレータ。これもオブジェクト。ユニットジェネレータとは信号(音)を作ったり処理したりするもので、一覧を見ると色々な種類が用意されている。これを適当に持ってきてつないで設定してやれば好きな音が作れる。つなぎ方は以前に書いたとおり「入力=>出力」で、さらに3個以上を直列につなぐときは、
SinOsc s => Gain g => JCRev r => dac;
のように一行で書くことができる。ちなみにGainは音量を調整する(増幅率を変える)ときに使って*1、JCRevは残響のエフェクトをかけるときに使う。フィードバックみたいにループを作ることもできるらしい。
チャイムを鳴らすコードを書いてみた。メロディはドミソド。最後のドは1オクターブ上のやつ。
SinOsc s => JCRev f => dac; .5 => f.gain; .1 => f.mix; // 残響をどのくらい重ねるか決めるパラメータ // [MIDIノート番号, 音の相対的な長さ]の配列 [[60,1], [64,1], [67,1], [72,3]] @=> int seq[][]; for(0 => int i; i < seq.cap(); i++) { seq[i][0] => Std.mtof => s.freq; (0.5 * seq[i][1])::second => now; }
MIDIノート番号とは音階を表す数で中央のドが60、半音上下すると1上下する数。関数mtofでノート番号を周波数に変換する。for文の内容はseqプレーヤーなので、seqの中身を変えれば他のメロディを鳴らすことができる。チャイムといえばウェストミンスターの鐘。
最後にChucK演算子の使い方についてメモ。上のコードのように関数に引数を渡すときChucK演算子を使うことができる。もちろん普通にStd.mtof(seq[i][0])と書くこともできる。複数の引数を取る関数の場合は、
(0.0, 10.0) => Std.rand2f => float f;
のように括弧で囲む。
*1:ただし全てのユニットジェネレータにはgainというパラメータがあって単体ならこれで調整できる