Tone.js Loop: Purpose and Playback Interval Control

This article explains the purpose of Tone.Loop in the Tone.js web audio framework and provides a straightforward guide on how to control its playback interval. You will learn how to schedule repeating musical events, change their timing dynamically, and keep your audio synchronized with the global timeline.

The Purpose of Tone.Loop

In Tone.js, Tone.Loop is a helper class designed to schedule a repeating event on the Tone.Transport timeline. Unlike native JavaScript timing functions like setInterval, Tone.Loop is strictly tied to the audio context clock and the Transport’s tempo (BPM). This ensures that your audio events remain sample-accurate, drift-free, and musically aligned.

You use Tone.Loop when you need to trigger a repetitive action—such as playing a drum hit, updating a visualizer on the beat, or triggering a synth note—without needing the complex step-sequencing features of Tone.Sequence or Tone.Pattern.

Controlling the Playback Interval

You control the playback interval of a Tone.Loop using its interval property. This property defines how often the loop’s callback function is executed.

1. Setting the Interval on Creation

When instantiating a Tone.Loop, you pass the callback function as the first argument and the playback interval as the second argument. The interval can be defined in musical notation (like "4n" for quarter notes or "8n" for eighth notes), seconds, or ticks.

// Create a loop that triggers a synth note every quarter note
const loop = new Tone.Loop((time) => {
    synth.triggerAttackRelease("C4", "8n", time);
}, "4n");

2. Changing the Interval Dynamically

You can read or update the loop’s playback speed at any time by modifying the .interval property directly. This change can be applied even while the loop is actively playing.

// Change the playback interval to eighth notes
loop.interval = "8n";

// Change the playback interval to every 0.5 seconds
loop.interval = 0.5;

3. Starting and Stopping the Loop

To hear the loop, you must start both the loop itself and the global Tone.Transport.

// Start the loop at the beginning of the Transport timeline
loop.start(0);

// Start the Transport to begin audio playback
Tone.Transport.start();

By leveraging Tone.Loop and adjusting its interval property, you can easily create dynamic, tempo-synced rhythmic patterns in your web audio applications.