FIRLMS
本函数最终求解出一个滤波器,求解过程使用均值方差来修正滤波器系数。主函数计算主要两部分:
- 第一步计算dst的结果,计算公式如下:
src[0]前会接上dlyLine延迟线,下面举例说明:
假设src数组长度len为4,taps数组长度tapsLen为3,则延迟线数组dlyLine长度也为tapsLen,dlyIndex范围[0, tapsLen - 1]
- 如果dlyIndex=0, 实际src数组可看成dlyLine[1],dlyLine[2],src[0],src[1],src[2],src[3]。
- 如果dlyIndex=1, 实际src数组可看成dlyLine[2],dlyLine[0],src[0],src[1],src[2],src[3]。
- 如果dlyIndex=2, 实际src数组可看成dlyLine[0],dlyLine[1],src[0],src[1],src[2],src[3]。
- 第二步修正taps数组,即修正滤波器系数,公式如下:
实际计算过程,每计算出一个dst[n]的值,就用该dst[n],更新一次taps数组。
该函数调用流程如下:
- 调用Init初始化FIRLMSPolicy结构体。
- 调用主函数。
- 调用GetTaps获取修正后的滤波器数组。
- 最后调用Release释放FIRPolicy函数所包含内存(16s、16sc使用32f、32fc初始化及释放)。
函数接口声明如下:
- 获取滤波器数组:
HmppResult HMPPS_FIRLMSGetTaps_32f(const HmppsFIRLMSPolicy_32f* policy, float *outTaps);
HmppResult HMPPS_FIRLMSGetTaps32f_16s(const HmppsFIRLMSPolicy32f_16s* policy, float *outTaps);
- 设置延迟线数组和偏移:
HmppResult HMPPS_FIRLMSSetDlyLine_32f(HmppsFIRLMSPolicy_32f* policy, const float *dlyLine, int32_t dlyLineIndex);
HmppResult HMPPS_FIRLMSSetDlyLine32f_16s(HmppsFIRLMSPolicy32f_16s* policy, const int16_t *dlyLine, int32_t dlyLineIndex);
- 获取延迟线数组和偏移:
HmppResult HMPPS_FIRLMSGetDlyLine_32f(const HmppsFIRLMSPolicy_32f* policy, float *dlyLine, int32_t *dlyLineIndex);
HmppResult HMPPS_FIRLMSGetDlyLine32f_16s(const HmppsFIRLMSPolicy32f_16s* policy, int16_t *dlyLine, int32_t *dlyLineIndex);
- 初始化操作:
HmppResult HMPPS_FIRLMSInit_32f(HmppsFIRLMSPolicy_32f **policy, const float *taps, int32_t tapsLen, const float *dlyLine, int dlyLineIndex);
HmppResult HMPPS_FIRLMSInit32f_16s(HmppsFIRLMSPolicy32f_16s **policy, const float *taps, int32_t tapsLen, const int16_t *dlyLine, int dlyLineIndex);
- 主函数操作:
HmppResult HMPPS_FIRLMS_32f(HmppsFIRLMSPolicy_32f *policy, const float *src, const float *ref, float *dst, int32_t len, float mu);
HmppResult HMPPS_FIRLMS32f_16s(HmppsFIRLMSPolicy32f_16s *policy, const int16_t *src, const int16_t *ref, int16_t *dst, int32_t len, float mu);
- 释放内存操作:
HmppResult HMPPS_FIRLMSRelease_32f(HmppsFIRLMSPolicy_32f *policy);
HmppResult HMPPS_FIRLMSRelease32f_16s(HmppsFIRLMSPolicy32f_16s *policy);
参数
参数名 |
描述 |
取值范围 |
输入/输出 |
---|---|---|---|
src |
指向源向量的指针。 |
非空 |
输入 |
ref |
指向参考向量的指针。 |
非空 |
输入 |
dst |
指向目标向量指针。 |
非空 |
输出 |
len |
源向量、参考向量、目标向量长度。 |
(0, INT_MAX] |
输入 |
taps |
指向滤波器向量的指针。 |
Init函数入参中,taps可以为NULL |
输入 |
tapsLen |
滤波器向量长度。 |
(0, INT_MAX] |
输入 |
dlyLine |
指向延迟线向量指针。 |
SetDIyLine入参中,不能为NULL Init函数入参中,可以为NULL |
输入 |
dlyLineIndex |
延迟线起始元素的偏移量。 |
[INT_MIN, INT_MAX] 实际会映射到[0,tapsLen) |
输入 |
policy(init函数中) |
指向内存存储FIRLMSPolicy的指针的指针。 |
非空 |
输出 |
policy(主函数中和release函数中) |
指向DFTPolicy结构体的指针。 |
非空 |
输入/输出 |
mu |
滤波器适配系数。 |
float数据,需要用户根据实际数据进行调节 |
输入 |
返回值
- 成功:返回HMPP_STS_NO_ERR。
- 失败:返回错误码。
错误码
错误码 |
描述 |
---|---|
HMPP_STS_NO_ERR |
表示没有错误。 |
HMPP_STS_NULL_PTR_ERR |
当任何指定的指针为空时指示错误。 |
HMPP_STS_SIZE_ERR |
当len小于或等于0时指示错误。 |
HMPP_STS_FIR_LEN_ERR |
当tapsLen小于或等于0时指示错误。 |
HMPPS_STS_POLICY_STATE_ERR |
policy结构体状态标识不对。 |
HMPP_STS_MALLOC_FAILED |
函数中进行内存申请失败。 |
注意
- 调用该接口计算之前,必须调用Init接口初始化FIRLMS规范结构。
- FIRLMSPolicy结构体初始化需在Init函数中进行申请的,用户无法自己进行该结构体申请定义。
- FIRLMSPolicy结构体初始化成功后,如果执行主函数失败,必须使用Release函数释放结构体。
- 主函数调用成功后,需要调用GetTaps函数从policy中获取最新的滤波器数组
- src不能和dst是同一数组,否则结果正确性无法保证。
示例
void FIRLMSExample(void) { const int tapsLen = 7; const int len = 32; float src[len] = { 0.15275501, 0.143135, 0.31686401, 0.26976699, 0.72030699, 0.50592899, 0.486655, 0.706716, 0.68356198, 0.77510101, 0.94214898, 1.05799, 1.29482, 1.14037, 1.43979, 1.44664, 1.55493, 1.57329, 1.68367, 1.70401, 1.85473, 1.86356, 2.2176099, 2.1915801, 2.24248, 2.1015699, 2.25688, 2.26349, 2.5790999, 2.6948299, 2.4193299, 2.69561 }; float ref[len]; float dst[len]; float taps[tapsLen]; float mu = 0.0005; for (int i = 0; i < tapsLen; ++i) { taps[i] = 1.0 / tapsLen; } HmppsFIRLMSPolicy_32f *policy = NULL; HmppResult result = HMPPS_FIRLMSInit_32f(&policy, taps, tapsLen, NULL, 0); if (result != HMPP_STS_NO_ERR) { printf("HMPPS_FIRLMSInit_32f result = %d\n", result); return; } result = HMPPS_FIRLMS_32f(policy, src, ref, dst, len, mu); if (result != HMPP_STS_NO_ERR) { printf("HMPPS_FIRLMS_32f result = %d\n", result); return; } printf("Dst: "); for (int i = 0; i < len; ++i) { printf("%f ", dst[i]); } printf("\n"); result = HMPPS_FIRLMSGetTaps_32f(policy, taps); if (result != HMPP_STS_NO_ERR) { printf("HMPPS_FIRLMSGetTaps_32f result = %d\n", result); return; } printf("Taps: "); for (int i = 0; i < tapsLen; ++i) { printf("%f ", taps[i]); } printf("\n"); HMPPS_FIRLMSRelease_32f(policy); }
运行结果:
Dst: 0.021822 0.042269 0.087532 0.126056 0.228895 0.297082 0.365800 0.443564 0.519442 0.570626 0.661690 0.704063 0.808335 0.893767 0.985927 1.080792 1.174086 1.177286 1.238281 1.184714 1.245834 1.165491 1.215122 1.248639 1.280253 1.287248 1.300077 1.297933 1.313811 1.096912 1.071277 0.833319 Taps: 0.031206 0.038017 0.041954 0.050642 0.050239 0.060425 0.061261