Classes | Streams-Patterns-Events > Patterns > Time

Pstep : Pattern : AbstractFunction : Object

timed, sample-and-hold embedding of values
Subclasses: Pseg

Description

Pstep is a "sample and hold" pattern: The value returned by next is held at each value in levels for the corresponding duration in durs. This cycling is similar to Ptuple, in that the current repeat ends when eiher pattern returns nil.

Pstep measures elapsed time using the thread's logical time. That is, it assumes it will be evaluated only exactly when needed, not before.

See Pseg for a pattern whose value changes like an Env.

Class Methods

Pstep.new(levels, durs: 1, repeats: 1)

Create an instance of Pstep.

Arguments:

levels

A number, collection, or Pattern that returns the levels.

durs

A number, collection, or Pattern that returns segments durations in beats.

repeats

An integer, or inf.

Inherited class methods

Instance Methods

Inherited instance methods

Undocumented instance methods

.durs

.durs = value

.embedInStream(inval)

.list

.list = value

.repeats

.repeats = value

Examples

(
// select a chord and duration and repeat it for a random time interval
p = Pstep(
    Pbind(
        \ctranspose, [0, 4, 7],
        \note,    Pwhite(0, 12),
        \dur,    Prand([0.2, 0.4, 0.8], inf)
    ),
    Prand([1, 2, 4], inf)/4
);
Ppar([p, p]).play;
)
// change degree independently of number of events that have been playing

(
Pchain(
    Ppar([
        Pbind(
            \degree, Pbrown(0, 12, 1),
            \dur, Pstep( Pseq([0.1, 0.2, 0.4, 0.8, 1.6], inf), 3.2)
        ),
        Pbind(
            \degree, Pbrown(0, 20, 1),
            \dur, Pstep( Pseq([0.1, 0.2, 0.4, 0.8, 1.6], inf), 4.5)
        )
    ]),
    Pbind(
        \scale, Pstep(Pseq([ [0, 2, 4, 5, 7, 9, 11], [0, 1, 2, 3, 4, 5, 6]], inf), 5),
        \db, Pstep(Pseq([2, -2, 0, -2], inf), 0.25) - 10
    )
).play;
)

// use a simple pattern
(
Pchain(
    Ppar([
        Pbind(
            \octave, [5, 6] + Prand([0, 0, \r], inf),
            \degree, Prout({ | ev | loop { ev = Pseq(ev[\degree]).embedInStream } }),
            \dur,    Prout({ loop { Pseq([0.2, 0.2, 0.2, 0.2, 0.3].scramble).embedInStream } })
        ),
        Pbind(
            \octave, 4,
            \legato, 1.2,
            \dur, Prout({ loop { Pseq([0.2, 0.2, 0.2, 0.2, 0.3].scramble * 5).embedInStream }})
        ),
    ]),
    Pstep(Pbind(
        \db, Pseq([0, -4, -2, -4, -3, -4, -3, -4], inf) - 20
    ), 0.2),
    Pstep(
        Pbind(
            \degree,     Pfunc({ {10.rand}.dup(10) }),
            \scale,    Pfunc({ {rrand(1, 2)}.dup(7).integrate })
        ),
        5
    )
).play
)



// change one parameter
(
Pbind(
    \degree, Pstep(Pseq([1, 2, 3, 4, 5]), 1.0).trace,
    \dur, Pseries(0.1, 0.1, 15)
).play;
)


// change degree independant of number of events that have been playing

(
var a, b;
a = Pbind(
    \degree, Pstep(Pseq([0, 2b, 3], 1), 1.0),
    \dur, Prand([0.2, 0.5, 1.1, 0.25, 0.15], inf)
);
b = Pbind(
    \degree, Pseq([0, 2b, 3], 1),
    \dur, 2,
    \ctranspose, -7
);
Pseq([Event.silent(1.25), Ppar([a, b])], inf).play;
)



// test tempo changes

(
var a, b;
a = Pbind(
    \degree, Pstep(Pseq([0, 2b, 3], 1), 1.0),
    \dur, Prand([0.2, 0.5, 1.1, 0.25, 0.15], 9)
);
b = Pbind(
    \degree, Pseq([0, 2b, 3], 1),
    \dur, 2,
    \ctranspose, -7
);

Ppar([a, b], inf).play;
)


SystemClock.sched(0, { TempoClock.default.tempo = [1, 2, 3, 5].choose.postln; 2 });

TempoClock.default.tempo = 1.0;



// timing test:
// parallel streams


(
var a, b, x;
var times, levels;

SynthDef(\pgrain,
    { arg out = 0, freq=800, sustain=0.001, amp=0.5, pan = 0;
        var window;
        window = Env.sine(sustain, amp);
        Out.ar(out,
            Pan2.ar(
                SinOsc.ar(freq) * EnvGen.ar(window, doneAction: Done.freeSelf),
                pan
            )
        )
    }
).add;

times = Pseq([3.4, 1, 0.2, 0.2, 0.2], inf);
levels = Pseq([0, 1, 2, 3, 4], inf);

a = Pstep(levels, times);
b = Pbind(\instrument, \pgrain, \octave, 7, \dur, 0.12, \degree, a);
x = times;

Ppar([b, Pset(\mtranspose, 2, b) ]).play;

b.play;
r {
    var z = x.asStream; // direct times
    0.5.wait;
    loop {
        z.next.wait;
        s.makeBundle(0.2, {
            Synth(\pgrain, [\freq, 3000, \sustain, 0.01]); // signal tone
        })
    }
}.play(quant:1)
)