SynthDef: instantiate with different Out modality by parameter

Hi guys,

To reduce some redundancy in my code, I would like my SynthDefs to be compatible both with a stereo and octophonic setup. I would like to instantiate a new synth from time to time selecting which “mode” it will work (stereo or octophonic) via a parameter.

I’ve tried with something like that:

SynthDef(\test_synth, {
	|out=0, amp=0.5, pan=0.0, width=2, mode=\stereo|
	var sig = SinOsc.ar(440) * amp;
	if( mode == \stereo, {
		Out.ar(out, Pan2.ar(sig, pan));
	}, {
		Out.ar(out, PanAz.ar(8, sig, pan, width:width));
	});
}).add;

But it doesn’t seem to work

I’ve also tried the following way (using an , say “nchans” parameter) but I think the SynthDef cannot compile because PanAz is expectiong to know the number of channels it will use in advance instead of at running time.

SynthDef(\test_synth, {
	|out=0, amp=0.5, pan=0.0, width=2, nchans=2|
	var sig = SinOsc.ar(440) * amp;
	Out.ar(out, PanAz.ar(nchans, sig, pan, width:width));
}).add;

Is there some way to add this feature?
Thank you so much for your help, as always.

Try Select.ar, using its first parameter as your “mode”, and the second parameter an array of two items – your Pan2 and PanAz options.

The reason your if(…) construction does not work is: a SynthDef is a static entity. The “if” is evaluated only once when you first build the SynthDef, and after that the UGen graph is a fixed set of connections. Hope that makes sense. Take a look here for more info – http://doc.sccode.org/Classes/SynthDef.html

Bruno

1 Like

Also see this help file which treats this common misunderstanding:

https://supercollider.github.io/tutorials/If-statements-in-a-SynthDef.html

You can use the if-ugen:

https://doc.sccode.org/Classes/UGen.html#-if

but Select is more clear imo. However, as written in the tutorial, you need mode as number, not as Symbol, as the server doesn’t know Symbols.

2 Likes

Thank you guys for your support!

1 Like

Hi guys and thanks for your replies.

I came out with a SynthDef like the following one (did you mean something like that)?

SynthDef(\test, {
	|out=0, freq=440, amp=0.5, atk=0.01, rel=1, pan=0.0, mode=0|
	var env = EnvGen.ar(Env.perc(atk, rel),1,doneAction:2);
	var sig = SinOsc.ar(freq) * amp * env;
	sig = Select.ar( mode,
		[
			Pan2.ar(sig, pan),
			PanAz.ar(8, sig, pan),
		]
	);
	Out.ar(out, sig);
}).add;

It seems to work pretty well when I set the mode to optophonic (mode=1): I can easily change the position of the sound inside the octophonic setup like I’m used to.
But, when I instantiate another synth in stereo mode (mode=0) I see something strange: sound is coming out from the main pair of speakers but also from the others (in other words, even if I see changes in panning the sound from left to right and viceversa, sound is coming out in a form of 4 stereo pairs).

here’s the code:

s.options.numOutputBusChannels_(8);
s.boot;
s.meter;

x = Synth(\test, [\mode,1, \amp, 0.5, \pan, 0.125])

And my meters

strange_behavs

Why?
Wheh I play the synth in stereo mode, I would like the sound to come out only from the first pair of speakers.
How to do that.
Thank you very much for your support and, by the way, merry Christmas to you all!

maybe try [Pan2.ar(sig, pan),0,0,0,0,0,0] or some such… (I’d have to check at my machine to be sure the right way but you get the idea:

I expect the Synth has 8 channels whichever mode is selected and that you need to keep the stereo sig from wrapping…

Another perhaps simpler idea might be to use PanAz for both versions and have \mode scale the pan parameter instead.

1 Like

That’s on the spot, just needs to take DCs instead (and I should have considered it)

SynthDef(\test, {
	|out=0, freq=440, amp=0.5, atk=0.01, rel=1, pan=0.0, mode=0|
	var env = EnvGen.ar(Env.perc(atk, rel),1,doneAction:2);
	var sig = SinOsc.ar(freq) * amp * env;
	sig = Select.ar(mode,
		[
			Pan2.ar(sig, pan) ++ DC.ar(0!6),
			PanAz.ar(8, sig, pan),
		]
	);
	Out.ar(out, sig);
}).add;

s.options.numOutputBusChannels_(8);
s.boot;
s.meter;

x = Synth(\test, [\mode, 0, \amp, 0.5, \pan, 1])

x = Synth(\test, [\mode, 1, \amp, 0.5, \pan, 0.5])
1 Like