应原先转载的一篇文章有好多朋友看的不是很明白,主要原因在于数字信号处理专业功底稍有欠缺,对于滤波器各种结构模型不是太清楚,导致对转载的文章有些异议,这里我重新根据我自己的应用场景,重新编辑一份关于MATLAB中涉及滤波器,生成C语言风格头文件,并在C语言中对信号进行滤波的描述。
- 1、 首先在MATLAB workspace控制台输入fdatool或者sptool中都有滤波器设计版块,如图1、图2所示。
- 2、 我的应用场景主要是由于在接收机采集的音频数据采样率不一样,导致上层软件对于数据存储的协议格式冲突,同时该型号接收机返回音频数据量较大等,需要对音频数据进行下采样,由于采样率之间的关系,导致了混叠噪声的出现,音频中混杂了“滋滋滋”的高频噪音信号,因此需要设计带阻滤波器将其滤除。
- 3、 一般来说信号滤波可以在时域或者频域进行,对于数据量小的场景可以直接fft,然后对于频域数据进行相应处理,比如将噪音谱线直接置零或者置零之后与邻近频率分量进行合成等,在ifft反变换到时域,这样一定程度上精度会大一点,不会对其他分量造成影响,因为滤波器处于理论状态,但是增加了运算量;另一种方式就是预先进行信号分析,设计好滤波器,在根据滤波器系数进行时域直接滤波,这样运算量相对小,采用合适的阶数运算效率也快。本文采用后一种方式。
- 4、 由下图的谱分析可以在fdatool中设计如下图所示频响的滤波器,为了降低阶数我们采用IIR响应滤波器,设计buttorworth带阻滤波器,如下图。
- 5、 直接设计出来的滤波器是Direct-Form II型滤波器,这样当我们直接导出滤波器系数时,MATLAB默认导出为分部组合的形式,也就是类似分子系数是一维,分母是多维,就类似于多项式分解后的形式,这样的系数对于程序猿编程来说不太方便,我们需要直接转换成float[]的一位数组,例如滤波器分子,分母系数为float NUM[],float DEN[],这样使用滤波器对信号进行滤波就方便多了。
- 6、 导出滤波器。选择FDATool->File->Export,将滤波器系数导出到workspace,系数为SOS,G滤波器类型为直节型,需要使用[NUM,DEN] = sos2tf(sos,g),转换得到我们需要的滤波器系数,可以手动保存为C语言头文件。
- 7、 导出滤波器(2)。直接在FDATool中设计滤波器不能很好的对信号用设计好的滤波器进行验证,所以我通常推荐使用sptool,主要分为三块,信号、滤波器、频谱。
- 信号中可以导入工作空间加载的信号,滤波器也都可以从工作空间导入,频谱可以用已导入的信号进行生成;其中,滤波器设计一栏点击apply可以对选中信号与选中滤波器进行滤波。
- 选中设计好的滤波器,如FIRbp[design],使用sptool->File->Export,就可以将选中的滤波器导出到workspace,具体可以参见图3,然后双击导出的滤波器对象,如图4所示,tf字段里面包含的就是滤波器的系数NUM,DEN了,其中NUM是滤波器的分子系数,DEN是滤波器的分母系数。设计滤波器一定要观察stable是否为yes,否则,滤波后的信号可能失真或者错误!
- 8、 上面主要讲到IIR因果滤波器的设计以及导出,因果滤波器由于存在反馈因此直接导出的C语言头文件不能直接供我们程序使用,需要在MATLAB调用sos2tf函数进行转换,但是设计FIR非因果滤波器,由于结构简单,系数只存在NUM,而DEN=1,因此我们可以直接使用Targets->Generate C header导出C语言头文件。而在sptool中导出FIR滤波器系数的方式和前面完全一样,因此,在sptool中设计滤波器及导出系数更为方便。
- 9、 FIR和IIR滤波器区别简述。简单来说FIR是有限长脉冲响应滤波器,IIR是无限长脉冲响应滤波器,FIR是非因果滤波器,线性相位,滤波结果在相位上没有失真,相反IIR一般相位非线性,因此滤波结果在相位上会有一定失真。
- 阶数而言,相同滤波效果时,FIR阶数较高,运算性能稍差,而IIR滤波器能用较低阶数完成同样的滤波效果,性能较高,但是不能保证信号相位,因此一般对相位敏感的场景使用FIR滤波器。
- 10、 另外,对于音频数据滤波的C++工程实例请下载我的资源“TestAudioFilter”。WindowsSDK版本:10.0.17134.0,编译环境vs2017.
- 欢迎大家拍砖,互相学习,共同进步!
/* * Filter Coefficients (C Source) generated by the Filter Design and Analysis Tool * Generated by MATLAB(R) 9.1 and the Signal Processing Toolbox 7.3. * Generated on: 31-Jul-2019 14:35:56 *//* * Discrete-Time FIR Filter (real)
* ------------------------------- *
Filter Structure : Direct-Form FIR
* Filter Length : 21
* Stable : Yes
* Linear Phase : Yes
(Type 1) *//* General type conversion for MATLAB generated C-code */
#include "tmwtypes.h"
/* * Expected path to tmwtypes.h */
const int BL = 21;
const real64_T B[21] = {
0.01959891419375,-0.000850799850284, -0.02092128872455, -0.02627519991705,
-0.01295563766471, 0.009686426254659, 0.02557484212732, 0.0233544670549,
0.004528582084577, -0.01755960715521, 0.9727891156463, -0.01755960715521,
0.004528582084577, 0.0233544670549, 0.02557484212732, 0.009686426254659,
-0.01295563766471, -0.02627519991705, -0.02092128872455,-0.000850799850284,
0.01959891419375};
图1 sptool工具箱界面
图2 滤波器设计界面
图3 滤波器系数导出界面
图4 滤波器系数导出
图5 音频信号滤波前后谱分析