Help with iteration, arrays or control structures in a synth

Hi,

I’m working on some drones to help me practice hearing spectra generated by FM in order to use them in improvising. In doing so I’ve been reminded that I understand iteration and arrays quite poorly and was wondering if someone could give me some basic feedback on a better way to organise this synth.

(
  Ndef(\pm1, {
  arg freq=110, modRatio = 1.5, amp=0.1, partials=5, lfo=2, pan=0;
  var sig, modFreq, amps, freqs;
 
 modFreq = freq * modRatio;
  freqs = [freq, freq+modFreq, freq-modFreq, freq + (2*modFreq), freq - (2*modFreq), freq + (3*modFreq),     freq - (3 * modFreq), freq + (4 * modFreq), freq - (4 * modFreq)];
 
  amps = [LFNoise1.kr(lfo).exprange(0.3, 0.8), LFNoise1.kr(lfo).exprange(0.3, 0.8), LFNoise1.kr(lfo).exp    range(0.3, 0.8), LFNoise1.kr(lfo).exprange(0.3, 0.8), LFNoise1.kr(lfo).exprange(0.3, 0.8), LFNoise1.kr    (lfo).exprange(0.3, 0.8), LFNoise1.kr(lfo).exprange(0.3, 0.8), LFNoise1.kr(lfo).exprange(0.3, 0.8), LF    Noise1.kr(lfo).exprange(0.3, 0.8)];
 
  sig = SinOsc.ar(freqs, 0, amps);
  sig = Mix.ar(sig) * amp;
  sig = Pan2.ar(sig, pan);
 
  }).play;
  )

A few questions:

  • I’m sure there’s a nicer way to organise the amps than to write out/copy+paste LFNoise1 nine times. But LFNoise1.kr(lfo).exprange(0.3, 0.8)!9 didn’t give the result I was after. I couldn’t really find anything in the help docs explaining why either.

  • similarly, I feel like there must be a better way to organise the frequencies, using iteration rather than writing out every item in the array

  • finally, I am wondering if there is a way to have these parameters controlled by an argument, so that when I want there to be more partials, I just update the partials argument, and then the formula + number of LFNoise1s controlling the amplitude matches.

Thanks in advance for any help!
Jordan

Hi Jordan,
https://sc-users.bham.ac.narkive.com/hc0aS92V/array-arguments-in-synthdefs

check out this old JM answer to arrays inside synthdefs - not using Ndef but it does show you how to use the syntax (!). Example uses /freq but you can shift that over to the amp argument pretty easily.

Thanks for this, super interesting.

I ended up just using an Eli Fieldsteel example as a basis, not sure why I forgot about it but anyway:

(
Ndef(\fm0, {
arg freq=110, modRatio=1.5, amp=0.1, partials=5, lfo=2, pan=0, out=0;
var sig, modFreq, amps, freqs, temp, sum;

modFreq = freq * modRatio;

sum=0;

5.do{
arg count;
temp = SinOsc.ar([freq + ((count + 1) * modFreq), freq - ((count+1) * modFreq)]) *
LFNoise1.kr(lfo).exprange(0.2, 0.8);
sum = sum + temp;
};

sig = SinOsc.ar(freq);    
sig = sig + sum;          
sig = sig * amp;          
sig = Splay.ar(sig);      
//sig = Pan2.ar(sig, pan);
//Out.ar(out, sig);       
}).play;                  
)