The gui should be mostly self explanatory I think, but if you want to use this with other inputs besides the test sound you'll need to set the input bus and send your sound through that.
// parrallel comb filters implemented as effect return
// send the synth defs(
(
SynthDef("ImpulseTest", {|bus = 3|
Out.ar(bus, [Impulse.ar(SinOsc.kr(0.23).range(0.5,23), 0.5)]);
}).send(s);
);
(
SynthDef("CombUnit",{| d1 = 0.001, d2 = 0.001, d3 = 0.001, d4 = 0.001, d5 = 0.001,
t1 = 1, t2 = 1, t3 = 1, t4 = 1, t5 = 1,
f1 = 20000, f2 = 20000, f3 = 20000, f4 = 20000, f5 = 20000,
vol = 1, inBus = 3, outBus = 0|
var in, out, c1, c2, c3, c4, c5;
in = In.ar(inBus, 1);
c1 = LPF.ar(CombC.ar(in, 1, d1, t1), f1);
c2 = LPF.ar(CombC.ar(in, 1, d2, t2), f2);
c3 = LPF.ar(CombC.ar(in, 1, d3, t3), f3);
c4 = LPF.ar(CombC.ar(in, 1, d4, t4), f4);
c5 = LPF.ar(CombC.ar(in, 1, d5, t5), f5);
out = (c1 + c2 + c3 + c4 + c5) * 0.2;
Out.ar([outBus, outBus + 1], out * vol);
}).send(s);
);
)
// create the synth
(
var grp, node, testNode, wComb, testRunning = 0, inputBus = 3;
s.sendMsg("s_new", "CombUnit", node = s.nextNodeID, 1, 1);
// s.sendMsg("g_new",grp = s.nextNodeID,1,1); // create group @ tail of default node
wComb = SCWindow("C O M A", Rect(100, 300, 720, 220))
.onClose_({
if(testRunning == 1, s.sendMsg("n_free", testNode));
s.sendMsg("n_free", node);
})
.front;
// input bus
SCNumberBox(wComb, Rect(10, 10, 30, 20))
.value_(3)
.action_({|v|
inputBus = v.value;
s.sendMsg("n_set", node, "inBus", inputBus);
if(testRunning == 0, s.sendMsg("n_set", testNode, "bus", inputBus));
});
SCStaticText(wComb, Rect(45, 10, 100, 20))
.string_("Input Bus");
// output bus
SCNumberBox(wComb, Rect(150, 10, 30, 20))
.value_(0)
.action_({|v| s.sendMsg("n_set", node, "outBus", v.value)});
SCStaticText(wComb, Rect(185, 10, 100, 20))
.string_("Output Bus");
// audio test
SCButton(wComb, Rect(300, 10, 100, 20))
.states_([
["Start Test", Color.green, Color.black],
["Stop Test", Color.red, Color.black]
])
.action_({
if(testRunning == 0, {
s.sendMsg("s_new", "ImpulseTest", testNode = s.nextNodeID, 0, 1, "bus", inputBus);
testRunning = 1;
},{
s.sendMsg("n_free", testNode);
testRunning = 0;
});
});
// comb frequencies
SCStaticText(wComb, Rect(10, 40, 100, 20)).string_("Comb Frequencies");
5.do{|i|
var box;
box = SCNumberBox(wComb, Rect(10, 60 + (i * 25), 40, 20))
.value_(950);
SCStaticText(wComb, Rect(55, 60 + (i * 25), 15, 20)).string_("Hz");
SCSlider(wComb, Rect(80, 60 + (i * 25), 130, 20))
.value_(0.5)
.action_({|v| var time, freq;
freq = [1, 20000, 6].asSpec.map(v.value);
time = 1.0 / freq;
s.sendMsg("n_set", node, i, time);
box.value_(freq.asInteger);
})
};
// resonances
SCStaticText(wComb, Rect(250, 40, 100, 20)).string_("Resonances");
5.do{|i|
var box;
box = SCNumberBox(wComb, Rect(250, 60 + (i * 25), 30, 20))
.value_(50);
SCStaticText(wComb, Rect(285, 60 + (i * 25), 15, 20)).string_("%");
SCSlider(wComb, Rect(300, 60 + (i * 25), 150, 20))
.value_(0.5)
.action_({|v|
s.sendMsg("n_set", node, i+5, [0, 9, 4].asSpec.map(v.value));
box.value_(v.value * 100);
});
};
// low pass frequencies
SCStaticText(wComb, Rect(555, 40, 100, 20)).string_("Low Pass Frequencies");
5.do{|i|
var box;
box = SCNumberBox(wComb, Rect(490, 60 + (i * 25), 40, 20)).value_(20000);
SCStaticText(wComb, Rect(535, 60 + (i * 25), 15, 20)).string_("Hz");
SCSlider(wComb, Rect(555, 60 + (i * 25), 150, 20))
.value_(1)
.action_({ |v| var freq;
freq = [20, 20000, \exp].asSpec.map(v.value);
s.sendMsg("n_set", node, i+10, freq);
box.value_(freq);
});
};
// volume control
SCStaticText(wComb, Rect(10, 190, 70, 20)).string_("Volume");
SCSlider(wComb, Rect(80, 190, 625, 20))
.value_(1)
.action_({|v| s.sendMsg("n_set", node, "vol", [0, 1, 4].asSpec.map(v.value))});
)