我要评分
获取效率
正确性
完整性
易理解

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.

Figure 1 Structure of an arbitrary-order filter

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.

Figure 2 Biquad filter containing 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:

  1. Call IIRInit to perform initialization.
  2. Call IIR to perform filtering.
  3. Call IIRGetDlyLine or IIRSetDlyLine to retrieve and set the delay line.
  4. 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. cannot be 0.

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