音を出して計器類でファンシーに表示しつつSynthDefします。
2017/04/30
2017/04/29
SuperColliderの関数と変数
関数
sclangでは {}
で囲んだ部分が関数になります。
{}
内の最後の式の評価値が返ってきます。関数の途中で値を返すことはできないようです。
関数を呼び出すには value
を使います。
f = { |a, b| a + b }; f.value(4, 5).postln; // 9 postln(value(f, 4, 5)); // 9 上と同じ。 g = { |a(10)| a * a * a }; // 引数のデフォルトを設定。 g.value.postln; // 1000 h = { |a, b ... arr| // ... arr で残りの引数をArrayにしてarrに代入。 var sum = 0; arr.do{ arg item; sum = sum + item }; // doは他言語のforeachに相当。 sum * a * b }; h.value(2, 3, 4, 5, 6).postln; // 90
()
ブロックと組み合わせると以下のような書き方ができます。
f = { |a, b| a + b }; f.value( c = 10.rand; c.postln; c, c );
変数
以降の例は一行ずつではなく、範囲選択して実行してください。エラーの種類が変わる場合があります。
var
で変数を宣言します。 var
による変数の宣言は関数の始めでしか行えません。また一番外側のスコープは関数とみなされています。
var alpha = 100; var beta = 200; alpha.postln; // 100 beta.postln; // 200 // var gamma; // コメントを外すとエラー。
変数のスコープについて確認してみます。
var alpha = 100; var beta = { |value| var gamma = 200; value + gamma.value }; beta.value(alpha).postln; // 300 // gamma.postln; // コメントを外すとエラー。
グローバル変数
これまでの例では var
による宣言なしに変数を使っている箇所がありました。それらは全てInterpreterによって用意されたグローバル変数です。
InterpreterはSuperCollider IDEの起動と共にインスタンスが作られ [a-z]
をグローバル変数として保持しています。その中でも s
は特殊でServerが代入されます。 s
は再代入などによって変更しないことが推奨されています。
a = 100; b = 200; a.postln; // 100 b.postln; // 200 c = 300; // グローバル変数なのでOK。
環境変数とEnvironment
sclangでは環境変数(Environment Variable)という変数を使うことができます。 ~
から始まる名前は currentEnvironment
に所属する環境変数となります。
currentEnvironment.postln; // Environment[ ] ~alpha = 100; ~alpha.postln; // 100 ~beta = 200; ~beta.postln; // 200 currentEnvironment.postln; // Environment[ (beta -> 200), (alpha -> 100) ]
SuperCollider IDEで新しいセッションを開始した時は currentEnvironment
には topEnvironment
が代入されています。 topEnvironment
はどこからでも参照できます。
var env = Environment.make; (currentEnvironment === topEnvironment).postln; // true (currentEnvironment === env).postln; // false ~value = 100; ~value.postln; // 100 env.push; (currentEnvironment === topEnvironment).postln; // false (currentEnvironment === env).postln; // true ~value.postln; // nil ~value = "hoge"; ~value.postln; // hoge topEnvironment.at(\value).postln; // 100 env.pop; (currentEnvironment === topEnvironment).postln; // true (currentEnvironment === env).postln; // false ~value.postln; // 100
Environmentはスタックに格納されているようです。 currentEnviromnet
は常にスタックの一番上を指しています。新しいEnvironmentを作った時は .push
でスタックに挿入できます。 .pop
はどのEnvironmentから呼び出されるかにかかわらず常にスタックの一番上を取り出すようです。
var env1 = Environment.make; var env2 = Environment.make; var checkEnv = { [ (currentEnvironment === topEnvironment), (currentEnvironment === env1), (currentEnvironment === env2) ] }; checkEnv.value.postln; // [ true, false, false ] env1.push; checkEnv.value.postln; // [ false, true, false ] env2.push; checkEnv.value.postln; // [ false, false, true ] env1.pop; checkEnv.value.postln; // [ false, true, false ] env2.pop; checkEnv.value.postln; // [ true, false, false ]
2017/04/27
SuperColliderのプラグインのインストール
公式によるプラグインの例の説明に基づいています。
プラグインは /path/to/SuperCollider/Extensions
に配置することでインストールされます。
プラグインをビルドする場合はSuperColliderのソースコードが必要になります。例としてf0pluginsをインストールします。
- SuperColliderのソースコードをダウンロードして解凍。
- f0pluginsのソースコードをダウンロードして解凍。
/path/to/f0plugins
で以下のコマンドを実行。
mkdir build; cd build cmake -DSC_PATH=/path/to/SuperCollider_Source -DINSTALL_DESTINATION=/usr/local/share/SuperCollider/Extensions .. sudo make install
-DSC_PATH
はSuperColliderのソースコードへのパス -DINSTALL_DESTINATION
は Extensions
へのパスを指定してください。
以上でインストールができているはずです。SuperCollider IDEで確認してみます。
- SuperCollider IDEを起動。
- Ctrl+Bでサーバを起動。
- 下のコードをペースト。
- ペーストしたコードを選択してCtrl+Return。
// Simple synth definition using the Atari2600 UGen: ( SynthDef(\atari2600, {|out= 0, gate= 1, tone0= 5, tone1= 8, freq0= 10, freq1= 20, amp= 1, pan= 0| var e, z; e= EnvGen.kr(Env.asr(0.01, amp, 0.05), gate, doneAction:2); z= Atari2600.ar(tone0, tone1, freq0, freq1, 15, 15); Out.ar(out, Pan2.ar(z * e, pan)); }).add ) // And a pattern to play it: ( Pbind( \instrument, \atari2600, \dur, Pseq([0.25, 0.25, 0.25, 0.45], inf), \amp, 0.8, \tone0, Pseq([Pseq([2, 5], 32), Pseq([3, 5], 32)], inf), \tone1, 14, \freq0, Pseq([Pbrown(28, 31, 1, 32), Pbrown(23, 26, 3, 32)], inf), \freq1, Pseq([Pn(10, 16), Pn(11, 16)], inf) ).play )
音が出れば成功です。
上の例は公式にあったものです。私の環境では実行できなかったので方法を調べました。
SuperColliderの()
SuperColliderの()はブロックのようにも使えるメソッドの呼び出しです。Messageとも関連がありますが、何と呼んでいいのかよくわかりません。lispのprognが感覚としては近いです。
まずはブロックとして使ってみます。SuperCollider IDEでは貼り付けた行にカーソルを合わせてCtrl+Returnで実行できます。
(a = 10; b = a * a; c = b * b; postln(c)) // 10000
メソッド名を指定すれば関数を呼び出せます。()は最後の式の評価値を返します。
postln(a = 10; b = a * a; c = b * b; c + c) // 20000
入れ子にしてみます。以下を範囲選択してCtrl+Returnで実行できます。
(postln( a = 10; c = ( b = a * a; b * b ); postln(b); // 100 c + c )); // 20000 postln(a) // 10
aからzの一文字で表される変数は、SuperColliderではグローバル変数として扱われます。
メソッド名は後ろにも書けます。
postln(100); // 100 100.postln; // 100 postln(neg(1)); // -1 1.neg.postln // -1
引数が2つ以上の場合は後ろに置けません。ただし先頭の引数は前に置くことができます。
squared(difsqr(4, 8)); // 2304 difsqr(4, 8).squared; // 2304 4.difsqr(8).squared // 2304 // (4, 8).difsqr.squared // エラー
2017/04/24
Fedora26でSuperColliderをコンパイル
Fedora25以降はCCRMAのリポジトリが無くなったのでソースコードからコンパイルしてインストールすることにしました。
基本はソースコードに同梱されているインストール方法に従えばいいのですが、ところどころ引っかかる部分があったのでまとめました。