这个问题比较复杂,最近本人也在研究数字滤波,
结合图片说一下
第一个图是fir的流程图,其中Z-1是延迟,是单个采样时间1/fs
n阶的fir滤波器就是选取最近的n+1个样本,然后使他们各自乘以自己的滤波器系数即图中的F(n),[一般其他书的表示是h(n)]
然后相加得到输出的y(n)就是一个输出点
,其中F(n)的得出需要根据采样频率和滤波器的通带和阻带来决定
其中为了改善旁瓣的幅值,一般在采样后给样本或者h(n)加窗,当然可以用"最佳方法"来做
得出h(n)大致方法是先将矩形窗进行DFT,得出h(n),然后对h(n)进行加窗得出h(k),然后将∑h(k)Xx(n)=y(n),假如阶数较多可以用傅里叶变换使时域变频域后再将卷积相加,可以利用FFT来改进实时性,提升速度
上面就是fir滤波器的简述
第二个图片上传不了,直接给链接
图中的Z-1是延时,iir滤波器也叫无限冲击响应滤波器,是有反馈的,
图中的是一阶的,相对fir滤波器来说,iir滤波器可以用较低的阶数来获得较好的滤波特效.但是其相位特性较差.
鉴于实用性,还是建议楼主去图书馆借书看,百度不可能得到确实的方案,
楼主可以去借"数字信号处理"的书,国外的中译本就有详细介绍fir和iir以及fft还有其他变换,国内的dsp大都几乎是dsp用户手册的中译本,对上述问题都是很简陋地带过,不予置评.
#include stdio.h
#include conio.h
#endif
#define SAMPLE double /* define the type used for data samples */
void clear(int ntaps, SAMPLE z[])
{
int ii;
for (ii = 0; ii ntaps; ii++) {
z[ii] = 0;
}
SAMPLE fir_basic(SAMPLE input, int ntaps, const SAMPLE h[], SAMPLE z[])
SAMPLE accum;
/* store input at the beginning of the delay line */
z[0] = input;
/* calc FIR */
accum = 0;
accum += h[ii] * z[ii];
/* shift delay line */
z[ii + 1] = z[ii];
return accum;
SAMPLE fir_circular(SAMPLE input, int ntaps, const SAMPLE h[], SAMPLE z[],
int *p_state)
int ii, state;
state = *p_state; /* copy the filter's state to a local */
z[state] = input;
if (++state = ntaps) { /* incr state and check for wrap */
state = 0;
/* calc FIR and shift data */
for (ii = ntaps - 1; ii = 0; ii--) {
accum += h[ii] * z[state];
if (++state = ntaps) { /* incr state and check for wrap */
*p_state = state; /* return new state to caller */
SAMPLE fir_shuffle(SAMPLE input, int ntaps, const SAMPLE h[], SAMPLE z[])
accum = h[ntaps - 1] * z[ntaps - 1];
SAMPLE fir_split(SAMPLE input, int ntaps, const SAMPLE h[], SAMPLE z[],
int ii, end_ntaps, state = *p_state;
SAMPLE const *p_h;
SAMPLE *p_z;
/* setup the filter */
p_h = h;
/* calculate the end part */
p_z = z + state;
*p_z = input;
end_ntaps = ntaps - state;
for (ii = 0; ii end_ntaps; ii++) {
accum += *p_h++ * *p_z++;
/* calculate the beginning part */
p_z = z;
for (ii = 0; ii state; ii++) {
/* decrement the state, wrapping if below zero */
if (--state 0) {
state += ntaps;
*p_state = state; /* return new state to caller */
SAMPLE fir_double_z(SAMPLE input, int ntaps, const SAMPLE h[], SAMPLE z[],
int ii, state = *p_state;
SAMPLE const *p_h, *p_z;
/* store input at the beginning of the delay line as well as ntaps more */
z[state] = z[state + ntaps] = input;
/* calculate the filter */
/* decrement state, wrapping if below zero */
SAMPLE fir_double_h(SAMPLE input, int ntaps, const SAMPLE h[], SAMPLE z[],
p_h = h + ntaps - state;
int main(void)
static SAMPLE imp[IMP_SIZE];
SAMPLE output;
/* make impulse input signal */
clear(IMP_SIZE, imp);
/* create a SAMPLEd h */
for (ii = 0; ii NTAPS; ii++) {
/* test FIR algorithms */
printf("Testing fir_basic:\n ");
clear(NTAPS, z);
for (ii = 0; ii IMP_SIZE; ii++) {
output = fir_basic(imp[ii], NTAPS, h, z);
printf("\n\n");
printf("Testing fir_shuffle:\n ");
output = fir_shuffle(imp[ii], NTAPS, h, z);
printf("Testing fir_circular:\n ");
output = fir_circular(imp[ii], NTAPS, h, z, state);
printf("Testing fir_split:\n ");
output = fir_split(imp[ii], NTAPS, h, z, state);
printf("Testing fir_double_z:\n ");
output = fir_double_z(imp[ii], NTAPS, h, z, state);
printf("Testing fir_double_h:\n ");
printf("\n\nHit any key to continue.");
getch();
return 0;
① fir_basic: 实现基本的FIR滤波器
#includestdio.h
#include math.h
class complex //定义一个类,实现复数的所有操作
double Real,Image; //实部与虚部
public:
complex(double r="0",double i="0"){Real=r;Image=i;}
double GetR(){return Real;} //取出实部
double GetI(){return Image;} //取出虚部
complex operator + (complex ); //复数加法
complex operator - (complex ); //复数减法
complex operator * (complex ); //复数乘法
void operator =(complex ); //复数 赋值
};
complex complex::operator + (complex c) //复数加法
complex t;
t.Real=Real+c.Real;
t.Image=Image+c.Image;
return t;
complex complex::operator - (complex c) //复数减法
t.Real=Real-c.Real;
t.Image=Image-c.Image;
complex complex::operator * (complex c) //复数乘法
t.Real=Real*c.Real-Image*c.Image;
t.Image=Real*c.Image+Image*c.Real;
void complex::operator = (complex c) //复数 赋值
Real=c.Real;
Image=c.Image;
void fft(complex a[],int length,int jishu) //实现fft的函数
complex u,Wn,t;
int i,j,k,m,kind,distance,other;
double tmp;
for(i=0;ilength;i++) //实现倒叙排列
k="i";
j=0;
for(m=0;mjishu;m++)
if(ij)
t="a";
a=a[j];
a[j]=t;
for(m=1;m=jishu;m++) //第m级蝶形运算,总级数为jishu
u=complex(1,0); //旋转因子初始值为 1
tmp=PI/kind;
Wn=complex(cos(tmp),-sin(tmp));//旋转因子Wn
for(j=0;jkind;j++) //每种蝶形运算的起始点为j,共有kind种
for(i=j;ilength;i+=distance) //同种蝶形运算
t=a[other]*u; // 蝶形运算的乘积项
a[other]=a-t; //蝶形运算
a=a+t; //蝶形运算
u="u"*Wn; //修改旋转因子,多乘一个基本DFT因子WN
void main(void)
double a,b;
x=complex(i,i+1);
printf("x(%d) = %lf + %lf i\n",i+1,x.GetR(),x.GetI());
printf("fft变换的结果为:\n");
printf("X(%d)= %lf + %lf i\n",i+1,x.GetR(),x.GetI());
double
B[1100]={0};
改成
void
FFT(double
data[],
int
nn,
isign)
具体程序如下:
#include
iostream.h
"math.h"
#includestring.h
stdlib.h
fstream.h
afx.h
//复数的快速傅里叶变换
n,j,i,m,mmax,istep;
tempr,tempi,theta,wpr,wpi,wr,wi,wtemp;
n
=
*
nn;
j
for
(i
i=n
;
//这个循环进行的是码位倒置.
if(
i)
tempr
data[j];
tempi
data[j
+
①.];
data[j]
data[i];
data[i
data[i]
tempr;
tempi;
m
/
while
(m
m)
-
m;
mmax
while(
)
istep
mmax;
theta
(isign
mmax);
wpr
theta);
wpi
sin(theta);
wr
①0;
wi
0.0;
for(
m=mmax;
i=n;
i=i+istep)
i
tempr=double(wr)*data[j]-double(wi)*data[j+1];//这两句表示蝶形因子的下一个数乘以W因子所得的实部和虚部.
tempi=double(wr)*data[j+1]+double(wi)*data[j];
//蝶形单元计算后下面单元的实部,下面为虚部,注意其变换之后的数组序号与书上蝶形单元是一致的
wtemp
wr;
wi;
istep;
main()
//本程序已经和MATLAB运算结果对比,准确无误,需要注意的的是,计算中数组都是从1开始取得,丢弃了A[0]等数据
char
ij;
CString
ij=1;
其中的数据格式见该文件
FILE
*fp
if(!fp)
cout"Open
file
is
failing!"endl;
return;
while(!feof(fp))
//feof(fp)有两个返回值:如果遇到文件结束,函数feof(fp)的值为1,否则为0.
//清空为0
//函数的功能是从fp所指文件中读入n-1个字符放入line为起始地址的空间内
sscanf(line,
"%s%s",
dataA,
dataB);
//dataA读入第一列,dataB读入第二列
B[ij]=atof(dataA);
//将字符型的dataA值转化为float型
ij++;
(int
//*******************************************正式计算FFT
//********************************************写入数据到workout.txt文件中
*pFile=fopen("workout.txt","a+");
//?a+只能在文件最后补充,光标在结尾.没有则创建
if
(A[k+1]=0)
else
strl1=strlen(str1);
//
用
法:fwrite(buffer,size,count,fp);
buffer:是一个指针,对fwrite来说,是要输出数据的地址.
size:要写入的字节数;
count:要进行写入size字节的数据项的个数;
fp:目标文件指针.
fwrite(str1,1,strl1,pFile);
fclose(pFile);
cout"计算完毕,到fft_test\workout.txt查看结果"endl;
以上就是土嘎嘎小编为大家整理的c语言傅里叶函数滤波相关主题介绍,如果您觉得小编更新的文章只要能对粉丝们有用,就是我们最大的鼓励和动力,不要忘记讲本站分享给您身边的朋友哦!!