1
votes

Today while struggling to make my C++ code (using Ooura FFT library) to give the same results as Matlab does, I finally found a problem and a solution.

In Matlab calculating reverse coefficients for a grid of amplitude-frequency response is done in a following way (code fragment from Matlab's internal fir2() function):

%H contains 8192 points of AFR data
Hconj = [H conj(H(npt-1:-1:2))];   % Fourier transform of real series
ht = real(ifft(Hconj));            % Symmetric real series

as a result we get back 16384 bins, and the second half of them can be thrown away, but the first half can later be used as FIR coefficients.

But if I do the same in Ooura using Real DFT rdft() function, I get coefficients which create a mirror effect in the resulting AFR, all the frequencies on the AFR plot are divided by 2.

So an idea came to me: in my C++ code I made my H twice as big (16384 points) and filled them all with frequency data without mirroring. And voila! it worked, now I got 16384 points, throw away everything after 8192 point and now the resulting AFR matches the Matlab's.

I was convinced that all standard FFT implementations need this mirroring. Is it just a quirk of Ooura that it DOES NOT need mirroring data in input, or maybe there is something else going on?

1

1 Answers

1
votes

A "real" FFT often does the mirroring internally by automatically using the complex conjugates of the input for the mirrored values. A standard FFT/IFFT doesn't do this because it has twice the degrees of freedom (e.g. to produce a complex output or, say, a complex domain filter from an IFFT) of an FFT/IFFT implementation constrained to real-only output.

The frequency bin step size of an FFT is controlled by its length. Half the length produces half the frequency step size, as in your original trial.