用C实现FFTWord格式.docx

上传人:b****3 文档编号:6899528 上传时间:2023-05-07 格式:DOCX 页数:16 大小:19.17KB
下载 相关 举报
用C实现FFTWord格式.docx_第1页
第1页 / 共16页
用C实现FFTWord格式.docx_第2页
第2页 / 共16页
用C实现FFTWord格式.docx_第3页
第3页 / 共16页
用C实现FFTWord格式.docx_第4页
第4页 / 共16页
用C实现FFTWord格式.docx_第5页
第5页 / 共16页
用C实现FFTWord格式.docx_第6页
第6页 / 共16页
用C实现FFTWord格式.docx_第7页
第7页 / 共16页
用C实现FFTWord格式.docx_第8页
第8页 / 共16页
用C实现FFTWord格式.docx_第9页
第9页 / 共16页
用C实现FFTWord格式.docx_第10页
第10页 / 共16页
用C实现FFTWord格式.docx_第11页
第11页 / 共16页
用C实现FFTWord格式.docx_第12页
第12页 / 共16页
用C实现FFTWord格式.docx_第13页
第13页 / 共16页
用C实现FFTWord格式.docx_第14页
第14页 / 共16页
用C实现FFTWord格式.docx_第15页
第15页 / 共16页
用C实现FFTWord格式.docx_第16页
第16页 / 共16页
亲,该文档总共16页,全部预览完了,如果喜欢就下载吧!
下载资源
资源描述

用C实现FFTWord格式.docx

《用C实现FFTWord格式.docx》由会员分享,可在线阅读,更多相关《用C实现FFTWord格式.docx(16页珍藏版)》请在冰点文库上搜索。

用C实现FFTWord格式.docx

