関数
関数は「fun 返り値の型 名前」で定義する。
fun int sqr(int x) { return x*x; }
オーバーロードも可能。なのに何故かStdでは rand(), randf() と rand2(int min, int max), rand2f(float min, float max) がわざわざ別名で実装されている。開発者が使う気ないのか?
引数に配列などのオブジェクトを渡すこともできる。例えば前日のseqプレイヤーの部分は関数として以下のように書き直せる。
fun void player(int seq[][], float unitTime) { for(0 => int i; i < seq.cap(); i++) { seq[i][0] => Std.mtof => s.freq; (unitTime * seq[i][1])::second => now; } }
再帰関数も書ける。再帰的処理といえばハノイの塔が有名で、exampleにも既に二種類ある(10月8日追記:オンラインのexamplesには四種類ある)けど別に自分で書いた。今回は波形に三角波を使ってみた。
TriOsc s => Pan2 p => dac; fun void move(int height, int from, int to) { // fromポールからディスクを取る 60 - height * 2 => Std.mtof => s.freq; from - 2 => p.pan; 100::ms => now; // toポールにディスクを置く 60 + height * 2 => Std.mtof => s.freq; to - 2 => p.pan; 100::ms => now; } fun void hanoi(int height, int from, int to, int other) { if (height > 0) { hanoi(height - 1, from, other, to); move(height, from, to); hanoi(height - 1, other, to, from); } } hanoi(10, 1, 3, 2);
ディスクを取るときと置くときに音が鳴る。音高はディスクの高さと関係していて、ディスクを取るときは基準音(中央のド)より低く、置くときは高くした。音の位置(左、中央、右)はポールの位置に対応している。ポールは三本あって左側から1,2,3に番号付けしたので、ポール番号から2を引けば-1,0,1の数になる。これをpanにセットした。
基準音や「* 2」の部分を色々変えると雰囲気が結構変わる。少しは楽しそうな領域に近づけたかも。