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