如何使用 Parks-McClellan 算法设计奈奎斯特插值滤波器?

信息处理 过滤器 帕克斯-麦克莱伦 插值
2021-12-23 01:37:02

我们可以使用Parks-McClellan算法轻松设计符合特定频域约束的插值滤波器。然而,如何实施时域约束还不是很清楚。特别是,我对生成奈奎斯特滤波器很感兴趣。因此,如果我以 的因子进行过采样N,我希望滤波器在kN,对于非零整数有过零k(这确保我的插值器的输入样本将出现在输出序列中)。

我看过 Harris 1谈到了一种设计半带滤波器的技术,即特殊情况 where N=2. 有没有通用的解决方案?(我知道我们可以很容易地用 window 方法设计过滤器,但这并没有给我们同样的控制。)

[1]通信系统的多速率信号处理,第 208-209 页

2个回答

一种设计方法(尽管仅限于 2 的幂)是从一个半带滤波器开始,每隔一个插入零(创建一个光谱副本),然后将其与具有更宽过渡带的第二个半带滤波器进行卷积。重复该过程,直到达到所需的 2 次方。

下面是一个创建 Fc=fs/8 且每 4 个样本过零的低通滤波器的示例:

b0=remez(34,[0 .45 .55 1],[1 1 0 0])';
b1=remez(6,[0 .25 .75 1],[1 1 0 0])';
b0up = zeros(1,2*length(b0)-1);
b0up(1:2:end) = b0;
B0up=freqz(b0up);
b2 = conv(b0up,b1);  % length = 34*2+1 + 6 = 75 coefficients

示例过滤器的比较

获得所需过零的一种方法是进行混合设计。

首先使用与通带和阻带同等权重的 Parks-McLellan/Remez 半带滤波器。由于它是一个半带滤波器,因此它在交替样本处将具有零。然后,您可以通过频域中的零填充通过 sin(x)/x 对时域进行插值。

示例:创建一个 fs/12 低通滤波器,每 6 个样本过零。

% prototype Remez filter 
taps=18; 
b = remez(taps,[0 .4 .6 1],[1 1 0 0])';  
% force halfband condition of zeros at every other sample
b(2:2:end)=0;  b(taps/2+1)=.5; 

% zero pad the time domain to give the Gibbs ripple some deadspace
B=fft(b,4*(taps+1) ); 
% split the frequency domain into two halves, split the Nyquist bin
Blo = [ B(1:length(B)/2) 0.5*B(length(B)/2+1) ]; 
Bhi = [ 0.5*B(length(B)/2+1) B(length(B)/2+2:length(B))  ]; 

% insert padding at pi to increase size 3x
Bpad = [ Blo zeros(1,3*length(B)-length(Blo)-length(Bhi) ) Bhi];  
bint = real( ifft(Bpad) ); % this has zeros every 6 samples

就阻带/通带纹波而言,生成的滤波器接近原型,但不如原型好。sin(x)/x 插值确实引入了一些低级振铃。您可能需要稍微过度设计原型滤波器,以在插值滤波器中获得所需的衰减水平。