29a.ch by Jonas Wagner

Impulse Response Creator

By

Screenshot of Impulse Response Creator Impulse Response Creator

I got a little bit obsessed with convolution reverb and measuring impulse responses over the last few weeks. As part of that I’ve built myself a few command line tools to create and process impulse responses. I have now bundled these up into a web application, in the hope that they may be useful to others.

What are impulse responses and convolution reverbs

If you want to evaluate the acoustics of a room you are in, you can clap your hands and listen to the echos and reverberation of the clap. An impulse response is very similar to that. It’s the response of a system to being excited with a short impulse like the clap in the example before.

The impulse response can then be used to simulate the sound of the room using a process called convolution. An easy way to think of this is that for every point on the input signal the impulse response is played back with the volume (and polarity) adjusted to match the input. This cascade of echos will then match what that input would have sounded like in the room.

This principle isn’t limited to rooms, speaker cabinets, or audio. It works for any linear time-invariant sysyem.

Capturing Impulse Responses

Impulse Response Spectrogram Spectrogram of the Impulse Response of a room.

In practice capturing accurate impulse responses is a bit more difficult than just clapping. Ideally the impulse used to excite the system is very brief. Infinitesimally brief. In order to get a good signal to noise ratio it should also be very loud, to get as much energy as possible into the system with that brief pulse.

The impulse generated by clapping hands isn’t very short, very intense, or easily reproducible. Better options are popping balloons or firing starter guns. Those methods are better than clapping but still far from ideal.

Can we avoid using an impulse to capture an impulse response?

Sweeping Sines

If we look at the problem from a frequency perspective an alternative approach becomes evident.

An ideal impulse is a short burst containing all frequencies at once. Instead of sending out all frequencies at once, we can send out different frequencies over time. To do so we can use a simple sine wave with a changing frequency over time. This test signal is also known as a sine sweep or chirp.

Now instead of an infinitesimally short pulse we can take as much time as we would like to send out our signal. This makes it easier to get a good signal to noise ratio and is much kinder to the equipment being measured.

Spectrogram of a sine sweep Spectrogram of a sine sweep. Response to the sine sweep Response to the sine sweep.

Note: The parallel lines above the sine sweep are due to harmonic distortion introduced in my measurement process. The horizontal noise are due to hum while measuring. Turns out getting good measurements in the real world is hard. But we can deal with those artifacts.

Deconvolution

There is just a tiny little problem, the response to our sine sweep isn’t a crisp impulse response instead it’s smeared out over time just like our test signal is. In order to get the impulse response we need to undo this smearing over time. This process is called deconvolution and it transforms the response to the sine sweep into an impulse response.

Deconvolved response to the sine sweep Response to the sine sweep after deconvolution.

Looking at the spectrogram in visual context, this boils down to shearing.

My actual implementation is based on Farina, Angelo. (2000). Simultaneous Measurement of Impulse Response and Distortion With a Swept-Sine Technique. or Wiener Deconvolution depending on the test signal and selected options. The technique by Farina also gets rid of the harmonic distortion.

If this explanation was a bit too handwavy, I suggest reading the paper by Angelo Farina. He strikes a good balance between detail and accessiblity.

Web Implementation

After having played around a bit with my CLI implementation I’ve realized that there aren’t (m)any easy to use online tools for creating impulse responses. So I went the extra mile and added a little web ui in the hope that this - admittedly very niche tool, might be useful to others.

All the DSP code for this project is implemented in Rust and compiled to wasm. The UI is written in Typescript and uses React. Everything is bundled up using vite and wasm-pack.

I’ve also written some integration tests using Playwright. Using Playwright was rather nice and low friction so I will likely it again in future projects.

Limitations

While there is a UI and a bit of plumbing for normalizing and trimming the generated impulse responses the core of the code is still what I’ve written for my experiments.

There are still many rough edges and potential for improvement. One obvious area is improved noise reducation, especially with regards to impulse noise) which lead to chirps leaking into the deconvolved impulse response.

Demo

Finally a little demo of what this can sound like. At first the arpeggio is played back without added reverb, then convolved with a measurement my room and finally convolved with the impulse folded back onto itself with some feedback for an ambient effect.