Reputation: 11
So I'm trying to write a program that is able to generate FIR coefficients of a filter that replicates a given frequency response. This program will end up being used on an audio processing application.
I'm using Matlab and if the desired response matches a classic LP, BP or HP it's all good. The built-in Matlab functions allow for a decent FIR filter to be designed that has minimal error regarding the target frequency response.
However, my project requires me to emulate "weirder" frequency responses such as:
This has revealed to be a challenge. The built-in functions I'm using are producing filters with enormous ripples. I tried to used a genetic algorithm for generating FIR coefficients that replicate the given frequency response but without success.
So does anyone know what's the best way to do this? Is there a different algorithm that I should try? Should I insist on the genetic algorithm? Is a FIR filter a good choice (given this is to be implemented on an audio processing program)?
Upvotes: 1
Views: 816
Reputation: 15
Please check out this GitHub repository which is an open-source software (Also available as a desktop app) to facilitate the design of multiband FIR, linear-phase digital filters. It creates optimal FIR filters (Least-squares sense) and has a lot of features such as the automatic generation of MATLAB code, plotting for analysis and delay/performance measures.
Upvotes: 0
Reputation: 607
You can quite easily generate a valid FIR filter. Assume your specification above is N/2 taps. Assume your specification is given the variable name S and is specified at the frequencies DC to Nyquist. We have to generate the frequencies above Nyquist and the linear phase component.
In matlab you can zero pad the filter and specify that you want a symmetric FIR (real in the time domain). To generate a zero phase filter, do the following :
N = 2*length(S);
s = ifft(S, N, 'symmetric');
Now you have the zero phase signal s and you want to shift your zero phase signal to make the linear phase component. We can simply circularly shift in the time domain like so :
s = circshift(s, N/2);
You can vary the shift amount to specify where you want the filter to start.
The signal s is now a linear phase signal matching your specification in the frequency domain exactly.
Upvotes: 1