Prototype VI - Digital Room Correction

Jon and I have long planned on using the spare CPU cycles of the MPC5200 on Digital Room Correction (DRC). Every room in which DigiSpeaker will be deployed will have its own unique frequency response. This means that certain frequencies will resonate in the room while still others will attenuate into nulls. In addition, the imperfections in the electronics and the transducers also contribute to various frequencies being amplified or attenuated. This all combines to deliver music which is, in some cases, wildly different from what the musician intended.

To fix this, Jon and I planned on using the 'DRC: Digital Room Correction' software package written by Denis Sbragion. There is a lot to this package. I will leave the details to the reader. However, in short, to use this package you play a test signal through your system and record the results through a calibrated microphone. You then use the DRC software package to compute a digital FIR filter based on the recorded signal which 'counteracts' the effects introduced in the music by the imperfections in the room, electronics and speakers.

The FIR filters used for DRC are not short. You have to use filters that are 16k to 64k in length to get enough frequency resolution to correct the errors in the system yet not introduce new errors. As you might imagine, running three 64k tap filters (one each for tweeter, midrange and woofer. Convolved with the DRC filter) can seriously tax the CPU. However, by configuring brutefir for eight partitions of 8k each, I was able to run three 64k tap filters and still have 40%+ of the CPU left. At 16k tap filters (which would be good enough for most situations), I was able to obtain well over 50% of the CPU left idle.

To record the test signal from our system, I bought a Behringer ECM8000 microphone and powered it with a Behringer Xenyx 502 mixer. I fiddled around with the input and mixer gains (as well as the amplitude setting of my system) until I was able to record signals that were load (from 50% to 80% of full input) without clipping.

I am currently using Audacity as my sound editing and recording tool. This program is really amazing. It has lots of features and it pretty intuitive. I am running it on my lab computer which is a Dell Dimension 4700. The Dell Dimension has an AC'97 sound card based on the Analog Devices AD1980 codec.

Typically, people doing DRC measurements play and record the test signals using the same sound card. However, DigiSpeaker has no analog input so I play the test signal with DigiSpeaker and record the test signal with the sound card in my computer. The problem with this setup is that the recorded test signal is not synchronised with the playback. To fix this problem, I put three tones at the beginning of the test signal of known length and frequency. I then use audacity to align the signals in Audacity and to cut off the test signals and any trailing signal so the input and recorded signals are 'time aligned'. Once this is done, I use the DRC software to produce the correction filter.

So, how do you create the test signal? The test signal is a logarithmic frequency sweep from 10Hz to 21000Hz. It is generated with a tool that comes with the DRC software. That tools is called 'glsweep' and you invoke it like so:

glsweep 44100 0.5 10 2100 45 2 0.05 0.005 sweep.pcm inverse.pcm

This command tells glsweep to produce a sweep with 2 seconds of silence at the beginning and 45 seconds of sweep from 10Hz to 21000Hz and store it in a file called 'sweep.pcm". The amplitude of sweep should be a consistent 0.5 of full amplitude. The beginning amplitude should taper up for the first 2.25 seconds (= 45 * 0.05) and trail off for 0.225 seconds (=45 * 0.005) at the end. Finally, the inverse of this sweep should be stored in 'inverse.pcm' for use by later calculations. This sweep can be seen in the top trace in the Audacity screen shot below.

I download this signal in the form of a WAV file (Adacity can make on very easily) to Digispeaker. I use the following command to play the test sweep through the system:

brutefir triamp_test.txt sweep.wav

This brutefir configuration file will split the sweep into three frequency ranges (tweeter, midrange, woofer) using three 2k tap crossover filters. They three filters can be seen in the 'Filters' and 'Filters (zoomed)' pictures below. Notice that these are amazing filters. The crossovers are 300Hz and 3000Hz. They all drop off to -80dB in only 100Hz before/after the crossover point. More aggressive drop-offs are possible but shouldn't be necessary given the expected quality of the system. The brutefir script (triamp_test.txt) is attached.

The second trace in the Audacity screen shot below shows the recorded result. Remember that the sweep is a logarithmic sweep of frequencies from 10Hz to 21000Hz. You can compute the exact frequency as a function of time with this formula:

log(f) = (0.073827(t-2)) + 1

Where 'f' is the frequency and 't' is the time that can be read long the top of the image. For instance, the lower crossover (300Hz) can be found in the traces at
22 seconds. That is:

