---
title: IIR
description: "初始化一个无限脉冲响应（IIR）滤波器并进行滤波。"
url: https://www.hikunpeng.com/document/detail/zh/kunpengboostkithistory/251RC1/accel/kunpengaccel_hmpp_06_0284.html
sourcePath: /source/zh/kunpengboostkithistory/251RC1/accel/kunpengaccel_hmpp_06_0284.html
indexId: 9d8a7ff4e154ebb43d17264f93b58e086daf31a651d02d86b502c02037eac28877
---
# IIR

初始化一个无限脉冲响应（IIR）滤波器并进行滤波。

HMPP支持两种IIR滤波器：任意阶滤波器和BiQuad滤波器。输入向量X[n]将被存储在src中，输出向量y[n]存储在dst中。

如图1所示描述了任意阶滤波器的结构。

图1 任意阶滤波器结构

其中X[n]为输入，y[n]为输出，order为滤波器阶数，a、b为滤波器系数，计算公式：


其中，，滤波器初始系数向量长度为order，排列顺序为：。

其中src和dst允许是同一个数组，支持原地操作。IIR接受长度为order延迟线，延迟线运行为空，若为空，会将延迟线会0填充。滤波计算完成后，延迟线将会被更新。

BiQuad滤波器是二阶IIR滤波器的级联，如图2所示描述了k个二阶滤波器组成的BiQuad滤波器。

图2 k个二阶滤波器组成的BiQuad滤波器

HMPP仅支持Direct Form 2（DF2）形式的延迟线。HMPPS_IIRGetDlyLine和HMPPS_IIRSetDlyLine函数返回/设置的延迟线也是DF2形式的。相较于Direct Form 1（DF1）形式的延迟线，存储DF2形式的延迟线元素的个数少一半。DF2形式的延迟线可以由DF1形式延迟线计算得到的信息，如果需要DF1形式的延迟线，请拷贝src数组和计算完成后dst数组的后order个元素作为DF1形式的延迟线。

IIR函数调用流程如下：

1. 使用对应的IIRInit函数进行初始化。
2. 使用IIR进行滤波操作。
3. 再使用IIRGetDlyLine或者IIRSetDlyLine检索设置延迟线。
4. 最后再使用IIRRelease对IIRInit申请的内存进行释放。

函数接口声明如下：

- 初始化操作：
  HmppResult HMPPS_IIRInit_32f(HmppsIIRPolicy_32f **policy, const float *taps, int order, const float *dlyLine);

  HmppResult HMPPS_IIRInit_64f(HmppsIIRPolicy_64f **policy, const double *taps, int order, const double *dlyLine);

  HmppResult HMPPS_IIRInit_32fc(HmppsIIRPolicy_32fc **policy, const Hmpp32fc *taps, int order, const Hmpp32fc *dlyLine);

  HmppResult HMPPS_IIRInit_64fc(HmppsIIRPolicy_64fc **policy, const Hmpp64fc *taps, int order, const Hmpp64fc *dlyLine);

  HmppResult HMPPS_IIRInit_BiQuad_32f(HmppsIIRPolicy_32f **policy, const float *taps, int numBq, const float *dlyLine);

  HmppResult HMPPS_IIRInit_BiQuad_64f(HmppsIIRPolicy_64f **policy, const double *taps, int numBq, const double *dlyLine);

  HmppResult HMPPS_IIRInit_BiQuad_32fc(HmppsIIRPolicy_32fc **policy, const Hmpp32fc *taps, int numBq, const Hmpp32fc *dlyLine);

  HmppResult HMPPS_IIRInit_BiQuad_64fc(HmppsIIRPolicy_64fc **policy, const Hmpp64fc *taps, int numBq, const Hmpp64fc *dlyLine);


- 获取延迟线操作：
  HmppResult HMPPS_IIRGetDlyLine_32f(const HmppsIIRPolicy_32f *policy, float *dlyLine);

  HmppResult HMPPS_IIRGetDlyLine_64f(const HmppsIIRPolicy_64f *policy, double *dlyLine);

  HmppResult HMPPS_IIRGetDlyLine_32fc(const HmppsIIRPolicy_32fc *policy, Hmpp32fc *dlyLine);

  HmppResult HMPPS_IIRGetDlyLine_64fc(const HmppsIIRPolicy_64fc *policy, Hmpp64fc *dlyLine);


