Actually, last night I didn’t read the code carefully enough.
In the specific example, it looks to me like an array isn’t necessary at all.
var posRatePulses = Array.fill(grainRateFwdRev, LFPulse.kr(0.1, 0, 0.1, grainOctaver, (grainRate)););
First, note the following difference:
Array.fill(10, rrand(1, 10));
-> [ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 ]
Array.fill(10, { rrand(1, 10) });
-> [ 5, 7, 6, 3, 2, 6, 2, 3, 8, 2 ]
By omitting braces from the second part of Array.fill, it means that even if grainRateFwdRev
were valid, you would get only n references to the same LFPulse, rather than n different LFPulses.
Assuming that you wanted n LFPulses, then… in this formulation, the pulses would all be the same, unless your (grainRate)
is different per array iteration.
In any case, here is how I would do it.
(
~makeSynthDefForN = { |maxPartials = 10|
SynthDef("pulsedemo" ++ maxPartials, { |out, gate = 1,
num = 1, amp = 0.02,
freq = 50, freqMul = 1.1,
pulseRate = 5, pulseRateRand = 5
|
var pulses = Array.fill(
maxPartials, // not a synth input!
{ |i|
LFPulse.kr(pulseRate * (pulseRateRand ** Rand(-1.0, 1.0)),
0, 0.1)
* Lag.kr(i < num, 0.1)
}
);
var f = freq;
var oscs = Array.fill(maxPartials, {
var osc = SinOsc.ar(f);
f = f * freqMul;
osc
});
var egs = Decay2.kr(pulses, 0.01, 0.08);
// there is a weird bug with Splay vs .scramble
// I shouldn't have to rearchitect Splay but... jeez...
// var sig = Splay.ar((oscs * egs).scramble);
var positions = Array.series(maxPartials, -1, 2 / (maxPartials - 1)).scramble;
var sig = Pan2.ar(oscs * egs, positions, amp / maxPartials).sum;
var mainEg = EnvGen.kr(Env.asr(0.01, 1, 0.1), gate, doneAction: 2);
Out.ar(out, (sig * mainEg).dup);
}).add;
};
)
~makeSynthDefForN.(50);
a = Synth("pulsedemo50", [num: 5, freq: 200, freqMul: 1.07, amp: 0.1]);
// MIDI would work just as well here
x = Slider(nil, Rect(800, 200, 150, 30)).front
.action_({ |view| a.set(\num, view.value * 50) });
a.free;
hjh
PS See Code markup: Correct style – it will help people to help you more efficiently.