Here first quoting an answer in this thread
Within one SynthDef, you cannot add or destroy voices dynamically. This has never been supported in SC3, and never will be. This is what “fixed graph” means – once you build a SynthDef, its structure is set in stone and you can’t make it bigger or smaller.
You can build a new def, and replace the Synth node (but there may be some discontinuity in the output).
You can make a SynthDef for one voice, and dynamically create and destroy Synth nodes, one for each voice (but phase correlation is not guaranteed).
dietcv’s “lpf” solution keeps the same number of voices continuously, but silences some of them. All the voices exist (nothing is created or destroyed on the fly), but you can dynamically mute them.
hjh
So in other words, you cannot set the start, end and step of forBy dynamically, these values have to be fixed when compiling the SynthDef. Below I refactored you code a bit and hardwired the values.
(
SynthDef(\sap, {|freq=440, gate=1, out=0, pan=0, amp=1, ampslope=1.0, atk = 0.3, rel = 1|
var array = (1, 5..1000); // these are the same values as in your forBy
var env = Env.asr(atk, amp, rel).kr(2, gate); // you had a gate argument so assume you want a sustaning envelope
var sound = array.collect{|i|
var phase = pi * (i%2);
var sig = Pan2.ar(SinOsc.ar(i * freq, phase , amp / (i**ampslope), 0.0), 0, 1);
sig * 0.1 // I scaled the signal down
}.sum; // you need to sum the signal to play the signal on a stereo bus.
Out.ar(out, sound * env);
}).add;
)
x = Synth(\sap, [freq: 220])
x.set(\gate, 0)