SuperCollider 3 Server


はじめに
音を出す
音を変える


 はじめに


SuperCollider 3 Server という音響合成のためのプログラミング・ツールに関して、少しずつ書きためていこうと思います。とは言っても、書こうとしている本人があまりよく分かっていないので、これから使おうと思っている人にとっては、あまり役に立たない気がします。何か間違ったことを書いていたら、ぜひ教えてください。

ソース・コードをダウンロードしてProject Builderを使ってコンパイルする方法もありますが、http://sourceforge.net/projects/supercollider からsnapshot versionをダウンロードしてそのまま使うほうが、とりあえずは手っ取り早いと思います。ただ、いずれにしてもまだベータ版以前の段階なので、MacOS9用のversion2.2.16より不完全な部分もありますが、既にそれを補って余りある、とても優れた音響合成環境を提供しています。
さらに、SuperCollider 3 Server (以下SC3。ちなみに、MacOS9用にSuperCollider version3d5.1というのがありますが、ここで言うSC3はMacOSX用です)はMacOSXの他にも、Linux上である程度動作可能なようです。ただし、作者のJames McCartneyは現在Appleに勤めているので、Windows版はまず出てこないでしょう。(と思ったら出たみたいですね。)
詳しくは、本家のサイトhttp://www.audiosynth.com/を参照してください。



 音を出す


早速、SC3 で音を出す簡単なコードを書いてみます。SC3を起動し、Fileメニューから"New"を選択するか、またはコマンド・キーを押しながらNキーを押して、新しいテキスト画面を開き、以下のコードを書きます。

s = Server.local;

s.boot;

(
SynthDef("sine", {
var osc;
osc = SinOsc.ar(800, 0, 0.1); // 800 Hz sine oscillator
Out.ar(0, osc); // send output to audio bus zero.
}).load(s);
)

s.sendMsg("/s_new", "sine", 1000, 1, 0);

s.sendMsg("/n_free", 1000);

s.quit;

1行目では、これから音を作っていく上で使うことになるServerを特定し、それを変数sに代入しています。音を出すためには、まずこのServerというものを起動させないといけません。2行目で変数sにbootというメソッドを使って、Serverを起動させています。

本当は、ここがSC3で一番面白いところなんですが、詳しいことは後で触れます。Serverという名前が表しているように、SC3を使えば、ネットワークを経由して他のコンピューターから音を出すことが、簡単にできるのです。ただ、ここではローカル・マシンだけを想定しています。

さて、書いたプログラムを実行するためには、実行したい行にカーソル(マウス・カーソルではなくて、点滅する縦棒のこと)を置いて、enterキーを押します。SC3を起動させると出てくる、「untitled」というウィンドウに、実行した結果がテキストで表示されます。実行したい部分が複数の行にまたがっている場合は、その部分全体を選択してハイライトさせておいてからenterキーを押します。その部分を( )でくくると、どちらか一方の括弧マークの上でダブルクリックすれば、( )内全体がハイライトされるので、ちょっと便利です。また、コードを書いていて括弧マークの一方を記入し忘れるというミスをした時に、この方法で簡単に書き忘れた箇所を見つけることもできます。

SynthDefというところからload(s)というところまでで、これから出す音を規定し、その規定をServerに転送します。この部分も、後で詳しく見ることにします。

s.sendMsg("/s_new", "sine", 1000, 1, 0) という行では、Serverに「新しくSynthを作れ」というコマンドを送っています。Synthというのは、実際に音を出す際のプロセスを、シンセサイザーに例えてそう呼んでいるのだと思いますが、SuperCollider特有の用語です。詳しく見ると、「.sendMsg」というのがServerにメッセージを送る際のメソッドで、( )の中の"/s_new"というのが、「新しくSynthを作れ」というコマンドです。さらにどういうSynthを作ればいいのかと言えば、その次の"sine"というコマンドで、SynthDefで規定した"sine"というSynthを作るよう指定しています。次の「1000」はSynthのID番号、「1」はactionの種類、最後の「0」はtargetのID番号ということなのですが、全部説明は後回しにします。

この行を実行すると、初めて音が鳴ります。ここではサイン波の持続音が鳴り続けることになります。この音を止めるには、次の s.sendMsg("/n_free", 1000) を実行しなければいけません。ここでServerに送っている「"/n_free", 1000」というコマンドは、ID番号1000というSynthのために使われていたnodeを解除するということで、これを実行することで音が鳴りやみます。

