The modern way
The Web Audio API uses the AudioContext()
interface to manage sources, filters, and destinations. Once you’ve created a new AudioContext()
, create an audio source node, like an AudioBufferSourceNode
or OscillatorNode
. As an example, consider a basic oscillator with a low pass filter applied.
Using the createBiquadFilter()
method
First, create a new AudioContext()
. Then create an audio source node, like an AudioBufferSourceNode
or OscillatorNode
. You'll create a sine
oscillator node, for this example, which has a frequency of 420 hertz from the moment it starts playing.
const audioCtx = new (window.AudioContext || window.webkitAudioContext)();
const oscillator = audioCtx.createOscillator()
oscillator.type = 'sine';
// Value is in hertz.
oscillator.frequency.setValueAtTime(420, audioCtx.currentTime);
Next, create an effect node using createBiquadFilter()
. Set the type to lowpass
and the frequency to start one second after the start of playback. Then connect the biquadFilter
to the oscillator
.
const biquadFilter = audioCtx.createBiquadFilter();
biquadFilter.type = 'lowpass';
biquadFilter.frequency.setValueAtTime(200, audioCtx.currentTime + 1);
oscillator.connect(biquadFilter);
Finally connect the biquadFilter
to the destination of the audioCtx
, before starting the oscillator
and stopping it after two seconds of playback.
biquadFilter.connect(audioCtx.destination);
oscillator.start();
oscillator.stop(2);
The sound from the oscillator is passed through the unaffected filter, and on to the destination, which is your computer's speakers. After one second of playback, the lowpass
filter comes into effect. After two seconds, the oscillator is stopped.
Other available filters and effects
Other filter nodes can be added to an AudioContext
to create different effects:
createWaveShaper()
is used to add distortion to a source.createGain()
is used to boost the overall signal of the source it's applied to.createConvolver()
is most commonly used to add reverb to a source.createDelay()
is used to add delay to the start of a source.createDynamicsCompressor()
is used to raise the volume of the quietest part of a source, and lower the volume of the loudest parts.createPanner()
andcreateStereoPanner()
are used for changing the spatial position of sound output.
The classic way
Before the availability of the Web Audio API, there was no way to add effects to audio in the browser. Workarounds using server-side rendering and switching between streams are possible, but this can incur a lot of network overhead.
Using the audio element
The only audio effects that can be directly controlled are playback and volume.
const audio = document.querySelector('audio');
// Sets audio volume to 50%
audio.volume = 0.5;
// Doubles the playback rate.
audio.playbackRate = 2;
Further reading
Demo
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link
rel="icon"
href="data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 100 100%22><text y=%22.9em%22 font-size=%2290%22>🔉</text></svg>"
/>
<title>How to add effects to audio</title>
</head>
<body>
<h1>How to add effects to audio</h1>
<button type="button">Press to hear audio effect</button>
</body>
</html>
:root {
color-scheme: dark light;
}
html {
box-sizing: border-box;
}
*,
*:before,
*:after {
box-sizing: inherit;
}
body {
margin: 1rem;
font-family: system-ui, sans-serif;
}
const button = document.querySelector('button');
button.addEventListener('click', () => {
const audioCtx = new (window.AudioContext || window.webkitAudioContext)();
const oscillator = audioCtx.createOscillator();
oscillator.type = 'sine';
// Value is in hertz.
oscillator.frequency.setValueAtTime(420, audioCtx.currentTime);
const biquadFilter = audioCtx.createBiquadFilter();
biquadFilter.type = 'lowpass';
biquadFilter.frequency.setValueAtTime(200, audioCtx.currentTime + 1);
oscillator.connect(biquadFilter);
biquadFilter.connect(audioCtx.destination);
oscillator.start();
oscillator.stop(2);
});