Pfsm
superclass: ListPatterns
finite state machine: every state links to possible next states (indices).
starting from one of the entry states one of these links is randomly
chosen used to get the next state. When an end state is reached, the stream ends.
Pfsm(list,repeats)
list:
[
[ entry states ],
item, [ next states ],
item, [ next states ],
...
end item (or nil), nil
]
next states: nil is terminal
(
SynthDef("help-sinegrain",
{ arg out=0, freq=440, sustain=0.05;
var env;
env = EnvGen.kr(Env.perc(0.01, sustain, 0.2), doneAction:2);
Out.ar(out, SinOsc.ar(freq, 0, env))
}).store;
)
(
a = Pfsm([
#[0,1],
67, #[0, 0, 3],
72, #[2],
73, #[0, 2],
Pseq([74, 75, 76, 77]), #[2, 3, 3],
nil, nil
], inf).asStream;
Routine({
loop({
Synth("help-sinegrain", [\freq, a.next.midicps]);
0.1.wait;
})
}).play;
)
(
Pfsm([
#[5, 6, 7], // entry states
//e1 (== state 0)
Pbind( \dur, Pseq([ 1/8, 3/8 ]), \midinote, Pseq([ 86, 75 ]) ),
//#[1], // as given in CMJ
// my de-boredom-ated version..
#[1, 1, 1, 1, 1, 1, 1, 8],
//e2 (== state 1)
Pbind( \dur, 1/2, \midinote, Pseq([ 69 ]) ),
#[0, 1],
//e3 (== state 2)
Pbind( \dur, 1/3, \midinote, Pseq([ 55, 60, 66 ]) ),
#[0, 1, 2, 2, 2, 2, 3, 3, 3, 3],
//e4 (== state 3)
Pbind( \dur, 1/4, \midinote, Pseq([ 81, 80, 77, 76 ]) ),
#[1, 4, 4, 4, 4],
//e5 (== state 4)
Pbind( \dur, Pseq([1, 2/3, 2/3, 2/3, 1]), \midinote, Pseq([ \, 70, 70, 70, \ ]) ),
#[2, 3],
//e6 (== state 5)
Pbind( \dur, 1/4, \midinote, Pseq([ 59, 61 ]) ),
#[0, 2, 4, 5, 5, 5, 5, 5, 5, 5],
//e7 (== state 6)
Pbind( \dur, 1/4, \midinote, Pseq([ 87, 88 ], 2) ),
#[4, 4, 4, 4, 6, 6, 6, 7, 7, 7],
//e8 (== state 7)
Pbind( \dur, 1, \midinote, Pseq([ 56 ]) ),
#[1, 3, 6, 6, 6],
// terminal state
nil, nil
]).play;
)