How to Release a Sustained Note in Tone.js
Controlling the duration of notes is fundamental to creating dynamic
web audio applications. This guide explains how to programmatically
trigger and release sustained notes in Tone.js using the
triggerAttack and triggerRelease methods,
allowing you to sustain sounds indefinitely until an event, such as a
user interaction, stops them.
To sustain a note indefinitely, you must split the synthesizer’s
activation into two distinct phases: triggering the attack to start the
sound, and triggering the release to stop it. This is different from the
common triggerAttackRelease() method, which automatically
schedules a release after a predefined duration.
Step 1: Initializing the Synthesizer
First, create an instance of a synthesizer (such as
Tone.Synth) and connect it to the master output.
import * as Tone from 'tone';
const synth = new Tone.Synth().toDestination();Step 2: Triggering the Sustained Note
To start playing a note and keep it sustaining, use the
triggerAttack method. This triggers the attack and decay
portion of the ADSR envelope, holding the sound at the sustain
level.
// Start playing a C4 note indefinitely
synth.triggerAttack("C4");Step 3: Programmatically Releasing the Note
To stop the sustained note, call the triggerRelease
method. This triggers the release phase of the envelope, fading the
sound out to silence.
// Stop the currently playing note
synth.triggerRelease();Handling Multiple Notes (PolySynth)
If you are using Tone.PolySynth to play chords, you must
specify which pitch to release so the synthesizer knows which active
note to stop.
const polySynth = new Tone.PolySynth().toDestination();
// Play a C major chord
polySynth.triggerAttack(["C4", "E4", "G4"]);
// Release only the E4 note programmatically
polySynth.triggerRelease(["E4"]);
// Release the remaining notes later
polySynth.triggerRelease(["C4", "G4"]);Interactive Example (Keyboard / Mouse Events)
In real-world applications, you will often want to bind these methods to user interface events, such as pointer down and pointer up actions on a virtual piano key.
const playButton = document.getElementById("play-button");
// Start note when the button is pressed
playButton.addEventListener("mousedown", () => {
Tone.start(); // Ensure AudioContext is resumed
synth.triggerAttack("A4");
});
// Release note when the button is released
playButton.addEventListener("mouseup", () => {
synth.triggerRelease();
});