Three.js From Zero · Article s9-01
S9-01 Web Audio Basics
Season 9 · Article 01
Web Audio Basics
The browser ships a modular synthesizer. AudioContext as the motherboard. Nodes (oscillator, filter, gain, delay, analyzer) plug into each other. Output the graph to speakers.
1. The graph
const ctx = new AudioContext();
// Oscillator (source)
const osc = ctx.createOscillator();
osc.type = 'sawtooth';
osc.frequency.value = 220;
// Gain (volume)
const gain = ctx.createGain();
gain.gain.value = 0.3;
// Connect: osc → gain → speakers
osc.connect(gain).connect(ctx.destination);
osc.start();
2. Main node types
OscillatorNode: sine, square, sawtooth, triangle, custom.GainNode: volume / amplitude envelope.BiquadFilterNode: lowpass, highpass, bandpass, notch…DelayNode: echo.ConvolverNode: reverb (S9-04).AudioBufferSourceNode: play a recorded sample.AnalyserNode: FFT output for visuals (S9-03).PannerNode: 3D spatial position (S9-02).AudioWorkletNode: custom DSP in an audio thread.
3. AudioParam scheduling
Every parameter can be scheduled with sample accuracy:
// ADSR envelope
gain.gain.setValueAtTime(0, ctx.currentTime);
gain.gain.linearRampToValueAtTime(1.0, ctx.currentTime + 0.01); // Attack
gain.gain.linearRampToValueAtTime(0.7, ctx.currentTime + 0.1); // Decay
// Sustain...
gain.gain.linearRampToValueAtTime(0, ctx.currentTime + 0.5); // Release
4. User gesture requirement
// Must start audio context in response to a click/tap/keydown
button.addEventListener('click', async () => {
if (ctx.state === 'suspended') await ctx.resume();
});
Browser policy: no audio until user interacts. Prevents ad autoplay spam.
5. Live demo — play with a synth
6. The graph pattern
Any synth is: sources → effects → master → destination. Copy and extend.
osc -> filter -> envelope (gain) -> delay ↴
\
master ← direct ↲
|
destination
7. WebAudio in Three.js
const listener = new THREE.AudioListener();
camera.add(listener);
const sound = new THREE.Audio(listener);
const loader = new THREE.AudioLoader();
loader.load('ambient.ogg', buf => {
sound.setBuffer(buf);
sound.setLoop(true);
sound.setVolume(0.5);
sound.play();
});
Three.js wraps Web Audio. AudioListener is attached to camera (your "ears"). Audio (non-positional) and PositionalAudio (spatial, S9-02).
8. Takeaways
- AudioContext is the root. Nodes are modules. Connect to build.
- OscillatorNode + GainNode + BiquadFilter = subtractive synth.
- AudioParam scheduling gives sample-accurate envelopes.
- Must start context on user gesture.
- Three.js AudioListener + Audio wrap Web Audio for scene use.