Create a Synthesizer with Tone.Synth in Tone.js

In this guide, you will learn how to build a basic web-based synthesizer using the Tone.Synth class in Tone.js. We will cover importing the library, initializing the synthesizer, triggering musical notes, and customizing the sound output using envelope and oscillator settings.

Setting Up Tone.js

To start using Tone.js, you need to include the library in your HTML file. You can load it directly via a CDN link.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Tone.js Synth</title>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/tone/14.8.49/Tone.js"></script>
</head>
<body>
    <button id="play-button">Play Note</button>
    <script>
        // JavaScript goes here
    </script>
</body>
</html>

Initializing Tone.Synth

The Tone.Synth object consists of a monophonic synthesizer made of one oscillator and an amplitude envelope. To hear sound, you must instantiate the synth and connect it to the master output (Tone.Destination).

const synth = new Tone.Synth().toDestination();

Triggering a Note

Modern web browsers block audio from playing automatically. You must trigger audio after a user interaction, such as clicking a button.

To play a note, use the triggerAttackRelease method. This method takes three primary arguments: 1. Note: The pitch of the note (e.g., "C4" for middle C). 2. Duration: How long the note should play (e.g., "8n" for an eighth note, "4n" for a quarter note). 3. Time (optional): When the note should start playing.

const button = document.getElementById("play-button");

button.addEventListener("click", async () => {
    // Start the audio context if it hasn't started yet
    await Tone.start();
    
    // Play a middle C for the duration of an eighth note
    synth.triggerAttackRelease("C4", "8n");
});

Customizing the Synthesizer

You can alter the character of the sound by passing configuration options into the Tone.Synth constructor. This allows you to change the oscillator type and adjust the ADSR (Attack, Decay, Sustain, Release) envelope.

const customizedSynth = new Tone.Synth({
    oscillator: {
        type: "sine" // Options: "sine", "square", "triangle", "sawtooth"
    },
    envelope: {
        attack: 0.1,  // Time to reach maximum volume (seconds)
        decay: 0.2,   // Time to transition to sustain level
        sustain: 0.5, // Volume level maintained while holding the note (0 to 1)
        release: 1.0  // Time it takes for the sound to fade out after release
    }
}).toDestination();

Complete Code Example

Below is a complete, working HTML example that initializes a customized synthesizer and plays a note when a button is clicked.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Tone.js Synthesizer</title>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/tone/14.8.49/Tone.js"></script>
</head>
<body>
    <button id="play-button" style="padding: 10px 20px; font-size: 16px;">Play Synth</button>

    <script>
        // Configure and initialize the synth
        const synth = new Tone.Synth({
            oscillator: {
                type: "triangle"
            },
            envelope: {
                attack: 0.05,
                decay: 0.1,
                sustain: 0.3,
                release: 1
            }
        }).toDestination();

        const button = document.getElementById("play-button");

        button.addEventListener("click", async () => {
            // Ensure the AudioContext is running
            await Tone.start();
            
            // Play an E4 note for a quarter note duration
            synth.triggerAttackRelease("E4", "4n");
        });
    </script>
</body>
</html>