log(300) = 0.073827(22-2) + 1

Once the test signal has been recorded from the system, it is convolved with the inverse of the sweep to create the impulse response for the system. The DRC software comes with a package to do this. It is called 'lsconv' and is invoked like this:

lsconv recorded.pcm inverse.pcm impulse.pcm

To produce the DRC filter, you run the DRC software with a given configuration file. DRC can be applied at different levels from normal to insane. Normal DRC fixes most problems but generally avoids adding artefacts to the music. At the other extreme, the 'insane' levels of DRC will correct the system to produce great sound at one location, but will sound strange if you move away from that location. Various levels of DRC configurations have been attached in the file 'drcconfigs.tar.gz'. In the results below, I am using normal DRC. Here is how you generate the DRC filter:

drc normal_62k.drc

This will produce a 62k tap filter that corrects the imperfections of my system. You can see this filter in the DRC plots below. It is the 'teal' line that is 'floating' just above the corrected crossover plots. I moved the DRC filter up by 5dB so that it did not obscure the other plots. Why only 62k taps you might ask? Well, I wanted to run three 64k tap filters crossover filters in brutefir. To do this, I wanted to convolve my DRC filter with each of my crossover filters to produce three filters that both crossover the music and correct the imperfections in my system. Since my crossover filters are 2k taps each, I decided to make my DRC filter 62k taps so that I could convolve them together to produce 64k tap filters. The results of this convolution are shown in the DRC (and DRC (zoomed)) plots below.

Once I had this procedure down, I produced DRC filters for each of the different DRC levels (normal, strong, extreme, insane) of various lengths (6k, 14k, 30k, 62k). I then convolved my crossover filters in every combinations to produce tweeter, midrange, and woofer filters from 8k taps to 64k taps. For the sake of brevity, I have only included results for 64k tap filters below. Traces 3 through 6 in the Audacity screen shot show recorded results for 64k tap corrected crossover filters with DRC from normal to insane. You can clearly see that even normal DRC adds a lot more 'fullness' to the signal. Also, I can attest that using DRC make the system 'come alive'. When you flip from 'no DRC' to 'DRC' and then back again, the result is like night and day. The DRC music is rich and full while the none-DRC music sounds tinny and weak.

Notice that I do have a problem right at the 300Hz crossover. In all the DRC plots the response seems to go to zero for a short period. I believe this is an experimental mistake that I am still investigating. If you examine the plots carefully, you will notice that DRC attenuates the signal right at about 275Hz. I believe that attenuation is supposed to be at 300Hz where there is a 'bulge' in the none-corrected recorded response of the system. This is probably due to my 'manual alignment' technique described above. That technique clearly needs some work.

Finally, I did try to chain the DRC filter with the three uncorrected crossover filters in brutefir. That result is shown in the last trace in the Audacity screen shot. I did this to investigate the 300Hz null. Notice that is has gone away (a little). Again, I think this is due to DRC being misaligned. However, in this case, the DRC filter is not attenuated by the steep rolloff of the crossover filters which means that the error is not so prominent.

Audacity. This is an Audacity screen shot that shows the experimental result of my tests. The top trace is the test signal played through the system. The second signal is the recorded test signal played through the system without DRC. The third through the sixth traces are test signal played through the system with various levels of DRC (from normal to insane). The last signal is the test signal played through the system with DRC chained with the three crossover filters. Click on the picture to enlarge.
Filters. Here is the three crossover filters plotted from 0Hz to 22050Hz. Each filter has 2k taps. Notice how steeply the filters rolloff, how greatly they are attenuated and how flat they are on top. At 2k taps, these filters are overkill for the quality of our electronics downstream. Click on the picture to enlarge.
Filters (zoomed). Here I have zoomed into the first two crossover points (300Hz and 3000Hz) to show the detail of the filters. Click on the picture to enlarge.
DRC. This plot shows the three corrected crossover filters along with the entire DRC fitler. The DRC filter is the 'teal' line that 'floats' above the other traces. I added 5dB to the DRC line so that it would not obscure the tops of the other traces. Without that offset, the teal trace would exactly tack the tops of the other plots. Click on the picture to enlarge.
DRC (zoomed). Here I have zoomed into the first two crossover poitns (300Hz and 3000Hz) to show the detail of the corrected filters. Click on the picture to enlarge.