IIR
Initializes an infinite impulse response (IIR) filter and performs filtering.
HMPP supports two types of IIR filters: arbitrary-order filter and biquad filter. The input vector X[n] is stored in src, and the output vector y[n] is stored in dst.
For details, see Figure 1.
X[n] is the input, y[n] is the output, order is the filter order, and a and b are filter taps. The calculation formula is as follows:

In this formula,
and
. order indicates the length of the initial filter tap vector arranged in the following sequence: 
src and dst can be the same array and support in-place operations. IIR accepts a delay line whose length is order. The delay line can be null. If the delay line is null, it is padded with 0s. After the filtering operation is complete, the delay line is updated.
The biquad filter is a cascade of second-order IIR filters. Figure 2 shows a biquad filter formed by k second-order filters.
HMPP supports only delay lines in Direct Form 2 (DF2). The delay lines returned or set by the HMPPS_IIRGetDlyLine and HMPPS_IIRSetDlyLine functions are also in the form of DF2. Compared with DF1, a DF2 delay line has only half of the number of elements in the corresponding DF1 delay line. A delay line in DF2 contains values calculated based on the corresponding DF1 delay line. To obtain the DF1 delay line, copy the src array and the last order elements in the dst array after calculation.
The function calling process is as follows:
- Call IIRInit to perform initialization.
- Call IIR to perform filtering.
- Call IIRGetDlyLine or IIRSetDlyLine to retrieve and set the delay line.
- Call IIRRelease to release the memory requested by IIRInit.
The function interface is declared as follows:
- Initialization:
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);
- Obtaining the delay line:
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);
- Setting the delay line:
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);
- Filtering:
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);
- Memory release:
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);
Parameters
Parameter |
Description |
Value Range |
Input/Output |
|---|---|---|---|
taps |
Pointer to filter taps |
Not null |
Input |
order |
Order of the IIR filter |
(0, INT_MAX] |
Input |
src |
Pointer to the source vector |
Not null |
Input |
dst |
Pointer to the destination vector |
Not null |
Output |
len |
Length of the source vector and destination vector |
(0, INT_MAX] |
Input |
numBq |
Number of cascading levels of the biquad filter |
(0, INT_MAX] |
Input |
dlyLine (in the Init and setDly functions) |
Pointer to the delay line vector |
The vector can be null. If it is null, the delay line is padded with 0s. |
Input |
dlyLine (in the getDly function) |
Pointer to the delay line values |
Not null |
Output |
policy (in the Init function) |
Pointer to the pointer to the IIRPolicy structure |
Not null |
Output |
policy (in the setDly function) |
Pointer to the IIRPolicy structure |
Not null |
Input |
policy (in the filter and release functions) |
Pointer to the IIRPolicy structure |
Not null |
Input |
Return Value
- Success: HMPP_STS_NO_ERR
- Failure: An error code is returned.
Error Codes
Error Code |
Description |
|---|---|
HMPP_STS_NO_ERR |
No error occurs. |
HMPP_STS_NULL_PTR_ERR |
Any of the specified pointers is null. |
HMPP_STS_SIZE_ERR |
The value of len is less than or equal to 0. |
HMPP_STS_DIV_BY_ZERO_ERR |
Divide-by-zero error. |
HMPP_STS_CONTEXT_MATCH_ERR |
The policy state is incorrect (an incorrect Init function is used). |
HMPP_STS_MALLOC_FAILED |
The Init function failed to allocate the memory required by the algorithm model. |
- Before this interface is called for calculation, the Init interface must be called to initialize the IIRPolicy standard structure.
- The initialization of the IIRPolicy structure must be applied for in the Init function. You cannot apply for or define this structure by yourself.
- After the IIRPolicy structure has been initialized, if a main function fails to be executed, the Release function must be used to release the structure.
- src and dst can be the same array, that is, in-place operations are allowed.
- The initialization functions of IIR and IIR BiQuad are different. Other operations share the same set of functions.
IIR Example
#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;
}
Output:
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
IIR BiQuad Example
#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;
}
Output:
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


