Passing args to "do" in SynthDef

I’m trying to control the number of times a “do” loop is run in a SynthDef. I set an arg “passes” to do the looping.
If I hard code a “4.do” I get the result I expect.

( SynthDef( \test, {|out=0,passes=4|
	var sig=0,i;
	4.do { |i| 
		sig = sig + SinOsc.ar(200*i,0,0.05);
	};
	Out.ar(out,sig) 
}).play
)

When I use “passes.do” I only get one sine wave out.

( SynthDef( \test, {|out=0,passes=4|
	var sig=0,i;
	passes.do { |i| 
		sig = sig + SinOsc.ar(200*i,0,0.05);
	};
	Out.ar(out,sig) 
}).play
)

Why is that?

This is a very frequently asked question! It’s quite a subtle aspect of Sc. I’m not sure the best place to point you, certainly someone else will know better, but perhaps this as a starting point?

https://doc.sccode.org/Classes/SynthDef.html#Static%20versus%20Dynamic%20Elements

I think I get it. I’m guessing when a Synthdef is sent to the server, a static collection of commands is constructed. If I put in a “10.do”, 10 copies of the enclosed function are instanced on the server. This can’t change.

Yes, the server reads the file format described at http://doc.sccode.org/Reference/Synth-Definition-File-Format.html

The ugenGraphFunc argument to Synthdef>build has various special rules associated with it.

One is that the function arguments are a kind of metaphor for control parameters, they’re one way to make named controls appear in the graph.

Correct. Luckily in many cases it’s still possible to get what you want by replacing one synth with another while it’s running. Take a look at the help for the Ndef class.

Thanks,
I’ve seen Ndef as a topic in this forum. I haven’t looked at it yet. It’s akin to Pdef? I’ve used it to replace running patterns.

Whoa! Just looked at the Ndef doc and ran the examples. It’s going to take a while to get my head around this.