0
$\begingroup$

Sorry if my question is some FIRFiltering basics, but I couldn't find a specific answer after some search.

I am trying to design a decimating low pass filter in C (actually in OpenCL with GPU) with the FIR approach by doing convolution. I have a software that generates the coefficients based on the cut-off frequency and the sampling frequency.

I realized that my filter generally works if the cut-off frequency is not too far away from sampling frequency, for example fsample = 1e7 and fcutoff = 1e4 would work. (maybe the attenuation is not enough). But if I increase the fsample to 1e8, the attenuation will be negligible.

Reading from this link: How many taps does an FIR filter need? I understand that I will need a number of tap of order 1e5 or 1e6 to have sufficient attenuation (~10 - 20 dB) for my application.

So my question is, in general, how should I design my filter to meet my requirement, if I really have to cut-off something massively oversampled? If not FIR, could you point me any other better approach, for example, can IIR work better?

Maybe I can follow the approach of multi-stage decimating FIR filter in this page? Great if you provide me with some references regarding how the stages should be determined. FIR-Decimation and Low-pass filter (taps vs number of input points vs number of decimation stages)

Thanks.

$\endgroup$
  • 1
    $\begingroup$ Have you considered to use a cascade of CIC and FIR? $\endgroup$ – Irreducible Jul 18 '18 at 5:50
2
$\begingroup$

If the desired cutoff frequency is very low relative to the sample rate, then yes, you would need a very high-order FIR filter to implement it. However, in these sort of cases, it's usually a better idea to use a multistage approach.

For example, say you wanted to decimate a signal by a factor of 10000. If you implement this with a decimating lowpass filter, it would need to have a cutoff frequency less than $\omega = \frac{\pi}{10000}$. This would require a filter with tens to hundreds of thousands of taps, depending on how much attenuation you require in the stopband. This is a lot of processing, especially if you're trying to do real-time processing. What's more, with really long filters like this, you can run into numerical precision issues; the filter that you get might not even give you the frequency response that you designed it for!

Instead, consider an approach with two stages: two identical filters that each decimate by a factor of 100. In this case, your cutoff frequency must be less than $\omega = \frac{\pi}{100}$. And you'll only need hundreds to thousands of taps in order to implement each filter. The computational cost of two few-thousand-tap filters is much less than the cost of one filter with hundreds of thousands of taps. This only becomes more apparent when you notice that the first filter decimates by a factor of 100, making the cost of the second one negligible compared to the first stage.

In short, when large rate changes like this are desired, multi-stage approaches are almost always what you want. The same logic follows for interpolation as well. Lyons has an easy-to-understand discussion of this topic in his introductory text Understanding Digital Signal Processing.

$\endgroup$
  • $\begingroup$ Thanks for the answer, I will work on implementing the multistage design. It is indeed not difficult with GPU, but I will need an extra step to calculate (and maybe optimize) what the intermediate stages should be. I will read the material you provided, but in general, should I always do an even split as you said: 10000 -> 100 &100, or could it be better with 10000 -> 1000 &10 or 10 & 1000? $\endgroup$ – Sandbo Jul 18 '18 at 17:08
  • $\begingroup$ Just adding to your answer, I found polyphase filter a very efficient solution to GPU FIR decimator. It speeds up the implementation by as much as 4-5 times. $\endgroup$ – Sandbo Jul 21 '18 at 3:22

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.