// reserve these for something else; JITLib should not touch
c = Bus.control(s, 4);
y = NodeProxy.control(s, 1);
// make some self-triggering decay as simple illustration
y[0] = { var oi = In.kr(\out.ir(42)); if(oi > 0.01, oi * 0.999, 1.0) };
y.get(\out) // 4 -- seems to respect others, but...
y.trace
the output from NodeProxy goes to the wrong bus. Apparently that only happens when In.kr(\out.ir)
is used that way inside the proxy function. The trace prints something like
unit 1 In
in 4
out 0
unit 10 Out
in 0 1
out
while the input is wired correctly, the output is not! Meaning NodeProxy corrupted (or overtook) a bus (number 0) reserved for something else. It doesnât matter how I (try to) initialize that \out.ir
. Itâs still bus 0 that NodeProxy outputs to!
Why does that happen and how can I prevent it?
Well, I fixed it by rewiring it as
y = NodeProxy.control(s, 1)
y[0] = { var oi = y.kr(1); if(oi > 0.01, oi * 0.9999, 1.0) }
Interestingly this auto-generates an In
thatâs properly wired to its own out. Tracing that prints something like:
unit 0 In
in 9
out 0.148356
unit 9 Out
in 9 0.148341
out
Still the question remains: why does NodeProxy output get so confused if you use In.kr(\out.ir)
explicitly inside it?
I sorta figured out whatâs going on. In the bugged example, somehow two out
controls get created for the same synth. A tree dump for that looks something like
1029 group
1031 temp__01726152607_1416
out: 14 gate: 1 fadeTime: 0.019999999552965 out: 0
There are two controls named out
! And one (used by the Out
) has the value 0, while the one used by In
the value given by the NodeProxy index⌠I have no idea how this is even possible to have two controls with the same name in the same synth.
Apparently, itâs actually legal to build SynthDefs with duplicate name controls. When built directly with SynthDef
that gives a hefty warning, but will still build it. Apparently, NodeProxy suppresses those warnings.
(SynthDef(\crazy, {
var c1 = Control.names(\out).ir(1), i = In.kr(c1);
var c2 = Control.names(\out).ir(3);
Out.kr(c2, i) }).add)
prints out something like
-> SynthDef:crazy
WARNING: Could not build msgFunc for this SynthDesc: duplicate control name out
Your synthdef has been saved in the library and loaded on the server, if running.
Use of this synth in Patterns will not detect argument names automatically because of the duplicate name(s).
But itâs totally legal to instantiate that:
x = Synth(\crazy)
Dumping the sever tree has something like
1032 crazy
out: 1 out: 3
Interestingly the new style NamedControl doesnât build duplicates.
(SynthDef(\crazyNot, {
var c1 = \out.ir(1), i = In.kr(c1);
var c2 = \out.ir;
Out.kr(c2, i) }).add)
This will create a single out
control. I guess a fix would be to change ProxySynthDef at line 127 (or so) where that happens in old-style:
outCtl = Control.names(\out).ir(0) + channelOffset;
Iâm still unsure why NodeProxy (e.g at line 615) has two controls one named out
and one named i_out
though. Anyway, just changing ProxySynthDef to read
outCtl = \out.ir(0) + channelOffset; // fix for dupes
fixes the first kind of example, to the extent that one can properly use In.kr(\out.ir)
. Attempting to pass a non-zero initialization value would obviously produce an ERROR: NamedControl: cannot have more than one set of default values in the same control
. The way the actual out
bus index gets set is through a setting/mapping later on in the NodeProxy code.
An interesting side-effect of this on-line fixer in ProxySynthDef
is that you can now Out.kr(\out.ir, ...)
reliably from NodeProxies. If that is used as the last statement, it has as interesting side-effect of bypassing the autogenerated EnvGate
. Out.kr itself returns zero (the actual output is a side-effect), so the EnvGate
gets optimized away in the UGen graph generation due to its multiplication with zero. That may break some things that depend on an envelope being always present and enveloping all the proxy output though.