# Smooth alteration of Tempo

How do you alter Tempo in a smooth way in SuperCollider? For example Accelerando, decelerando (probably not the right name), and maybe some
sort of Rubato. It seems bpm only wants a single number, whereas for some
musical ideas you would want bpm controlled by EnvGen and so forth.

                     Thank You For Your Attention


If you’re up to installing a library, you can do this in Alga:

(
Alga.boot({
a = AP((
def: { SinOsc.ar * EnvPerc.ar(release: 0.1 * \tempo.kr(1)) },
tempo: Pfunc { Alga.clocks[Server.default].tempo.reciprocal }
)).play(chans: 2)
})
)

//10 times faster
Alga.interpTempo(tempo: 10, time: 5)

//Using a shape
Alga.interpTempo(tempo: 3, time: 8, shape: Env([0, 1, 0, 1], [1, 2, 3]))


Pseg works for this. If it’s not obvious from the example, the timing of Pseg follows your tempo also - which means each envelope segment is 8 beats, not 8 seconds. This makes the most musical sense, but it becomes harder to e.g. have a slow tempo increase over an absolute period of time.

(
Pdef(\tempoFlux, Pbind(
\scale, Scale.melodicMinor,
\dur, 1/8,
\degree, Pseq([
-1, 2, 3, 5, 4, 1
], inf) + Pseq([0, -2], inf).durStep(8),
\tempo, Pseg([0.5, 4, 0.5], [8, 8]).repeat
)).play
)

1 Like

@elgiano once shared with me this approach:

// accelerate all patterns from 1 to 2 in 10 seconds
Task { (1,1.01..2).do { |t| TempoClock.default.tempo = t; 0.1.wait } }.play

// nicer
(
~glissTempo = { |target = 2, dur = 3, step = 0.01|
Tdef(\tempoChange) {
var current = TempoClock.default.tempo;
var numSteps = (target - current) / step;
var stepDur = dur / numSteps;
if (numSteps < 0) { step = step.neg; numSteps = numSteps.neg; };

(current, step .. target).do { |newTempo|
TempoClock.default.tempo = newTempo;
stepDur.wait;
}
};
)

// go to 120bpm in 3 seconds
~glissTempo.(2, 3)

1 Like

I use this extension:

https://swiki.hfbk-hamburg.de/MusicTechnology/763

1 Like

I installed this library and installed AlgaUGens in the directory where Platform.userExtensionDir points (/home/clfest/.local/share/SuperCollider/Extensions). The code above doesn’t seem to work, that is we get the beep, but the //10 times faster code seems to have no effect, as does the line beneath it, and it seems they should. Please advise.

                               Thank You For Your Attention


My bad, just pushed a fix for it.

Apparently my SuperCollider doesn’t understand ‘durStep’. When I commented it out I saw what I think your example is supposed to demonstrate.

Would this TempoClock extension be suitable for real time modification of the TempoClock, for example if you were going to ‘conduct’ a piece?

                   Thank You For Your Attention


Loaded the new Quark but it doesn’t seem to help.

     Thank You For Your Attention


For simulating by-ear tempo changes between several musicians (resp. their clocks),
there is the ListeningClock quark, which can do smooth clock tempo changes using
various warps.

(
// prep: make a listening clock,
t = ListeningClock.new.permanent_(true);

// a fast attack sound to use
SynthDef(\ping, {|freq, pan, amp=0.3|
var e = EnvGen.ar(Env.perc(0, 0.1, amp), doneAction:2);
var z = SinOsc.ar(freq, 0, 0.2);
OffsetOut.ar(0, Pan2.ar(z*e, pan));

// a pattern on clock t:
Pdef(\a,
Pbind(\instrument, \ping,
\degree, Pseq((0..7), inf),
\dur, 0.25, \pan, -0.5, \amp, 0.5
)
).play(t);
)

// makes a smooth tempo change on a listening clock
// newTempo is the tempo to go to,
// time is the transition time,
// and warp the warp of the interpolation from current to new tempo.

t.verbose_(true);