Feel free to add tricks of your own! I will come back to this page whenever I come up with something new.
- hjh
Getting a new value from one stream only when another stream changes
(or, holding a value until another stream changes)
// many repeated values here Pstutter(Pwhite(4, 9, inf), Pxrand((0.1, 0.2 .. 0.5), inf)).asStream.nextN(20); --> [ 0.3, 0.3, 0.3, 0.3, 0.3, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.3, 0.3, 0.3, 0.3, 0.1, 0.1, 0.1 ] // used as duration, I want each distinct value to have a different frequency // but repeated dur values should keep the same frequency // StreamClutch holds the value until another stream returns true // so the condition stream checks for a non-zero difference // between the latest dur and the previous one p = Pbind( \dur, Pstutter(Pwhite(4, 9, inf), Pxrand((0.1, 0.2 .. 0.5), inf)), \freq, StreamClutch(Pexprand(200, 800, inf), (Pdiff(Pkey(\dur)).abs > 0).asStream) ).play; p.stop;
Returning the same value every time the stream is accessed at the same logical clock time
We need to hold onto another stream that returns the amount of logical time since the last access. Penvir attaches an arbitrary container to a pattern, and its members can be used while evaluating the pattern.
Penvir((delta: Pdiff(Ptime(inf)).asStream), StreamClutch(Pwhite(1, 10, inf), { ~delta.next > 0 }), false)
In a Pbind, delaying the output of a stream by one value
This trick works only in this configuration. Trying to do it with one Pbind key – pattern - Pdiff(pattern) – does not work. You must get the base value in one key, then delay it in another.
p = Pbind( \a, Pwhite(1, 10, inf), \delay1, Pkey(\a) - Pdiff(Pkey(\a)) ).asStream; 20.do({ p.next(()).postln });