如何在幅频响应上使用逆 FFT?
Posted
技术标签:
【中文标题】如何在幅频响应上使用逆 FFT?【英文标题】:How to use inverse FFT on amplitude-frequency response? 【发布时间】:2011-10-18 17:21:09 【问题描述】:我正在尝试创建一个用于计算图形均衡器 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 是错误的。我是否需要将我的 binamps 矢量延长两倍并在其第二部分创建一个镜像?如果是这种情况,那么仅仅是 Matlab 的 ifft 实现还是其他 C/C++ FFT 库(尤其是 Ooura FFT)需要镜像数据来进行逆 FFT?
还有什么我应该知道的以从 ifft 中获取 FIR 系数吗?
【问题讨论】:
【参考方案1】:您的频域矢量必须是复数而不仅仅是实数,并且它需要关于中点对称才能获得纯实时域信号。将实部设置为所需的幅度值并将虚部设置为零。实部需要均匀对称,这样A[N - i] = A[i]
(A[0]
和 A[N / 2]
是“特殊的”,即 DC 和 Nyquist 分量 - 只需将它们设置为零。)
上述内容适用于任何通用复数到复数 FFT/IFFT,而不仅仅是 MATLAB 的实现。
请注意,如果您尝试设计具有任意频率响应的时域滤波器,则需要先在频域中进行一些窗口化。您可能会发现 this article 很有帮助 - 它谈到了使用 MATLAB 进行任意 FIR 滤波器设计,特别是 fir2。
【讨论】:
非常感谢,fir2 函数确实为我的案例提供了很好的结果。我想,那么我只需要找到这个函数在内部是如何工作的,并在 C++ 中实现相同的算法。【参考方案2】:要获得真实的结果,任何典型的通用 IFFT(不仅仅是 Matlab 的实现)的输入都需要是复共轭对称的。因此,使用给定数量的独立规范点进行 IFFT 将需要至少两倍长的 FFT(最好甚至更长,以允许从最高频率截止到零的一些过渡)。
试图通过丢弃复杂结果的“虚构”部分来获得真实结果是行不通的,因为您将丢弃时域滤波器对于给定频率响应输入所需的实际所需信息内容IFFT。但是,如果原始数据是共轭对称的,那么 IFFT/FFT 结果的虚部将是(通常是微不足道的)可以丢弃的舍入误差噪声。
此外,有限频率响应的 DTFT 将产生无限长的 FIR。要获得有限长度的 FIR,您需要对频率响应规范的规范进行折衷,以便时域表示的后半部分中剩下的能量很少,必须从 FIR 中截断以使其可实现或有限.一种常见的(但不是最好的)方法是对 IFFT 产生的 FIR 结果进行窗口化,并且通过反复试验,尝试不同的窗口,直到找到 FFT 产生结果的 FIR 滤波器“足够接近”您的原始频率规格。
【讨论】:
以上是关于如何在幅频响应上使用逆 FFT?的主要内容,如果未能解决你的问题,请参考以下文章