(
// 1. Percussive Synths (now with internal oscillators)
SynthDef(\pulseTone, { |out=0, freq=440, rate=1, attack=0.01, decay=0.3, amp=0.1|
var trig = Impulse.kr(rate);
var env = EnvGen.ar(Env.perc(attack, decay), trig);
var sig = SinOsc.ar(freq, 0, env * amp);
Out.ar(out, sig);
}).add;
)
(
SynthDef(\dustNoise, { |out=0, freq=2000, dustRate=0.3, attack=0.01, decay=0.8, amp=0.1|
var trig = Dust.kr(dustRate);
var env = EnvGen.ar(Env.perc(attack, decay), trig);
var sig = BPF.ar(PinkNoise.ar(amp), freq, 0.3) * env;
Out.ar(out, sig);
}).add;
)
(
// 2. FM Percussion
SynthDef(\fmPerc, { |out=0, carFreq=110, modFreq=220, rate=1, index=10, amp=0.1|
var trig = Impulse.kr(rate);
var env = EnvGen.ar(Env.perc(0.01, 0.5), trig);
var sig = PMOsc.ar(carFreq, modFreq, index, 0, env * amp);
Out.ar(out, sig);
}).add;
)
(
// 3. Mixer with Panning and Reverb
SynthDef(\mixer, { |out=0, in1, in2, in3, pan1= -0.7, pan2=0, pan3=0.7|
var sig1 = In.ar(in1, 1);
var sig2 = In.ar(in2, 1);
var sig3 = In.ar(in3, 1);
var mix = Mix([
Pan2.ar(sig1, pan1),
Pan2.ar(sig2, pan2),
Pan2.ar(sig3, pan3)
]);
mix = FreeVerb.ar(mix, 0.3, 0.8, 0.5) * 0.5;
Out.ar(out, mix);
}).add;
)
// Now create the pulsed piece
(
s.waitForBoot {
~buses = { Bus.audio(s, 1) } ! 3;
// Create pulsed sounds (each with their own envelope)
~pulse1 = Synth(\pulseTone, [\out, ~buses[0], \freq, 99, \rate, 1/2.0, \amp, 0.3]);
~pulse2 = Synth(\pulseTone, [\out, ~buses[1], \freq, 440, \rate, 1/2.3, \decay, 0.5]);
~noise = Synth(\dustNoise, [\out, ~buses[2], \freq, 2000, \dustRate, 0.3]);
// FM percussion triggered separately
~fmTrig = {
var trig = Impulse.kr(1/2.7);
SendTrig.kr(trig, 0, 1);
trig.poll(trig); // debug
0; // silent
}.play;
~fm = Synth(\fmPerc, [\out, ~buses[2], \rate, 1/3.0, \amp, 0.2]);
// Create mixer
~mixer = Synth(\mixer, [
\in1, ~buses[0],
\in2, ~buses[1],
\in3, ~buses[2]
], addAction: 'addToTail');
// Randomize FM index
~oscFunc = OSCFunc({ |msg|
~fm.set(\index, rrand(5, 15), \carFreq, rrand(80, 120));
}, '/tr', s.addr);
};
)
// Cleanup
(
[~pulse1, ~pulse2, ~noise, ~fm, ~mixer, ~fmTrig].do(_.free);
~oscFunc.free;
~buses.do(_.free);
)