Pspawner dynamic control of multiple event streams from a Routine
superclass: Proutine
related class: Spawner
Pspawner allows a routine to dynamically start and stop subpatterns.
see also Pspawn
Pspawner(function)
The function defines a Routine that receives a Spawner as its sole argument. All control of subpatterns
is through the spawner
Spawner responds to the messages:
par(pattern, delta = 0)
Begin an event stream in parallel to the routine. If delta is non-zero, the pattern will begin that many beats
after 'now', provided that now + delta is later than the next event that the Spawner will generate. The
method returns the stream. This may be called from any object
seq(pattern)
run the entire pattern and then return control to the routine
wait(dur)
wait dur seconds and then return control to the routine
suspend (stream)
Find the stream in the Spawner and stop it, returns nil if the stream is not found, the stream otherwise
suspendAll
Stop all substreams of the Spawner
// example 1: a simple Pspawner
(
Pspawner({ | sp |
// parallel in-c'ish pulses will run throughout the example
sp.par(Pbind(*[ degree: [0,7], octave: 7, dur: 0.2, db: Pseq([-20, -24, -22, -24], inf)]) );
// scales in sequence with pauses
sp.seq(
Pbind(*[ degree: Pseq((0..7).mirror), dur: 0.2])
);
sp.wait(0.4);
sp.seq(
Ppar([
Pbind(*[ degree: Pseq((0..7).mirror), dur: 0.2, octave: 4]),
Pbind(*[ degree: Pseq((0..7).reverse.mirror), dur: 0.2])
])
);
sp.wait(3);
sp.seq(
Pbind(*[ degree: Pseq((0..7).mirror), dur: 0.2, mtranspose: (0,2..14)])
);
// scales overlaped at 0.4 second intervals
10.do {
sp.par(
Pbind(*[ degree: Pseq((0..7).mirror), dur: 0.2])
);
sp.wait(0.4)
};
sp.wait(1.6);
sp.suspendAll;
}).play
)
(
// example 2: create 5 streams at 4 second intervals
// then delete them in the order they were created
Pspawner({ | sp |
var streams, stream;
// start patterns, collect the resultant event streams
streams = [2, 3, 4, 6, 7, 8].collect { | i |
stream = sp.par(Pbind(*[
harmonic: i,
ctranspose: [0, 1, 3]/40,
octave: Pbrown(2,8,2), dur: 1/i, db: -30
]) );
sp.wait(4);
stream;
};
// now stop those streams one by one
streams.do { | s | sp.suspend(s); sp.wait(4) };
}).play
)
(
// example 3: define a Pspawner and use Pattern manipulations
p = Pspawner({ | sp |
sp.par(Pbind(*[octave: 5, degree: Pbrown( -7, 7, 3), dur: 0.2]) );
sp.wait(2);
sp.par(Pbind(*[octave: 5, degree: Pbrown( -7, 7, 3), dur: 0.1]) );
sp.wait(1);
sp.par(Pbind(*[octave: 6, degree: Pbrown( -7, 7, 3), dur: 0.05]) );
sp.wait(0.5);
sp.wait(4);
sp.par(Pbind(*[octave: 5, degree: Pbrown( -7, 7, 3), dur: 0.2]) );
sp.wait(4);
sp.suspendAll;
});
)
// play the basic patten
( p.play )
(
// manipulate it with Pchain
Pchain(
Pbind(*[ctranspose: 0 + Pwhite(-0.1, 0.1)]),
Pbind(*[mtranspose: Pkey(\mtranspose) + Pstutter(8, Prand([0,[-3,0,2],[0,2,4,6,8,10]], inf)) ] ),
Pn(Pseq([p, (type:\rest, dur: 0.4)]) ),
Pbind(*[
db: Pstep(Pseq([-10, -13, -13, -11, -13, -13], inf), 0.1) - 10,
mtranspose: Pstep(Pwhite(-7, 7), Prand([5,4,2],inf) )
])
).play(protoEvent: Event.default)
)
// example 4: altering the contents of the Pspawner from separate code
(
a = Pspawner({ |sp |
c = sp; // store the Spawner in a global variable
100.do{ sp.wait(1) }
});
a.play;
)
( // c will not be valid until the Pspawner has run
b = c.par( // now start a pattern in spawner
Pbind(*[degree: Pseq((0..6) ++ (7..1), inf), dur: 0.2])
);
)
c.suspend(b) // we can suspend and resume the stream
c.par(b)
c.suspend(b)
b = c.par( // or just start up a new pattern
Pbind(*[degree: Pseq((0..6) ++ (7..1), inf), dur: 0.2])
);
// example 5: Spawner can be used directly in the manner of Pspawner.
// This allows external code to access to the spawner whether or not it has run
(
c = Spawner({ |sp |
100.do{ sp.wait(1) }
});
b = c.par( // now start a pattern in spawner
Pbind(*[degree: Pseq((0..6) ++ (7..1), inf), dur: 0.2])
);
c.play; // in this case, c is always valid
)
c.suspend(b) // we can suspend and resume the stream
c.par(b)
c.suspend(b)
b = c.par( // or just start up a new pattern
Pbind(*[degree: Pseq((0..6) ++ (7..1), inf), dur: 0.2])
);
Pspawner({ | sp |
(1..5).do { | i |
sp.par(Pbind(*[
octave: i + 2,
degree: Pwhite(0,7), dur: 1/i, db: -30
]) );
sp.wait(4);
};
sp.suspendAll;
}).play