The SynthDef part in the following code has a similar feature of your intention:
https://sccode.org/1-5hC
(
s.options.numWireBufs = 128;
s.reboot
)
(
~numSliders = 64;
~mul = 0.1;
~freq = 220;
SynthDef(\overtone_additive, { |overtoneFirst = 1, overtoneLast = 8|
var freq, mul, numOvertones, maxLayers, amplitudes, temp, signalArray, sum;
mul = \mul.kr(~mul);
freq = \freq.kr(~freq);
maxLayers = ~numSliders;
amplitudes = \amplitudes.kr(1 ! maxLayers);
numOvertones = overtoneLast - overtoneFirst + 1;
signalArray = maxLayers.collect { |i|
var nthOvertone, minDetect, maxDetect, aliasingDetect, switch;
nthOvertone = i + 1 * freq;
minDetect = overtoneFirst <= (i + 1);
maxDetect = overtoneLast >= (i + 1);
aliasingDetect = nthOvertone < (SampleRate.ir / 2);
switch = (minDetect * maxDetect * aliasingDetect).lag(0.1);
SinOsc.ar(nthOvertone) * switch * numOvertones.lag(0.1).reciprocal.sqrt
};
signalArray = signalArray * amplitudes;
sum = signalArray.sum * mul.lag(0.1);
Out.ar(0, sum * [1, -1]);
}).add
)
x = Synth(\overtone_additive);
x.set(\overtoneFirst, 1, \overtoneLast, 1);
x.set(\overtoneFirst, 2, \overtoneLast, 2);
x.set(\overtoneFirst, 1, \overtoneLast, 2);
x.set(\overtoneFirst, 1, \overtoneLast, 3);
x.set(\overtoneFirst, 4, \overtoneLast, 7);
x.free
The following code is the revision to add “steps” to your code, but I could not configure it in SynthDef, so I used it in x.set with array for the argument \amplitudes
. You will find a UGen scope with 10 channels when you evaluate the SynthDef code without modifying it, and you will see that it works as you want. After confirming its functionality, you could increase the ~maxLayers
environment variable. I think 1000 is too high: More than 10 makes it hard to see the signal output via UGen Scope.
(
~maxLayers = 10;
SynthDef(\aSynth, { |freq = 440, atk = 0.3, rel = 1, amp = 0.1, pan = 0, ampSlope = 1, gate = 1|
var maxLayers, amplitudes, numOvertones, temp, signalArray, signal;
maxLayers = ~maxLayers;
amplitudes = \amplitudes.kr(1 ! maxLayers);
signalArray = maxLayers.collect { |i|
var nthOvertone, minDetect, maxDetect, aliasingDetect, switch, phase, aSignal;
nthOvertone = i + 1 * freq;
aliasingDetect = nthOvertone < (SampleRate.ir / 2);
switch = aliasingDetect.lag(0.1);
phase = pi * (i + 1 % 2);
aSignal = SinOsc.ar(nthOvertone, phase) / (i + 1 ** ampSlope) * switch;
};
signalArray = signalArray * amplitudes;
signal = signalArray.scope.sum * amp;
signal = signal * Env.asr(atk, 1, rel).kr(Done.freeSelf, gate);
signal = Pan2.ar(signal, pan);
OffsetOut.ar(0, signal);
}).add
)
x = Synth(\aSynth);
x.set(\ampSlope, 0.4)
x.set(\amplitudes, a = 10; (1..a).collect{ |item| if ((1, 4..a).includes(item)) {1} {0} })
x.set(\amplitudes, a = 10; (1..a).collect{ |item| if ((1, 3..a).includes(item)) {1} {0} })
x.release
test video
The code above and the code in the video is slightly different.