采用频率采样方法的 FIR 滤波器设计 - 为 IDFT 设置适当的相位响应

信息处理 过滤器设计
2022-01-27 00:48:18

我想使用 IDFT 变换实现线性相位 FIR 滤波器设计的频率采样方法。

我的程序是这样的:

  1. 确定频率点中所需的幅度响应值
  2. 我添加了具有群延迟 (N-1)/2 的线性相位响应函数,以获得复杂的频率响应值和频率中的等距点
  3. 使用 IDFT 计算系统的脉冲响应。

这种方法适用于奇数长度的 FIR 滤波器,但我对偶数长度的 FIR 滤波器有问题 - 我只是没有得到正确的结果。

我想我做错了可能是相位函数或其他东西 - 但是什么?

在此先感谢,问候,布尔。

4个回答

你的程序当然是正确的。在细节中,事情通常会出错。一件重要的事情是如何将所需的频率响应扩展到奈奎斯特之外,同时考虑到所需的对称性。为了使滤波器系数为实值,所需的频率响应必须满足

(1)D[k]=D[Nk],k=0,1,,N1

在哪里表示复共轭,并且N是 FFT 长度(= 滤波器长度)。从 (1) 可以得出,对于偶数N,复杂的期望频率响应的元素是

D0,D1,,DN/2,DN/21,,D1

对于奇数N你得到

D0,D1,,D(N1)/2,D(N1)/2,,D1
请注意,为了满足(1),D0而且,甚至N,DN/2必须是实值。

这个小 Matlab/Octave 代码适用于偶数和奇数滤波器长度。

% 线性相位 FIR 滤波器的频率采样设计

N = 64; % FFT 长度 = 滤波器长度
np = 地板(N/2) + 1; % 独立频率点数
n = 0:np-1;
w = n*2*pi/N;% 频率向量
M = sin(n*pi/(np-1)); % 一些期望的幅度响应
D = M.*exp(-1i*(N-1)/2*w); % 所需的复杂频率响应(线性相位)
D = [D,conj(D(N-np+1:-1:2))]; % 为 IFFT 附加冗余点
h = ifft(D); % 计算脉冲响应
max(abs(imag(h))) % 应该非常接近于 0
h = 实数(h);% 消除数值错误

% 检查结果
[H,w2] = 频率 (h,1,4*N);
绘图(w/2/pi,abs(D(1:np)),'.',w2/2/pi,abs(H))

我想建议对 Matt L.

我认为更好的方法是使用大量频率样本(> 1024),无论需要多少抽头。这可以防止在只需要几次抽头时丢失如此多的频域信息。

如果频率样本描述了一个线性相位滤波器,那么所需的抽头将位于 Inverse FFT 输出的中心 bin 中。只需将输出截断为所需长度并应用适当的时域窗口,例如 Kaiser。

如果通过一个窗口滤波器的简单示例进行操作,则这种过采样的使用给出了与常用的 sinc 脉冲公式相同的结果,精确到小数点后几位。

链接详细描述了这种频率过采样的方法。特别是,它展示了如何为各种滤波器类型(偶数或奇数抽头计数、低通、带通等)设置频域相位。

N为奇数时,h(n)=1/N[H(0)+ 2∑_(k=1)^((N-1)/2)▒〖Re{H(k) e^(j2πnk/ N)}]]

对于 N 为偶数且 H(N/2)=0 , h(n)=1/N [H(0)+2∑_1^(N/2-1)▒Re{H(k) e^(j2πnk /N)}]

您的代码逻辑可能是正确的。我和你有同样的问题,最后我发现我的C代码是错误的,例如,在C代码中我使用inttype除2,但是它应该使用2.02.0f不使用2