Merge pull request #506 from andrewcsmith/patch-2
[supercollider.git] / SCClassLibrary / Common / Streams / Ppar.sc
blob60a224dfd72c810df896a9f2db24397fa37ea3e5
1 Ppar : ListPattern {
2         initStreams { arg priorityQ;
3                 list.do({ arg pattern, i;
4                         priorityQ.put(0.0, pattern.asStream);
5                 });
6         }
8         embedInStream { arg inval;
9                 var assn;
10                 var priorityQ = PriorityQueue.new;
12                 repeats.value(inval).do({ arg j;
13                         var outval, stream, nexttime, now = 0.0;
15                         this.initStreams(priorityQ);
17                         // if first event not at time zero
18                         if (priorityQ.notEmpty and: { (nexttime = priorityQ.topPriority) > 0.0 }) {
19                                 outval = Event.silent(nexttime, inval);
20                                 inval = outval.yield;
21                                 now = nexttime;
22                         };
24                         while { priorityQ.notEmpty } {
25                                 stream = priorityQ.pop;
26                                 outval = stream.next(inval).asEvent;
27                                 if (outval.isNil) {
28                                         nexttime = priorityQ.topPriority;
29                                         if (nexttime.notNil, {
30                                                 // that child stream ended, so rest until next one
31                                                 outval = Event.silent(nexttime - now, inval);
32                                                 inval = outval.yield;
33                                                 now = nexttime;
34                                         },{
35                                                 priorityQ.clear;
36                                         });
37                                 } {
38                                         // requeue stream
39                                         priorityQ.put(now + outval.delta, stream);
40                                         nexttime = priorityQ.topPriority;
41                                         outval.put(\delta, nexttime - now);
43                                         inval = outval.yield;
44                                         // inval ?? { this.purgeQueue(priorityQ); ^nil.yield };
45                                         now = nexttime;
46                                 };
47                         };
48                 });
49                 ^inval;
50         }
53 Ptpar : Ppar {
54         initStreams { arg priorityQ;
55                 forBy(0, list.size-1, 2, { arg i;
56                         priorityQ.put(list.at(i).value, list.at(i+1).asStream);
57                 });
58         }
62 Pgpar : Ppar {
63         embedInStream { arg inevent;
64                 var     server, ids, patterns, event, ingroup, cleanup, stream;
65                 var     lag = 0, clock = thisThread.clock,
66                         groupReleaseTime = inevent[\groupReleaseTime] ? 0.1;
68                 server = inevent[\server] ?? { Server.default };
69                 ingroup = inevent[\group];
70                 ids = { server.nextNodeID } ! this.numberOfGroups;
72                 event = inevent.copy;
73                 event[\addAction] = 1;
74                 event[\type] = \group;
75                 event[\delta] = 0;
76                 event[\id] = ids;
77                 event[\group] = ingroup;
79                 inevent = event.yield.copy;
80                 cleanup = EventStreamCleanup.new;
81                 cleanup.addFunction(inevent, { | flag |
82                         if (flag) {
83                                 ( lag: lag - clock.beats + groupReleaseTime,
84                                         type: \kill, id: ids, server: server
85                                 ).play
86                         };
87                 });
89                 patterns = this.wrapPatterns(ids);
90                 stream = this.class.implClass.new(patterns, repeats).asStream;
92                 inevent !? { inevent = inevent.copy; inevent[\group] = ingroup };
93                 loop {
94                         event = stream.next(inevent) ?? { ^cleanup.exit(inevent) };
95                         cleanup.update(event);
96                         lag = max(lag, clock.beats + event.use { ~sustain.value });
97                         inevent = event.yield;
98                 }
99         }
101         numberOfGroups { ^list.size }
102         wrapPatterns { arg ids;
103                 ^ids.collect { |id, i| Psetpre(\group, id, list[i]) };
104         }
106         *implClass { ^Ppar }
109 Pgtpar : Pgpar {
110         numberOfGroups { ^list.size div: 2 }
112         wrapPatterns { arg ids;
113                 var patterns = list.copy;
114                 ids.do { |id, i| patterns[((i << 1) + 1)] = Psetpre(\group, id, patterns[(i << 1) + 1]) };
115                 ^patterns
116         }
118         *implClass { ^Ptpar }