I want to implement a FIR highpass filter for acoustic signals.

I generate the FIR using Python's SciPy code:

import numpy as np
import scipy

# Parameters
nfft = 512 # FFT length
cutoff = 100 # Cutoff in Hz
fs = 16000 # Sampling rate in Hz

# Frequency related sizes
kbins = int(nfft//2 + 1)

# FIR filter via firwin
numtaps = 251
taps = scipy.signal.firwin(numtaps, cutoff, pass_zero="highpass", fs=fs)

# Compute the filter h in frequency domain using FFT
h = np.fft.fft(taps, nfft)
h = h[0:kbins]

return h

Since my application requires working in the frequency domain in RT, the FIR highpass filter is converted to frequency domain (see code above) and applied on frequencies. Thereafter I do the IFFT to get the signal back in time domain.

When I use this highpass filter with nfft=4096 it sounds well, but when I use it with nfft=512 it sounds bad, as the speaker is hoarse, like a broken vinyl record.

I suspect it is because the given number of taps, 251, is inadequate to small FFT lengths. Therefore I have the following questions:

  1. In theory, is the number of FIR taps depend on FFT window length, or can we choose a "magic number" that fits all window lengths?
  2. In theory, what are valid numbers of taps ranges for a given FFT length? What is the minimal number of taps and maximal number of taps allowed to a given FFT? By allowed I mean will produce good results and won't add distortion to the signal.
  3. Is there a formula or a rule of thumb allowing me to input FFT length and calculate the minimal/maximal/optimal number of taps in the FIR?
  4. What is the best number of taps for speech filtering with FFT lengths of 256 to 8192 samples, given fs=16000?

Remarks [added in edit]:

The frame work is filtering buffer-wise using overlap-add. The window used is BiOr-Hanning with size nfft and overlap of 50%. After the buffer is read and windowed I do FFT, apply the highpass FIR on it, doing IFFT and then overlap-add with Hanning window (here BiOr-Hanning is the biorthogonal window to Hanning, ment to complement it in overlap-add analysis/synthesis).

  • $\begingroup$ Does this answer your question? Why is it a bad idea to filter by zeroing out FFT bins? $\endgroup$ Commented Aug 21, 2022 at 13:13
  • $\begingroup$ that's not how you filter in frequency domain – you get cyclic effects over the FFT length / filter-non-continuities at the ends of your FFTs: Multiplication in DFT domain is equivalent to cyclic convolution in time, but what you need is standard, acyclic convolution. So, this won't work. You need to look into overlap-save*/*overlap-add. $\endgroup$ Commented Aug 21, 2022 at 13:14
  • 1
    $\begingroup$ @MarcusMüller I am using overlap-add method, with overlap of 50% and Hanning window. The application I want to add the HPF to is doing processing in the frequency-domain, so it is natural to HP-filter it also in frequency domain, as it involves only multiplications once the FIR was calculated (once). The question is how to optimize the FIR for a FFT window length (with Hanning, overlap-add). I will add these details to the question. $\endgroup$ Commented Aug 21, 2022 at 13:22
  • $\begingroup$ ah, shucks! Thanks :) In that case, please also state the dimensions of your spectral vectors, because, you'll want to fit these. 251, although a bit of a strange length, does sound relatively generous for an audio application, but whether it's sufficient depends the width between stop and passband you need to achieve :) $\endgroup$ Commented Aug 21, 2022 at 13:26
  • $\begingroup$ @MarcusMüller: I am using sampling rate of fs=16000 Hz. By what you mean "spectral vector dimensions"? If I am using FFT of nfft = 2^n then I will have K = int(nfft/2 + 1) frequency bins. Nyquist frequency will be 8000 Hz so each bin will span over f_Ny/K Hz. $\endgroup$ Commented Aug 21, 2022 at 13:31

2 Answers 2


I think you got it backwards: the number of taps is determined by your filter requirements (cutoff frequency, steepness, attenuation, etc). The FFT length is then derived from the filter length, not vice versa.

  1. If you implement overlap/add or overlap/save, the FFT length needs to be at least twice the FIR length
  2. Again for overlap add, any filter length less of equal half the FFT length is fine.
  3. Again: max FIR length is half the FFT length
  4. Depends on the requirements of your filter, not the FFT length (as long as $N_{FFT} >= 2N_{FIR}$)

I recommend reading up on Overlap Add and understanding the math behind it, especially time domain aliasing. For filtering, there is no need for Hanning window and 50% overlap. Rectangular and 0% overlap works just fine.

If all you need is a highpass, then a simple IIR will do just fine and it's complexity is independent of the cutoff frequency (whereas number of taps for an FIR depends a lot on the cutoff frequency).

  1. Needs to fit the FFT length (i.e. be at most the FFT length); otherwise, you can't multiply an FFT'ed vecotr with the frequency domain filter in your overlap-algorithm. This has little to do with distortion, but simply with possibility to compute a result at all.
  2. How many taps does an FIR filter need?
  3. 256, can't go any higher. Also, speech filtering needs no narrow transition width, so probably much shorter filters will do. Note that you mention real-time up top: Don't forget that frequency-domain processing, due to the need to accumulate a full FFT worth of samples before you can even start to process, has a lot of delay, by itself. If this is for recording, or broadcasting, that doesn't matter. But you can't build a phone with a 8192-length FFT: That's half a second of minimum delay, and that will be very annoying for both ends of the communication. Generally, for anything that is a modern 32 or 64 bit processor, and I explicitly include mid-range microprocessors here, single-channel audio sampling rate processing is not much work, and you might well get away with doing things in the time domain, less efficiently.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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