Well here are some hacks I found while working on a timeline system… quite probably unhelpful but who knows.
It’s definitely not seamless, but it is actually possible to schedule a routine back in time – so that according to the clock it should have started a certain amount of time ago and it speeds through the routine until it’s at your desired starting point.
(
var routine = Routine({ 1.postln; 2.wait; 3.postln; 4.wait; 5.postln; 6.wait; 7.postln; });
TempoClock.sched(-10, { routine.play; nil });
)
This is ok if you don’t care about all the stuff before your specific starting point happening immediately.
The problem with this method is it prohibits you from doing anything in your routine that for instance creates a synth and then later frees it, since there’s the possibility those two messages will be sent to the server simultaneously and you’ll get synths playing forever.
If you are diligent about separating the server commands you need executed in a certain order from the ones it’s ok to zip forward through, you can get away with something like this:
(
var synth = {
VarSaw.ar(\freq.kr(440, 0.2), 0, \width.kr(1, 1), 0.1)
}.play;
var cleanup = {
synth.free;
};
var routine = Routine {
synth.set(\width, 0);
0.25.wait;
synth.set(\freq, 220);
0.5.wait;
synth.set(\width, 1);
synth.set(\freq, 440);
1.wait;
synth.set(\freq, 220);
synth.set(\width, 0);
1.5.wait;
synth.set(\freq, 330);
1.wait;
synth.set(\width, 0.5);
0.5.wait;
synth.set(\width, 1);
1.5.wait;
synth.set(\freq, 220);
2.5.wait;
synth.set(\width, 0.5);
};
{
Server.default.sync;
TempoClock.sched(-2, { { |inval|
routine.embedInStream(inval);
Server.default.sync;
cleanup.();
}.fork; nil });
}.fork;
)
As a side note, if you’re using a specific type of routine called an event stream, which is the type of routine that patterns generate, you have a fastForward method:
(
var pattern = Pbind(\degree, Pseq([0, 1, 2, 3, 4, 5]));
var stream = pattern.asStream;
{
stream.fastForward(2).wait;
EventStreamPlayer(stream).play;
}.fork;
)