Passing an array to a UGen argument duplicates the whole signal graph, one copy per array element
Multichannel expansion is SuperCollider’s rule that whenever an array appears where a single value is expected in a UGen argument, SC silently duplicates the entire UGen graph once per array element, producing an array of outputs. Saw.ar([440, 570]) builds two independent Saw waves — 440 Hz on bus 0 (left), 570 Hz on bus 1 (right) — routed to consecutive output buses starting from the first Out.ar bus. Multiple arrays in the same graph expand concurrently; when arrays at different arguments differ in length, the shorter one wraps to match the longest. The misconception to correct: an array does not make one sound with several frequencies — it makes several parallel synth copies. Mix folds the channels down to mono; Splay folds them to stereo with even panning. !n is shorthand for .dup(n); note the subtle distinction between duplicating a UGen instance (one shared copy) and duplicating an argument (one unique instance each) — critical for random generators.
Examples
{Out.ar(0, Saw.ar([440,570], mul:0.1))}.play; // 440 Hz left, 570 Hz right
{Splay.ar(SinOsc.ar([100,300,500,700,900], mul:0.1))}.play; // 5 sines panned L→R
Mix(SinOsc.ar([100,300,500,700], mul:0.05)); // fold to mono
{PinkNoise.ar(0.5)!2}.play; // same noise both channels (one instance duplicated)
{PinkNoise.ar(0.5!2)}.play; // different noise per channel (two unique instances)
Assessment
Explain step by step what {SinOsc.ar([440,550,660],mul:0.1)}.play does: how many signals are created, where each goes, what you hear on a stereo system. Then contrast the output of PinkNoise.ar(0.5)!2 vs PinkNoise.ar(0.5!2) — which is correlated stereo, which is true stereo? Finally write a 4-voice additive patch expanded from one array and mix it to stereo with Splay.