Psmartstutter : Pstutter


Exactly like Pstutter, except for a small but significant implementation detail.


In Pstutter, values are retrieved from the main pattern and repeated n times, where n is obtained from a second pattern. When the caller requests a new value from the Pstutter stream, it may optionally pass in a value (such as an event prototype, for event streams). This value is passed into Pstutter's child streams, so that they may be decisions about the next value to return based on the caller's request. In particular, the n stream has only information from the caller on which to base its calculation.


Psmartstutter, by contrast, passes the caller's input value to its main pattern, but then passes the main pattern's return value into the n stream, so that the n stream can use the value that will be repeated to determine how many times to repeat it.


*new(n, pattern)


n: Pattern returning the number of times to repeat successive values from the main pattern.

pattern: The main pattern, which returns the values to be repeated.


Simple example - the number x gets repeated x times. This is not possible with Pstutter while it's trivial with Psmartstutter.


p = Psmartstutter(Pfunc({ |n| n }), Pxrand((1..5), inf)).asStream;

p.nextN(20);

[ 1, 5, 5, 5, 5, 5, 4, 4, 4, 4, 3, 3, 3, 1, 2, 2, 3, 3, 3, 2 ]


If you want lower return values to be repeated more times.


p = Psmartstutter(Pfunc({ |x| (10 / x).asInteger }), Pwhite(1, 10, inf)).asStream;

p.nextN(30);

[ 8, 6, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 7, 5, 5, 8, 6, 10, 2, 2, 2, 2, 2, 4, 4, 8, 3, 3, 3, 8 ]


Using a similar concept for Pbind deltas:


SynthDef(\sinGrain, { |outbus = 0, freq, amp, dur, pan|

var sig = Pan2.ar(SinOsc.ar(freq, 0, amp) * EnvGen.kr(Env.sine(dur), doneAction:2), pan);

Out.ar(outbus, sig);

}).memStore;


p = Pbind(

\freq, Pwhite(0.0, 1.0, inf).linexp(0.0, 1.0, 300.0, 2400.0),

\amp, Pwhite(0.5, 1.0, inf),

\delta, Psmartstutter(Pfunc({ |x| (0.5 / x).asInteger }), Pwhite(0.1, 0.5, inf)),

\dur, Pkey(\delta) * Pwhite(1.0, 1.8, inf),

\pan, Pwhite(-0.8, 0.8, inf)

).play;


p.stop;