Problems with variable literal array and NamedControl

I missed Daniel’s answer before writing this… posting anyway.

So, on the one hand, A: “As I read, that literal array arguments are fixed in size at the point of SynthDef compilation”

And on the other hand, B: “the default array declared in the SynthDef is limiting the size of the array passed to it via the event, and not replaced by it as I’d expect.”

If array arguments are fixed in size, then how would one expect them to be replaced in synth messaging?

The answer is, of course, that they are not replaced, because they cannot be replaced. The SynthDef structure must be absolutely, 100% fixed and unchanging at the time of compiling it. You can write a new SynthDef with the same name and replace the old one, but you cannot do any form of Synth.new or aSynth.set or pattern synth messaging and expect the structure to change.

How is the array size related to structure? Because all of the array elements have to be connected to inputs of other units. If you have more or fewer array elements, then you need more or fewer connections. That’s a change in structure, so it’s illegal.

There is no difference between:

SynthDef(\name, { |arrayArg = #[0, 0, 0, 0, 0]|
	...
}).add;

and

SynthDef(\name, {
	var arrayArg = NamedControl.kr(\arrayArg, #[0, 0, 0, 0, 0]);
	...
}).add;

None. No difference. (Well, there is one difference – the function-arg syntax will fold the array into a long list of channels of one Control UGen, whereas NamedControl always creates a separate Control unit for itself. But that’s irrelevant to array sizes.)

Your best workaround, I think, is to pass another argument for the number of elements that you’re actually using.

(
SynthDef(\trill, { |rate = 0.25, octave = 0, arraySize = 1|
	// Changing to .kr
	// .ir doesn't change, so why poll it?
	// and why is it named notesAr? It's not .ar
	var notesAr = \notesAr.kr(#[0, 0, 0, 0, 0]);
	// Dseq acts like Pn; Dser acts like Pser
	var notes = Dseq([Dser(notesAr, arraySize)], inf);
	var seq = Duty.kr(rate, level: notes);
	// one octave == 12 midinotes
	var osc = LFTri.ar((seq + (octave * 12)).midicps, mul: 0.1)!2;
	var env = EnvGen.kr(Env.linen(2, 4, 2), doneAction: 2);
	Out.ar(0, osc * env);
}).add;  // 'store' litters your HD with .scsyndef files you might not need
)

a = Synth(\trill, [rate: 0.05, octave: 5, arraySize: 2, notesAr: [0, 2]]);
a.set(\arraySize, 4, \notesAr, [0, 4, 2, 5]);

hjh