Ryosuke Nakagawaのブログ

まなびをシェア

SuperColliderのrecordNRTでOSCコマンドから音を生成する

SuperColliderとは

SuperColliderは音響合成やアルゴリズム作曲のための統合開発環境です.
オープンソースであり,Windows, macOS, Linuxで使えます.

SuperColliderでリアルタイム録音する

SuperColliderを使っていると生成された音を録音したくなります.
リアルタイム録音がしたいときは,以下のようにs.recordで録音できます.

// 以降はコメント

s.boot; // サーバーを起動する

// 適当なsynthを定義する
(
SynthDef("bubbles", { |out|
    var f, sound;
    f = LFSaw.kr(0.4, 0, 24, LFSaw.kr([8,7.23], 0, 3, 80)).midicps; // glissando function
    sound = CombN.ar(SinOsc.ar(f, 0, 0.04), 0.2, 0.2, 4); // echoing sine wave
    Out.ar(out, sound);
}).add;
)

x = Synth.new("bubbles");

s.prepareForRecord; // 録音の準備をさせる.このコマンドは無くても録音できる.

s.record; // 録音を開始する

s.pauseRecording; // 録音を一時停止する

s.record // 録音を再開する

s.stopRecording; // 録音を終了する

x.free; // 音を止める

この方法の欠点は,長さが10分の音を録音したかったら,実時間で10分かかる点です.

リアルタイムではない録音をする

私は研究でSuperColliderを使っているのですが,周波数を100Hz~2000Hzの範囲で100Hz刻みにして音を数種類作りたいみたいなことがしばしばあります.
上記の方法で録音すると,1個の音が5分としたら20個の音を録音するのに100分かかります.
そういうときはrecordNRTを使いましょう.NRTはNon-RealTimeを意味します.

公式のヘルプから引用します.

// 以降はコメント

// 適当なsynthを定義する
(
SynthDef("NRTsine", { |out, freq = 440|
	Out.ar(out,
		 SinOsc.ar(freq, 0, 0.2)
	)
}).writeDefFile; // 必ずwriteDefFileをすること.recordNRTするときはaddはNG.
)
(
var f, o;
g = [
	[0.1, [\s_new, \NRTsine, 1000, 0, 0, \freq, 440]], // 開始から0.1秒後にNRTsineというsynthをfreq=440で生成する.
	[0.2, [\s_new, \NRTsine, 1001, 0, 0, \freq, 660]], // 開始から0.2秒後にNRTsineというsynthをfreq=660で生成する.
	[0.3, [\s_new, \NRTsine, 1002, 0, 0, \freq, 220]], // 開始から0.3秒後にNRTsineというsynthをfreq=220で生成する.
	[1, [\c_set, 0, 0]] // 開始から1秒後に録音をやめる.
	];
o = ServerOptions.new.numOutputBusChannels = 1; // モノラルで録音する.
Score.recordNRT(g, "help-oscFile.osc", "helpNRT.aiff", options: o); // helpNRT.aiffというファイル名で録音される
)

これで時間の大幅な短縮ができる.複数ファイルを作りたいときはコードの後半を下のように書き換えてやればOKです.

(
for(1,20,{
	arg i; // Iは繰り返しの回数
	var f, o;
	g = [
		[0.1, [\s_new, \NRTsine, 1000, 0, 0, \freq, 440]], // 開始から0.1秒後にNRTsineというsynthをfreq=440で生成する.
		[0.2, [\s_new, \NRTsine, 1001, 0, 0, \freq, 660]], // 開始から0.2秒後にNRTsineというsynthをfreq=660で生成する.
		[0.3, [\s_new, \NRTsine, 1002, 0, 0, \freq, 220]], // 開始から0.3秒後にNRTsineというsynthをfreq=220で生成する.
		[1, [\c_set, 0, 0]] // 開始から1秒後に録音をやめる.
		];
	o = ServerOptions.new.numOutputBusChannels = 1; // モノラルで録音する.
	Score.recordNRT(g, "help-oscFile.osc", "helpNRT-"++i.asString++".aiff", options: o); // helpNRT-1.aiff, helpNRT-2.aiff ... というファイル名で録音される
})
)