2017/04/30

SuperColliderで音を出す

音を出して計器類でファンシーに表示しつつSynthDefします。

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をインストールします。

  1. SuperColliderのソースコードをダウンロードして解凍。
  2. f0pluginsのソースコードをダウンロードして解凍。
  3. /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_DESTINATIONExtensions へのパスを指定してください。

以上でインストールができているはずです。SuperCollider IDEで確認してみます。

  1. SuperCollider IDEを起動。
  2. Ctrl+Bでサーバを起動。
  3. 下のコードをペースト。
  4. ペーストしたコードを選択して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の()

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

Snake






遊んでみる

Snakeは古典的なゲームです。

ヘビの体をより長く伸ばすことがゲームの目的です。矢印キーの左右でヘビを操り、エサを食べさせることで体が伸びます。ヘビは自分の体か画面の端にぶつかると死にます。

Fedora26でSuperColliderをコンパイル

SuperColliderは音の合成やアルゴリズムによる作曲に使われるソフトウェアです。
Fedora25以降はCCRMAのリポジトリが無くなったのでソースコードからコンパイルしてインストールすることにしました。

基本はソースコードに同梱されているインストール方法に従えばいいのですが、ところどころ引っかかる部分があったのでまとめました。