#include <stdio.h>
#include <math.h>
#include <complex> //复数运算
#define PI 3.1415926
#define FFTNum 32//1024 //8
#define FFTCodeBit 5//10 //3
//必须要加这句才能用复数运算。。
using namespace std;
complex<double> ci(0,1);
float signalIn0[FFTNum];
float signalIn[FFTNum];
complex<double> Csignal[FFTNum];//={0,1,2,3,4,5,6,7};
//码位倒置
int CodeInv(int inLocal,int codeBit)
{
int outLocal=0,tempInL;
int cntCodeBit=0;
tempInL=inLocal;
for (;cntCodeBit<codeBit;)
{
outLocal<<=1;
outLocal+=tempInL%2;
cntCodeBit++;
tempInL>>=1;
}
return outLocal;
}
/*--------------------------------------
|要遍历一遍,而且要多用一倍的空间,不好|
--------------------------------------*/
void InvSignal()
{
int fcnt=0;
int invLocal;
for (;fcnt<FFTNum;fcnt++)
{
invLocal=CodeInv(fcnt,FFTCodeBit);
signalIn[fcnt]=signalIn0[invLocal];
}
}
//存入复数数组
void R2CSignal()
{
int RCcnt=0;
for (;RCcnt<FFTNum;RCcnt++)
{
complex<double> tempC(signalIn[RCcnt],0);
Csignal[RCcnt]=tempC;
}
}
//求蝶形运算的W
complex<double> wnk(int wN,int wk)
{
complex<double> w(0,0);
double en = -2*PI*wk/wN;
w=exp(ci*en);
return w;
}
//sin信号发生函数
void SinCreate(int freq,double Ts)
{
int scnt=0;
for (;scnt<FFTNum;scnt++)
{
signalIn0[scnt]=sin(2*PI*freq*Ts*scnt);
}
}
//复数取模后存入实数数组
void C2RSignal()
{
int rcCnt=0;
float Re,Im,mode;
for (;rcCnt<FFTNum;rcCnt++)
{
Re=Csignal[rcCnt].real();
Im=Csignal[rcCnt].imag();
mode=sqrt(Re*Re+Im*Im);
if(mode<0.00001)
mode=0;
signalIn[rcCnt]=mode;
}
}
void FFTN2()
{
int bit=0,k,nn;
int Nx,S1L,S2L;
complex<double> WNk(0,0),tempX(0,0);
InvSignal();
R2CSignal();
//WNk=wnk(8,3);//WNk._Re,WNk._Im实部和虚部
for (;bit<FFTCodeBit;bit++)//bit...0~9
{
Nx=FFTNum>>(FFTCodeBit-bit);
for (k=0;k<Nx;k++)//0<=k<Nx=FFTNum>>x...x=(FFTCodeBit-bit)---->10~1
{
//为WNk赋值
WNk=wnk(FFTNum>>(FFTCodeBit-bit-1),k);
for (nn=0;nn<FFTNum/(2*Nx);nn++)//group number=1>>(x-1),每组中有Nx个蝶形运算
{
//x1=0..2..4..6--->4gp,Nx=1个W;
//x1=0,4..1,5--->2gp,Nx=2个W;
//x1=0,1,2,3--->1gp,Nx=4个W;
S1L=2*Nx*nn+k;
S2L=S1L+(1<<bit);
tempX=WNk*Csignal[S2L];
Csignal[S2L]=Csignal[S1L]-tempX;
Csignal[S1L]+=tempX;//x2-x1=1,2,4.....1<<bit
}
}
}
C2RSignal();
}
void main()
{
SinCreate(50,0.000625);
FFTN2();
}