Access Web Audio API AudioContext from Tone.js

Tone.js is a powerful framework built on top of the Web Audio API, but sometimes you need to bypass its abstractions to work directly with the browser’s native audio engine. This article explains how to access the underlying raw AudioContext in Tone.js, retrieve native audio nodes, and safely integrate raw Web Audio API components with your Tone.js graph.

Accessing the Raw AudioContext

In modern versions of Tone.js (v14+), the global Tone.context is a wrapped version of the browser’s native AudioContext. To access the raw, native AudioContext object, you must target the rawContext property of the Tone.js context wrapper.

You can access it using the following code:

import * as Tone from "tone";

// Ensure the context is started (usually triggered by a user interaction)
await Tone.start();

// Access the raw Web Audio API AudioContext
const rawContext = Tone.context.rawContext;

console.log(rawContext); // Outputs: AudioContext {...}

Once you have the rawContext, you can use any native Web Audio API methods, such as createOscillator(), createGain(), or createBiquadFilter().

Creating and Manipulating Native Nodes

With the raw context in hand, you can instantiate native Web Audio API nodes directly. This is useful when you want to use custom Web Audio utilities, third-party library nodes, or audio worklets that are not natively supported by Tone.js wrappers.

// Create a native GainNode using the raw context
const nativeGain = rawContext.createGain();
nativeGain.gain.setValueAtTime(0.5, rawContext.currentTime);

Connecting Native Nodes to Tone.js

To make your native Web Audio nodes interact with your Tone.js setup, you need to connect them. Tone.js nodes and native nodes can be connected in both directions.

Connecting a Tone.js Node to a Native Node

Tone.js nodes are designed to connect directly to native Web Audio AudioNode objects using the standard .connect() method.

const synth = new Tone.Synth().toDestination();
const nativeDelay = rawContext.createDelay();

// Connect the Tone.js Synth directly to the native Web Audio Delay node
synth.connect(nativeDelay);

// Connect the native Delay node to the Tone.js destination
nativeDelay.connect(Tone.Destination.input);

Connecting a Native Node to a Tone.js Node

To connect a native Web Audio node into a Tone.js node, you must connect the native node to the Tone.js node’s .input property. Tone.js components wrap native nodes, and the .input property exposes the entry point of that specific wrapper.

const nativeOscillator = rawContext.createOscillator();
const toneFilter = new Tone.Filter(1000, "lowpass").toDestination();

// Connect native node to the input of the Tone.js node
nativeOscillator.connect(toneFilter.input);

// Start the native oscillator
nativeOscillator.start();