2 var <>list, <>durs, <>repeats;
4 *new { arg levels, durs = 1, repeats = 1;
5 ^super.newCopyArgs(levels, durs, repeats).init
7 init { if (list.isKindOf(Collection)) { list = Pseq(list); } }
9 embedInStream { arg inval;
11 thisThread.endBeat = thisThread.endBeat ? thisThread.beats;
12 // endBeat > beats only if Pfindur ended something early
13 thisThread.endBeat = thisThread.endBeat min: thisThread.beats;
15 repeats.value(inval).do { | i |
16 stream = Ptuple([list, durs]).asStream;
18 { #val, dur = stream.next(inval) ? [nil, nil];
22 thisThread.endBeat = thisThread.endBeat + dur;
24 { thisThread.endBeat > thisThread.beats },
25 { inval = val.embedInStream(inval) }
32 ^[list, durs, repeats]
39 *new { arg levels, durs = 1, curves = \lin, repeats = 1 ;
40 ^super.new(levels, durs, repeats).curves_(curves)
42 embedInStream { arg inval;
43 var valStream, durStream, curveStream, startVal, val, dur, curve;
45 var startTime, curTime;
46 repeats.value(inval).do {
47 valStream = list.asStream;
48 durStream = durs.asStream;
49 curveStream = curves.asStream;
50 val = valStream.next(inval) ?? {^inval};
51 thisThread.endBeat = thisThread.endBeat ? thisThread.beats min: thisThread.beats;
54 val = valStream.next(inval);
55 dur = durStream.next(inval);
56 curve = curveStream.next(inval);
58 val.notNil and: { dur.notNil and: { curve.notNil } }
60 startTime = thisThread.endBeat;
61 thisThread.endBeat = thisThread.endBeat + dur;
62 if (startVal.isArray) {
63 env = [startVal,val, dur, curve].flop.collect { | args |
64 Env([args[0], args[1]], [args[2]], args[3]) };
65 while { thisThread.endBeat > curTime = thisThread.beats } {
66 inval = yield(env.collect{ | e | e.at(curTime - startTime)})
69 env = Env([startVal, val], [dur], curve);
70 while { thisThread.endBeat > curTime = thisThread.beats } {
71 inval = yield(env.at(curTime - startTime))
78 ^[list, durs, curves, repeats]