3.3 极点-零点IIR实现
在上一小节的全极点实现方式中,零点由于较为复杂被省略,若加入零点,IIR的误差会大幅降低。这样生成的仍然是四个极点相同的二阶级联IIR滤波器,然而它们的零点不同。由于它们的极点和3.2中的一样,这里只给出零点(传递函数的分母)部分:
可以看到,它们唯一不同点在于两个符号的正负不同。为了方便实现可以定义一个函数,给定生成零点的第二项的系数的函数,生成一个(或多个)IIR滤波器的参数。用和全极点滤波器类似的方法,以下Matlab代码生成一个(或多个)极点-零点滤波器的参数,给定zero_func函数。
function [B, A] = make_erb_pass_polezero_cascade(fs, pass_freq, pass_band, zero_func)
T = 1 / fs;
f0 = pass_freq;
BW = 1.019 * 2 * pi * pass_band;
E = exp(BW * T);
n_channel = length(pass_freq);
B = zeros(n_channel, 2);
A = zeros(n_channel, 3);
B(:, 1) = T;
B(:, 2) = zero_func(T, f0, E);
A(:, 1) = 1;
A(:, 2) = - 2 * cos(2 * f0 * pi * T) ./ E;
A(:, 3) = E .^ (-2);
cz = exp(- 2 * j * pi * f0 * T);
g = (T + B(:, 2) .* cz) ./ ...
(1 + A(:, 2) .* cz + A(:, 3) .* cz .^ 2);
B(:, 1) ./= abs(g);
B(:, 2) ./= abs(g);
end
类似make_erb_bank_allpole_cascade,以下代码根据采样频率和各频道中心频率生成GTF滤波器组的参数:
function [B1, B2, B3, B4, A] = make_erb_bank_polezero_cascade(fs, bank_freq)
BW = erb_bandwidth(bank_freq);
f0 = bank_freq;
zcoef1 = @(T, cf, E) - (T * cos(2 * f0 * pi * T) ./ E ...
+ sqrt(3 + 2 ^ 1.5) * T * sin(2 * f0 * pi * T) ./ E);
zcoef2 = @(T, cf, E) - (T * cos(2 * f0 * pi * T) ./ E ...
- sqrt(3 + 2 ^ 1.5) * T * sin(2 * f0 * pi * T) ./ E);
zcoef3 = @(T, cf, E) - (T * cos(2 * f0 * pi * T) ./ E ...
+ sqrt(3 - 2 ^ 1.5) * T * sin(2 * f0 * pi * T) ./ E);
zcoef4 = @(T, cf, E) - (T * cos(2 * f0 * pi * T) ./ E ...
- sqrt(3 - 2 ^ 1.5) * T * sin(2 * f0 * pi * T) ./ E);
[B1 A] = make_erb_pass_polezero_cascade(fs, bank_freq, BW, zcoef1);
B2 = make_erb_pass_polezero_cascade(fs, bank_freq, BW, zcoef2);
B3 = make_erb_pass_polezero_cascade(fs, bank_freq, BW, zcoef3);
B4 = make_erb_pass_polezero_cascade(fs, bank_freq, BW, zcoef4);
end
在执行滤波时,唯一的区别是每个滤波器的零点参数不同:function y = gtf_polezero(B1, B2, B3, B4, A, x)
n_channel = rows(A);
y = zeros(length(x), n_channel);
for i = 1:n_channel
y(:, i) = filter(B1(i, :), A(i, :), x);
y(:, i) = filter(B2(i, :), A(i, :), y(:, i));
y(:, i) = filter(B3(i, :), A(i, :), y(:, i));
y(:, i) = filter(B4(i, :), A(i, :), y(:, i));
end
end
下图比较了三种方法(FIR, 全极点IIR,极点-零点IIR)实现的GTF滤波器的脉冲响应和频率响应,FIR应当是最准确的;可以看到全极点IIR产生了较大的频谱倾斜:
极点-零点IIR实现的GTF滤波器带来了性能和质量的折衷,所以这是最为常用的实现方式之一。