TidalCyclesの標準で用意されているエフェクト(グローバルエフェクト)にroomリバーブがありますが、個人的にこのリバーブ感がとても好きなので重宝しています。
ただ、実はこのroomリバーブのリバーブ音はほぼモノラルなので、音の位置に拘った演奏・曲作りする際には結構不便です。
なので書き換えちゃいましょう。
Macの場合は
~/Library/Application Support/SuperCollider/downloaded-quarks/SuperDirt/synths/core-synths-global.scd
を書き換えるか、起動時に上書きするようにするのがいいと思います。今回は起動時に上書きする場合のコードを紹介します(書き換えるだけの場合は~dirt.numChannels
をnumChannels
のままにしておけば動くはずです)
Server.default.waitForBoot{
~dirt = SuperDirt(2, Server.default);
// 音源を読み込んだり
// ~dirt.loadSoundFiles(thisProcess.nowExecutingPath.dirname ++ "/samples/*");
// Server.default.sync;
~dirt.loadSoundFiles;
Server.default.sync;
// ここにグローバルエフェクトの定義を書く(後述)
...
// wait load
Server.default.sync;
~dirt.start(57120, 0 ! 12);
}
実装
-SynthDef("dirt_reverb" ++ numChannels, { |dryBus, effectBus, gate = 1, room = 0, size = 0.1, dry = 0|
+SynthDef("dirt_reverb" ++ ~dirt.numChannels, { |dryBus, effectBus, gate = 1, room = 0, size = 0.1, dry = 0|
var in, snd, loop, depth;
- in = In.ar(dryBus, numChannels).asArray.sum; // 元の音源の全チャンネルの音が足し合わさっている(モノラル感の主な原因)
+ in = In.ar(dryBus, ~dirt.numChannels);
in = in * room.lag(LFNoise1.kr(1).range(0.01, 0.02)); // regulate input
- 4.do { in = AllpassN.ar(in, 0.03, { Rand(0.005, 0.02) }.dup(numChannels), 1) };
+ 4.do { in = AllpassN.ar(in, 0.03, { Rand(0.005, 0.02) }, 1) };
depth = size.lag(0.02).linexp(0, 1, 0.01, 0.98); // change depth between 0.1 and 0.98
- loop = LocalIn.ar(numChannels) * { depth + Rand(0, 0.05) }.dup(numChannels);
+ loop = LocalIn.ar(~dirt.numChannels) * { depth + Rand(0, 0.05) };
loop = OnePole.ar(loop, 0.5); // 0-1
- loop = AllpassN.ar(loop, 0.05, { Rand(0.01, 0.05) }.dup(numChannels), 2);
+ loop = AllpassN.ar(loop, 0.05, { Rand(0.01, 0.05) }, 2);
loop = DelayN.ar(loop, 0.3, [0.19, 0.26] + { Rand(-0.003, 0.003) }.dup(2));
- loop = AllpassN.ar(loop, 0.05, { Rand(0.03, 0.15) }.dup(numChannels), 2);
+ loop = AllpassN.ar(loop, 0.05, { Rand(0.03, 0.15) }, 2);
loop = loop + in;
loop = LeakDC.ar(loop);
LocalOut.ar(loop);
snd = loop;
snd = snd * (1 - dry).lag(LFNoise1.kr(1).range(0.01, 0.02));
DirtPause.ar(snd, graceTime:4);
snd = snd * EnvGen.kr(Env.asr, gate, doneAction:2);
Out.ar(effectBus, snd);
}, [\ir, \ir]).add;
完成
SynthDef("dirt_reverb" ++ ~dirt.numChannels, { |dryBus, effectBus, gate = 1, room = 0, size = 0.1, dry = 0|
var in, snd, loop, depth;
in = In.ar(dryBus, ~dirt.numChannels);
in = in * room.lag(LFNoise1.kr(1).range(0.01, 0.02)); // regulate input
4.do { in = AllpassN.ar(in, 0.03, { Rand(0.005, 0.02) }, 1) };
depth = size.lag(0.02).linexp(0, 1, 0.01, 0.98); // change depth between 0.1 and 0.98
loop = LocalIn.ar(~dirt.numChannels) * { depth + Rand(0, 0.05) };
loop = OnePole.ar(loop, 0.5); // 0-1
loop = AllpassN.ar(loop, 0.05, { Rand(0.01, 0.05) }, 2);
loop = DelayN.ar(loop, 0.3, [0.19, 0.26] + { Rand(-0.003, 0.003) }.dup(2));
loop = AllpassN.ar(loop, 0.05, { Rand(0.03, 0.15) }, 2);
loop = loop + in;
loop = LeakDC.ar(loop);
LocalOut.ar(loop);
snd = loop;
snd = snd * (1 - dry).lag(LFNoise1.kr(1).range(0.01, 0.02));
DirtPause.ar(snd, graceTime:4);
snd = snd * EnvGen.kr(Env.asr, gate, doneAction:2);
Out.ar(effectBus, snd);
}, [\ir, \ir]).add;