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:
- 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?
- 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.
- 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?
- 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).
fs=16000 Hz
. By what you mean "spectral vector dimensions"? If I am using FFT ofnfft = 2^n
then I will haveK = int(nfft/2 + 1)
frequency bins. Nyquist frequency will be8000 Hz
so each bin will span overf_Ny/K
Hz. $\endgroup$