SuperCollider CLASSES

Pdfsm

deterministic finite state machine

Description

Pdfsm is a deterministic finite state machine with signal input (written by by ccos).

Class Methods

*new (list, startState: 0, repeats: 1)

Arguments:

list

a list consisting of the stream which gives input signals to determine state transitions, and then dictionary entries, one for each state, mapping the destination state and yield streams to those input signals.

startState

an integer index for the state to start with.

repeats

an integer giving the number of times the pattern should cycle. A cycle ends when the signal stream ends or nil is given for the destination state to a signal value, see below.

Inherited class methods

Instance Methods

Inherited instance methods

Undocumented instance methods

-embedInStream (inval)

-startState

-startState = value

Examples

list structure:
[
signal stream
can be a stream of anything which can serve as a key for an associative collection. integers, symbols, etc... asStream is called on this for each repeat.
states
states should be an instance of IdentityDictionary, Event or some other associative collection.

]
list syntax:
[
signal stream,
( // state 0,
signal value : [destination state, return stream or pattern],
signal value : [destination state, return stream or pattern]
),
... // state 1 ... N
]
Any number of states can be given, and are indexed by the order in which they are given.

If the fsm is in state x and it receives a signal value y it looks up y in the state dictionary supplied for x, if there is no y entry, it looks for a \default entry and uses that.

The next state is then set to destination state, and the stream yielded is given by return stream or pattern. That is unless the destination state is given as nil, or if a destination state is given for which you have not supplied a dictionary - in both cases the current cycle ends and any remaining repeats are executed. If there is no signal value given for a particular signal, and no \default is supplied then one will get a runtime error.

(
    p = Pdfsm(
        [
            Pseq( [\foo,\bar], 2 ), // foobar signals
            ( // state 0
                \foo : [ 1, Pseq([ 0, 1 ], 2 ) ]
            ),
            ( // state 1
                \bar : [ 0, 3 ]
            )
        ],
        0,
        2
    ).asStream;

    11.do({ p.next.postln });
)

(
SynthDef(\help_Pdfsm1,
    { 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, freq + 0.1.rand2], 0, env))
    }).add;
)

(
var p;
p = Pdfsm(
    [
        Prand([0,1,2],inf),    // signalStream

        IdentityDictionary[    // state 0
            0 -> [ 2, Pseq([67,68,69], 2) ],
            1 -> [ 0, 66 ],
            2 -> [ 1, 65 ]
        ],
        IdentityDictionary[    // state 1
            1 -> [ 1, Pseq([69,68,67],2) ],
            \default -> [ 0, 70 ]
        ],
        IdentityDictionary[
            0 -> [ 0, 71 ],
            1 -> [ 0, 72 ],
            2 -> [ nil ]    // signalStream is infinitely long,
                    // so the fsm only ends because of this nil
                    // 2 -> [nil, nil] is also fine
        ]
    ],
    1,                 // startState
    1                 // repeats
).asStream;

Routine({
    var freq;
    while({ (freq = p.next.postln).notNil },{
        Synth(\help_Pdfsm1, [ \freq, freq.midicps ]);
        0.1.wait;
    })
}).play;
)

(
SynthDef(\help_Pdfsm2,
    { arg freq, gate=1;
        var n=8, env, osc;
        env = Linen.kr( gate, 0.01, 1, 0.03, 2 );
        osc = {Mix.fill( n, { arg i;
            FSinOsc.ar(freq + Rand(-2.0,2.0), Rand(0, 0.05pi)) ring4:
            FSinOsc.ar(freq * (i+1));
        })}.dup * FSinOsc.kr(Rand(1.5,4.5),{Rand(-0.1pi,0.1pi)}.dup,0.6,env*0.4);
        Out.ar(0, env * osc / (n*4) )
    }).add;
)

(
var n=3, base, penult;

base = [3,4,4,0];

for( 1, n, { arg i;
    penult = Pbind( \degree, Pshuf(base - (i*5), 2), \dur, Pseq([0.2],2) );
    Pset(
        \instrument, \help_Pdfsm2,
        Pdfsm(
            [
                Pseq([    // signalStream
                    Pn(1,22 + i),
                    Pn(0,4),
                    Pn(1,8),
                    Pseq([
                        Pn(0,3),
                        Prand([0,1],8),
                        Pn(1,8)
                    ], 3 ),
                    Pn(2,2)
                ], 1 ),
                (    // state 0
                    0 : [ 0, Pbind( \degree, Pseq(base - i, 1), \dur, Pxrand([0.2,0.3],4) ) ],
                    1 : [ 1, Pbind(
                            \degree, Pseq(base.reverse - (i*2), 2),
                            \dur, Pseq([0.2,0.21],1)
                            )
                        ],
                    2 :    [ 2, penult ]
                ),
                (    // state 1
                    0 : [ 0, Pbind( \degree, Pshuf(base * i.neg, 8), \dur, Pseq([0.08],8) ) ],
                    1 : [ 0, Pbind( \degree, Pseq(base - (i*3),3+i), \dur, Pseq([0.11],3+i) ) ],
                    2 : [ 2, penult ]
                ),
                (    // state 2
                    \default : [ 2, Pbind(
                                    \degree, Prand(base - (i*7), 5),
                                    \dur, Prand([0.6,0.8],5)
                                )
                            ]
                )
            ],
            i % 2         // startState
        )
    ).play;
})
)