CSI-DSP  Version 1.0.0
CSI DSP Software Library
函数
有限冲激响应(FIR)抽取器

函数

void csky_fir_decimate_f32 (const csky_fir_decimate_instance_f32 *S, float32_t *pSrc, float32_t *pDst, uint32_t blockSize)
 浮点FIR抽取处理函数 更多...
 
void csky_fir_decimate_fast_q15 (const csky_fir_decimate_instance_q15 *S, q15_t *pSrc, q15_t *pDst, uint32_t blockSize)
 Q15 FIR抽取器处理函数 (快速版本) 更多...
 
void csky_fir_decimate_fast_q31 (csky_fir_decimate_instance_q31 *S, q31_t *pSrc, q31_t *pDst, uint32_t blockSize)
 Q31 FIR抽取器处理函数 (快速版本) 更多...
 
csky_status csky_fir_decimate_init_f32 (csky_fir_decimate_instance_f32 *S, uint16_t numTaps, uint8_t M, float32_t *pCoeffs, float32_t *pState, uint32_t blockSize)
 浮点FIR抽取器的初始化函数 更多...
 
csky_status csky_fir_decimate_init_q15 (csky_fir_decimate_instance_q15 *S, uint16_t numTaps, uint8_t M, q15_t *pCoeffs, q15_t *pState, uint32_t blockSize)
 Q15 FIR抽取器的初始化函数 更多...
 
csky_status csky_fir_decimate_init_q31 (csky_fir_decimate_instance_q31 *S, uint16_t numTaps, uint8_t M, q31_t *pCoeffs, q31_t *pState, uint32_t blockSize)
 Q31 FIR抽取器的初始化函数 更多...
 
void csky_fir_decimate_q15 (const csky_fir_decimate_instance_q15 *S, q15_t *pSrc, q15_t *pDst, uint32_t blockSize)
 Q15 FIR抽取器处理函数 更多...
 
void csky_fir_decimate_q31 (const csky_fir_decimate_instance_q31 *S, q31_t *pSrc, q31_t *pDst, uint32_t blockSize)
 Q31 FIR抽取处理函数 更多...
 

简要说明

这些函数将FIR滤波器和抽取器组合在一起。 它们用于多速率系统中,用于降低信号的采样率而不引入混叠失真。 从概念上讲,这些函数等同于下面的框图:

FIRDecimator.gif
FIR抽取器中的组件

当用因子 M 抽取时, 信号应该通过1/M截止频率的低通滤波器预滤波,防止混叠失真。 函数的使用者负责提供滤波器的系数。

CSI DSP库中的FIR抽取器组合了FIR滤波器和抽取器。 不会计算每个 M 的FIR滤波器输出,丢弃 M-1 , 只计算抽取器的输出样本。 函数以块为单位操作输入和输出数据。 pSrc 指向输入数组,数组大小是 blockSizepDst 指向输出数组,数组大小是 blockSize/M . 为了取得整数个输出样本 blockSize ,输入必须是抽取因子 M 的整数倍数。

为Q15,Q31和浮点分别提供了不同的函数。

算法:
FIR部分的算法使用的是标准形式过滤器:
     y[n] = b[0] * x[n] + b[1] * x[n-1] + b[2] * x[n-2] + ...+ b[numTaps-1] * x[n-numTaps+1]
  
其中, b[n] 是滤波器的系数
pCoeffs 指向系数数组,数组大小是 numTaps. 系数按如下顺序排列保存:
     {b[numTaps-1], b[numTaps-2], b[N-2], ..., b[1], b[0]}
  
pState 指向状态数组,数组大小是 numTaps + blockSize - 1. 样本在状态缓存中保存的顺序是:
     {x[n-numTaps+1], x[n-numTaps], x[n-numTaps-1], x[n-numTaps-2]....x[0], x[1], ..., x[blockSize-1]}
  
状态变量会在每块数据处理后更新,系数不会更新。
结构体实例
滤波器的系数和状态变量都保存在数据结构的实例中。 每个滤波器都必须要有一个结构体实例。 系数数组可能可以在几个实例之间共享,但是状态变量数组必须单独分配。 为浮点,Q31和Q15数据类型分别提供了不同的结构体实例声明。
初始化函数
每种数据类型都有一个相应的初始化函数。 初始化函数处理以下操作:
  • 设置内部结构体字段的值
  • 清零状态缓存
  • 确保输入的大小是抽取因子的整数倍 如果手动初始化,而不调用初始化函数,需要指定结构体实例的以下字段: numTaps, pCoeffs, M (抽取因子), pState. pState中的所有值置0.
