---
title: FIRMR
description: "对源矢量执行多速率FIR滤波，多速率是与单速率相对的。"
url: https://www.hikunpeng.com/document/detail/zh/kunpengboostkithistory/2200/accel/kunpengaccel_hmpp_06_0142.html
sourcePath: /source/zh/kunpengboostkithistory/2200/accel/kunpengaccel_hmpp_06_0142.html
indexId: 37afc3fa04cf92f50460ccd706c1605c870f2ea5d4bdbd71289ad4f9cb13a51475
---
# FIRMR

对源矢量执行多速率FIR滤波，多速率是与单速率相对的。

计算taps向量（长度为tapsLen）和src向量（长度为numIters * downFactor）、dlySrc向量（长度为(tapsLen + upFactor - 1) / upFactor）的相关线性点积运算，目标向量存储到dst向量中，延迟线目标向量存储在dlyDst中。

计算公式从FIRSR的计算公式发展而来，如下：

；

；

；

。

其中，

- src是延迟线向量和源向量的组合。
- tapsN是FIR滤波器系数组成的特定序列的二维数组。
- upFactor：滤波信号内部上行采样所依据的因子。即在输入信号的每个样本之间插入upFactor - 1个零。
- upPhase：非零样本在upFactor- 上采样输入信号的长度块内的偏移相位。
- downFactor：FIR响应内部向下采样的因子。即从上采样滤波器响应的每downFactor -上采样滤波器响应的长度输出块中丢弃downFactor-1个输出样本。
- downPhase：非丢弃样本位于上采样滤波器响应块内的偏移相位。
dlySrc向量和dlyDst支持空值：

  - 如果dlySrc为空，该函数使用全零值的延迟线。
  - 如果dlyDst为空，该函数不会将任何数据复制到目标延迟线。

FIRMR函数调用流程如下：

1. 调用Init初始化FIRPolicy结构体，
2. 调用主函数，
3. 最后调用Release释放FIRPolicy函数所包含内存（16s、16sc使用32f、32fc初始化及释放）。

函数接口声明如下：

- 初始化操作：
  HmppResult HMPPS_FIRMRInit_32f(const float *taps, int32_t tapsLen, int32_t upFactor, int32_t upPhase, int32_t downFactor, int32_t downPhase, HmppsFIRPolicy_32f **policy);

  HmppResult HMPPS_FIRMRInit_64f(const double *taps, int32_t tapsLen, int32_t upFactor, int32_t upPhase, int32_t downFactor, int32_t downPhase, HmppsFIRPolicy_64f **policy);

  HmppResult HMPPS_FIRMRInit_32fc(const Hmpp32fc *taps, int32_t tapsLen, int32_t upFactor, int32_t upPhase, int32_t downFactor, int32_t downPhase, HmppsFIRPolicy_32fc **policy);

  HmppResult HMPPS_FIRMRInit_64fc(const Hmpp64fc *taps, int32_t tapsLen, int32_t upFactor, int32_t upPhase, int32_t downFactor, int32_t downPhase, HmppsFIRPolicy_64fc **policy);

  HmppResult HMPPS_FIRMRInit32f_32fc(const float *taps, int32_t tapsLen, int32_t upFactor, int32_t upPhase, int32_t downFactor, int32_t downPhase, HmppsFIRPolicy_32f **policy);

- 主函数操作：
  HmppResult HMPPS_FIRMR_16s(const int16_t *src, int16_t *dst, int32_t numIters, HmppsFIRPolicy_32f *policy, const int16_t *dlySrc, int16_t *dlyDst);

  HmppResult HMPPS_FIRMR_32f(const float *src, float *dst, int32_t numIters, HmppsFIRPolicy_32f *policy, const float *dlySrc, float *dlyDst);

  HmppResult HMPPS_FIRMR_64f(const double *src, double *dst, int32_t numIters, HmppsFIRPolicy_64f *policy, const double *dlySrc, double *dlyDst);

  HmppResult HMPPS_FIRMR_16sc(const Hmpp16sc *src, Hmpp16sc *dst, int32_t numIters, HmppsFIRPolicy_32fc *policy, const Hmpp16sc *dlySrc, Hmpp16sc *dlyDst);

  HmppResult HMPPS_FIRMR_32fc(const Hmpp32fc *src, Hmpp32fc *dst, int32_t numIters, HmppsFIRPolicy_32fc *policy, const Hmpp32fc *dlySrc, Hmpp32fc *dlyDst);

  HmppResult HMPPS_FIRMR_64fc(const Hmpp64fc *src, Hmpp64fc *dst, int32_t numIters, HmppsFIRPolicy_64fc *policy, const Hmpp64fc *dlySrc, Hmpp64fc *dlyDst);

  HmppResult HMPPS_FIRMR32f_32fc(const Hmpp32fc *src, Hmpp32fc *dst, int32_t numIters, HmppsFIRPolicy_32f *policy, const Hmpp32fc *dlySrc, Hmpp32fc *dlyDst);

- 释放内存操作：
  HmppResult HMPPS_FIRMRRelease_32f(HmppsFIRPolicy_32f *policy);

  HmppResult HMPPS_FIRMRRelease_64f(HmppsFIRPolicy_64f *policy);

  HmppResult HMPPS_FIRMRRelease_32fc(HmppsFIRPolicy_32fc *policy);

  HmppResult HMPPS_FIRMRRelease_64fc(HmppsFIRPolicy_64fc *policy);

  HmppResult HMPPS_FIRMRRelease32f_32fc(HmppsFIRPolicy_32f *policy);


#### 参数