- 设置延迟线操作：
  HmppResult HMPPS_IIRSetDlyLine_32f(HmppsIIRPolicy_32f *policy, const float *dlyLine);

  HmppResult HMPPS_IIRSetDlyLine_64f(HmppsIIRPolicy_64f *policy, const double *dlyLine);

  HmppResult HMPPS_IIRSetDlyLine_32fc(HmppsIIRPolicy_32fc *policy, const Hmpp32fc *dlyLine);

  HmppResult HMPPS_IIRSetDlyLine_64fc(HmppsIIRPolicy_64fc *policy, const Hmpp64fc *dlyLine);


- 滤波操作：
  HmppResult HMPPS_IIR_32f(const float *src, float *dst, int len, HmppsIIRPolicy_32f *policy);

  HmppResult HMPPS_IIR_64f(const double *src, double *dst, int len, HmppsIIRPolicy_64f *policy);

  HmppResult HMPPS_IIR_32fc(const Hmpp32fc *src, Hmpp32fc *dst, int len, HmppsIIRPolicy_32fc *policy);

  HmppResult HMPPS_IIR_64fc(const Hmpp64fc *src, Hmpp64fc *dst, int len, HmppsIIRPolicy_64fc *policy);


- 释放内存操作：
  HmppResult HMPPS_IIRRelease_32f(HmppsIIRPolicy_32f *policy);

  HmppResult HMPPS_IIRRelease_64f(HmppsIIRPolicy_64f *policy);

  HmppResult HMPPS_IIRRelease_32fc(HmppsIIRPolicy_32fc *policy);

  HmppResult HMPPS_IIRRelease_64fc(HmppsIIRPolicy_64fc *policy);

  HmppResult HMPPS_IIRRelease_BiQuad_32f(HmppsIIRPolicy_32f *policy);

  HmppResult HMPPS_IIRRelease_BiQuad_64f(HmppsIIRPolicy_64f *policy);

  HmppResult HMPPS_IIRRelease_BiQuad_32fc(HmppsIIRPolicy_32fc *policy);

  HmppResult HMPPS_IIRRelease_BiQuad_64fc(HmppsIIRPolicy_64fc *policy);


#### 参数

| 参数名 | 描述 | 取值范围 | 输入/输出 |
| --- | --- | --- | --- |
| taps | 指向滤波器系数的指针。 | 非空 | 输入 |
| order | IIR滤波器的阶数。 | (0, INT\_MAX] | 输入 |
| src | 指向源向量指针 | 非空 | 输入 |
| dst | 指向目标向量的指针。 | 非空 | 输出 |
| len | 源向量和目标向量长度 | (0, INT\_MAX] | 输入 |
| numBq | BiQuad滤波器的级数。 | (0, INT\_MAX] | 输入 |
| dlyLine（init和setDly函数中） | 指向包含延迟线向量的指针。 | 向量可以为NULL，如果为NULL，则用全零填充延迟线。 | 输入 |
| dlyLine（getDly函数中） | 指向延迟线值的指针。 | 非空 | 输出 |
| policy（init函数中） | 指向内存存储IIRPolicy的指针的指针。 | 非空 | 输出 |
| policy（setDly函数中） | 指向IIRPolicy结构体的指针。 | 非空 | 输入 |
| policy（滤波函数中和release函数中） | 指向IIRPolicy结构体的指针。 | 非空 | 输入 |


#### 返回值

- 成功：返回HMPP_STS_NO_ERR。
- 失败：返回错误码。


#### 错误码

| 错误码 | 描述 |
| --- | --- |
| HMPP\_STS\_NO\_ERR | 表示没有错误。 |
| HMPP\_STS\_NULL\_PTR\_ERR | 当任何指定的指针为空时指示错误。 |
| HMPP\_STS\_SIZE\_ERR | 当len小于或等于0时指示错误。 |
| HMPP\_STS\_DIV\_BY\_ZERO\_ERR | 除0错误，不能为0。 |
| HMPP\_STS\_CONTEXT\_MATCH\_ERR | 表示Policy状态不正确时出错（使用了错误的Init函数）。 |
| HMPP\_STS\_MALLOC\_FAILED | Init函数中进行算法模型所需内存申请失败。 |


- 调用该接口计算之前，必须调用Init接口初始化IIRPolicy规范结构。
- IIRPolicy结构体初始化需在Init函数中进行申请的，用户无法自己进行该结构体申请定义。
- IIRPolicy结构体初始化成功后，如果执行主函数失败，必须使用Release函数释放结构体。
- src和dst支持是同一数组，即原地（inplace）操作。
- IIR和IIR BiQuad的初始化函数不同，其他操作共用一套函数。


