NamedControl: a better way to write SynthDef arguments

This is generally good because it groups control names with their “types”, but it does have one downside: if you spread out the SynthDef inputs/controls through the code, and there’s a lot of them e.g. 20 params is not uncommon for some of my synths, it’s a real mess figuring out the full list of parameters when you look at the code. So what I do know is duplicate/move the list to the beginning of the SynthDef as vars, i.e. for a trivial example, instead of just

(SynthDef(\beep, {
	ReplaceOut.ar(\out.ir(0), \amp.kr(0.5) * SinOsc.ar(\freq.kr(440)).dup);
}).add;)

I do

(SynthDef(\beep, {
	var out = \out.ir(0), amp = \amp.kr(0.5), freq = \freq.kr(440);
	ReplaceOut.ar(out, amp * SinOsc.ar(freq).dup);
}).add;)

That looks duplicative, but with a lot controls (20+) and 20+ lines of code in a SynthDef, it helps me to have the full list upfront in the code (which is what args`does).

The var “overloading” of the named controls does work properly, i.e. there are no compile errors and you can still change their values with messages (e.g. Node.set, .map) still work properly, as it turns out.

Oddly enough, you can also write arg instead of var there:

(SynthDef(\beep, {
	arg out = \out.ir(0), amp = \amp.kr(0.5), freq = \freq.kr(440);
	ReplaceOut.ar(out, amp * SinOsc.ar(freq).dup);
}).add;)

It seems to work too for set or map but it doesn’t for the initial values which don’t get set anymore in this latter (arg instead of var approach). The reason for that is clear if you do

SynthDescLib.global.synthDescs.at(\beep);

With the var you get

-> SynthDesc 'beep' 
Controls:
ControlName  P 0 out scalar 0.0
ControlName  P 1 amp control 0.5
ControlName  P 2 freq control 440.0
   O audio ReplaceOut out 2

but with the arg instead you get

-> SynthDesc 'beep' 
Controls:
ControlName  P 0 out control 0.0
ControlName  P 1 amp control 0.0
ControlName  P 2 freq control 0.0
   O audio ReplaceOut out 2

Likewise if you “save” the SynthDef to a client var, and perform allControlNames on that object:

-> [ ControlName  P 0 out scalar 0, ControlName  P 1 amp control 0.5, ControlName  P 2 freq control 440 ]

vs

-> [ ControlName  P 0 out control 0.0, ControlName  P 1 amp control 0.0, ControlName  P 2 freq control 0.0 ]
1 Like