A lightweight, pure‑Python module that adds realistic reverberation to audio using convolution. Place your dry signal in any real‑world space captured by an impulse response (IR).
- Fast FFT convolution with NumPy – processes multi‑second files in seconds.
- True stereo reverb – four convolutions (L→L, L→R, R→L, R→R) for natural spatial imaging.
- Handles mono/stereo inputs (always returns stereo).
- Simple dry/wet mix + automatic normalization to prevent clipping.
- Works with standard library – only NumPy is required.
- Python 3.13+
pip install -r requirements.txt
- Download
conv_reverb.pyinto your project folder. - Now You can use it in your projects.
from conv_reverb import convolve_reverb
import numpy as np
import wave, array
# Load audio (16‑bit PCM WAV)
def load_wav(file):
with wave.open(file, 'rb') as wf:
ch, sw, fs, frames, _, _ = wf.getparams()
if sw != 2: raise ValueError("Only 16‑bit PCM supported.")
audio = array.array('h', wf.readframes(frames))
audio = np.array(audio, dtype=np.float32) / 32768.0
return audio.reshape(-1, 2) if ch == 2 else audio, fs
# Load your dry signal and an IR from the ir_rvbs folder
signal, fs_sig = load_wav("voice.wav")
ir, fs_ir = load_wav("ir_rvbs/cathedral_ir.wav")
if fs_sig != fs_ir:
print("Sample rates must match! Resample your IR first.")
exit(1)
# Apply reverb (subtle ambience)
output = convolve_reverb(signal, ir, wet=0.02, dry=1.0, normalize=True)
# Save result (always stereo)
def save_wav(file, audio, fs):
audio = np.clip(audio, -1.0, 1.0)
ints = (audio * 32767).astype(np.int16)
if audio.ndim == 2: ints = ints.flatten()
with wave.open(file, 'wb') as wf:
wf.setnchannels(2)
wf.setsampwidth(2)
wf.setframerate(fs)
wf.writeframes(array.array('h', ints.tobytes()))
save_wav("reverbed.wav", output, fs_sig)convolve_reverb(signal, ir, wet=0.5, dry=0.5, normalize=True, keep_length=True)| Parameter | Description |
|---|---|
signal, ir |
NumPy arrays: 1D (mono) or 2D (samples × channels). Must have same sample rate. |
wet, dry |
Mix levels (0.0–1.0). dry=1.0, wet=0.02 gives subtle ambience. |
normalize |
If True, scales output to peak ≤ 1.0 (recommended). |
keep_length |
If True, output length = input length; else full tail (longer). |
Returns: stereo array, shape (samples_out, 2).
- Find free IRs at OpenAIR or EchoThief.
- If your IR file is 41000, use
FFmpegto resample it:
ffmpeg -i ir.wav -ar 48000 ir_48k.wav. - place the
ir_48k.wavin the same directory as the module
Pull requests are welcome! Please open an issue first to discuss changes.
If you use this module in your work, please cite:
@misc{rabbitq8_conv_reverb_2026,
author = {Rabbit Q8},
title = {conv_reverb: A lightweight Python convolution reverb module},
year = {2026},
publisher = {GitHub},
howpublished = {\url{https://github.com/rabbitq8/Convolution-Reverb-for-Python}}
}MIT © Rabbit Q8