How to Use Tone.js Analyser for Audio Visualization
This article provides a comprehensive guide on using
Tone.Analyser in Tone.js to extract real-time frequency
data for audio visualizers. You will learn what the Analyser node is,
how to configure it within your audio graph, and how to retrieve and
format frequency data to create dynamic, real-time visual displays.
What is Tone.Analyser?
Tone.Analyser is a node in the Tone.js framework that
acts as a bridge to the Web Audio API’s native
AnalyserNode. It allows you to analyze the audio signal
passing through it in real-time without altering the sound output.
The analyser can extract two main types of data: * FFT (Fast Fourier Transform): Splits the audio signal into its individual frequency components (bass, mids, treble). This is ideal for creating frequency bar visualizers. * Waveform: Captures the amplitude of the audio signal over time. This is ideal for creating oscilloscope-style visualizers.
Setting Up Tone.Analyser
To analyze audio, you must route your audio source through the
Tone.Analyser node before sending it to the speakers
(Tone.Destination).
Here is how to initialize and connect an analyser:
// Create an analyser of type "fft" with a buffer size of 256
const analyser = new Tone.Analyser("fft", 256);
// Create a sound source (e.g., a synth)
const synth = new Tone.Synth().toDestination();
// Connect the synth to the analyser
synth.connect(analyser);Key Parameters:
- Type: Can be
"fft"or"waveform". To retrieve frequency data, use"fft". - Size: The FFT size must be a power of two (e.g., 32, 64, 128, 256, 512, 1024). It determines the frequency resolution. A higher number provides more detailed frequency bins but requires more processing power.
Retrieving Frequency Data
To get the frequency data at any given moment, call the
.getValue() method on the analyser. This returns a
Float32Array containing decibel values for each frequency
bin. The values typically range from -140 dB (silence) to
0 dB (maximum volume).
const frequencyData = analyser.getValue();
console.log(frequencyData);
// Output: Float32Array representing amplitude levels at different frequenciesCreating a Real-Time Visualizer Loop
To build a continuous visualization, you must query the frequency
data repeatedly using a render loop. The standard web API for this is
requestAnimationFrame.
Below is a complete implementation showing how to fetch frequency data and map it to a visual display, such as an HTML5 Canvas:
const canvas = document.getElementById("visualizer");
const ctx = canvas.getContext("2d");
function draw() {
// Schedule the next update
requestAnimationFrame(draw);
// Retrieve the current frequency data array
const data = analyser.getValue();
// Clear the canvas for the new frame
ctx.clearRect(0, 0, canvas.width, canvas.height);
const barWidth = canvas.width / data.length;
for (let i = 0; i < data.length; i++) {
// Convert dB value to a positive height scale
// e.g., mapping -140dB to 0dB into a height value
const dbValue = data[i];
const normalizedValue = Math.max(0, dbValue + 140);
const barHeight = (normalizedValue / 140) * canvas.height;
const x = i * barWidth;
const y = canvas.height - barHeight;
// Draw the frequency bar
ctx.fillStyle = `rgb(${barHeight + 100}, 50, 250)`;
ctx.fillRect(x, y, barWidth - 1, barHeight);
}
}
// Start the loop
draw();By connecting any active Tone.js instrument or player to the
analyser, the Float32Array values will dynamically change
with the music, providing the exact data needed to power your custom
visualizers.