#### IIR示例

```
#define ORDER 4
#define TAPS_LEN ( (ORDER + 1) * 2)
#define SRC_LEN 10
#define DLY_LEN ORDER
void IIRExample(void) {
float taps[TAPS_LEN] = {0.0390, -0.1560, 0.2340, -0.1560, 0.0390, 1.0000, 0.9532, 0.7746, 0.2338, 0.0366};
float src[SRC_LEN] = {186, 431, 689, 206, 716, 90, 695, -153};
float dlySrc[DLY_LEN] = {123, 312, 781, 249};
float dlyDst[DLY_LEN];
float dst[SRC_LEN];
HmppsIIRPolicy_32f *policy = NULL;
HmppResult result;
result = HMPPS_IIRInit_32f(&policy, taps, ORDER, dlySrc);
printf("HMPPS_IIRInit_32f result = %d\n", result);
if (result != HMPP_STS_NO_ERR) {
return;
}
result = HMPPS_IIR_32f(src, dst, SRC_LEN, policy);
printf("HMPPS_IIR_32f result = %d\n", result);
if (result != HMPP_STS_NO_ERR) {
return;
}
int32_t i;
printf("dstLen = %d\ndst =", SRC_LEN);
for (i = 0; i < SRC_LEN; ++i) {
printf(" %f", dst[i]);
}
HMPPS_IIRGetDlyLine_32f(policy, dlyDst);
printf("\ndlyDstLen = %d\ndlyDst =", DLY_LEN);
for (i = 0; i < DLY_LEN; ++i) {
printf(" %f", dlyDst[i]);
}
printf("\n");
HMPPS_IIRRelease_32f(policy);
policy = NULL;
}
```

运行结果：

```
HMPPS_IIRInit_32f result = 0
HMPPS_IIR_32f result = 0
dstLen = 10
dst = 130.253998 175.634888 515.849060 -436.819489 68.000931 -4.148865 209.873474 -393.737732 411.605988 -276.982147
dlyDstLen = 4
dlyDst = 80.536873 126.760712 49.693642 10.137547
```


#### IIRBiQuad示例

```
#define NUM_BQ 2
#define TAPS_LEN (NUM_BQ * 6)
#define SRC_LEN 8
#define DLY_LEN (NUM_BQ * 2)
void BiQuadExample(void) {
float taps[TAPS_LEN] = {0.1980326, -0.39606521, 0.1980326, 1., 0.40919919, 0.2013296, 0.197444, -0.394888,  0.197444, 1., 0.41195841, 0.20173442};
float src[SRC_LEN] = {186, 431, 689, 206, 716, 90, 695, -153};
float dlySrc[DLY_LEN] = {694.24421981, -100.19274855, -681.3183156 , -324.66495805};
float dlyDst[DLY_LEN];
float dst[SRC_LEN];
HmppsIIRPolicy_32f *policy = NULL;
HmppResult result;
result = HMPPS_IIRInit_BiQuad_32f(&policy, taps, NUM_BQ, dlySrc);
printf("HMPPS_IIRInit_BiQuad_32f result = %d\n", result);
if (result != HMPP_STS_NO_ERR) {
return;
}
result = HMPPS_IIR_32f(src, dst, SRC_LEN, policy);
printf("HMPPS_IIR_32f result = %d\n", result);
if (result != HMPP_STS_NO_ERR) {
return;
}
int32_t i;
printf("dstLen = %d\ndst =", SRC_LEN);
for (i = 0; i < SRC_LEN; ++i) {
printf(" %f", dst[i]);
}
HMPPS_IIRGetDlyLine_32f(policy, dlyDst);
printf("\ndlyDstLen = %d\ndlyDst =", DLY_LEN);
for (i = 0; i < DLY_LEN; ++i) {
printf(" %f", dlyDst[i]);
}
printf("\n");
HMPPS_IIRRelease_32f(policy);
policy = NULL;
}
```

运行结果：

```
HMPPS_IIRInit_BiQuad_32f result = 0
HMPPS_IIR_32f result = 0
dstLen = 8
dst = -536.971313 -468.691376 601.606384 -250.059616 58.091927 -136.327194 271.481598 -341.952698
dlyDstLen = 4
dlyDst = 280.199768 41.936638 291.383179 -1.857876
```
