Merge pull request #506 from andrewcsmith/patch-2
[supercollider.git] / SCClassLibrary / Common / Collections / Array.sc
blob5e5ad3bbe179ce84ad8974bda591cdfad82159f9
1 Array[slot] : ArrayedCollection {
3         *with { arg ... args;
4                 // return an array of the arguments given
5                 // cool! the interpreter does it for me..
6                 ^args
7         }
8         reverse {
9                 _ArrayReverse
10                 ^this.primitiveFailed
11         }
12         scramble {
13                 _ArrayScramble
14                 ^this.primitiveFailed
15         }
16         mirror {
17                 _ArrayMirror
18                 ^this.primitiveFailed
19         }
20         mirror1 {
21                 _ArrayMirror1
22                 ^this.primitiveFailed
23         }
24         mirror2 {
25                 _ArrayMirror2
26                 ^this.primitiveFailed
27         }
28         stutter { arg n=2;
29                 _ArrayStutter
30                 ^this.primitiveFailed
31         }
32         rotate { arg n=1;
33                 _ArrayRotate
34                 ^this.primitiveFailed
35         }
36         pyramid { arg patternType=1; // an integer from 1-10
37                 _ArrayPyramid
38                 ^this.primitiveFailed
39         }
40         pyramidg { arg patternType=1;
41                 var list = [];
42                 var lastIndex = this.lastIndex;
43                 if (patternType == 1) {
44                         for (0,lastIndex) {|i| list = list.add(this[0..i]) };
45                         ^list
46                 };
47                 if (patternType == 2) {
48                         for (0,lastIndex) {|i| list = list.add(this[lastIndex-i..lastIndex]) };
49                         ^list
50                 };
51                 if (patternType == 3) {
52                         for (lastIndex,0) {|i| list = list.add(this[0..i]) };
53                         ^list
54                 };
55                 if (patternType == 4) {
56                         for (0,lastIndex) {|i| list = list.add(this[i..lastIndex]) };
57                         ^list
58                 };
59                 if (patternType == 5) {
60                         for (0,lastIndex)   {|i| list = list.add(this[0..i]) };
61                         for (lastIndex-1,0) {|i| list = list.add(this[0..i]) };
62                         ^list
63                 };
64                 if (patternType == 6) {
65                         for (0,lastIndex)   {|i| list = list.add(this[lastIndex-i..lastIndex]) };
66                         for (lastIndex-1,0) {|i| list = list.add(this[lastIndex-i..lastIndex]) };
67                         ^list
68                 };
69                 if (patternType == 7) {
70                         for (lastIndex,0) {|i| list = list.add(this[0..i]) };
71                         for (1,lastIndex) {|i| list = list.add(this[0..i]) };
72                         ^list
73                 };
74                 if (patternType == 8) {
75                         for (0,lastIndex)   {|i| list = list.add(this[i..lastIndex]) };
76                         for (lastIndex-1,0) {|i| list = list.add(this[i..lastIndex]) };
77                         ^list
78                 };
79                 if (patternType == 9) {
80                         for (0,lastIndex) {|i| list = list.add(this[0..i]) };
81                         for (1,lastIndex) {|i| list = list.add(this[i..lastIndex]) };
82                         ^list
83                 };
84                 if (patternType == 10) {
85                         for (0,lastIndex)   {|i| list = list.add(this[lastIndex-i..lastIndex]) };
86                         for (lastIndex-1,0) {|i| list = list.add(this[0..i]) };
87                         ^list
88                 };
89         }
90         sputter { arg probability=0.25, maxlen = 100;
91                 var i=0;
92                 var list = Array.new;
93                 var size = this.size;
94                 probability = 1.0 - probability;
95                 while { (i < size) and: { list.size < maxlen }}{
96                         list = list.add(this[i]);
97                         if (probability.coin) { i = i + 1; }
98                 };
99                 ^list
100         }
102         lace { arg length;
103                 _ArrayLace
104                 ^this.primitiveFailed
105         }
106         permute { arg nthPermutation;
107                 _ArrayPermute
108                 ^this.primitiveFailed
109         }
110         allTuples { arg maxTuples = 16384;
111                 _ArrayAllTuples
112                 ^this.primitiveFailed
113         }
114         wrapExtend { arg length;
115                 _ArrayExtendWrap
116                 ^this.primitiveFailed
117         }
118         foldExtend { arg length;
119                 _ArrayExtendFold
120                 ^this.primitiveFailed
121         }
122         clipExtend { arg length;
123                 _ArrayExtendLast
124                 ^this.primitiveFailed
125         }
126         slide { arg windowLength=3, stepSize=1;
127                 _ArraySlide
128                 ^this.primitiveFailed
129         }
130         containsSeqColl {
131                 _ArrayContainsSeqColl
132                 ^this.primitiveFailed
133         }
135         //************** inconsistent argnames, see SequenceableColllection unlace!
136         unlace { arg clumpSize=2, numChan=1, clip=false;
137                 ^if(clip) {
138                         super.unlace(clumpSize, numChan)
139                 } {
140                         this.prUnlace(clumpSize, numChan) // clip not yet implemented in primitive
141                 }
142         }
143         prUnlace { arg clumpSize=2, numChan=1;
144                 _ArrayUnlace
145                 ^this.primitiveFailed;
146         }
147         interlace { arg clumpSize=1;
148                 //_ArrayInterlace
149                 //^this.primitiveFailed;
150                 Error("interlace was replaced by lace\n").throw
151         }
152         deinterlace { arg clumpSize=2, numChan=1;
153                 //_ArrayUnlace
154                 //^this.primitiveFailed;
155                 Error("deinterlace was replaced by unlace\n").throw
156         }
158         // multiChannelExpand and flop do the same thing.
159         flop {
160                 _ArrayMultiChannelExpand
161                 ^super.flop
162         }
163         multiChannelExpand {
164                 _ArrayMultiChannelExpand
165                 ^super.flop
166         }
167         envirPairs {
168                 // given an array of symbols, this returns an array of pairs of symbol, value
169                 // from the current environment
170                 var result;
171                 this.do {|name|
172                         var value = name.envirGet;
173                         value !? { result = result.add(name).add(value); };
174                 };
175                 ^result
176         }
178         shift { arg n, filler = 0.0;
179                 var fill = Array.fill(n.abs, filler);
180                 var remain = this.drop(n.neg);
181                 ^if (n<0) { remain ++ fill } { fill ++ remain }
182         }
184         powerset {
185                 var arrSize = this.size;
186                 var powersize = (2 ** arrSize).asInteger;
187                 var powersOf2 = ({ |i| 2 ** i }).dup(arrSize);
189                 ^Array.fill(powersize, { |i|
190                         var elemArr = Array.new;
191                         powersOf2.do { |mod, j|
192                                 if (i div: mod % 2 != 0) {
193                                         elemArr = elemArr.add(this[j])
194                                 };
195                         };
196                         elemArr;
197                 });
198         }
200         // UGen support:
201         source {
202                 // returns the source UGen from an Array of OutputProxy(s)
203                 var elem = this.at(0);
204                 if (elem.isKindOf(OutputProxy), {
205                         ^elem.source
206                 },{
207                         Error("source: Not an Array of OutputProxy(s)\n").throw;
208                 });
209         }
210         asUGenInput { arg for; ^this.collect(_.asUGenInput(for)) }
211         asControlInput { ^this.collect(_.asControlInput) }
213         isValidUGenInput { ^true }
214         numChannels { ^this.size }
216         // multichannel UGen-poll
217         poll { arg trig = 10, label, trigid = -1;
218                 if(label.isNil){ label = this.size.collect{|index| "UGen Array [%]".format(index) } };
219                 ^Poll(trig, this, label, trigid)
220         }
221         dpoll { arg label, run = 1, trigid = -1;
222                 if(label.isNil){ label = this.size.collect{|index| "UGen Array [%]".format(index) } };
223                 ^Dpoll(this, label, run, trigid)
224         }
226         envAt { arg time;
227                 _ArrayEnvAt
228                 ^this.primitiveFailed
229         }
231 //      // 2D array support
232 //      *newClear2D { arg rows=1, cols=1;
233 //              ^super.fill(rows, { Array.newClear(cols) });
234 //      }
235 //      *new2D { arg rows=1, cols=1;
236 //              ^this.newClear2D(rows, cols);
237 //      }
238 //      at2D { arg row, col; ^this.at(row).at(col) }
239 //      put2D { arg row, col, val; ^this.at(row).put(col, val) }
240 //      fill2D { arg val;
241 //              this.do({ arg row;
242 //                      row.size.do({ arg i;
243 //                              row.put(i, val)
244 //                      })
245 //              })
246 //      }
249         // IdentitySet support
250         atIdentityHash { arg argKey;
251                 _Array_AtIdentityHash
252                 ^this.primitiveFailed
253         }
254         // IdentityDictionary support
255         atIdentityHashInPairs { arg argKey;
256                 _Array_AtIdentityHashInPairs
257                 ^this.primitiveFailed
258         }
260         asSpec { ^ControlSpec( *this ) }
262         // threads
263         fork { arg join (this.size), clock, quant=0.0, stackSize=64;
264                 var count = 0;
265                 var cond = Condition({ count >= join });
266                 this.do({ arg func;
267                         Routine({ arg time;
268                                 func.value(time);
269                                 count = count + 1;
270                                 cond.signal;
271                         }).play(clock, quant);
272                 });
273                 cond.wait;
274         }
276         // UGen support
277         madd { arg mul = 1.0, add = 0.0;
278                 ^MulAdd(this, mul, add);
279         }
281         // OSC
282         asRawOSC {
283                 _Array_OSCBytes
284                 ^this.primitiveFailed;
285         }
287         printOn { arg stream;
288                 if (stream.atLimit, { ^this });
289                 stream << "[ " ;
290                 this.printItemsOn(stream);
291                 stream << " ]" ;
292         }
293         storeOn { arg stream;
294                 if (stream.atLimit, { ^this });
295                 stream << "[ " ;
296                 this.storeItemsOn(stream);
297                 stream << " ]" ;
298         }
299         prUnarchive { arg slotArray;
300                 slotArray.pairsDo {|index, slots| this[index].setSlots(slots) };
301                 this.do {|obj| obj.initFromArchive };
302                 ^this.first
303         }