Hi Alexandre,
The '|i|' is the same as 'arg i;' so yes, it is an alternative way to define arguments for a function.
The reason for it becoming multichannel without it is that you are mixing the same multichannel signal in the order of arrayfreq.size.
Say your arrayfreq looks like this:
[110,220,330,440,550,660]
That's six frequencies, and chucking them into the freq argument in the SinOsc creates six SinOscs because of multichannel expansion.
If you do:
Mix.fill(arrayfreq.size, {SinOsc.ar(arrayfreq, arrayphase)});
you will get a six channel signal and the wavepeaks will be ±6.0. 1+1+1+1+1+1 is 6 right? If you examine the separate channels more closely you'll find that the first channel plays the 110Hz, the second the 220Hz etc.
What Mix.fill does is that it says: "Do this function n number of times and mix it all down to one channel", and in this case it is actually the same result as as what .sum does. When you define an argument for the function, in this case the |i| part, the arguments value will be the number of times the function has been executed. You can use this data for indexing into arrays, or you can use it to generate other things such harmonic overtones.
The example above could be made with:
Mix.fill(6, {|i| SinOsc.ar( (i+1) * 110)});
You can read the help file on multichannel expansion in the docs, just search for 'multichannel expansion'
Please ask if something is unclear.
+Eirik