Generating and running FIR filters for active loudspeakers

Status
Not open for further replies.
I'm not sure if this fits in the loudspeaker forum better, but my questions deal more with digital filter design than loudspeaker crossover design. I'm interested in hearing about other's experiences with FIR filtering as I'm getting surprisingly poor results.

Now that I have an EMU 1820m, I am starting to dabble in setting up an active loudspeaker. I started out generating some simple FIR filters in Matlab. These are just brick wall filters using the fir1 command. I'm not yet at the stage of trying to account for individual driver responses or using shallower slopes.

k=2^n; % order of filter
fn1=2*fxo1/fs; % normalized subsonic cutoff frequency
i=linspace(1,k,k); % k-tap filter array
window_filt = window(@blackman,k+1);
hir=fir1(k,fn1,'high',window_filt,'scale'); % high-pass impulse response
sub=fir1(k,fn1,'low',window_filt,'scale'); % low-pass impulse response

I then export the impulse response of the filter as 32bit .wav and run it with convolver (convolver.sf.net). I'm using the directx version as I haven't had any luck with the vst so far. Surprisingly, stopband attenuation looks like it's only -44 db. This is much worse than running the same filter in Matlab which seems to give hundreds of db of stopband attenuation. Even with a cap on the tweeters to block DC, I'm not sure I want to hook them up to these filters yet. I tried running the same filters through a different convolver (SIR) and got a better -66 db, but SIR seems to be taylored towards reverb effects. I'd love to try brutefir someday. I also tried different filter lengths (2048, 16384, and 32768 taps). I did try the hamming window but its stopband attenuation was not as good in Matlab so I didn't bother running it through the convolver.

Anyway, should this stopband performance be surprising, or are there some fundamental flaws with my methods here? Is this a convolver issue or a filter design issue or a little of both? It looks like most people either use a package like Acourate to generate their filters, or use something like a foobar or winamp plugin to generate and run filters. I'd appreciate any feedback or sharing of similar experiences.
thanks!
Dan
 
I don't see where you window the impulse response.

Also, there is a tradeoff between filter slope and stop band attenuation for any given temporal length, and you are using brick wall filters...

What does an fft of the impulse response as loaded from file look like?

Regards, Dan.
 
Try experimenting with kaiser window function. Some months ago I was experimenting with subwoofer crossovers and managed to create a filter with quick slope to -60dB followed by approx. -18dB/oct slope. Filter was 3072 samples long with a crossover point of 100Hz.
 
I didn't realize there was a tradeoff between filter slope and stopband attenuation. Maybe it's worth trying to generate more shallow filters to see if it improves.

The window is set by generating a vector with the window function:
k=2^n; % order and length of filter
window_filt = window(@blackman,k+1);

and then that vector is an input to fir1 which calculates filter coefficients. I didn't actually window the filter coefficients because I assumed Matlab already did that as part of the fuction.

Attached is an fft of the impulse responses for the high and low pass filters. They are 2048 taps at 2000 hz. Filtering a 1 sample impulse with Matlab's filter function gives a similar plot but shows some ripple. Increasing the taps helps the stopband attenuation slightly, but as you can see from this plot from Matlab attenuation is better than 100 db already. Quite a difference from convolver which is 44 db. I know Matlab runs with more precision than convolver which is 32 bit, but I'm still surprised by this.

I did try the kaiser window in Matlab but the Matlab sim gives 50 db attenuation. Maybe it's worth plugging the resulting filter into convolver to see if the stopband improves or degrades by the same amount.

I did see that the .wav export for Matlab is integer for 16 and 24 bit files while 32 bits are sent out as floating point. Convolver is supposed to be able to handle floating point pcm files, but perhaps it has some trouble with floating point waves? I'm going to try a 24 bit file just to see what happens.

thanks for the input,
Dan
 

Attachments

  • filter_ir.jpg
    filter_ir.jpg
    55.8 KB · Views: 298
My recollection is hazy, but I think that by adjusting kaiser window parameters one can get arbitrary passband ripple and stopband attenuation. As was mentioned, trade off is slope steepness. I believe the slope will be steep enough with the filter lengths and frequencies you are playing with in almost any case.
 
If you're still experimenting with FIR kernel design, I'd recommend trying the filter design tool in MATLAB. Just type fdatool at the prompt and go from there. It's nothing you can't do manually, but it's nice and quick to try different designs, and plots lots of useful information automatically.
 
Status
Not open for further replies.