3

我正在尝试创建一个应用程序来计算图形均衡器 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)') 

所以我想,我用错了。我是否需要将我的 binamps 向量加倍并在第二部分创建一个镜像?如果是这种情况,那么仅仅是 Matlab 的 ifft 实现还是其他 C/C++ FFT 库(尤其是 Ooura FFT)需要镜像数据来进行逆 FFT?

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

4

2 回答 2

3

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

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

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

于 2011-10-18T17:37:43.587 回答
2

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

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

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

于 2011-10-18T19:01:56.457 回答