スコアとレンダリング

疲れるのは嫌なので、もっとこう、マシンぽく自動的にできないものか、ということでした。

スコア

x = [
[0.0, [ \s_new, \hoge, 1000, 0, 0, \nn, 60 ]],
		// 0.0秒後、ノード1000番としてhogeを立ち上げる。nnは60
[0.5, [ \n_set, 1000, \nn, 62 ]],
		// 0.5秒後、1000番のnnは62
[1.0, [ \n_set, 1000, \nn, 64 ]],
[1.5, [ \n_set, 1000, \nn, 65 ]],
[2.0, [ \n_set, 1000, \nn, 67 ]],
[3.0, [ \n_free, 1000]],
		// 3.0秒後、1000番を片付ける
[3.0, [ \c_set, 0, 0]],	
		// 3.0秒後、おわり
];

このスコアというのを書くと、シンセの立ち上げや引数の切り替えを時間に沿ってスケジュールできる。
音を並べることが作曲だとすれば、既にその段階に入りつつあると。
然る後に以下を実行。

Score.play(x);		// xをスコアとして演奏

いやー良い曲だ。
ノードナンバーというのは、同じ名前のシンセを複数立ち上げて、個別の番号で管理できる。
例えばこう。ちなみに時間は順不同に書いても大丈夫らしい。

SynthDef("hoge", {
	arg nn;
	var a, b;
	a = SinOsc.ar(nn.midicps);
	b = Pan2.ar(a, 0, 0.5);
	Out.ar(0, b);
}).store;

x = [
[0.0, [ \s_new, \hoge, 1000, 0, 0, \nn, 60 ]],
[0.5, [ \n_set, 1000, \nn, 62 ]],
[1.0, [ \n_set, 1000, \nn, 64 ]],
[1.5, [ \n_set, 1000, \nn, 65 ]],
[2.0, [ \n_set, 1000, \nn, 67 ]],

[0.0, [ \s_new, \hoge, 1001, 0, 0, \nn, 64 ]],
[0.5, [ \n_set, 1001, \nn, 65 ]],
[1.0, [ \n_set, 1001, \nn, 67 ]],
[1.5, [ \n_set, 1001, \nn, 69 ]],
[2.0, [ \n_set, 1001, \nn, 71 ]],

[3.0, [ \n_free, 1000]],
[3.0, [ \n_free, 1001]],
[3.0, [ \c_set, 0, 0]],	
];

Score.play(x);

スコアを途中で止めたい場合があるとしますと、以下のようにします。

y = Score.new(x);
y.play;	// 演奏開始
y.stop;	// 演奏中止

レンダリング

スコアが書けるといよいよ録音というか、レンダリングが可能になります。
これのコードは多少ぐちゃぐちゃしてるので、何も考えんとコピペ。

o = ServerOptions.new.numOutputBusChannels = 1;
Score.recordNRT(x, "hoge.osc", "hoge.wav", // xをレンダリング
headerFormat: "WAV", sampleFormat: "int16",
options: o);

スコアをレンダリングということで、先にスコアの部分を実行しておく。
本体フォルダにhoge.wavができました。素晴らしい。
他の形式も可能。例えばこれを24bitのステレオにしたければ

o = ServerOptions.new.numOutputBusChannels = 2;
Score.recordNRT(x, "hoge.osc", "hoge.wav",
headerFormat: "WAV", sampleFormat: "int24",
options: o);

これで音声ファイルが作れるようになってしまいました。
ものによるでしょうが、概ね実際の演奏時間より早く書き出せるのは何かと便利。