初始化一个无限脉冲响应(IIR)滤波器并进行滤波。
HMPP支持两种IIR滤波器:任意阶滤波器和BiQuad滤波器。输入向量X[n]将被存储在src中,输出向量y[n]存储在dst中。
如图1所示描述了任意阶滤波器的结构。
其中X[n]为输入,y[n]为输出,order为滤波器阶数,a、b为滤波器系数,计算公式:
其中,
,滤波器初始系数向量长度为order,排列顺序为:
。
其中src和dst允许是同一个数组,支持原地操作。IIR接受长度为order延迟线,延迟线运行为空,若为空,会将延迟线会用0填充。滤波计算完成后,延迟线将会被更新。
BiQuad滤波器是二阶IIR滤波器的级联,如图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函数调用流程如下:
函数接口声明如下:
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_NULL_PTR_ERR |
当任何指定的指针为空时指示错误。 |
HMPP_STS_SIZE_ERR |
当len小于或等于0时指示错误。 |
HMPP_STS_DIV_BY_ZERO_ERR |
除0错误, |
HMPP_STS_CONTEXT_MATCH_ERR |
表示Policy状态不正确时出错(使用了错误的Init函数)。 |
HMPP_STS_MALLOC_FAILED |
Init函数中进行算法模型所需内存申请失败。 |
#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
#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