sc – SynthDef

まだ途中だけど忘れないようにメモ。
SynthDefs and Synths


SynthDefによって、SinとかSawとかNoiseとか様々なUGenを使った自作の音、つまり楽器を定義できる。

以下2つは同じ意味。

{ SinOsc.ar(440, 0, 0.2) }.play;
SynthDef.new("tutorial-SinOsc", { Out.ar(0, SinOsc.ar(440, 0, 0.2)) }).play;

OutというのもUGenの類で、その名の通りarまたは krをサーバーのバスに出力する。
Outに与える第1引数はバスの番号で、デフォルトでは0。
第2引数はUGenオブジェクト、っぽい。
例えばステレオでならす場合こんな感じで宣言可能で、

SynthDef.new("tutorial-SinOsc-stereo", { var outArray;
outArray = [SinOsc.ar(440, 0, 0.2), SinOsc.ar(442, 0, 0.2)];
Out.ar(0, outArray)
}).play;

この場合ステレオになるので、左チャンネルが0(指定したバス)、右チャンネルが1(指定したバス+1)ということらしい。
バスというのはまだ詳しくみてないんだけど、多分MTRで言うトラックみたいなもんだろうと勝手に推測。違ったらすみません。

また、playした際の返り値というかオブジェクト、今まで完璧に無視してたけど、

x = { SinOsc.ar(660, 0, 0.2) }.play;
y = SynthDef.new("tutorial-SinOsc", { Out.ar(0, SinOsc.ar(440, 0, 0.2)) }).play;
x.free;
y.free;

こういうことが可能。
freeというのはstop、ってことだと思うとOKっぽいです。実際に音が止まります。
バスを開放、ってぐらいのイメージ?

で、ここまではSynthDefしてすぐにplayしてたけど、そういう使い方はあまりないはずで、
実際には宣言だけして、後でオブジェクト作成して鳴らす、って流れが多そう。
そういう場合はこう。

SynthDef.new("tutorial-PinkNoise", { Out.ar(0, PinkNoise.ar(0.3)) }).send(s);
x = Synth.new("tutorial-PinkNoise");
y = Synth.new("tutorial-PinkNoise");
x.free; y.free;

send(s)ってのは、変数sに格納されたサーバーにSynthDefを送る、ということ。
sはデフォルトでサーバーオブジェクトが入ってるので、とりあえずsで。
複数台をネットワークでつないで、とか複雑なことやらない限り&内容の上書きとかしない限り、sはサーバーだと思っていいはず。

なぜSynthDefをサーバーに送るかといえば、それはサーバーが持つべきものだから。
scではサーバーとクライアント(?)に明確にわかれていて、間はOSCでつながっている訳なんだけど、
クライアントはあくまでもメッセージを送るだけで、実際の処理はサーバーで行われているっぽい、です。
まだこの辺も詳しくみてないので非常に怪しいです。すみません。

ちなみにこういうことも可能っぽい。

f = { SinOsc.ar(440 + 200.rand, 0, 0.2) };
x = f.play;
y = f.play;
z = f.play;
x.free; y.free; z.free;

フム、なるほど。
Function.playが返すのはSynthオブジェクトなんですね。
きっとこれも暗黙のうちにサーバーにSynthDef送ってるんでしょう、多分。
なぜならメッセージにSynth(“temp__3” : 1003)とか表示されるから。
しかもその都度randされた値が渡されているようで、周波数の違う音が3個なります。
つまりその都度SynthDefしてるってことか。

これを以下の様に書くと、1つの音しかしなくなります。

SynthDef("tutorial-NoRand", { Out.ar(0, SinOsc.ar(440 + 200.rand, 0, 0.2)) }).send(s);
x = Synth("tutorial-NoRand");
y = Synth("tutorial-NoRand");
z = Synth("tutorial-NoRand");
x.free; y.free; z.free;

SynthDefすると、バイトコードを作成して送るらしく、多分その時点でrandが行われて値が固まって宣言されるんですね。
となるとここを変えたい場合は引数が必要ですね。

(
SynthDef("tutorial-args", { arg freq = 440, out = 0;
Out.ar(out, SinOsc.ar(freq, 0, 0.2));
}).send(s);
)
x = Synth("tutorial-args");
y = Synth("tutorial-args", ["freq", 660]);
z = Synth("tutorial-args", ["freq", 880, "out", 1]);
x.free; y.free; z.free;

ってばっちり次の例題に出てきてましたwww
読者の心を読んでいるね作者さん。GJ。
と、まぁこういうことだそうです。

バスに関して勘違いしてたんですが、ステレオ環境では0が左、1が右、っていうのはどうやら固定みたいです。
なので最後のz = …の行が右から聞こえます。
これはもっとたくさんのバスを使って、みたいなことは出来るんですかね。
まぁそこもぼちぼち調べます。

あとさっき突然.newが外れましたが、あれはなくても鳴ってるんで、いらないんじゃないでしょうか。
おそらく明示的なオブジェクトの作成、ってことなんじゃないかと。

C++で言う、
Hoge a("hogehoge");
Hoge b = Hoge("hogehoge");

みたいな違いなんじゃないかと。これも推測。
まぁ大体そんなところでしょう、OO言語でのnewなんて:)

そう、あとSynthDefした音はファイルに保存しとくことも可能だそうです。
おそらくバイナリデータ、というかsendした時のバイトコードがまんま書かれるんじゃないかと推測。
この辺はまた後日詳しく調べます。

あと名前がString何だけどSymbolでもOK・・・?なのか・・・?
まぁその辺も後日。

とにかくまだしばらくtutorial〜。

———————————————————— 余談
やっぱりscやるならMacが良さそうだ。
Cocoaと連携したりとか、楽しそう過ぎる。
これでQuartzComposerと連携したりとか出きるって解釈でOK?
やっぱりmacノートは1台欲しいなぁ、、、

コメントを残す

メールアドレスが公開されることはありません。