Mul value zero in mutlicahannel expansion

This should give us an additive square , for some reason mul doesn’t like value zero in [ ]
When replaceing zero with near zero value 0.000001 it works and we get an additive square

//doesn'work
(
{
	(SinOsc.ar([100,200,300,400,500,600,700,800,900,1000], mul:[1,0,1/3,0,1/5,0,1/7,0,1/9,0]))!2;
}.play
)


//works 
(
{
	(SinOsc.ar([100,200,300,400,500,600,700,800,900,1000], mul:[1,0.000001,1/3,0.000001,1/5,0.0000001,1/7,0.0000001,1/9,0.000001]))!2;
}.play
)

I’m not precisely sure why the first example fails, but I think it is, in part, related to multichannel expansion. You are first constructing a 10-channel signal, then applying a second layer of multichannel expansion with !2. This produces an array of size 2, and each item is a 10-channel signal. When you try to play this on the server, you should expect some sort of strange result.

If you mix the 10-channel signal to mono before stereo expansion, it’ll work:

(
{
	SinOsc.ar(
		[100, 200, 300, 400, 500, 600, 700, 800, 900, 1000],
		mul:[1, 0, 1/3, 0, 1/5, 0, 1/7, 0, 1/9, 0]
	).sum!2
}.play
)

This may also be related to the MulAdd UGen, which is created behind the scenes in most cases. In the MulAdd help file, it says

This UGen is very efficient (it performs various optimisation checks, for example)

Which suggests that it might be doing something related to control/audio rates. I was able to reproduce your problem using a simpler example:

//normal use of array to create a multichannel signal
{ [ PinkNoise.ar(0.1), SinOsc.ar(500, mul:0.3) ] }.play;

//"double array" causes two signals to be mixed and played on bus 0
{ [[ PinkNoise.ar(0.1), SinOsc.ar(500, mul:0.3) ]] }.play;

//mul: 0 in either UGen produces the same error
{ [[ PinkNoise.ar(0.1), SinOsc.ar(500, mul:0) ]] }.play;

Someone else might be able to explain this error with more accuracy.

a UGen with a hardcoded mul out put of 0 and no add offset will always output 0s, so the ugen graph builder for synthdefs (which happens in Function:play) optimizes it out.

here is a short example, observe the difference when evaluating:

SinOsc.ar(100, mul: [1, 0.0])
→ [ a SinOsc, 0.0 ]

SinOsc.ar(100, mul: [1, 0.1])
→ [ a SinOsc, a BinaryOpUGen ]

so, here is a fix

(
{
sum(SinOsc.ar([100,200,300,400,500,600,700,800,900,1000], mul:[1,0,1/3,0,1/5,0,1/7,0,1/9,0]))!2;
}.play
)