|
void | csky_biquad_cascade_df1_f32 (const csky_biquad_casd_df1_inst_f32 *S, float32_t *pSrc, float32_t *pDst, uint32_t blockSize) |
|
void | csky_biquad_cascade_df1_fast_q15 (const csky_biquad_casd_df1_inst_q15 *S, q15_t *pSrc, q15_t *pDst, uint32_t blockSize) |
|
void | csky_biquad_cascade_df1_fast_q31 (const csky_biquad_casd_df1_inst_q31 *S, q31_t *pSrc, q31_t *pDst, uint32_t blockSize) |
|
void | csky_biquad_cascade_df1_init_f32 (csky_biquad_casd_df1_inst_f32 *S, uint8_t numStages, float32_t *pCoeffs, float32_t *pState) |
| 浮点二阶级联滤波器的初始化函数 更多...
|
|
void | csky_biquad_cascade_df1_init_q15 (csky_biquad_casd_df1_inst_q15 *S, uint8_t numStages, q15_t *pCoeffs, q15_t *pState, int8_t postShift) |
|
void | csky_biquad_cascade_df1_init_q31 (csky_biquad_casd_df1_inst_q31 *S, uint8_t numStages, q31_t *pCoeffs, q31_t *pState, int8_t postShift) |
|
void | csky_biquad_cascade_df1_q15 (const csky_biquad_casd_df1_inst_q15 *S, q15_t *pSrc, q15_t *pDst, uint32_t blockSize) |
| Q15二阶级联滤波器处理函数 更多...
|
|
void | csky_biquad_cascade_df1_q31 (const csky_biquad_casd_df1_inst_q31 *S, q31_t *pSrc, q31_t *pDst, uint32_t blockSize) |
| Q31二阶级联滤波器处理函数 更多...
|
|
这些函数实现了任意阶递归(IIR)滤波器。 滤波器是由二阶单元Biquad级联实现。 为Q15,Q31和浮点数据类型都提供了函数。
函数以块单位操作输入输出数据。每次调用函数通过滤波器处理 blockSize
个样本。 pSrc
指向输入数组数据, pDst
指向输出数组数据。 两个数组都包含 blockSize
个数值.
- 算法
- 每个二阶阶段都使用差分方程实现一个二阶滤波:
y[n] = b0 * x[n] + b1 * x[n-1] + b2 * x[n-2] + a1 * y[n-1] + a2 * y[n-2]
直接I型每个阶段使用5个系数和4个状态变量。
单个二阶滤波阶段
系数 b0, b1 和 b2
与输入信号 x[n]
相乘,并且被称为前馈系数。 系数 a1
和 a2
与输出信号 y[n]
相乘,并且被称为反馈系数。
- 需要注意反馈系数的符号. 有些设计工具使用差分方程:
y[n] = b0 * x[n] + b1 * x[n-1] + b2 * x[n-2] - a1 * y[n-1] - a2 * y[n-2]
这种情况下,反馈系数 a1
和 a2
在使用CSI DSP库的时候,必须取相反数。
- 高阶滤波器通过级联的二阶单元实现。
numStages
指定使用了多少二阶阶段。 比如,第8阶滤波器是numStages=4
的二阶阶段。
使用二阶级联的8阶滤波器
第9阶滤波器可以看做 numStages=5
的二阶阶段,系数配置为第一阶 (b2=0
和 a2=0
).
pState
指向状态变量数组. 每个二阶阶段有4个状态变量 x[n-1], x[n-2], y[n-1],
和 y[n-2]
. 状态变量被排列在 pState
:
{x[n-1], x[n-2], y[n-1], y[n-2]}
- 阶段1使用最开始的4个状态变量,阶段2使用接下来的4个状态变量,依次类推。 状态变量数组总共有
4*numStages
个值。 每个块数据处理会更新状态变量,不会更新系数。
- 结构体实例
- 滤波器的系数和状态变量都保存在数据结构中。 每个滤波器都必须有一个单独的结构体实例。 系数数组可能可以在几个实例共享,但是变量数组不能共享。 支持的3种数据类型都有定义不同的结构体实例类型.
- 初始化函数
- 每种数据类型都有相应的初始化函数。 初始化函数处理以下操作:
- 设置数据结构字段的值.
- 清零状态buffer的值. 不使用初始化函数,手动处理这些操作,需要设置结构体实例内的以下字段: numStages, pCoeffs, pState. 将pState的所有值置0.
- 是否使用初始化函数是可选的. 但是,如果使用初始化函数,则结构体实例不能被放在常量数据段。 想要将结构体实例放在常量数据段,则必须手动的初始化结构体实例。 在静态初始化之前,先把状态buffer中的值置0。 下列代码演示了静态初始化3中不同数据类型的滤波器的结构体实例。
csky_biquad_casd_df1_inst_f32 S1 = {numStages, pState, pCoeffs};
csky_biquad_casd_df1_inst_q15 S2 = {numStages, pState, pCoeffs, postShift};
csky_biquad_casd_df1_inst_q31 S3 = {numStages, pState, pCoeffs, postShift};
其中 numStages
是滤波器中二阶阶段的数量; pState
是状态buffer的地址; pCoeffs
是系数buffer的地址; postShift
是移位数.
- 定点行为
- 使用Q15和Q31版本的二阶级联滤波函数需要多加注意。 需要考虑以下问题:
- 系数的缩放: 滤波器系数表示为小数值,并且系数限制在
[-1 +1)
范围之间. 定点函数有一个额外的缩放参数 postShift
, 用于给滤波器系数放大到超过[+1 -1)
范围。 滤波器的累加器的输出是一个移位寄存器,结果移动postShift
位.
定点二阶累加后带移位
这本质上将滤波器的系数缩放了2^postShift
倍. 比如,为了表示系数
{1.5, -0.8, 1.2, 1.6, -0.9}
可以设置pCoeffs数组为:
{0.75, -0.4, 0.6, 0.8, -0.45}
并且设置postShift=1
- 滤波器增益: 二阶滤波器的频率响应是它函数的一个系数。 通过滤波器的增益可能超过1.0,这意味着滤波器增加了某些频率的幅度。 这意味着幅度小于1.0的输入信号可能导致输出大于 1.0,因此基于滤波器的实现,这些信号可能会饱和或溢出。 为了避免这种行为,滤波器需要按比例缩小,使得其峰值增益小于1.0,或输入信号必须按比例缩小,以便输入和滤波器的组合不会溢出
- 溢出和饱和: 对于Q15和Q31版本, 在各自函数的说明文档分别描述.
- 参数
-
[in] | *S | 指向一个浮点二阶级联结构实例 |
[in] | *pSrc | 指向输入数据块 |
[out] | *pDst | 指向输出数据块 |
[in] | blockSize | 每个块需要处理的样本数量 |
- 返回
- none.
- 参数
-
[in] | *S | 指向Q15二阶级联数据结构实例. |
[in] | *pSrc | 指向输入数据块 |
[out] | *pDst | 指向输出数据块 |
[in] | blockSize | 处理的样本数量 |
- 返回
- none.
缩放和溢出行为:
- 快速版本使用一个2.30格式的32位累加器。 累加器维持了中间乘法结果的所有精度,但是只有一个守护位。 因此,如果累加器结果溢出,会往符号位覆盖,而不是截断。 为了防止溢出,输入信号必须先缩小两个位,到[-0.25 +0.25)范围。 2.30累加器的结果移动
postShift
位,并且结果通过丢弃低16位,截断为1.15格式。
- 参考函数
csky_biquad_cascade_df1_q15()
使用了64位累加器实现了一个更慢的版本防止精度丢失。慢的和快的版本使用了相同的结构体实例。 使用函数 csky_biquad_cascade_df1_init_q15()
初始化滤波器结构.
- 参数
-
[in,out] | *S | 指向浮点二阶级联滤波器结构体实例 |
[in] | numStages | 滤波器中二阶阶段的数量 |
[in] | *pCoeffs | 指向滤波器系数数组 |
[in] | *pState | 指向状态数组 |
- 返回
- none
系数和状态顺序:
- 系数按以下顺序保存在数组
pCoeffs
:
{b10, b11, b12, a11, a12, b20, b21, b22, a21, a22, ...}
- 其中
b1x
和 a1x
是第一个阶段的系数, b2x
和 a2x
是第二个阶段的系数,依次类推。 pCoeffs
数组总共有5*numStages
个数值.
pState
是指向状态数组的指针. 每个二阶阶段有4个状态变量x[n-1], x[n-2], y[n-1],
和 y[n-2]
. 状态变量排列在pState
数组的顺序如下:
{x[n-1], x[n-2], y[n-1], y[n-2]}
最前面是第一阶段的4个状态变量, 然后是第二阶段的4个状态变量,依次类推。 状态数组总共有4*numStages
个数值. 状态变量在数据块处理之后更新,系数不会更新。
- 参数
-
[in,out] | *S | 指向Q15二阶级联结构体实例 |
[in] | numStages | 滤波器内二阶阶段的数量 |
[in] | *pCoeffs | 指向滤波器系数 |
[in] | *pState | 指向状态buffer |
[in] | postShift | 累加器结果的移位数 |
- 返回
- none
系数和状态顺序:
- 系数按以下顺序保存在数组
pCoeffs
:
{b10, 0, b11, b12, a11, a12, b20, 0, b21, b22, a21, a22, ...}
其中 b1x
和 a1x
是第一阶段的系数, b2x
和 a2x
是第二阶段的系数,依次类推。 pCoeffs
有 6*numStages
个值. b1
和 b2
中间的填充的16位的0, 是为了让系数能够32位对齐。
- 状态变量保存在数组
pState
. 每个二阶阶段有4个状态变量 x[n-1], x[n-2], y[n-1],
和 y[n-2]
. 状态变量排列在 pState
数组中的形式如下:
{x[n-1], x[n-2], y[n-1], y[n-2]}
阶段1使用最开始的4个状态变量,阶段2使用接下来的4个状态变量,依次类推。 状态数组总共有 4*numStages
个值. 每个块数据处理会更新状态变量,不会更新系数。
- 参数
-
[in,out] | *S | 指向Q31二阶级联结构体实例 |
[in] | numStages | 滤波器中二阶阶段的数量 |
[in] | *pCoeffs | 指向滤波器系数buffer |
[in] | *pState | 指向状态buffer |
[in] | postShift | 累加器结果的移位数 |
- 返回
- none
系数和状态顺序:
- 保存在数组
pCoeffs
的系数,按照以下顺序排列:
{b10, b11, b12, a11, a12, b20, b21, b22, a21, a22, ...}
其中 b1x
和 a1x
是第一阶段的系数, b2x
和 a2x
是第二阶段的系数,依次类推。 pCoeffs
数组总共有 5*numStages
个值.
pState
指向状态变量数组。 每个二阶阶段有4个状态变量 x[n-1], x[n-2], y[n-1],
和 y[n-2]
. 状态变量在数组 pState
中的排列顺序:
{x[n-1], x[n-2], y[n-1], y[n-2]}
阶段1使用最开始的4个状态变量,阶段2使用接下来的4个状态变量,依次类推。 状态变量数组总共有 4*numStages
个值. 每个块数据处理会更新状态变量,不会更新系数。
- 示例:
- csky_graphic_equalizer_example_q31.c.
- 参数
-
[in] | *S | 指向Q15二阶级联结构体实例 |
[in] | *pSrc | 指向输入数据块 |
[out] | *pDst | 指向输出数据块 |
[in] | blockSize | 每次处理的数据数量 |
- 返回
- none.
缩放和溢出行为:
- 函数实现使用了一个内部64位累加器。 系数和状态变量都用1.15格式表示,相乘的结果是2.30格式。 2.30格式的中间结果用一个64位的累加器累加成34.30格式的结果。 这里可以保留中间结果的精度,并且不会溢出。 最后的结果,饱和转换为1.15格式。
- 参考:函数
csky_biquad_cascade_df1_fast_q15()
是一个更快的版本,但是丢失了部分精度。
- 参数
-
[in] | *S | 指向Q31二阶级联滤波器结构体实例 |
[in] | *pSrc | 指向输入数据块 |
[out] | *pDst | 指向输出数据块 |
[in] | blockSize | 处理样本的数量 |
- 返回
- none.
缩放和溢出行为:
- 函数实现使用了一个内部64位累加器。 累加器是2.62格式,维护了中间结果的所有精度,但是只有一个保护位。 因此,如果累加器结果溢出,会往符号位溢出,而不是截断。 为了防止溢出,输入信号必须缩小2位,缩放到 [-0.25 +0.25) 区间. 在处理5个相乘结果累加之后, 2.62 累加器移动
postShift
位,并且丢弃低32位,将结果截断为1.31格式。
- 参考:函数
csky_biquad_cascade_df1_fast_q31()
是一个快速版本,但是丢失了更多精度的实现。
- 示例:
- csky_graphic_equalizer_example_q31.c.