1 PfadeIn : FilterPattern {
2 var <>fadeTime, <>holdTime=0, <>tolerance;
3 *new { arg pattern, fadeTime=1.0, holdTime=0.0, tolerance=0.0001;
4 ^super.new(pattern).fadeTime_(fadeTime).holdTime_(holdTime).tolerance_(tolerance)
6 embedInStream { arg inval;
7 var outval, elapsed=0, stream, c;
8 stream = pattern.asStream;
11 if(holdTime > 0.0) { Event.silent(holdTime, inval).yield };
13 outval = stream.next(inval);
14 if(outval.isNil) { ^nil.yield };
16 elapsed = elapsed + outval.delta;
17 c = elapsed / fadeTime;
20 ^stream.embedInStream(inval);
23 outval[\amp] = c.max(0) * outval[\amp];
24 // outval[\amp] = (c.max(0) * pi * 0.25).sin * outval[\amp];
30 storeArgs { ^[ pattern, fadeTime, holdTime, tolerance ] }
34 asStream { | cleanup| ^Routine({ arg inval; this.embedInStream(inval, cleanup) }) }
36 embedInStream { arg inval, cleanup;
37 var outval, elapsed=0, stream, c;
38 stream = pattern.asStream;
39 cleanup ?? { cleanup = EventStreamCleanup.new };
41 inval = stream.next(inval) ?? { ^cleanup.exit(inval) };
42 cleanup.update(inval);
44 elapsed = elapsed + inval.delta;
45 if(elapsed.round(tolerance) <= holdTime) {
48 c = elapsed - holdTime / fadeTime;
52 inval[\amp] = (1.0 - c.max(0)) * inval[\amp];
61 PfinQuant : FilterPattern {
64 *new { arg pattern, quant, clock;
65 ^super.new(pattern).quant_(quant).clock_(clock)
68 embedInStream { arg inval;
69 var value, stream = pattern.asStream;
70 var referenceClock = clock ? thisThread.clock;
71 var endAt = quant.nextTimeOnGrid(referenceClock);
73 value = stream.next(inval);
74 value.notNil and: { referenceClock.beats < endAt }