How to Mute Tracks with Tone.Transport in Tone.js
This article explains how to mute and unmute specific audio tracks in
Tone.js by combining track-level volume controls with the timing
capabilities of Tone.Transport. You will learn how to set
up individual audio channels, control their mute states, and schedule
mute/unmute events to happen automatically at specific points along the
playback timeline.
Understanding Tone.Transport and Audio Tracks
In Tone.js, Tone.Transport acts as the master timeline
and sequencer, governing playback, tempo, and scheduling. It does not
handle audio routing directly. To mute or unmute specific tracks, you
must route your sound sources (like synthesizers or players) through
individual Tone.Channel nodes. You can then manipulate the
mute property of these channels, either in real-time or by
scheduling the actions on the Tone.Transport timeline.
Step 1: Set Up Your Tracks Using Tone.Channel
To control individual tracks, route each audio source through its own
Tone.Channel.
// Create audio sources
const synthTrack = new Tone.Synth().toDestination();
const drumTrack = new Tone.Player("drums.wav");
// Create channels for independent control
const synthChannel = new Tone.Channel().toDestination();
const drumChannel = new Tone.Channel().toDestination();
// Connect the sources to their respective channels
synthTrack.connect(synthChannel);
drumTrack.connect(drumChannel);Step 2: Manually Muting and Unmuting Tracks
Each Tone.Channel has a boolean mute
property. You can toggle this property at any time during playback to
instantly mute or unmute the track.
// Mute the drum track
drumChannel.mute = true;
// Unmute the drum track
drumChannel.mute = false;Step 3: Scheduling Mute and Unmute Events with Tone.Transport
To automate the muting and unmuting of tracks at precise times during
playback, use Tone.Transport.schedule(). This method allows
you to queue state changes at specific measures, beats, or seconds.
// Start the transport
Tone.Transport.start();
// Schedule the drum track to mute at the beginning of measure 4
Tone.Transport.schedule((time) => {
// Draw changes on the next animation frame for UI synchronization if needed
Tone.Draw.schedule(() => {
drumChannel.mute = true;
console.log("Drums muted at measure 4");
}, time);
}, "4:0:0");
// Schedule the drum track to unmute at the beginning of measure 8
Tone.Transport.schedule((time) => {
Tone.Draw.schedule(() => {
drumChannel.mute = false;
console.log("Drums unmuted at measure 8");
}, time);
}, "8:0:0");Step 4: Toggling Mute via User Interaction
If you want to allow users to mute or unmute tracks interactively
while Tone.Transport is running, bind the channel’s
mute property directly to a button event listener:
const muteButton = document.getElementById("mute-drums-btn");
muteButton.addEventListener("click", () => {
// Toggle the mute state
drumChannel.mute = !drumChannel.mute;
// Update button text to reflect current state
muteButton.innerText = drumChannel.mute ? "Unmute Drums" : "Mute Drums";
});