Routine and GUI


#1

Hi Forum,

I am trying to create a GUI to trigger a sequence of synthdefs from an array. The problem I am encountering is the setting of arguments with a slider - normally not difficult. However in this case I want to set the arguments for some of member of the array and not others. Question: how do I populate an array with instances of a synth?

some code here to make the question a bit clearer.

~routine = {
(

	r = Routine { 
		
		10.do { arg i;
			
			~arr = Array.fill(10,{|i| ("arraySynth"++i )}).yield;
			
			
		}
	};
			
	z = Routine{
		10.do {|i|

			Synth(~arr[i].value.postln);
			
			rrand(0.4,1).wait;
		}
	}.play;
)

}

//then when the above function is triggered the slider from a GUI (shown below) will set some of the synths and //not others…

Slider(w,Rect(140,240,150,50))
.action_({ arg slider2;

Synth.set(~arr[2..6].set(\amp_z, slider2.value.postln));

});

Hope this is clear -


#2

Hi again,

that doesn’t seem too clear without the rest of the code - I add a synthdef here to make things a bit more understandable… Still don’t quite get how to make an array of Synths with unique names… The following code works - but I want to create an array of Synths that I can set individually with a slider or other GUI element. Any help much appreciated.

10.do({|i|
	var name;
	name = "arrayTest"++i;
	SynthDef(name, { arg out = 0.0;

	
		 var z = BPF.ar(BrownNoise.ar(0.1.dup),2000, 0.2, mul:0.4);
		var env = EnvGen.kr(Env.perc(0.01, 1.0), doneAction: 2);
		Out.ar(out, Pan2.ar(LPF.ar(z, 1000), 0,env));
	}).add;
});
//test..
Synth(\arrayTest2);

(

r = Routine { arg inval;
	   
  // Post the value passed in when started.
    10.do { arg i;
        inval = ("arrayTest"++i ).yield;

    }
};


z = Routine{
 10.do {
       // r.value.postln;
		Synth(r.value.postln);
		
		rrand(0.001,0.01).wait;
    }
}
)

z.play;

Edit : I just noticed that when you copy this code it doesn’t format the strings in theSC IDE correctly…you need to rewrite the strings.
Edit 2: formatted.


#3

It looks like the issue is the distinction between the name of the SynthDef (a Symbol to which that SynthDef is bound in SynthDescLib.global) and the Environment variable to which a particular Synth is bound.

Just to be clear, a SynthDef is essentially a template for producing Synths. The Synths are what you want to be able to target with your sliders, so the name of the SynthDef is not important here. In your example, the Synths created by Routine “z” are not bound to anything in the Environment, so you have no way of accessing them to set their parameters, just like if you hadn’t assigned that Routine to interpreter variable “z”, you wouldn’t be able to play or stop it.

Here’s an example of how you can make an array of Synths from a single SynthDef and refer to them individually:

(
    {
        s.bootSync;

        // a simple SynthDef that just plays a sine wave, with one parameter to set frequency
        SynthDef.new(\test, { OffsetOut.ar(0, SinOsc.ar(\freq.kr(440)) * 0.2!2) }).add;

        s.sync;

        // an array of four synths
        ~synths = 4.collect({ Synth.new(\test) });

        s.sync;

        // wait for two seconds with all Synths tuned to 440hz
        2.wait;

        // now cycle through the array four times, setting each Synth's frequency, then waiting 0.5 seconds
        4.do({
            ~synths.do({|x, i|
                ("Setting frequency of Synth" + i).postln;
                x.set(\freq, 110.rrand(880));
                0.5.wait
            })
        });

        // iterate over the Array, freeing all Synths
        ~synths.do({|x, i| 
            ("Freeing Synth" + i).postln;
            x.free 
        })
    }.fork
)

In case it’s not clear from the above the Synths are all made from the same SynthDef with the same name, and the Array that contains them is bound to a single Environment variable, ~synths, but you can refer to each Synth in the Array individually in the same way that you can address any element of any Array. For example, to refer to the first Synth you could do ~synths[0].set(\freq, 220) or ~synths.at(0).set(\freq, 220).

Hope that helps!


#4

Hi Catnip,

thanks for the answer - I will check this out. I actually changed my approach a little because I couldn’t get the GUI part of the code working. Using Tdef’s and making arrays of synths inside those defs seems to work.

However I would like to get this working the way you have it above - that looks good. :slight_smile: