fft 和 ifft 的 C 语言程序
最近要做 FFT 和 IFFT,在网上搜来搜去,总是不大好理解,于是就根据大学里
学的数字信号处理(西电.刘顺兰等)中的图 3-9 和图 3-10 自己写了一下,有用
的朋友可以拿去,希望能对大家有帮助。
注:其中的 M 为 11,这是因为我做了 N=2048 个点的 FFT,2^11=2048,M 值可根
据需要更改,若 N 不是 2 的整数次幂,应补零。其中 xin 为输入信号,并且也应
该是 COMPX 类型量。
1、按时间抽取(DIT)的基-2FFT 算法(C)
#include "math.h"
typedef struct //定义表示复数的结构体
{
float real;
float imag;
}COMPX;
COMPX EE(COMPX b1,COMPX b2) //复数相乘函数
{
COMPX b3;
b3.real=b1.real*b2.real-b1.imag*b2.imag;
b3.imag=b1.real*b2.imag+b1.imag*b2.real;
return(b3);
}
void FFT(COMPX *xin,int N) //FFT 运算
{
int m,LH,nm,I,k,J,M,K;
float p,ps ;
int B,N1;
COMPX w,T;
M=11; //对应 N 值为 2048
//下面是倒序的程序
LH=N/2;
J=LH;
N1=N-2;
/*变址运算*/
for(I=1;I<=N1;I++)
{
if(I
}
K=LH;
while(J>=K)
{
J=J-K;
K=K/2;
}
J=J+K;
}
//下面是 DIT-FFT 运算程序
for(m=1;m<=M;m++)
{
B=pow(2,m-1);
for(J=0;J<=B-1;J++)
{
p=pow(2,M-m)*J;
ps=2*pi/N*p;
w.real=cos(ps);
w.imag=-sin(ps);
for(k=J;k<=N-1;k=k+pow(2,m))
{
T=EE(xin[k+B],w);
xin[k+B].real=xin[k].real-T.real;
xin[k+B].imag=xin[k].imag-T.imag;
xin[k].real=xin[k].real+T.real;
xin[k].imag=xin[k].imag+T.imag;
}
}
}
}
2、IFFT
根据定义可知,IFFT 与 FFT 算法没有差别,只需将上面的 w.imag=-sin(ps);改
写为 w.imag=sin(ps);
并在最后一个大括号前加上以下语句就可以了:
for(k=0;k
xin[k].imag=xin[k].imag/N;
}
也就是乘了一个常数因子 1/N。
水林声 作于 嘉兴 JRC 大楼 208 室 小雨后
附图: