无题
完整的源代码、逐行分析及调用示例
源代码:4阶IIR滤波器实现
1 | typedef float flt32_t; |
代码逐行分析:
结构体定义
-
IirFilter4thCoef
结构体定义:1
2
3
4typedef struct IirFilter4thCoef_ {
flt32_t B[5];
flt32_t A[5];
} IirFilter4thCoef;B[5]
和A[5]
分别表示IIR滤波器的前馈(feedforward)和反馈(feedback)系数。滤波器的输出由这两个系数控制。
-
IirFilter4th
结构体定义:1
2
3
4typedef struct IirFilter4th_ {
flt32_t x_delay[4]; // 前四个输入的延迟
flt32_t y_delay[4]; // 前四个输出的延迟
} IirFilter4th;x_delay[4]
和y_delay[4]
存储最近4个输入和输出的延迟值,帮助计算当前输出。
函数 IirFilter4th_Proc
的实现:
1 | static inline flt32_t IirFilter4th_Proc(flt32_t input, const IirFilter4thCoef *coef, IirFilter4th *filter) |
- 输入参数:
input
:当前输入的信号值。coef
:指向存储滤波器前馈和反馈系数的结构体的指针。filter
:指向滤波器的状态(延迟输入和输出)的指针。
-
初始化变量:
1
2
3flt32_t output;
flt32_t bx = coef->B[0] * input; // 前馈计算从B[0] * input开始
flt32_t ay = 0.f; // 反馈部分初始值bx
是前馈部分的初始值,由当前输入乘以系数B[0]
计算。ay
是反馈部分,初始为0,用于存储反馈项的计算结果。
-
计算前馈和反馈部分:
1
2
3
4
5for (i = 0; i < 4; i++)
{
bx += coef->B[i + 1] * filter->x_delay[i]; // 前馈项
ay += coef->A[i + 1] * filter->y_delay[i]; // 反馈项
}- 该循环对先前的4个输入 (
x_delay
) 和输出 (y_delay
) 进行处理:bx
累加过去的输入值乘以前馈系数B[i+1]
。ay
累加过去的输出值乘以反馈系数A[i+1]
。
- 该循环对先前的4个输入 (
-
计算输出:
1
output = (bx - ay) / coef->A[0]; // 前馈 - 反馈 / A[0]
- 输出值是前馈项减去反馈项,再除以
A[0]
,这符合IIR滤波器的标准公式。
- 输出值是前馈项减去反馈项,再除以
-
更新延迟缓冲区:
1
2
3
4
5
6
7for (i = 3; i > 0; i--)
{
filter->x_delay[i] = filter->x_delay[i - 1]; // 更新x延迟
filter->y_delay[i] = filter->y_delay[i - 1]; // 更新y延迟
}
filter->x_delay[0] = input; // 当前输入保存为最新延迟
filter->y_delay[0] = output; // 当前输出保存为最新延迟- 延迟缓冲区的元素依次向后移动,以保持滤波器的状态。当前输入和输出被放置在缓冲区的最前面 (
x_delay[0]
和y_delay[0]
)。
- 延迟缓冲区的元素依次向后移动,以保持滤波器的状态。当前输入和输出被放置在缓冲区的最前面 (
-
返回输出:
1
return output; // 返回当前滤波后的输出
函数调用示例:
1 |
|
运行示例输出:
1 | Input: 1.00, Output: 0.10 |
总结:
- 结构体
IirFilter4thCoef
:保存了4阶IIR滤波器的前馈系数(B[5]
)和反馈系数(A[5]
)。 - 结构体
IirFilter4th
:保存了滤波器的状态,即最近4个输入(x_delay[4]
)和输出(y_delay[4]
)。 IirFilter4th_Proc
函数:处理每一个输入样本,通过递归的方式结合过去的输入和输出计算当前的输出,并更新滤波器的状态。
通过该实现,您可以对输入信号进行4阶IIR滤波。
评论