| 参数名 | 描述 | 取值范围 | 输入/输出 |
| --- | --- | --- | --- |
| taps | 指向滤波器系数的指针。 | 非空 | 输入 |
| tapsLen | FIR滤波器系数的长度。 | (0, INT\_MAX] | 输入 |
| upFactor | 多速率上采样因子。 | (0, INT\_MAX] | 输入 |
| upPhase | 上采样信号的相位。 | [0, upFactor] | 输入 |
| downFacor | 多速率下采样因子。 | (0, INT\_MAX] | 输入 |
| downPhase | 下采样信号的相位。 | [0, downFacor] | 输入 |
| src | 指向源向量的指针。 | 非空 | 输入 |
| numIters | 与函数过滤的样本数量相关联的迭代次数。源向量的元素(numIters\* downFactor)被过滤，结果(numIter \* upFactor)的样本被存储在目标数组中。 | (0, INT\_MAX] | 输入 |
| dst | 指向目的向量的指针。 | 非空 | 输出 |
| dlySrc | 指向包含源延迟线值向量的指针。 | 向量可以为NULL，如果为非NULL，则数组长度定义为( tapsLen+ upFactor \- 1) / upFactor | 输入 |
| dlyDst | 指向包含目标延迟线值向量的指针。 | 向量可以为NULL，如果为非NULL，则数组长度定义为( tapsLen+ upFactor \- 1) / upFactor | 输出 |
| policy （init函数中） | 指向内存存储FIRPolicy的指针的指针。 | 非空 | 输出 |
| policy （主函数中和release函数中） | 指向FIRPolicy结构体的指针。 | 非空 | 输入 |


#### 返回值

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


#### 错误码

| 错误码 | 描述 |
| --- | --- |
| HMPP\_STS\_NO\_ERR | 表示没有错误。 |
| HMPP\_STS\_NULL\_PTR\_ERR | 当任何指定的指针为空时指示错误。 |
| HMPP\_STS\_SIZE\_ERR | 当tapsLen或numIters小于或等于0时指示错误。 |
| HMPP\_STS\_OVERFLOW\_ERR | 指示计算溢出时错误。 |
| HMPP\_STS\_FIRMR\_FACTOR\_ERR | 采样因子小于或等于0时错误。 |
| HMPP\_STS\_FIRMR\_PHASE\_ERR | 相位小于0或采用因子小于相位时错误。 |
| HMPP\_STS\_MALLOC\_FAILED | Init函数中进行算法模型所需内存申请失败。 |


#### 注意

- 调用该接口计算之前，必须调用Init接口初始化FIRPolicy规范结构。
- FIRPolicy结构体初始化需在Init函数中进行申请的，用户无法自己进行该结构体申请定义。
- FIRPolicy结构体初始化成功后，如果执行主函数失败，必须使用Release函数释放结构体。
- src不能和dst是同一数组，否则可能导致结果错误。


#### 示例

```
#define TPAS_SIZE_S 8
#define UP_FACTOR_SIZE_S 5
#define UP_PHASE_SIZE_S 4
#define DOWN_FACTOR_SIZE_S 3
#define DOWN_PHASE_SIZE_S 2
#define NUM_ITERS_SIZE_S 2
void FIRMRExample(void)
{
int32_t tapsLen = TPAS_SIZE_S;
int32_t upFactor = UP_FACTOR_SIZE_S;
int32_t upPhase = UP_PHASE_SIZE_S;
int32_t downFacor = DOWN_FACTOR_SIZE_S;
int32_t downPhase = DOWN_PHASE_SIZE_S;
int32_t numIters = NUM_ITERS_SIZE_S;
float taps[TPAS_SIZE_S] = { -0.023, -3.1463, 35.5304, -0.0622, 0.2213, 0.0127, 0.0183, 59.8159 };
float src[NUM_ITERS_SIZE_S * DOWN_FACTOR_SIZE_S] = { 0.3065, -1.8737, -58.7455, 155.8426, -0.0294, 4.3917 };
float dlySrc[(TPAS_SIZE_S + UP_FACTOR_SIZE_S - 1) / UP_FACTOR_SIZE_S] = { 0.2107, -40.6842};
float dst[NUM_ITERS_SIZE_S * UP_FACTOR_SIZE_S] = { 0.0f };
float dlyDst[TPAS_SIZE_S - 1] = { 0.0f };
HmppsFIRPolicy_32f *policy = NULL;
HmppResult result;
result = HMPPS_FIRMRInit_32f(taps, tapsLen, upFactor, upPhase, downFacor, downPhase, &policy);
printf("HMPPS_FIRMRInit_32f result = %d\n", result);
if (result != HMPP_STS_NO_ERR) {
return;
}
result = HMPPS_FIRMR_32f(src, dst, numIters, policy, dlySrc, dlyDst);
printf("HMPPS_FIRMR_32f result = %d\n", result);
HMPPS_FIRMRRelease_32f(policy);
policy = NULL;
if (result != HMPP_STS_NO_ERR) {
return;
}
int32_t i;
int32_t dstLen = numIters * upFactor;
int32_t dlyLen = (tapsLen + upFactor - 1) / upFactor;
printf("dstLen = %d\ndst =", dstLen);
for(i = 0; i < dstLen; ++i){
printf(" %f", dst[i]);
}
printf("\ndlyDstLen = %d\ndst2 =", dlyLen);
for(i = 0; i < dlyLen; ++i){
printf(" %f", dlyDst[i]);
}
printf("\n");
}
```

运行结果：

```
HMPPS_FIRMRInit_32f result = 0
HMPPS_FIRMR_32f result = 0
dstLen = 10
dst = 2.530557 -1.708862 0.067828 -48.239738 1.327350 3.653970 -491.402649 34.487968 9320.820312 -0.101382
dlyDstLen = 2
dst2 = -0.029400 4.391700
```
