如何在幅频响应中使用逆FFT?

时间:2011-10-18 17:21:09

标签: matlab fft frequency-analysis

我正在尝试创建一个计算图形均衡器FIR滤波器系数的应用程序。我正在使用Matlab进行一些原型设计,但是我遇到了一些问题。

我已经开始使用以下Matlab代码:

    % binamps vector holds 2^13 = 8192 bins of desired amplitude values for frequencies in range 0.001 .. 22050 Hz (half of samplerate 44100 Hz)
    % it looks just fine, when I use Matlab plot() function 
    % now I get ifft
    n = size(binamps,1);
    iff = ifft(binamps, n);
    coeffs = real(iff); % throw away the imaginary part, because FIR module will not use it anyway  

但是当我对系数的fft()进行处理时,我发现频率被拉伸了2次并且我的AFR数据的结尾丢失了:

p = fft(coeffs, n); % take the fourier transform of coefficients for a test

nUniquePts = ceil((n+1)/2); 
p = p(1:nUniquePts); % select just the first half since the second half 
                       % is a mirror image of the first
p = abs(p); % take the absolute value, or the magnitude 
p = p/n; % scale by the number of points so that
           % the magnitude does not depend on the length 
           % of the signal or on its sampling frequency  
p = p.^2;  % square it to get the power 

sampFreq = 44100;
freqArray = (0:nUniquePts-1) * (sampFreq / n); % create the frequency array 
semilogx(freqArray, 10*log10(p)) 
axis([10, 30000 -Inf Inf])
xlabel('Frequency (Hz)') 
ylabel('Power (dB)') 

所以我想,我正在使用ifft错误。我需要让我的binamp矢量两倍长,并在它的第二部分创建一个镜子吗?如果是这种情况,那么它只是一个Matlab实现的ifft或其他C / C ++ FFT库(尤其是Ooura FFT)需要用于逆FFT的镜像数据吗?

还有什么我应该知道的,以便从ifft中获取FIR系数吗?

2 个答案:

答案 0 :(得分:3)

您的频域向量需要复杂而不仅仅是实数,并且需要关于中点对称才能获得纯粹的实时域信号。将实部设置为所需的幅度值,并将虚部设置为零。实部需要具有均匀对称性,以使A[N - i] = A[i]A[0]A[N / 2]为“特殊”,即DC和奈奎斯特分量 - 只需将它们设置为零。)

以上内容适用于任何通用的复杂到复杂的FFT / IFFT,而不仅仅是MATLAB的实现。

请注意,如果您尝试设计具有任意频率响应的时域滤波器,则需要首先在频域中进行一些窗口化。您可能会发现this article有用 - 它讨论了任意FIR滤波器设计使用MATLAB,特别是fir2

答案 1 :(得分:2)

为了获得真实的结果,任何典型的通用IFFT(不仅仅是Matlab的实现)的输入都需要是复共轭对称的。因此,使用给定数量的独立规格点进行IFFT将需要至少两倍的FFT(优选甚至更长以允许从最高频率截止转变为零)。

试图通过丢弃复杂结果的“虚构”部分来获得真实结果将不起作用,因为您将丢弃实际所需的信息内容,时域滤波器需要输入给定的频率响应IFFT。但是,如果原始数据是共轭对称的,那么IFFT / FFT结果的虚部将是(通常无关紧要的)可以丢弃的舍入误差噪声。

此外,有限频率响应的DTFT将产生无限长的FIR。要获得有限长度的FIR,您需要妥协您的频率响应规范的规范,以便在时域表示的后一部分中留下很少的能量,必须从FIR截断以使其可实现或有限。一种常见(但不是必要的最佳)方法是窗口IFFT产生的FIR结果,并通过反复试验尝试不同的窗口,直到找到FFT产生结果的FIR滤波器“足够接近你的原始频率规格。