View this PageEdit this PageUploads to this PageHistory of this PageTop of the SwikiRecent ChangesSearch the SwikiHelp Guide

Nifty Pattern tricks

Home   How To   Code Pool   Public Library   Theory   Events
Since I use patterns a lot, I often run into problems that can't be solved with very simple pattern applications, but which can be handled gracefully using just a little trickery. Or, to be more precise, using some little-known but very powerful patterns.

Feel free to add tricks of your own! I will come back to this page whenever I come up with something new.



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 });


Link to this Page