How can I pass values from 3D Array as arguments to a synthdef

Hi Everyone,

I´ve a 3d array with frequency and amplitude values. These values have to be read by a synth so that with those data it processes a signal.
In other words, the synth has to read each row of the array and add the signals with the frequency and amplitude values of each cell. For example:

myarray = [f1,a1] [f2,a2], [f3,a3]
[f4,a4] [f5,a5], [f6,a6]
[f7,a7] [f8,a8] [f9,a9]

And my SynthDef is
Synthdef.new(\sinth{
arg freq, amp;
var sig;
sig = SinOsc.ar(freq, mul:amp);
Out.ar (0,sig);
}).add;

n = number of row
For (i = 0 to i=2)
var freqi, ampi;
freqi = myarray[n-1] [i] [0];
ampi = myarray[n-1] [i] [1];
xi = Synth.new (\sinth,[\freq, freqi],[\amp, ampi]);
end

How can I do this in SC? I´m a beginner. I need to do Additive Synthesis with the values of the row.

Thank u for your help…

(
var f1,f2,f3,f4,f5,f6,f7,f8,f9,a1,a2,a3,a4,a5,a6,a7,a8,a9;
f1 = 10;
f2 = 40;
f3 = 100;
f4 = 50;
f5 = 150;
f6 = 250;
f7 = 400;
f8 = 60;
f9 = 80;
a1 = a4 = a7 = 0.75;
a2 = a5 = a8 = 0.5;
a3 = a7 = a9 = 0.23;

y = Array.fillND([3, 3, 2]).debug("start y");

y[0][0][0] = f1;
y[0][0][1] = a1;
y[0][1][0] = f2;
y[0][1][1] = a2;
y[0][2][0] = f3;
y[0][2][1] = a3;
y[1][0][0] = f4;
y[1][0][1] = a4;
y[1][1][0] = f5;
y[1][1][1] = a5;
y[1][2][0] = f6;
y[1][2][1] = a6;
y[2][0][0] = f7; 
y[2][0][1] = a7;
y[2][1][0] = f8;
y[2][1][1] = a8;
y[2][2][0] = f9;
y[2][2][1] = a9;

y.debug("new y");
)

(
SynthDef.new(\wow, {
	arg freq = 60, amp = 0.1, gate = 1, wowrelease = 3;
	var chorus, source, filtermod, env, snd;
	chorus = Lag.kr(freq, 2) * LFNoise2.kr([0.4, 0.5, 0.7, 1, 2, 5, 10]).range
	(1, 1.02);
	source = LFSaw.ar(chorus) * 0.5;
	filtermod = SinOsc.kr(1/16).range(1, 10);
	env = Env.asr(1, amp, wowrelease).kr(2, gate);
	snd = LPF.ar(in: source, freq: freq * filtermod, mul: env);
	Out.ar(0, Splay.ar(snd))
}).add;
)
´´´
(
var n = (row number);

// myarray[n] accesses the row
// then you want to 'do' something to each row element
myarray[n].do { |pair|
	Synth(\sinth, [freq: pair[0], amp: pair[1]]);
};

// but you don't have access to the Synth objects that way
// so this might be better:
x = myarray[n].do { |pair|
	Synth(\sinth, [freq: pair[0], amp: pair[1]]);
};

// now 'x' is [a Synth, a Synth, a Synth]
// and you can free them:
x.do { |synth| synth.free };
)

hjh

I’m sure James meant

x = myarray[n].collect { |pair| 
   Synth(\sinth, [freq: pair[0], amp: pair[1]]); 
};

@soundgold The reason why your question about 3d array, as you formulated it in the title, is not being answered directly, is because you can’t pass multidimensional arrays to synths directly. You need to restructure that somehow, and there are two main strategies:

  1. implied by you and @jamshark70: when a synth is doing the same thing in “parallel” copies, there are good chances you can break it down in multiple copies of the same synth.
  2. use multichannel controls: this is less flexible because you have to specify beforehand the number of, in this case, frequencies and amplitudes your synth accepts, whereas if you create multiple synths you can extend that at will just by creating/destroying synths.

But I met cases when you want to use option number 2. So I will post an example of that for your use case.

// this synthdef accepts 9 freqs and 9 amps
SynthDef(\sinth9){
    var freqs = \freqs.kr(0!9);
    var amps = \amps.kr(0!9);
    var sig = SinOsc.ar(freqs) * amps;
    Out.ar (0,sig);
}.add;

x = Synth(\sinth9, [freqs: myarray.flop[0], amps: myarray.flop[1]])