Showing posts with label comb filter. Show all posts
Showing posts with label comb filter. Show all posts

Thursday, September 17, 2009

Comb Filter Effect

Another handy snippet of code pulled from the SC-Users list once again. Credit for this goes to Kernal, kernel@audiospillage.com.
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))});
)