FIR数字滤波器 C语言实现 matlab设计FIR参数
一、matlab生成FIR参数
matlab设置FIR低通滤波器;类型为Equiripple;Minimun order;Density Factor:20;FS:48000;Fpass:2000;Fstop:3000
截图如下:
matlab生成的文件:
/*
* Filter Coefficients (C Source) generated by the Filter Design and Analysis Tool
* Generated by MATLAB(R) 8.3 and the Signal Processing Toolbox 6.21.
* Generated on: 09-Apr-2019 19:12:44
*/
/*
* Discrete-Time FIR Filter (real)
* -------------------------------
* Filter Structure : Direct-Form FIR
* Filter Length : 123
* Stable : Yes
* Linear Phase : Yes (Type 1)
*/
/* General type conversion for MATLAB generated C-code */
#include "tmwtypes.h"
/*
* Expected path to tmwtypes.h
* C:\Program Files\MATLAB\R2014a\extern\include\tmwtypes.h
*/
const int BL = 123;
const real64_T B[123] = {
0.0001360451914991,0.0002262888817035,0.0003965803319844,0.0006312539200957,
0.0009355633241083, 0.001309236648182, 0.001744872618442, 0.002226801945518,
0.002730493014036, 0.003222772025161, 0.003663165534679, 0.004006360217194,
0.004205541864475, 0.004216556097853, 0.004002816277717, 0.003540330440438,
0.002822144453948, 0.001862120287894,0.0006973073109746,-0.0006119369920544,
-0.001983640856593,-0.003318413157519,-0.004506446727724,-0.005435571887282,
-0.006001870323296,-0.006119947527137,-0.005733568813427,-0.004824520298617,
-0.00341927651389,-0.001592186502186,0.0005354126982925, 0.002800560784687,
0.005008607037074, 0.006947276436672, 0.008403971523628, 0.009185160264968,
0.009136320756536, 0.008160512460662, 0.006234031320806, 0.003417281486418,
-0.000140582672696,-0.004203985407577,-0.008460927434939, -0.01254030346479,
-0.0160355731694, -0.0185336042736, -0.01964621013305, -0.01904244446867,
-0.01647859242042, -0.01182363839845, -0.00507764624829, 0.003618723559849,
0.01398475687634, 0.02561077650534, 0.03797936581551, 0.0504954195521,
0.06252304008649, 0.07342670241521, 0.08261345985954, 0.08957326774504,
0.09391406996638, 0.09538907833652, 0.09391406996638, 0.08957326774504,
0.08261345985954, 0.07342670241521, 0.06252304008649, 0.0504954195521,
0.03797936581551, 0.02561077650534, 0.01398475687634, 0.003618723559849,
-0.00507764624829, -0.01182363839845, -0.01647859242042, -0.01904244446867,
-0.01964621013305, -0.0185336042736, -0.0160355731694, -0.01254030346479,
-0.008460927434939,-0.004203985407577,-0.000140582672696, 0.003417281486418,
0.006234031320806, 0.008160512460662, 0.009136320756536, 0.009185160264968,
0.008403971523628, 0.006947276436672, 0.005008607037074, 0.002800560784687,
0.0005354126982925,-0.001592186502186, -0.00341927651389,-0.004824520298617,
-0.005733568813427,-0.006119947527137,-0.006001870323296,-0.005435571887282,
-0.004506446727724,-0.003318413157519,-0.001983640856593,-0.0006119369920544,
0.0006973073109746, 0.001862120287894, 0.002822144453948, 0.003540330440438,
0.004002816277717, 0.004216556097853, 0.004205541864475, 0.004006360217194,
0.003663165534679, 0.003222772025161, 0.002730493014036, 0.002226801945518,
0.001744872618442, 0.001309236648182,0.0009355633241083,0.0006312539200957,
0.0003965803319844,0.0002262888817035,0.0001360451914991
};
二、FIR c语言实现
void process(float *x,float *y,int N)
{
int i = 0,j = 0,k=0;
float temp;
for (k = 0; k < N; k++)
{
state[0] = x[k];
for (i = 0, temp = 0; i < FIR_FILTER_LENGTH; i++)
temp += FIR_COFFES[i] * state[i];
y[k] = temp;
for (j = FIR_FILTER_LENGTH - 1; j > -1 ; j--)
state[j+1] = state[j];
}
}
三、VS工程项目
我的项目是用一个123阶的FIR低通滤波器滤除4k以后的信号,所以我的测试文件含有500Hz,1000Hz,2000Hz,4000Hz信号叠加。测试文件为48K采样率,32位float,小端模式,单声道。
#include <stdio.h>
#include <math.h>
#define FRAME_READ_LENGTH (256)
#define Factor 2.0*3.1415926/48000.0
#define FIR_FILTER_LENGTH 123
float FIR_COFFES[FIR_FILTER_LENGTH]=
{
0.0001360451914991,0.0002262888817035,0.0003965803319844,0.0006312539200957,
0.0009355633241083, 0.001309236648182, 0.001744872618442, 0.002226801945518,
0.002730493014036, 0.003222772025161, 0.003663165534679, 0.004006360217194,
0.004205541864475, 0.004216556097853, 0.004002816277717, 0.003540330440438,
0.002822144453948, 0.001862120287894,0.0006973073109746,-0.0006119369920544,
-0.001983640856593,-0.003318413157519,-0.004506446727724,-0.005435571887282,
-0.006001870323296,-0.006119947527137,-0.005733568813427,-0.004824520298617,
-0.00341927651389,-0.001592186502186,0.0005354126982925, 0.002800560784687,
0.005008607037074, 0.006947276436672, 0.008403971523628, 0.009185160264968,
0.009136320756536, 0.008160512460662, 0.006234031320806, 0.003417281486418,
-0.000140582672696,-0.004203985407577,-0.008460927434939, -0.01254030346479,
-0.0160355731694, -0.0185336042736, -0.01964621013305, -0.01904244446867,
-0.01647859242042, -0.01182363839845, -0.00507764624829, 0.003618723559849,
0.01398475687634, 0.02561077650534, 0.03797936581551, 0.0504954195521,
0.06252304008649, 0.07342670241521, 0.08261345985954, 0.08957326774504,
0.09391406996638, 0.09538907833652, 0.09391406996638, 0.08957326774504,
0.08261345985954, 0.07342670241521, 0.06252304008649, 0.0504954195521,
0.03797936581551, 0.02561077650534, 0.01398475687634, 0.003618723559849,
-0.00507764624829, -0.01182363839845, -0.01647859242042, -0.01904244446867,
-0.01964621013305, -0.0185336042736, -0.0160355731694, -0.01254030346479,
-0.008460927434939,-0.004203985407577,-0.000140582672696, 0.003417281486418,
0.006234031320806, 0.008160512460662, 0.009136320756536, 0.009185160264968,
0.008403971523628, 0.006947276436672, 0.005008607037074, 0.002800560784687,
0.0005354126982925,-0.001592186502186, -0.00341927651389,-0.004824520298617,
-0.005733568813427,-0.006119947527137,-0.006001870323296,-0.005435571887282,
-0.004506446727724,-0.003318413157519,-0.001983640856593,-0.0006119369920544,
0.0006973073109746, 0.001862120287894, 0.002822144453948, 0.003540330440438,
0.004002816277717, 0.004216556097853, 0.004205541864475, 0.004006360217194,
0.003663165534679, 0.003222772025161, 0.002730493014036, 0.002226801945518,
0.001744872618442, 0.001309236648182,0.0009355633241083,0.0006312539200957,
0.0003965803319844,0.0002262888817035,0.0001360451914991
};
float state[FIR_FILTER_LENGTH+1]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
void process(float *x,float *y,int N)
{
int i = 0,j = 0,k=0;
float temp;
for (k = 0; k < N; k++)
{
state[0] = x[k];
for (i = 0, temp = 0; i < FIR_FILTER_LENGTH; i++)
temp += FIR_COFFES[i] * state[i];
y[k] = temp;
for (j = FIR_FILTER_LENGTH - 1; j > -1 ; j--)
state[j+1] = state[j];
}
}
int main()
{
int nReadLen = 0;
FILE *pSrcFile = fopen("..\\sin500-1000-2000-4000.pcm","rb");
FILE *pDstFile = fopen("..\\write.pcm","wb");
float pReadData[FRAME_READ_LENGTH] = {0};
float pWriteData[FRAME_READ_LENGTH] = {0};
#if 0//统计FIR参数之和 1.01
int i = 0,k = 0;
float temp;
for (i = 0, temp = 0; i < FIR_FILTER_LENGTH; i++)
temp += FIR_COFFES[i];
printf("%lf\n",temp);
#endif
if ((pSrcFile == NULL)||(pDstFile == NULL))
{
return 0 ;
}
nReadLen = fread(pReadData,sizeof(float),FRAME_READ_LENGTH,pSrcFile);
while(nReadLen==FRAME_READ_LENGTH)
{
process(pReadData,pWriteData,FRAME_READ_LENGTH);
fwrite(pWriteData,sizeof(float),FRAME_READ_LENGTH,pDstFile);
nReadLen = fread(pReadData,sizeof(float),FRAME_READ_LENGTH,pSrcFile);
}
fclose(pSrcFile);
fclose(pDstFile);
printf("----------finished!--------\n");
return 0;
}
四、信号频谱图对比
滤波前:
滤波后: