Load and Play Audio with Tone.Player in Tone.js

This guide explains how to load and play a single audio sample using the Tone.Player node in Tone.js, a powerful framework for creating interactive music in the browser. You will learn how to initialize the player with an audio file path, connect it to the audio output, and trigger the playback in response to user interaction to satisfy browser security policies.

Step 1: Include Tone.js in Your Project

First, ensure you have Tone.js included in your project. You can install it via npm or include it directly in your HTML file using a CDN:

<script src="https://cdnjs.cloudflare.com/ajax/libs/tone/14.8.49/Tone.js"></script>

Step 2: Create and Configure Tone.Player

The Tone.Player object is designed to load and play an audio buffer. To create one, pass the URL or local file path of your audio sample (such as an MP3 or WAV file) to the constructor and connect it to the master output using .toDestination().

// Create the player and connect it to the speakers
const player = new Tone.Player("https://tonejs.github.io/audio/drum-samples/handclap.mp3").toDestination();

Step 3: Handle the User Interaction and Play

Modern browsers prevent websites from playing audio automatically. You must trigger playback inside a user-initiated event, such as a button click. Additionally, you must resume the audio context using Tone.start() before the sound can be heard.

Here is a complete, minimal JavaScript implementation:

// Reference to a button in your HTML
const playButton = document.querySelector('#play-button');

playButton.addEventListener('click', async () => {
    // Start the Tone.js audio context on user gesture
    await Tone.start();
    
    // Ensure the audio sample is loaded before playing
    if (player.loaded) {
        player.start();
    } else {
        console.log("Audio is still loading. Please try again in a moment.");
    }
});

Step 4: Optional Configuration

Loop the Audio

If you want the sample to repeat continuously, set the loop property to true:

player.loop = true;
player.start();

Use a Callback

If you need to perform an action precisely when the audio file finishes loading, you can pass a callback function as the second argument to the constructor:

const player = new Tone.Player("sound.mp3", () => {
    console.log("Audio file loaded and ready to play!");
}).toDestination();