xlabel('

Time(s)'

ylabel('

Amplitude(volt)'

title('

Singnal'

holdon;

stem(t2,signal2,'

r'

axis([0T*(N+ZeroNum)-11]);

 

%作FFT变换,计算其幅值,归一化处理,并画出频谱。

Y=fft(signal2,N);

Pyy=Y.*conj(Y);

Pyy=(Pyy/sum(Pyy))*2;

f=0:

fs/(N-1):

fs/2;

4

subplot(2,1,2);

bar(f,Pyy(1:

N/2));

Frequency(Hz)'

Amplitude'

Frequencycompnentsofsignal'

axis([0fs/20ceil(max(Pyy))])

gridon;

———————————————————————————————————————

这是一个傅里叶变化的子函数,你可以自己做主函数传递你这里的参数验证

//入口参数:

//l:

l=0,傅立叶变换;

l=1,逆傅立叶变换

//il:

il=0,不计算傅立叶变换或逆变换模和幅角;

il=1,计算模和幅角

//n:

输入的点数,为偶数,一般为32,64,128,...,1024等

//k:

满足n=2^k(k>

0),实质上k是n个采样数据可以分解为偶次幂和奇次幂的次数

//pr[]:

l=0时,存放N点采样数据的实部

//l=1时,存放傅立叶变换的N个实部

//pi[]:

l=0时,存放N点采样数据的虚部

//l=1时,存放傅立叶变换的N个虚部

//

//出口参数:

//fr[]:

l=0,返回傅立叶变换的实部

//l=1,返回逆傅立叶变换的实部

//fi[]:

l=0,返回傅立叶变换的虚部

//l=1,返回逆傅立叶变换的虚部

il=1,l=0时,返回傅立叶变换的模

//il=1,l=1时,返回逆傅立叶变换的模

il=1,l=0时,返回傅立叶变换的辐角

//il=1,l=1时,返回逆傅立叶变换的辐角

voidkbfft(double*pr,double*pi,intn,intk,double*fr,double*fi,intl,intil)

{

intit,m,is,i,j,nv,l0;

doublep,q,s,vr,vi,poddr,poddi;

//排序

for(it=0;

it<

=n-1;

it++)

{m=it;

is=0;

for(i=0;

i<

=k-1;

i++)

{j=m/2;

is=2*is+(m-2*j);

m=j;

fr[it]=pr[is];

fi[it]=pi[is];

}

//蝶形运算

pr[0]=1.0;

pi[0]=0.0;

p=6.283185306/(1.0*n);

pr[1]=cos(p);

pi[1]=-sin(p);

if(l!

=0)pi[1]=-pi[1];

for(i=2;

{p=pr[i-1]*pr[1];

q=pi[i-1]*pi[1];

s=(pr[i-1]+pi[i-1])*(pr[1]+pi[1]);

pr[i]=p-q;

pi[i]=s-p-q;

=n-2;

it=it+2)

{vr=fr[it];

vi=fi[it];

fr[it]=vr+fr[it+1];

fi[it]=vi+fi[it+1];

fr[it+1]=vr-fr[it+1];

fi[it+1]=vi-fi[it+1];

m=n/2;

nv=2;

for(l0=k-2;

l0>

=0;

l0--)

{m=m/2;

nv=2*nv;

=(m-1)*nv;

it=it+nv)

for(j=0;

j<

=(nv/2)-1;

j++)

{p=pr[m*j]*fr[it+j+nv/2];

q=pi[m*j]*fi[it+j+nv/2];

s=pr[m*j]+pi[m*j];

s=s*(fr[it+j+nv/2]+fi[it+j+nv/2]);

poddr=p-q;

poddi=s-p-q;

fr[it+j+nv/2]=fr[it+j]-poddr;

fi[it+j+nv/2]=fi[it+j]-poddi;

fr[it+j]=fr[it+j]+poddr;

fi[it+j]=fi[it+j]+poddi;

=0)

{fr[i]=fr[i]/(1.0*n);

fi[i]=fi[i]/(1.0*n);

if(il!

{pr[i]=sqrt(fr[i]*fr[i]+fi[i]*fi[i]);

pr[i]=(pr[i]/(n/2));

//各次谐波幅值,其中pr[1]为基波幅值

if(fabs(fr[i])<

0.000001*fabs(fi[i]))//fabs()是取绝对值函数,浮点型的0在内存中并不是严格等于0,可以认为当一个浮点数离原点足够近时,也就是f>

0.00001&

&

f<

-0.00001,认为f是0

{if((fi[i]*fr[i])>

0)pi[i]=90.0;

elsepi[i]=-90.0;

else

pi[i]=atan(fi[i]/fr[i])*360.0/6.283185306;

return;

}

FFTinCcode用C语言实现FFT

#include<

stdio.h>

math.h>

//此代码来源《数字信号处理C语言程序集》殷福亮、宋爱军,沈阳:

辽宁科学技术出版社,1997.7

//数组x存储时域序列的实部,数组y存储时域序列的虚部

//n代表N点FFT,sign=1为FFT,sign=-1为IFFT

voidFFT(doublex[],doubley[],intn,intsign)

{

inti,j,k,l,m,n1,n2;

doublec,c1,e,s,s1,t,tr,ti;

//Calculatei=log2N

for(j=1,i=1;

16;

m=i;

j=2*j;

if(j==n)

break;

//计算蝶形图的输入下标(码位倒读)

n1=n-1;

for(j=0,i=0;

n1;

if(i<

j)

{

tr=x[j];

ti=y[j];

x[j]=x[i];

y[j]=y[i];

x[i]=tr;

y[i]=ti;

k=n/2;

while(k<

(j+1))

j=j-k;

k=k/2;

j=j+k;

//计算每一级的输出,l为某一级,i为同一级的不同群,使用同一内存(即位运算)

n1=1;

for(l=1;

l<

=m;

l++)

n1=2*n1;

n2=n1/2;

e=3.1415926/n2;

c=1.0;

s=0.0;

c1=cos(e);

s1=-sign*sin(e);

for(j=0;

n2;

for(i=j;

n;

i+=n1)

k=i+n2;

tr=c*x[k]-s*y[k];

ti=c*y[k]+s*x[k];

x[k]=x[i]-tr;

y[k]=y[i]-ti;

x[i]=x[i]+tr;

y[i]=y[i]+ti;

t=c;

c=c*c1-s*s1;

s=t*s1+s*c1;

//如果是求IFFT,再除以N

if(sign==-1)

for(i=0;

x[i]/=n;

y[i]/=n;

intmain()

doublex[4]={1,2,-1,3};

//郑君里《信号与系统》上的例子,下P145

doubley[4]={0};

inti;

4;

printf("

%d%f%f\n"

i,x[i],y[i]);

FFT(x,y,4,1);

FFT(x,y,4,-1);

return1;

《数字信号处理C语言程序集》殷福亮、宋爱军

pdf下载地址

以前信号与系统学得很浅,目前正在学习,代码只是看懂了个大概,对于是如何实现W的计算的没看懂,希望有谁看懂了解释一下,呵呵......

还有一点我没有看懂就是,变换出来的频域序列和频率是怎么对应的,好像是N/2=采样频率的一半,正好满足耐奎斯特,N/2以后和以前是对称的,不知道理解的正确与否,希望牛人指点....

C语言FFT和IFFT实现(2007-05-0718:

40:

15)转载标签:

基_2fft(频率抽取dif法)c语言算法程序分类:

学习资料

基-2FFT(频率抽取DIF法)算法程序

/*基2-DIF-FFT的C语言算法程序*/

/*输入:

序列点数、序列值*/

/*输出:

输入序列FFT变换后的数值及又把FFT结果反变换得到原输入序列(与输入序列相同),*/

/*还输出输入序列的IFFT结果(应与原序列相同)*/

#include"

conio.h"

math.h"

stdio.h"

#defineN64

#definePI3.1415926

#definew0(0.125*PI)

#defineCmul(a,b,c)a.x=b.x*c.x-b.y*c.y;

a.y=b.x*c.y+b.y*c.x;

/*利用结构体做复数乘法*/

#defineCequal(a,b)a.x=b.x;

a.y=b.y;

/*结构体a的值赋给b*/

#defineCadd(a,b,c)a.x=b.x+c.x;

a.y=b.y+c.y;

/*结构体实现复数的加减*/

#defineCsub(a,b,c)a.x=b.x-c.x;

a.y=b.y-c.y;

#defineWn(w,r)w.x=cos(2.0*PI*r/n);

w.y=-sin(2.0*PI*r/n);

/*旋转因子的分解*/

structcomp

floatx;

floaty;

};

voidmain()

inti,j,nu2,nm1,n,m,le,le1,k,ip,z;

intflag,f,n1;

structcompa[N],t,t1,w,d;

floata_ipx,m1;

printf("

\nThisprogramisaboutFFTbyDIFway."

\npleaseenterN:

"

scanf("

%d"

&

n1);

n=n1;

m1=log(n1)/log

(2);

m=log(n1)/log

(2);

/*级数*/

if(m!

=m1)n=pow(2,m+1);

for(i=0;

i<

i++){a[i].x=a[i].y=0.0;

}/*所有存储单元清零*/

\n"

i++)/*录入数据到存储单元,以结构体的形式分别存储实部和虚部*/

\npleaseenterdata(%d)_[Re]:

i);

%f"

a[i].x);

\npleaseenterdata(%d)_[Im]:

a[i].y);

for(z=0;

z<

=2;

z++)/*z=0,时计算FFT;

z=1时计算新序列的IFFT;

z=2时计算原序列的IFFT*/

flag=-1;

/*flag控制r的增加*/

for(m=(log(n)/log

(2));

m>

=1;

m--)/*此循环控制级数m*/

le=pow(2,m);

/*le控制同一级中具有相同的碟形结的距离*/

flag++;

le1=le/2;

/*le1控制在同一级中有不同的个数*/

for(j=0;

j<

le1;

j++)/*此循环控制同一级中r的增加,实现一级不同的蝶形运算*/

for(i=j;

=(n-1);

i+=le)/*此循环控制一级中具有相同的碟形运算*/

ip=i+le1;

Cequal(t,a[i]);

Cequal(t1,a[ip]);

f=(int)(i*pow(2,flag))%n;

Wn(w,f);

Cadd(a[i],t,t1);

/*计算*/

Csub(a[ip],t,t1);

/*计算

a_ipx=a[ip].x;

*/

if(z==1)

w.y*=-1;

if(z==2)

a[ip].x=a[ip].x*w.x-a[ip].y*w.y;

a[ip].y=a_ipx*w.y+a[ip].y*w.x;

/*计算,反变换则取反*/

nu2=n/2;

/*用雷德算法将倒位序输出变为自然序输出*/

nm1=n-2;

j=0;

i=0;

while(i<

=nm1)

if(i<

j)

Cequal(d,a[j]);

Cequal(a[j],a[i]);

Cequal(a[i],d);

k=nu2;

=j)

j=j-k;

k=k/2;

j=j+k;

i=i+1;

if(z==0)

\ninputnumfft:

\n\n"

elseif(z==1)

\nshengchengxinnumifft(input):

);

\ninputnumifft"

i++)

%7.4f"

a[i].x);

if(a[i].y>

+%7.4fj\n"

a[i].y);

-%7.4fj\n"

fabs(a[i].y));

a[i].x=a[i].x/n;

/*IFFT需将结果除以n*/

a[i].y=a[i].y/n;

a[i].x/n);

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 自然科学 > 数学

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2