Load External Audio from CORS URL in Tone.js

Loading external audio files into Tone.js from a different domain requires proper Cross-Origin Resource Sharing (CORS) configuration. This article provides a straightforward guide on how to configure and load external audio assets using Tone.js Player and ToneAudioBuffer when dealing with CORS-enabled URLs.

Understanding CORS in Tone.js

Tone.js relies on the browser’s native fetch API and Web Audio API to retrieve and decode audio files. When you attempt to load an audio file from a domain different from the one hosting your website, the browser enforces the Same-Origin Policy.

To successfully load the audio, two conditions must be met: 1. The external server hosting the audio file must send the Access-Control-Allow-Origin header in its response. 2. Tone.js must request the resource using standard CORS mode, which it does by default when fetching assets.

Loading Audio using Tone.Player

You can load an external CORS-enabled audio file directly by passing its URL to a Tone.Player instance.

Here is a clean implementation:

// Ensure the audio context is started after a user interaction
document.querySelector('button').addEventListener('click', async () => {
    await Tone.start();
    
    // URL of the CORS-enabled external audio file
    const externalAudioUrl = "https://example-cors-enabled-site.com/audio.mp3";

    // Create the player and load the external file
    const player = new Tone.Player({
        url: externalAudioUrl,
        onload: () => {
            console.log("Audio loaded successfully.");
            player.start();
        },
        onerror: (error) => {
            console.error("Error loading audio file:", error);
        }
    }).toDestination();
});

Loading Audio using Tone.ToneAudioBuffer

If you want to load the audio buffer separately before assigning it to a player or an instrument, you can use Tone.ToneAudioBuffer.

const externalAudioUrl = "https://example-cors-enabled-site.com/audio.mp3";

const buffer = new Tone.ToneAudioBuffer(externalAudioUrl, () => {
    console.log("Buffer loaded.");
    
    // Assign the loaded buffer to a player
    const player = new Tone.Player(buffer).toDestination();
    player.start();
}, (error) => {
    console.error("Failed to load buffer:", error);
});

Troubleshooting Common Issues