C語言實現FIR濾波
fir.c和fir.h見
https://download.csdn.net/download/weixin_43216875/12010587
1. fir.h
#ifndef FIR_H
#define FIR_H
#include <math.h>
int max(int a,int b);
int min(int a, int b);
void conv(double *data_1,double *data_2, int length_1, int length_2, double *target);
double bessel0(double x);
double kaiser(int i , int n, double beta);
double window(int type, int n, int i, double beta);
void firwin(int n, int band, double fln, double fhn, int wn, double h[]);
/*
*n——整型變量。濾波器的階數。
band——整型變量。濾波器的類型。取值爲1、2、3和4,分別對應低通、高通、帶通和帶阻濾波器。
fln——雙精度實型變量。
fhn——雙精度實型變量。
對於低通和高通濾波器,fln:通帶邊界頻率;對於帶通和帶阻濾波器,fIn:通帶下邊界頻率,fhn:通帶上邊界頻率
wn——整型變量。窗函數的類型;取值1到7,分別對應矩形窗,圖基窗,三角窗,漢寧窗,海明窗,布拉克曼窗和凱塞窗。
h——雙精度實型-~維數組,長度爲(n+1).存放FIR濾波器的係數。
函數firwin()調用以下函數:子函數window(),窗函數的計算。子函數Kaiser(),凱塞窗的計算。子函數bessel0(),貝塞耳函數的計算。
*/
#endif // FIR_H
2. main函數
#include <iostream>
using namespace std;
#include <math.h>
#include "fir.h"
#define PI 3.1415926535897932384626433832795028841971
#define N 50000//與matlab中保持一致
int main()
{
double signal[N];//原始數據
double t[N];//時間序列
double h[21];//濾波器係數爲階數+1
double denoise[N+21-1];
for(int i = 0; i<N ; i++)
t[i] = i*static_cast<double>(5)/N;//時間序列0~5秒
for(int i = 0; i<N ; i++)
signal[i] = sin(2*PI*t[i]) + 0.5*sin(2*PI*1000*t[i]);
firwin(20, 1, 1e-3, 1e-3, 5, h);
/*
20:階數
1:低通濾波
1e-3:截止頻率,與matlab中“5/Fs*2”相同
5:海明窗
*/
for(int i = 0; i<N ; i++)
h[i] = 100*h[i];
conv(h,signal,21,N,denoise);
/*
h:數據1
signal:數據2
21:數據1長度
N:數據2長度
denoise:卷積結果
*/
FILE * fp;
fp = fopen("F:/signal.txt","wb");
for(int i=0;i<N;i++)
fprintf(fp,"%lf\r\n",signal[i]);//將signal寫入文本
fclose(fp);
fp = fopen("F:/denoise.txt","wb");
for(int i=0;i<N+21-1;i++)
fprintf(fp,"%lf\r\n",denoise[i]);//將denoise寫入文本
fclose(fp);
return 0;
}
3. 與Matlab對比
(1)Matlab運行結果
Fs = 10000;%採樣頻域10kHz
N = 5*Fs;
t = 0:1/Fs:5;
signal = sin(2*pi*t)+0.5*sin(2*pi*1000*t);%2個不同頻率的正弦信號疊加
subplot(2,1,1)
plot(t,signal);
b = fir1(20,5/Fs*2);
denoise = conv(b, signal);
denoise_fir = denoise(20/2+1:end-20/2);
subplot(2,1,2)
plot(t,denoise_fir);
(2)C語言運行結果