この後、再び s.sendMsg("/s_new", "sine", 1000, 1, 0) を実行すると、また同じ音が鳴ります。つまり、s.sendMsg〜の2行を使って、音を出したり止めたりできるわけです。ただし、最後の行(s.quit)でServerの活動を終了してしまうと、Serverをもう一度s.bootで起動しない限り、音は出なくなります。

こうして書いたコードのファイルは、保存してまた同じ音を出すのに使えます。Fileメニューから"Save"を選択するか、コマンド・キーを押しながらSキーを押して、適当な名前を付けて保存してください。OS9より安定性が増したとは言え、SC3が突然クラッシュしてしまうこともあり得るので、なるべくこまめに保存する癖をつけたほうがいいと思います。そうしないと、せっかく苦労して書いたコードが無駄になってしまうこともあるからです。

以上、分かりにくい説明だったかもしれませんが、SC3のHelpフォルダーに入っている「Tutorial.rtf」に全て詳しく書かれていますので、そちらを参考にしてください。



 音を変える


SC3ではまずSynthを定義し、それをServerに転送して、そこへ向けてコマンドを送り、音を出すというのが、基本的な仕組みです。一度ServerにSynthの定義が転送されると、synthdefsフォルダーの中に"〜.scsynthdef"というファイルで保存されます。Serverがコマンドを受ける時には、このscsynthdefのファイルが使われるのです。では、Synthの定義はどのようにするのでしょうか。

もしもSC2をご存じなら、SynthDef("〜", {-----}).load(s)の{-----}の部分は見慣れた形になっていると思います。違うのは最後のOut.ar(〜〜〜)という所ですね。まずは詳しく{-----}の部分を見ていきましょう。

var osc;
osc = SinOsc.ar(800, 0, 0.1); // 800 Hz sine oscillator
Out.ar(0, osc); // send output to audio bus zero

最初に"var osc;"として、変数oscを宣言しています。ここでは、oscという名前を付けて、データのメモリ内での領域を確保しているのだと思います。それから、コードの文末には必ず";"(セミコロン)を付けます。
次の行では、作ったばかりの変数に早速データを入れています。
SinOscというのはサイン波のオシレーターを表す「クラス」です。「クラス」というのは、同じ種類の仲間を作るための鋳型のようなものです。一定の形が予め用意されていて、中身は好きなものを入れることができるという、大変便利なものです。この場合は、サイン波という形が用意されていて、その周波数、位相(フェイズ)、増幅値などは自由に決めることができます。
".ar"というのは、オーディオ・レートでデータを送るための「メソッド」です。オーディオ・レートというのが一体どれくらいの速度なのかはさておき、「メソッド」というのは、与えられたクラスを好きなように変えるための方法だと考えてください。メソッドの後に(  )の中に入っている数字は、クラスで使われる引数です。この引数の順番はクラスのメソッドごとに決まっていて、SinOsc.arの場合は、freq(周波数)、phase(位相)、mul(増幅値)の順です。つまり、SinOsc.ar(800, 0, 0.1)の場合は、周波数が800Hz、位相は0で、増幅する値は0.1ということになります。
こうした引数の値は、だいたい予め初期値が設定されています。例えば、SinOsc.arの場合は、freqが440.0、phaseが0.0、mulが1.0となっています。と言うことは、何も引数に値を入れずSinOsc.arと書くだけでも、定義として成立するわけです。試してみましょう。

s = Server.local;
s.boot;
SynthDef("testSinOsc1", {
var osc;
osc = SinOsc.ar; // 440 Hz sine oscillator
Out.ar(0, osc); // send output to audio bus zero
}).load(s);

s.sendMsg("/s_new", "testSinOsc1", 1000, 1, 0);
s.sendMsg("/n_free", 1000);
s.quit;

