This week I discovered just how bad the acoustics in my front room are. At my typical listening position (sat in front of the computer) there are two huge spikes in the frequency response at around 45Hz and 140Hz (measured with JAAA, an audio analyzer). Unsurprisingly this has a big effect on the music I make, to the extent that some of it sounds wrong to my ears when I listen in other environments (even including other spots in the same room):

- source audio composed and recorded digitally
- recorded with mics at four different listening positions

So I was looking around for ways to mitigate the problem, starting with simple things like moving the desk and speakers to a different position in the room. But my desk is heavy and bulky and has a zillion cables dangling all over it, so moving it around is awkward. Referring back to my blog post about modes on a plate I thought computer simulation could be part of the answer.

Happily I found a really nice paper full of equations (even two different room response modelling algorithms) and a section on just the problem I'm facing (namely optimising speaker and listener positions to get the frequency response as flat as possible):

Room Sizing and Optimization at Low Frequencies

Trevor J. Cox, Peter D'Antonio, and Mark R. Avis

J. Audio Eng. Soc., Vol. 52, No. 6, 2004 June

I implemented in Haskell (source code links at the end of this
post) the first prediction model in the paper, the **modal
decomposition model**. I made a couple of slight changes
to the equations in the paper: the term \(w_n \delta_n\) is a bit
redundant, because \(\delta_n\) has a division by \(w_n\), so I
avoid dividing and multiplying again (which avoids NaN dread when
\(w_n\) is \(0\)). Here are some of its predictions (click for
larger):

The yellow room is where my computer is, and has roughly accurate
room size and speaker and listener positions, but I guessed the wall
absorption coefficients (and the algorithm to convert absorption
coefficients to admittances, I used Daniel A. Russell's
Absorption Coefficients and Impedance).
The bathroom likewise (though I have no
speakers in the bathroom and I don't sing in the shower), and the
standard room size and absorption is from the paper but I picked the
positions myself. I used \(343 m s^{-1}\) as the speed of sound.
I used **gnuplot** to smooth the computed data using its
kernel density method, as the specific locations of the narrow peaks
and troughs in the response are very sensitive to slight variations in
the parameters.

Then I generated some
pink noise
with **audacity**, and recorded it for analysis. Note that
this measures the combined frequency response of the sound-card DAC, the
speaker cones, the mics, and the recorder ADC; as well as the room response
I'm interested in - so it's not really a proper test, just enough to get
a rough idea. I also performed the test with stereo speakers, the modal
model code can be extended for more speakers quite easily but I didn't use
that for the graph above.

I wrote a small C program using **fftw** and
**sndfile** to get the spectrum (I used ~21 seconds), and
more gnuplot stuff to smooth it - the FFT has linear frequency but I
wanted to convert it to logarithmic frequency, and gnuplot kernel density
smoothing needs to know the resolution of the data, which increases with
frequency when \(\log\)ing. I added the modal prediction to the graph,
it's actually not too far out:

Source code download links: