This looks so much better already, I can actually see what the code is doing.
You can probably stop there… but just to show off some more language features…
{
var mk_gate = {|freq|
[LFDClipNoise.ar(freq), LFDNoise0.ar(freq)]
};
var mk_wv = { |wv, freq, gate|
wv.asClass.ar(freq) * Env.perc.ar(0, mk_gate.(gate))
};
var sa = mk_wv.(wv: \SinOsc, freq: [[48, 49]], gate: [10, 5, 2.5].choose);
var sb = mk_wv.(wv: \Saw, freq: 48 * 16, gate: [10, 5, 2.5].choose);
var sc = mk_wv.(wv: \Pulse, freq: 48 * 32, gate: [10, 5, 2.5].choose);
var dry = (sa + sb + sc) * 0.3;
var rev = FreeVerb.ar(dry) + dry;
var comb = CombC.ar(rev) + rev;
comb * 0.3;
}.play
There are two things here. First you can use more multichannel expansion, note the double brackets for sa
’s freq, this makes sure the envelope is applied to both.
And since you are varying the Ugen class, you can actually just pass this as a symbol and use .asClass
.
This is what I love about supercollider. Say you want to talk about different waveforms. Make a function that takes a waveform and now you can talk/compose/think using just what you care about: chef’s kiss.
Now for just the waveforms you have, the above was probably overkill and you’d be better off writing the classes directly, however…
var dry = [
mk_wv.(wv: \SinOsc, freq: [[48, 49]], gate: [10, 5, 2.5].choose),
mk_wv.(wv: \Saw, freq: 48 * 16, gate: [10, 5, 2.5].choose),
mk_wv.(wv: \Pulse, freq: 48 * 32, gate: [10, 5, 2.5].choose)
].sum * 0.3;
If you rejig it into an array… now the code is just asking for more elements to be added.
Here you said that the refactoring invited multiplier be added to the code.
The point being, how you write the code, structure it and group it together, engenders different musical actions. Supercollider is flexible enough to allow you to talk about what you want.