最初の例でも使われてますが、"//"と書かれた部分からその行の最後までは「コメント」と言って、コード自体には全く影響ありません。コードを読む時に分かりやすく解説を加えるために使う方法です。
最初の例と比べて、低い音が大きく聴こえたでしょうか? 最初の例では周波数が800Hzで、0.1の増幅値だったのに比べ、今回の例ではそれぞれ440Hzと1.0になっていたはずなので、もしそう聴こえたら正常です。当然、引数に別の数値を用いることもできます。freqやmulの値を変えて、試してみてください。
さて、SC3には(SC2と同様に)こうしたクラスがたくさん用意されています。多くのクラスにはヘルプ・ファイルが用意されていて、例えばSinOscの場合、"SinOsc"の上をダブルクリックしてハイライトさせてから、コマンド・キーと"?"キー(shiftキー+"/"キー)を同時に押すと、自動的にSinOscのヘルプ・ファイルが開きます。それを見れば、SinOscというクラスがどういうクラスで、どういうメソッドを使って、その引数にはどういうものがあって、どういう順番になっているのかが分かります。それによると、
SinOsc.ar(freq, phase, mul, add)
となっています。"add"というのは何でしょう?
SinOscはmulの値が1.0であれば、-1.0と1.0の間で変化するサイン波のグラフとして表すことができます。もしもmulの値を2.0にすれば、変化する値の幅は-2.0と2.0の間ということになりますね。では、これを0.1と0.9の間にしたい場合にはどうすればいいのでしょうか。そうするためにaddという引数が必要になります。まず、0.1と0.9の差は0.8ですから、その半分の0.4をmulの値にします。そして、addの値を0.5にすれば、SinOscの値は0.1と0.9の間を変化することになります。これまで試してきた2つの例から、SinOscのmulの値は音量と関係があるように思われるので、この音量を0.1と0.9の間で周期的に変化させてみましょう。そうするためには、mulのところにもう1つSinOscを使えばいいはずです。変化の周期は1秒ということにしましょう。これは新しく加えたSinOscのfreqのところを1.0にすればいいはずです。出す音の周波数は660Hzにします。これは、最初の例で800としていたfreqの値を660に変えればいいはずです。

s = Server.local;
s.boot;
SynthDef("testSinOsc2", {
var osc;
osc = SinOsc.ar(660, 0, SinOsc.ar(1, 0, 0.4, 0.5)); // 440 Hz sine oscillator
// mul between 0.1 and 0.9
Out.ar(0, osc); // send output to audio bus zero
}).load(s);

s.sendMsg("/s_new", "testSinOsc2", 1000, 1, 0);
s.sendMsg("/n_free", 1000);
s.quit;

音が1秒周期で大きくなったり小さくなったりしたでしょうか。この周期をもっと速くすると、音量が変化するというよりも、音自体が変わったように聴こえます。これがAM変調(amplitude modulation)の基本ですね。

s = Server.local;
s.boot;
SynthDef("testSinOsc2.1", {
var osc;
osc = SinOsc.ar(660, 0, SinOsc.ar(100, 0, 0.4, 0.5)); // AM sine oscillator
// mul between 0.1 and 0.9
Out.ar(0, osc); // send output to audio bus zero
}).load(s);

s.sendMsg("/s_new", "testSinOsc2.1", 1000, 1, 0);
s.sendMsg("/n_free", 1000);
s.quit;

同じようにfreqの値を速い周期で変化させれば、FM変調(frequency modulation)になります。周波数を440Hzと660Hzの間で、0.01秒周期で変化させてみましょう。もとのSinOscのfreqのところにもう1つSinOsc.ar(100, 0, 110, 550)というSinOscを置けばいいはずです。

s = Server.local;
s.boot;
SynthDef("testSinOsc3", {
var osc;
osc = SinOsc.ar(SinOsc.ar(100, 0, 110, 550), 0, 0.1); // FM sine oscillator
// freq between 440 and 660
Out.ar(0, osc); // send output to audio bus zero
}).load(s);

s.sendMsg("/s_new", "testSinOsc3", 1000, 1, 0);
s.sendMsg("/n_free", 1000);
s.quit;

変調の種類でもう1つ、PM変調(phase modulation)というのがあります。ここで使われるのが引数phaseです。phaseの値はラジアン(radian)で表されるとヘルプ・ファイルに書いてあるので、0と2πの間で変化させてみましょう。πはSCではpiと書きます。変化の周期は0.1秒ということにしましょう。となると、SinOsc.ar(10, 0, pi, pi)をもとのSinOscのphaseのところに置けばいいことになります。

s = Server.local;
s.boot;
SynthDef("testSinOsc4", {
var osc;
osc = SinOsc.ar(660, SinOsc.ar(10, 0, pi, pi), 0.1); // PM sine oscillator
// phase between 0 and 2pi
Out.ar(0, osc); // send output to audio bus zero
}).load(s);

s.sendMsg("/s_new", "testSinOsc4", 1000, 1, 0);
s.sendMsg("/n_free", 1000);
s.quit;

音を出すための道具は何もSinOscだけではありませんが、今回はSinOscだけを使って音を作ってみました。

では、次のページ更新まで、ごきげんよう。





HOME