是否使用初始化函数是可选的。 但是,使用了初始化函数,则不能将结构体实例放在常量数据段。 要将结构体实例放在常量数据段,则必须手动初始化结构体实例。 下面的代码,为3种不同的滤波器,静态的初始化了结构体实例。
*csky_fir_decimate_instance_f32 S = {M, numTaps, pCoeffs, pState};
*csky_fir_decimate_instance_q31 S = {M, numTaps, pCoeffs, pState};
*csky_fir_decimate_instance_q15 S = {M, numTaps, pCoeffs, pState};
  
其中 M 是抽取因子; numTaps 是滤波器中的系数的数量; pCoeffs 是系数缓存的地址; pState 是状态缓存的地址。 在静态初始化之前,要确保状态缓存中的值已经清零。
定点行为
使用定点FIR抽取器滤波函数需要注意。 特别是要考虑,在每个函数内使用的累加器的溢出和饱和行为。 具体参考每个函数各自的文档和使用说明。

函数说明

void csky_fir_decimate_f32 ( const csky_fir_decimate_instance_f32 S,
float32_t pSrc,
float32_t pDst,
uint32_t  blockSize 
)
参数
[in]*S指向浮点FIR抽取结构体实例
[in]*pSrc指向输入数据块
[out]*pDst指向输出数据块
[in]blockSize输入样本的数量
返回
none.
void csky_fir_decimate_fast_q15 ( const csky_fir_decimate_instance_q15 S,
q15_t pSrc,
q15_t pDst,
uint32_t  blockSize 
)
参数
[in]*S指向Q15 FIR抽取结构体实例
[in]*pSrc指向输入数据块
[out]*pDst指向输出数据块
[in]blockSize输入样本的数量
返回
none
限制
如果芯片不支持分对齐访问,则定义宏 UNALIGNED_SUPPORT_DISABLE 同时,输入,输出,临时buffer,都应该是32位对齐。

缩放和溢出行为:

快速版本实现使用了2.30格式的32位累加器。 累加器维持了中间乘法的所有精度,但是只有一个保护位。 因此如果累加器的结果溢出,会扭曲最后结果。 为了防止溢出,输入信号需要缩小log2(numTaps) 位 (log2 是2为底的对数) 最后,2.30格式的丢弃低15位截断为2.15,然后饱和生成1.15格式的结果。
函数 csky_fir_decimate_q15() 是这个函数的一个慢速版本,使用了64位累加器防止溢出,保留了更多的精度。 慢速和快速版本使用相同的结构体实例。 使用函数 csky_fir_decimate_init_q15() 可以初始化滤波器结构体。
void csky_fir_decimate_fast_q31 ( csky_fir_decimate_instance_q31 S,
q31_t pSrc,
q31_t pDst,
uint32_t  blockSize 
)
参数
[in]*S指向Q31 FIR抽取结构体实例
[in]*pSrc指向输入数据块
[out]*pDst指向输出数据块
[in]blockSize输入样本的数量
返回
none

缩放和溢出行为:

这个函数为了优化速度,舍弃了一些定点精度和溢出保护。 每个 1.31 和 1.31 相乘的结果是 2.30 格式. 这些中间结果在一个2.30累加器相加。 最后累加器饱和转换为1.31的结果。 快速版本跟标准版本的有相同的溢出行为,由于丢弃了低32位相乘结果,维持了更少的精度。 为了防止溢出,输入信号还需要缩小 log2(numTaps) 个位 (其中 log2 是2为底的对数).
函数 csky_fir_decimate_q31() 是这个函数的一个慢速版本,使用了一个64位累加器,提供了更多的精度。 慢速和快速版本使用相同的结构体实例。 使用函数 csky_fir_decimate_init_q31() 可以初始化滤波器结构体。
csky_status csky_fir_decimate_init_f32 ( csky_fir_decimate_instance_f32 S,
uint16_t  numTaps,
uint8_t  M,
float32_t pCoeffs,
float32_t pState,
uint32_t  blockSize 
)
参数
[in,out]*S指向浮点IR抽取器结构体实例
[in]numTaps滤波器系数的数量
[in]M抽取因子
[in]*pCoeffs指向滤波器系数
[in]*pState指向状态缓存
[in]blockSize输入样本的数量
返回
如果函数初始化成功,则返回 CSKY_MATH_SUCCESS ,如果 blockSize 不是 M 的整数倍,则返回CSKY_MATH_LENGTH_ERROR.

