1
votes

I have a list of amplitude frequency response points. The amplitudes are given in decibels.

The task is to export this AFR list to a set of coefficients for some hardware DSP device. I know the file format for this device. The specification for the device says that it needs 12288 coefficients and the DSP has 2 FIR filter blocks (6144 taps each). The idea is that after loading those coefficients, this device should work as an equalizer which transforms the signal according to the initial amplitue-frequency point list.

I have found out that the coefficients for a FIR filter can be calculated by taking the inverse Fourier transform of the desired frequency response and also using some windowing function (preferably not rectangle).

The problem is that I am not good at signal processing, I do not know much about FIRs, I have used FFT to get the frequency response from audio data, but I still have a pretty vague idea about how FFT and related stuff works.

The calculation of points should be done in C# or C++ (I am good at creating C++/CLI wrappers) so I can integrate it into already existing application. The exporting process is not time critical, so I can use simple and slow algorithms, but anyway it should not take more than a minute on a mid-range computer.

Is there any free library or code to get FIR coefficients from the amplitude-frequency response data?

The best solution would be something like a "black box" so I can just feed the list of AFR points and get out 12288 coefficients, but I would be grateful also for multiple libraries/pieces of code if only it can be put together easily.

Additional info:

  • sampling frequency for audio which will be passed through this FIR, is 44100 Hz

  • the overall characteristics of the signal can be loosely defined as "musical", FIR will be used for equalizing high quality audio, so any errors and signal distortions are acceptable if they cannot be heard by a trained ear on a high-end audio systems

  • diffrences between adjacent amplitudes in initial AFR points theoretically may be in range [0 dB .. 80 dB], but in real life tests they usually were in range [0 dB ... 2 dB]

  • AFR points are with growing distance between them, the first points are 20.17246114 20.68984457 and the last two 21632.14039 21754.41533

the points were calculated using the following formula:

       float x;
       for(int i = 0; i<bandPoints; i++){
               x = (((float)i + 1) / ((float)(bandPoints + 2)));
               bandsHz[i] = ((x*x)*(22000-20))+20; // 20...22000
       }
1
Not sure if this is possible without the phase of the frequency response. Perhaps it could be approximated, e.g. by assuming that the filter has linear phase.Steve Tjoa
How close together are the given frequency points, what is the maximum difference between adjacent amplitudes, what is the allowed error in the resultant FIR filter response, and what is the sample rate? There is a relationship between those answers, and the approximate required length of the FIR.hotpaw2
@hotpaw2 I added more informationJustAMartin

1 Answers

5
votes

The standard way of finding good FIR coefficients is using the "Remez exchange" algorithm. I found a link to some code (haven't tried it myself) that you may find useful: http://www.janovetz.com/jake/remez/remez-19980711.zip. Another key word to search for is "Parks-McClellan".

Input to the algorithm is a description of the amplitude versus frequency and a set of weight factors versus frequency that describes the relative importance of meeting the amplitude requirement at that frequency. The algorithm then finds the optimum filter in the mini-max sense (minimizing the maximum error).