How to Accelerate Tempo in Tone.js Using Transport

This article explains how to dynamically speed up the tempo of your audio application in Tone.js by manipulating the playback rate of the master Transport. You will learn how to use the playbackRate property and its built-in signal methods to create smooth, automated tempo accelerations (accelerandos) in your web audio projects.

Understanding Tone.Transport.playbackRate

In Tone.js, Tone.Transport governs the timing of scheduled events, loops, and synths. While you can change the tempo by directly adjusting Tone.Transport.bpm.value, the playbackRate property serves as a multiplier for the current BPM.

A playbackRate of 1.0 runs the Transport at its default speed. Setting it to 2.0 doubles the speed, while 0.5 halves it. Because playbackRate is a Tone.Signal, you can smoothly ramp this value up or down over time using automation methods, rather than making abrupt, stepped changes.

Implementing Smooth Tempo Acceleration

The most effective way to accelerate the tempo is to use the rampTo method on the playbackRate signal. This transitions the playback speed from its current value to a target multiplier over a specified duration.

Here is a practical code example demonstrating how to trigger a smooth tempo acceleration over 4 seconds:

import * as Tone from 'tone';

// 1. Create a simple synth and loop to hear the tempo change
const synth = new Tone.Synth().toDestination();
const loop = new Tone.Loop((time) => {
  synth.triggerAttackRelease("C4", "8n", time);
}, "4n").start(0);

// Set initial tempo
Tone.Transport.bpm.value = 120;
Tone.Transport.start();

// 2. Function to accelerate the tempo
function triggerTempoAcceleration() {
  const targetRate = 2.0; // Double the speed (effectively 240 BPM)
  const duration = 4;     // Transition duration in seconds

  // Smoothly ramp the playback rate
  Tone.Transport.playbackRate.rampTo(targetRate, duration);
}

// Example trigger: Start the acceleration after 2 seconds
setTimeout(() => {
  triggerTempoAcceleration();
}, 2000);

Precise Scheduling with Linear Ramp

If you need precise musical scheduling relative to the Transport’s timeline rather than real-time seconds, you can use linearRampToValueAtTime. This allows you to schedule the acceleration to start and end at specific bars or beats.

// Ramp the playback rate from 1.0 to 1.5 starting at measure 2, ending at measure 6
Tone.Transport.playbackRate.setValueAtTime(1.0, "2:0:0");
Tone.Transport.playbackRate.linearRampToValueAtTime(1.5, "6:0:0");

By leveraging playbackRate as a signal, you can easily create expressive, dynamic timing effects like dramatic builds, gradual slowdowns, or organic tempo fluctuations in your interactive music applications.