I'm implementing (in software) FIR filters. I have done two implementation: convolutional one and based on multiplication in frequency domain with FFT/IFFT. I'm using standard FFT implementation (not my own) and overlap-add processing.
FFT parameters are automatically selected to be like this: $fftSize = 2 * 2^{\lceil\log2(nTaps)\rceil}$, $samplesPerOp = fftSize - nTaps + 1$ and $overlapSize = nTaps - 1$.
Now I'm testing my implementation. I've generated signal as $\cos(F_1*2*pi*n/F_s) + \cos(F_2*2*pi*n/F_s)$, where $F_1 = 10$, $F_2 = 1000$ and $F_s = 44100$. Also, I design two set of taps via windowed-sinc method: one for low-pass, with transition band $110Hz - 900Hz$ and other high-pass with same transition band. I've tried different windows - Hamming, Blackman-Harris and others.
I apply these two filters to signal, with convoluted and FFT implementations. Low-pass filter works perfectly well in both cases: when I select $nTaps$ large enough (via estimation formula from textbook - "Multirate signal processing" by frederic j. harris, for 90dB attenuation it gives me $nTaps = 327$ taps) I got clean 10Hz signal from both implementations (they are differ on edges of signal, but it is expected, of course)
But high-pass filter behaves strange. Convolutional implementation works. It gives almost undesturbed 1000Hz sine wave. And FFT implementation returns a mess. Result of FFT filtering looks like 1000Hz signal, but it is very corrupted - phase jitter, amplitude jitter, etc.
It looks like, I do something wrong, but I could not understand what. Each textbook, tutorial and article about using FFT for FIR filtering doesn't mention something like this.
Oh, I'm using double
, not fixed-point arithmetic, so precision loss should not be a problem.
And, not, it is not HW :)
Here are pictures from gnuplot (1/5 of «second»):
Low-Pass, convolution on top, FFT on down: http://lev.serebryakov.spb.ru/dsp/dsp-low-pass-side-by-side.png
High-Pass, convolution on top, FFT on down: http://lev.serebryakov.spb.ru/dsp/dsp-high-pass-side-by-side.png