【问题标题】:How to implement IIR filters in C?如何在 C 中实现 IIR 滤波器?
【发布时间】:2014-10-27 17:09:24
【问题描述】:

我正在尝试在 C 中实现简单的 IIR(直接形式 I)过滤器。

对于高通(10 Hz,每秒 256 个样本)我这样做:

int Diff = Sample - Previous_Sample;

HP_Output = ((HP_Output + Diff) * 4) / 5;

对于低通(10 Hz @ 32 个样本/秒)我这样做:

int Diff = Sample - LP_Output ;

LP_Output = ((LP_Output + Diff) * 2) / 3; 

现在我想知道:这两种实现在数学上是否正确?

如果我想改变输入采样率(或滤波器频率),我该如何计算新的因子?

【问题讨论】:

  • 您的代码中完全缺少的是时间。采样率很重要。一个实用的过滤器使用许多样本,而不仅仅是一个。使用谷歌查找答案,最佳查询是“iir 系数计算器”。
  • @HansPassant 我为每个样本调用该函数(每秒 256 个样本)
  • 不是我的意思,您必须存储旧样本。记录在 T-1、T-2、T-3 等处。您需要一个数组。一旦你阅读了谷歌点击,这将非常明显,你将不得不花时间。
  • @HansPassant 我将过滤后的样本直接存储到磁盘,所以我没有可用历史记录的数组,但为什么这与过滤器有关?此外,历史记录间接包含在 HP_Output 和 LP_Output 中。
  • 嗯,当然可以。甚至您的 sn-p 也有历史记录,它是 Previous_Sample。只有一个,你不能得到比一阶过滤器更好的东西。当然,存储更多内容完全是微不足道的,循环缓冲区使其高效。很难猜出心理障碍。

标签: c filter filtering signal-processing


【解决方案1】:

高通输出对于一阶滤波器实现是正确的。 从high-pass filter realization on wikipedia,给定采样率fs和滤波器截止频率fc,所需因子alpha可以从关系式中得到:

产生:

在提供的 sn-p 中,这将导致 alpha ~ 4/5

对于一阶低通滤波器,您的代码基本上只输出缩放的输入样本(自 LP_Output + Diff == LP_Output + Sample - LP_Output == Sample 起)。相反,我希望:

LP_Output = LP_Output + Diff * 2 / 3;

现在,因子alpha 可以类似地从基于low-pass filter realization on wikipedia 的推导中获得:

同样,在提供的 sn-p 中,这会导致 alpha ~ 2/3

最后,正如 Hans 在 cmets 中指出的那样,对于高阶滤波器实现,您应该查看 IIR 滤波器设计工具来导出系数。

【讨论】:

  • 我不太明白您将 'LP_Output = ((LP_Output + Diff) * 2) / 3' 更改为 'LP_Output = LP_Output + Diff * 2 / 3' 的建议,因为它似乎没有对结果有什么影响吗?两行代码输出相同的值?
  • LP_Output + Diff * 2 / 3 等价于LP_Output + (Diff * 2 / 3)。例如,如果当前 LP_Output 是 42,而新输入 Sample 是 6,那么您的代码将给出 Diff == 6-42 == -36,然后更新 LP_Output == ((42 + -36) * 2)/3 == ((6)*2)/3 == 4。我的版本将LP_Output 更新为`LP_Output == 42 + -36*2/3 == 42 + (-24) == 18。
猜你喜欢
  • 2014-05-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-03-23
  • 2012-04-06
  • 1970-01-01
相关资源
最近更新 更多