Selection which UGen to use based on a SynthDef argument

Hi,
I’m trying to build a SynthDef where one can select which type of UGen to use:

SynthDef(\sd,{
	arg type=0;
	var sig;
	sig=[SinOsc.ar, Saw.ar, Pulse.ar].at(type)*0.2;
	Out.ar(1,sig);
}).add;

And I receive the following error:

(…)The preceding error dump is for ERROR: Primitive ‘_BasicAt’ failed.
Index not an Integer
RECEIVER: [ a SinOsc, a Saw, a Pulse ]

I guess I understand the reason why. My analyse is that - at the “compile-time” - SC has no certainty that type will remain an Integer over execution.

I tried to replace type by type.trunc, type.asInt, type.asInteger, … and this doesn’t do any good. How to resolve that ?

Hiya,

The simple answer is to use Select.ar(index, […ugens…])

I might reply with a longer comment explaining why, I’m on mobile right now.
J

1 Like

Gosh !! This is the example I came across yesterday and I couldn’t manage to find again. Thanks.

The answer depends on whether you want to select the UGen at compile time or at runtime.

In the first case you’re constructing a SynthDef procedurally, which looks like:

(
     ~bar = 0;

     SynthDef.new(\foo, {
         var sig;

         sig = [SinOsc.ar, Saw.ar, Pulse.ar][~bar];
         sig = sig * 0.2!2;

         Out.ar(0, sig)
     }).add
)

~baz = Synth.new(\foo)
~baz.free

In the second case, you can use e.g. Select and parameterize the selection, as @jordan said:

(
     SynthDef.new(\foo, {
         var sig;

         sig = [SinOsc.ar, Saw.ar, Pulse.ar];
         sig = Select.ar(\bar.kr(0), sig);
         sig = sig * 0.2!2;

         Out.ar(0, sig)
     }).add
)

~baz = Synth.new(\foo)
~baz.set(\bar, 0)
~baz.set(\bar, 1)
~baz.set(\bar, 2)
~baz.free
1 Like