Merge pull request #506 from andrewcsmith/patch-2
[supercollider.git] / SCClassLibrary / Common / Audio / Mix.sc
blob89caad57db332a069b7c4e7a8cd35ca39830f5ac
1 Mix {
2         *new { arg array;
3                 var reducedArray = array.asArray.clump(4);
4                 var mixedArray = reducedArray.collect {|a|
5                         if (a.size == 4) {
6                                 Sum4(*a)
7                         } {
8                                 if (a.size == 3) {
9                                         Sum3(*a)
10                                 } {
11                                         a.sum
12                                 }
13                         }
14         };
16                 if (mixedArray.size < 3) {
17                         ^mixedArray.sum
18                 };
20                 if (mixedArray.size == 3) {
21                         ^Sum3(*mixedArray)
22                 } {
23                         ^Mix(mixedArray)
24                 }
25         }
27         // support this common idiom
28         *fill { arg n, function;
29                 var array = Array.fill(n, function);
30                 ^this.new(array);
31         }
33         // and these common idioms
34         *ar { |array|
35                 var result = this.new(array);
36                 ^switch(result.rate)
37                         { \audio } { result }
38                         { \control } { K2A.ar(result) }
39                         { \scalar } { DC.ar(result) }
40                         { Error("Unsupported rate % for Mix.ar".format(result.rate)).throw };
41         }
43         *kr { |array|
44                 var result;
45                 // 'rate' on an array returns the fastest rate
46                 // ('audio' takes precedence over 'control' over 'scalar')
47                 if(array.rate == \audio) {
48                         "Audio rate input(s) to Mix.kr will result in signal degradation.".warn;
49                         array.do { |unit|
50                                 if(unit.rate == \audio) {
51                                         (unit + unit.rate).postln;
52                                         unit.dumpArgs;
53                                 };
54                         };
55                         array = array.collect { |unit|
56                                 if(unit.rate == \audio) { A2K.kr(unit) } { unit };
57                         };
58                 };
59                 result = this.new(array);
60                 ^switch(result.rate)
61                         { \control } { result }
62                         { \scalar } { DC.kr(result) }
63                         { Error("Unsupported rate % for Mix.kr".format(result.rate)).throw };
64         }
66         *arFill { |n, function|
67                 ^this.ar(Array.fill(n, function))
68         }
70         *krFill { |n, function|
71                 ^this.kr(Array.fill(n, function))
72         }
76 NumChannels {
78         *ar { arg input, numChannels = 2, mixdown = true;
80                 if(input.size > 1) { // collection
81                    ^input
82                         .clump(input.size / numChannels)
83                         .collect { arg chan, i;
84                                 if(chan.size == 1) {
85                                         chan.at(0)
86                                 } {
87                                         if(mixdown) {
88                                                 Mix.new(chan)
89                                         } {
90                                                 chan.at(0)
91                                         }
92                                 }
93                         }
94                 } {
95                         // single ugen or single item collection
96                         if(input.isSequenceableCollection) {
97                                 input = input.at(0);
98                         };
100                         if(numChannels == 1) {
101                                 ^input
102                         } {
103                                 ^Array.fill(numChannels, input)
104                         }
105                 }
106         }