tf2sos
来获取二阶部分的系数,这与我预期的4个二阶部分的6x4系数有关。 在实施为SOS之前,8阶滤波器需要存储7个先前的采样值(以及输出值)。现在,当实现为二阶部分时,流程如何从输入到输出工作,我是否只需要存储2个先前的样本值?还是第一个过滤器的输出作为
x_in
馈入第二个过滤器,依此类推?#1 楼
这是您说的最后一句话(“还是第一个过滤器的输出作为x_in馈入第二个过滤器,依此类推?”)。这个想法很简单:您将双二阶视为级联的独立二阶滤波器。第一个滤波器的输出是第二个滤波器的输入,依此类推,因此延迟线分布在各个滤波器之间。如果您需要在内存受限的环境中优化结构,则可以注意到相邻的二元模型具有冗余延迟存储器(即,阶段1的最后几个输出样本与阶段2的最后几个输入样本相同,因此您不必不必像单独隔离过滤器那样单独存储它们。评论
$ \ begingroup $
谢谢!我只是设法在MATLAB中快速做到这一点。早先造成混乱的原因是我忘了增加收益(ugh!),因此各种各样的想法开始蔓延。
$ \ endgroup $
–anasimtiaz
2011-09-12 14:20
$ \ begingroup $
如果您不费吹灰之力从tf2sos请求增益作为输出arg(就像在我发布的示例代码中一样),那么您就不必费心将其再次乘回。
$ \ endgroup $
–learnvst
2012-2-24在17:55
#2 楼
实际上,有两种方法可以实现二阶部分:并行和串行。在串行版本中,第N部分的输出是第N + 1部分的输入。在并行版本中,所有部分都具有相同的输入(并且只有一个实零而不是共轭复数零对),并且每个部分的输出都被简单地求和。这两种方法是通过对Z域传递函数。警告:这是一个数值棘手的问题,对于极点靠近单位圆的典型音频滤波器,标准的Matlab实现“ residuez”可能会产生很大的数值误差。
#3 楼
这里有一些演示代码,以说明为什么更好地级联二阶部分。clc
sr = 44100;
order = 13;
[b,a] = butter(order,1000/(sr/2),'low');
[sos] = tf2sos(b,a);
x = [1; zeros(299,1)]; %impulse
% all in one
Y = filter(b,a,x);
% cascaded biquads
Z = x;
for nn = 1:size(sos,1);
Z = filter(sos(nn,1:3),sos(nn,4:6), Z );
end
cla; plot(Y, 'k'); hold on; plot(Z,':r'); hold off
对于上面示例中给出的低通滤波器,大约12到13的数量级,会增加数值误差,从而给出明显不同的脉冲响应。不使用级联二元组的实现。
ORDER = 10
ORDER = 13
评论
$ \ begingroup $
@learvst如果我错了,请纠正我,但是您的代码却错过了收获。不应该是:[sos gain] = tf2sos(b,a); // nn = 1的其余代码:size(sos,1); Z = filter(sos(nn,1:3),sos(nn,4:6),Z);结束Z = filter(gain,1,Z);
$ \ endgroup $
–user915783
2015年3月30日23:44
评论
您需要为每个阶段存储以前的状态,具体取决于该阶段中过滤器的顺序,因此它不会像您提到的那样只是2