How to Create Procedural Audio Effects in JavaScript With Web Audio API
Procedural audio refers to sound that is generated algorithmically rather than being pre-recorded. Using the Web Audio API, you can create dynamic, interactive, and adaptable soundscapes directly in the browser — ideal for games, web-based instruments, and educational tools. This article dives deeper into how to use JavaScript and the Web Audio API to build custom audio effects programmatically. 1. Creating an Audio Context Everything starts with an AudioContext, which manages all audio operations: const audioCtx = new (window.AudioContext || window.webkitAudioContext)(); 2. Crafting a Custom Noise Generator White noise can be generated by filling an audio buffer with random values: function createWhiteNoise(ctx) { const bufferSize = 2 * ctx.sampleRate; const buffer = ctx.createBuffer(1, bufferSize, ctx.sampleRate); const output = buffer.getChannelData(0); for (let i = 0; i < bufferSize; i++) { output[i] = Math.random() * 2 - 1; } const whiteNoise = ctx.createBufferSource(); whiteNoise.buffer = buffer; whiteNoise.loop = true; return whiteNoise; } const noise = createWhiteNoise(audioCtx); noise.connect(audioCtx.destination); noise.start(); 3. Dynamic Filtered Effects (e.g., Wind or Water) Use a bandpass filter to shape noise into something resembling wind or water: const filter = audioCtx.createBiquadFilter(); filter.type = "bandpass"; filter.frequency.value = 1000; filter.Q.value = 10; noise.connect(filter); filter.connect(audioCtx.destination); 4. Procedural Tone Generator With Frequency Modulation You can modulate frequency with another oscillator to create evolving tones: const carrier = audioCtx.createOscillator(); const modulator = audioCtx.createOscillator(); const modulationGain = audioCtx.createGain(); modulator.frequency.value = 4; // Hz modulationGain.gain.value = 50; modulator.connect(modulationGain); modulationGain.connect(carrier.frequency); carrier.type = 'sawtooth'; carrier.frequency.value = 440; carrier.connect(audioCtx.destination); modulator.start(); carrier.start(); 5. Real-Time Envelope Shaping Create natural-sounding note dynamics using GainNode automation: function playEnvelope(freq = 440) { const osc = audioCtx.createOscillator(); const gain = audioCtx.createGain(); osc.type = 'triangle'; osc.frequency.value = freq; gain.gain.setValueAtTime(0, audioCtx.currentTime); gain.gain.linearRampToValueAtTime(0.6, audioCtx.currentTime + 0.1); // attack gain.gain.exponentialRampToValueAtTime(0.001, audioCtx.currentTime + 1); // decay osc.connect(gain); gain.connect(audioCtx.destination); osc.start(); osc.stop(audioCtx.currentTime + 1); } document.body.innerHTML += 'Play Note'; 6. Putting It All Together Now you can combine noise, oscillators, filters, and envelopes to create custom sound effects like lasers, explosions, or weather systems — fully generated in the browser! Conclusion Procedural audio is a powerful concept, and the Web Audio API puts it at your fingertips. With practice, you can build fully interactive soundscapes that respond to user behavior or system events, opening the door to immersive web experiences. If this post helped you, consider supporting me here: buymeacoffee.com/hexshift
Procedural audio refers to sound that is generated algorithmically rather than being pre-recorded. Using the Web Audio API, you can create dynamic, interactive, and adaptable soundscapes directly in the browser — ideal for games, web-based instruments, and educational tools. This article dives deeper into how to use JavaScript and the Web Audio API to build custom audio effects programmatically.
1. Creating an Audio Context
Everything starts with an AudioContext
, which manages all audio operations:
const audioCtx = new (window.AudioContext || window.webkitAudioContext)();
2. Crafting a Custom Noise Generator
White noise can be generated by filling an audio buffer with random values:
function createWhiteNoise(ctx) {
const bufferSize = 2 * ctx.sampleRate;
const buffer = ctx.createBuffer(1, bufferSize, ctx.sampleRate);
const output = buffer.getChannelData(0);
for (let i = 0; i < bufferSize; i++) {
output[i] = Math.random() * 2 - 1;
}
const whiteNoise = ctx.createBufferSource();
whiteNoise.buffer = buffer;
whiteNoise.loop = true;
return whiteNoise;
}
const noise = createWhiteNoise(audioCtx);
noise.connect(audioCtx.destination);
noise.start();
3. Dynamic Filtered Effects (e.g., Wind or Water)
Use a bandpass filter to shape noise into something resembling wind or water:
const filter = audioCtx.createBiquadFilter();
filter.type = "bandpass";
filter.frequency.value = 1000;
filter.Q.value = 10;
noise.connect(filter);
filter.connect(audioCtx.destination);
4. Procedural Tone Generator With Frequency Modulation
You can modulate frequency with another oscillator to create evolving tones:
const carrier = audioCtx.createOscillator();
const modulator = audioCtx.createOscillator();
const modulationGain = audioCtx.createGain();
modulator.frequency.value = 4; // Hz
modulationGain.gain.value = 50;
modulator.connect(modulationGain);
modulationGain.connect(carrier.frequency);
carrier.type = 'sawtooth';
carrier.frequency.value = 440;
carrier.connect(audioCtx.destination);
modulator.start();
carrier.start();
5. Real-Time Envelope Shaping
Create natural-sounding note dynamics using GainNode automation:
function playEnvelope(freq = 440) {
const osc = audioCtx.createOscillator();
const gain = audioCtx.createGain();
osc.type = 'triangle';
osc.frequency.value = freq;
gain.gain.setValueAtTime(0, audioCtx.currentTime);
gain.gain.linearRampToValueAtTime(0.6, audioCtx.currentTime + 0.1); // attack
gain.gain.exponentialRampToValueAtTime(0.001, audioCtx.currentTime + 1); // decay
osc.connect(gain);
gain.connect(audioCtx.destination);
osc.start();
osc.stop(audioCtx.currentTime + 1);
}
document.body.innerHTML += '';
6. Putting It All Together
Now you can combine noise, oscillators, filters, and envelopes to create custom sound effects like lasers, explosions, or weather systems — fully generated in the browser!
Conclusion
Procedural audio is a powerful concept, and the Web Audio API puts it at your fingertips. With practice, you can build fully interactive soundscapes that respond to user behavior or system events, opening the door to immersive web experiences.
If this post helped you, consider supporting me here: buymeacoffee.com/hexshift