Table of Contents
Initial version From Google AI Mode
To create a web page that allows users to select an audio clip and apply different impulse convolutions (reverb effects), you can use the Web Audio API. This API provides a ConvolverNode specifically designed to simulate acoustic spaces by processing an audio source with an impulse response (IR) file.
Core Components
- AudioContext: The environment where all audio processing happens.
- AudioBufferSourceNode: Loads and plays your selected audio clip.
- ConvolverNode: Applies the mathematical convolution of the IR to the audio.
- GainNode: Controls the “wet” (effect) and “dry” (original) signal levels.
Implementation Guide
You can build this using a simple HTML structure with a <select> dropdown for both your audio clips and your impulse responses.
1. HTML Structure
Create a simple interface with dropdowns and a play button.
<label for="audioSelect">Choose Audio Clip:</label>
<select id="audioSelect">
<option value="drums.wav">Drum Loop</option>
<option value="vocals.wav">Vocals</option>
</select>
<label for="irSelect">Choose Impulse Response:</label>
<select id="irSelect">
<option value="hall.wav">Large Hall</option>
<option value="room.wav">Small Room</option>
<option value="plate.wav">Plate Reverb</option>
</select>
<button id="playBtn">Play with Effect</button>
2. JavaScript Logic
The script handles fetching the audio files as ArrayBuffers, decoding them into AudioBuffers, and routing them through the ConvolverNode.
const audioCtx = new (window.AudioContext || window.webkitAudioContext)();
let convolver = audioCtx.createConvolver();
async function getBuffer(url) {
const response = await fetch(url);
const arrayBuffer = await response.arrayBuffer();
return await audioCtx.decodeAudioData(arrayBuffer);
}
async function playAudio() {
// Resume context for browser security
if (audioCtx.state === 'suspended') await audioCtx.resume();
// Load selected files
const audioFile = document.getElementById('audioSelect').value;
const irFile = document.getElementById('irSelect').value;
const source = audioCtx.createBufferSource();
source.buffer = await getBuffer(audioFile);
convolver.buffer = await getBuffer(irFile);
// Route: Source -> Convolver -> Destination (Speakers)
source.connect(convolver);
convolver.connect(audioCtx.destination);
source.start();
}
document.getElementById('playBtn').addEventListener('click', playAudio);
Key Considerations
- Impulse Response Source: You can find free IR files on sites like Reverb.js.
- Normalization: By default, the
convolver.normalizeproperty istrue, which helps maintain consistent volume regardless of the IR file’s gain. - Dry/Wet Mix: To allow users to adjust the intensity, connect the source to both the destination (Dry) and the convolver (Wet) using separate
GainNodes.
Would you like a more advanced version that includes a visual waveform display or real-time dry/wet sliders?
Refinement – generate html and js for a web page to select an audio clip to play through a selected impulse
Used prompt to Gemini “generate html and js for a web page to select an audio clip to play through a selected impulse”
Response as follows…
To create a web page that performs impulse response convolution, you can use the Web Audio API. This involves loading two audio files: your “dry” source (the clip) and your “impulse” (the acoustic fingerprint of a space).
Below is a clean, functional implementation based on the concepts discussed in the Composers Inside Electronics (CIE) documentation.
1. HTML Structure
This setup provides dropdowns for your files and a master “Play” button. Note that for this to work, your audio files must be hosted on the same server or a server with CORS enabled.
HTML
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Audio Convolution Lab</title>
<style>
body { font-family: sans-serif; padding: 20px; line-height: 1.6; }
.control-group { margin-bottom: 15px; }
label { display: block; font-weight: bold; }
button { padding: 10px 20px; cursor: pointer; background: #007bff; color: white; border: none; border-radius: 4px; }
</style>
</head>
<body>
<h2>Convolution Reverb Player</h2>
<div class="control-group">
<label for="audioSelect">Source Audio:</label>
<select id="audioSelect">
<option value="drums.wav">Drum Loop</option>
<option value="vocals.wav">Vocals</option>
</select>
</div>
<div class="control-group">
<label for="irSelect">Impulse Response (Space):</label>
<select id="irSelect">
<option value="hall.wav">Large Concert Hall</option>
<option value="cathedral.wav">Cathedral</option>
<option value="plate.wav">Vintage Plate</option>
</select>
</div>
<button id="playBtn">Play with Effect</button>
<script src="app.js"></script>
</body>
</html>
2. JavaScript Logic (app.js)
This script handles the asynchronous loading of audio data and the routing of the ConvolverNode.
JavaScript
const audioCtx = new (window.AudioContext || window.webkitAudioContext)();
let currentSource = null;
// Helper function to fetch and decode audio files
async function getBuffer(url) {
const response = await fetch(url);
const arrayBuffer = await response.arrayBuffer();
return await audioCtx.decodeAudioData(arrayBuffer);
}
async function playAudio() {
// Stop previous playback if it exists
if (currentSource) {
currentSource.stop();
}
// Resume context (required by browsers for user-initiated audio)
if (audioCtx.state === 'suspended') {
await audioCtx.resume();
}
// 1. Get selected file paths
const audioFile = document.getElementById('audioSelect').value;
const irFile = document.getElementById('irSelect').value;
// 2. Load buffers
const sourceBuffer = await getBuffer(audioFile);
const impulseBuffer = await getBuffer(irFile);
// 3. Create Nodes
const source = audioCtx.createBufferSource();
const convolver = audioCtx.createConvolver();
source.buffer = sourceBuffer;
convolver.buffer = impulseBuffer;
// 4. Routing: Source -> Convolver -> Speakers
source.connect(convolver);
convolver.connect(audioCtx.destination);
// 5. Start playback
source.start();
currentSource = source;
}
document.getElementById('playBtn').addEventListener('click', playAudio);
Key Technical Details
- ConvolverNode: This is the heart of the effect. It performs a mathematical operation called convolution, which multiplies the input signal by the impulse response in the time domain.
- Impulse Response (IR): Ensure your IR files are short, high-quality
.wavor.aiffiles. Long IRs (like 10-second cathedrals) require more CPU processing. - Dry/Wet Mix: To hear the original sound mixed with the reverb, you would typically add a GainNode for the “Dry” signal (Source -> Destination) and another for the “Wet” signal (Source -> Convolver -> Destination).
- Normalization: By default,
convolver.normalizeis set totrue, which attempts to prevent the volume from exploding when applying dense reverbs.
How to Run
The initial version just has the first “drums” and “hall” file.
Local for debugging and development
Files in ~/Dropbox/PY/CONVOLVER_PAGE
app.js
convolver.html
drums.wav
hall.wav
From terminal “sh”…
python -m http.server 8000
http://localhost:8000/convolver.html
From browser over internet
Uploaded to the domain documents folder and invoked via browser over the net
https://composers-inside-electronics.net/documents/convolver.html
Static snapshot

and as live iframe … just click “Play with Effect” button