描述说明:

pCoeffs 指向的滤波器系数数组,保存的顺序如下:
   {b[numTaps-1], b[numTaps-2], b[N-2], ..., b[1], b[0]}
pState 指向状态变量数组, pState 的长度是 numTaps+blockSize-1 个字,其中 blockSize 是传递给 csky_fir_decimate_f32() 的输入样本数量. M 是抽取因子.
csky_status csky_fir_decimate_init_q15 ( csky_fir_decimate_instance_q15 S,
uint16_t  numTaps,
uint8_t  M,
q15_t pCoeffs,
q15_t pState,
uint32_t  blockSize 
)
参数
[in,out]*S指向Q15 FIR抽取器结构体实例
[in]numTaps滤波器系数的数量
[in]M抽取因子
[in]*pCoeffs指向滤波器系数
[in]*pState指向状态缓存
[in]blockSize输入样本的数量
返回
如果函数初始化成功,则返回 CSKY_MATH_SUCCESS, 如果blockSize 不是M的整数倍,则返回CSKY_MATH_LENGTH_ERROR.

描述说明:

pCoeffs 指向的滤波器系数数组,保存的顺序如下:
   {b[numTaps-1], b[numTaps-2], b[N-2], ..., b[1], b[0]}
pState 指向状态变量数组, pState 的长度是 numTaps+blockSize-1 个字,其中 blockSize 是传递给 csky_fir_decimate_q15() 的输入样本数量. M 是抽取因子.
csky_status csky_fir_decimate_init_q31 ( csky_fir_decimate_instance_q31 S,
uint16_t  numTaps,
uint8_t  M,
q31_t pCoeffs,
q31_t pState,
uint32_t  blockSize 
)
参数
[in,out]*S指向Q31 FIR抽取器结构体实例
[in]numTaps滤波器系数的数量.
[in]M抽取因子.
[in]*pCoeffs指向滤波器系数.
[in]*pState指向状态缓存.
[in]blockSize输入样本的数量.
返回
如果函数初始化成功,则返回 CSKY_MATH_SUCCESS, 如果blockSize 不是M的整数倍,则返回CSKY_MATH_LENGTH_ERROR.

描述说明:

pCoeffs 指向的滤波器系数数组,保存的顺序如下:
   {b[numTaps-1], b[numTaps-2], b[N-2], ..., b[1], b[0]}
pState 指向状态变量数组, pState 的长度是 numTaps+blockSize-1 个字,其中 blockSize 是传递给 csky_fir_decimate_q31() 的输入样本数量. M 是抽取因子.
void csky_fir_decimate_q15 ( const csky_fir_decimate_instance_q15 S,
q15_t pSrc,
q15_t pDst,
uint32_t  blockSize 
)
参数
[in]*S指向Q15 FIR抽取结构体实例
[in]*pSrc指向输入数据块
[out]*pDst指向输出数据块
[in]blockSize输入样本的数量
返回
none.

缩放和溢出行为:

函数实现使用了一个内部64位累加器。 输入数据表示为1.15格式。 中间乘法生成2.30格式的结果,结果在34.30格式的64位累加器累加。 因为有33位保护位,所以不会有溢出的风险。同时还可以保存所有的中间乘法结果的精度。 最后,34.30格式的丢弃低15位截断为34.15,然后饱和生成1.15格式的结果。
函数 csky_fir_decimate_fast_q15() 是这个函数的一个快速版本,但是丢失了更多的精度
void csky_fir_decimate_q31 ( const csky_fir_decimate_instance_q31 S,
q31_t pSrc,
q31_t pDst,
uint32_t  blockSize 
)
参数
[in]*S指向Q31 FIR抽取结构体实例
[in]*pSrc指向输入数据块
[out]*pDst指向输出数据块
[in]blockSize输入样本的数量
返回
none

缩放和溢出行为:

函数实现使用了一个内部64位累加器。 输入数据表示为1.31格式。 中间乘法生成2.62格式的结果,结果在2.62格式的64位累加器累加。 因为只有一个保护位,所以需要缩小输入信号来防止溢出。 因为最多会有numTaps个加法进位,所以需要缩小log2(numTaps)才可以保证没有溢出。 最后,2.62格式右移31位,然后饱和生成1.31格式的结果。
函数 csky_fir_decimate_fast_q31() 是这个函数的一个快速版本,但是丢失了更多的精度。