Monitor Real-Time Audio Levels Using Tone.Meter
In web audio development, visualizing volume levels is essential for
creating interactive and responsive applications. This article provides
a straightforward guide on how to monitor real-time audio levels using
the Tone.Meter class in Tone.js. You will learn how to set
up the audio context, connect an audio source to a meter, and retrieve
decibel values to create visual level indicators.
Understanding Tone.Meter
Tone.Meter is a utility node in Tone.js that measures
the volume of the audio signal passing through it. By default, it
calculates the Root Mean Square (RMS) of the input signal and returns
the value in decibels (dB). The values typically range from
-Infinity (complete silence) to 0 (maximum
volume before clipping).
Step-by-Step Implementation
To monitor audio levels, you need to create an audio source, connect
it to a Tone.Meter instance, and continuously read the
meter’s value using a loop.
1. Initialize Tone.js and Create the Nodes
First, set up your audio source (such as an oscillator, player, or
microphone input) and instantiate the Tone.Meter.
import * as Tone from 'tone';
// Create an audio source (e.g., a sine wave oscillator)
const oscillator = new Tone.Oscillator(440, "sine");
// Create the meter instance
const meter = new Tone.Meter();2. Connect the Audio Graph
To monitor the audio without blocking it from reaching the speakers,
connect the source to the meter, and then connect the meter to the
master output (toDestination).
// Connect the oscillator to the meter
oscillator.connect(meter);
// Connect the meter to the speakers so we can hear it
meter.toDestination();3. Read Values in Real-Time
To get real-time feedback, retrieve the meter values inside a
recursive loop using requestAnimationFrame. This matches
the refresh rate of the user’s browser for smooth animations.
function updateMeter() {
// Get the current decibel level
const db = meter.getValue();
// Convert decibels to a normalized range between 0 and 1
const level = Tone.dbToGain(db);
// Output the values (or use them to update a UI element)
console.log(`Volume: ${db.toFixed(2)} dB (Normalized: ${level.toFixed(2)})`);
// Request the next frame
requestAnimationFrame(updateMeter);
}4. Trigger Audio on User Interaction
Modern browsers require a user gesture to start the Web Audio API context. Bind the startup logic to a button click.
const startButton = document.getElementById('start-btn');
startButton.addEventListener('click', async () => {
// Start the Tone.js audio context
await Tone.start();
// Start the oscillator
oscillator.start();
// Begin the monitoring loop
updateMeter();
});Customizing Meter Behavior
You can customize the responsiveness of the meter by adjusting the
smoothing property during initialization. The smoothing
value ranges from 0 (instant reaction) to 1
(highly smoothed transition).
const smoothMeter = new Tone.Meter({
smoothing: 0.8 // Default is 0.8
});