Convolution reverb (not reverberation) is a method of simulating reverberation. Basically, you apply (using a mathematical process called convolution) an impulse response to the recording you want to change. An impulse response is simply a recorded sonic impulse, or short sample of the response of a space to a loud sound: often they are made by firing a starter pistol in the location being sampled and recording until the echoes die out.
Convolution provides some of the most realistic reverberation effects available right now, but is a much slower algorithm than alternatives like comb filters and delay lines; it cannot be applied in realtime like some filters can: often, professionals will use specialized hardware to convolve their sounds
The most important decision to make when preparing to apply convolution to a piece is that of which impulse to use. The piece being processed will, ideally, acquire the flavor of the impulse. An impulse recorded in a large cathedral will be reverberant and booming, and an impulse recorded in a tin can will be small and, well, tinny.
The kind of convolution used in digital signal processing is discrete, meaning it operates on a finite number of points. If we were operating on actual continuous waves, we'd use the continuous convolution formula. (The '*' in this context is the symbol for convolution, not multiplication.)
Discrete Convolution:
Unfortunately, this takes a long, long time if your files are more than a few seconds long. This is because when performing convolution, you're multiplying and adding, at some points, thousands of points, thousands of times. Below you can see how complicated performing this type of convolution is on mere five and four element lists.
Step by Step Convolution
Thankfully, there's a better way to do this: instead of performing the operation in the time domain, we can perform a Fourier transform to get into the frequency domain where we can then multiply the spectra of the two sound files. One little caveat; we've got to ensure that the waves have the same number of samples in them: that is, their arrays are equal in length.
Once that's done (which is a simple, fast, linear operation), we can take the inverse Fourier transform of the result to get back into the time domain. This is how I created the reverb effect in my samples.
Convolution Theorem:
So now we've got an algorithmic way of performing convolution on two waveforms...
- Pad the impulse and sample waveform with zeros so they are the length of the sum of them minus one (this is to ensure no data is lost during convolution: study the example above to see why 0's are required.)
- Perform the Fourier transform on each waveform.
- Multiply the result of the transforms...
- Perform the inverse transform on the product.1
- Export as a wave file.
So now that we have an algorithm and an impulse, let's find a bit of music to convolve. I chose English Suite No. 2 in A Minor, BWV 807: IV. Sarabande by J.S. Bach, played by Glenn Gould: BWV 807: IV.2
Next, we need some tools to actually do the Fourier transform and import and export our wave files. After trying Python and some libraries (numpy, matplotlib and pylab) I decided that just working in Mathematica would be an easier choice. Mathematica has all the functions I need pre-installed and the language itself is fun to work in.
Mathematica Code:
imp = Flatten[Import["~/Desktop/domkyrkan1.wav", "Data"]];
snd = Flatten[Import["~/Desktop/BWV807short.wav", "Data"]];
paddingIMP = Length[snd] + Length[imp] - 1 - Length[imp];
paddingSND = Length[snd] + Length[imp] - 1 - Length[snd];
imp = Join[imp, Table[0, {paddingIMP}]];
snd = Join[snd, Table[0, {paddingSND}]];
conv = Fourier[imp] * Fourier[snd];
iconv = InverseFourier[conv];
ListPlay[iconv, SampleRate -> 44100, SampleDepth -> 16, PlayRange -> All ]
That's all that is required for convolving two signals. Here's the result: Scary Gould.3 What has happened is the frequencies of the song sample have been shaped to that of the impulse: some are enhanced, some are subdued. The entire wave is somewhat slurred, too, taking on the flavor of the reverberation from the impulse.
You may notice some clipping in these samples - that's because Mathematica improperly scales amplitudes before exporting to wav files. This could be avoided by using professional audio software or simply carrying out the convolution with another set of tools like Python with Pylab and Scikits.audiolab. I used Mathematica here because I could get accomplish what was necessary to demonstrate in a few number of steps, which outweighed the minor inconvenience of some clipping.
UPDATE: 07/20/2010 The code above has been fixed to (hopefully) ameliorate the clipping issues on export. The key bit I hadn't included was adding the "PlayRange -> All" option to the ListPlay function. I'm not quite sure how Wolfram & Co. would expect people to do that, but hey, it works.
This is, really, all that goes into convolution reverb. The only limitations are the time it takes to carry out the procedure and the impulse responses you can gather. Otherwise, this simple technique is close to limitless in terms of creative possibility.