FFTConvert.h
//---------------------------------------------------------------------------
#ifdef _MSC_VER
#include <afxwin.h> // MFC core and standard components
#endif
#ifndef _MSC_VER
#include <vcl.h>
#endif
//---------------------------------------------------------------------------
class TFFTConvert
{
private:
DWORD Power;
WORD Count;
double *SinTable;
WORD *IndexTable;
public:
double *Real;
double *Imag;
double MainReal;
double MainImag;
TFFTConvert(int power);
~TFFTConvert();
void Convert(float * src, float * dest);
void Convert(float * src, float * dest, float *onefreq,float & mainfreq,int OneCyclePNumber);
void Convert(double * src, double * dest);
void Convert(double * src, double * dest,double*onefreq,double & mainfreq,int OneCyclePNumber);
private:
void Scale();
void DoFFT();
void CreateIndexTable();
void CreateSinTable();
void Return(float * dest);
void Return(double * dest);
};
//---------------------------------------------------------------------------
FFTConvert.cpp
//---------------------------------------------------------------------------
#include "FFTConvert.h"
#include <math.h>
#define Pi 3.1415926
#define MapIndex(x) IndexTable[(x)]
#define SIN(x) SinTable[(x)]
//---------------------------------------------------------------------------
TFFTConvert::TFFTConvert(int power)
{
//TODO: Add your source code here
Power = power;
Count =WORD(pow(2,power));
Real = new double[Count];
Imag = new double[Count];
IndexTable = new WORD[Count];
SinTable = new double[Count];
CreateIndexTable();
CreateSinTable();
MainReal=0;
MainImag=0;
}
//---------------------------------------------------------------------------
TFFTConvert::~TFFTConvert()
{
//TODO: Add your source code here
delete Real;
delete Imag;
delete IndexTable;
delete SinTable;
}
//---------------------------------------------------------------------------
void TFFTConvert::Convert(float * src, float * dest, float *onefreq,float & mainfreq,int OneCyclePNumber)
{
//TODO: Add your source code here
for(int i=0;i<Count;i++)
{
Real[i] = src[i];
Imag[i] = 0;
}
Scale();
DoFFT();
Return(dest);
MainImag=Imag[OneCyclePNumber/2];
MainReal=Real[OneCyclePNumber/2];
int imag=0;
if(MainImag>0) imag=1;
if(MainImag==0) imag=0;
if(MainImag<0) imag=-1;
int real=0;
if(MainReal>0) real=1;
if(MainReal==0) real=0;
if(MainReal<0) real=-1;
double angle;
MainImag=FormatFloat("0.00000",MainImag).ToDouble();
MainReal=FormatFloat("0.00000",MainReal).ToDouble();
if(MainImag!=0)
angle=atan(MainReal/MainImag);
else
angle=Pi/2;
angle+=Pi/2;
if(imag>0&&real<0)
angle+=Pi*3/2;
if(imag<0&&real<0)
angle+=Pi;
for(int i=0;i<Count;i++)
{
onefreq[i]=sin(2*Pi/OneCyclePNumber*i+angle);
}
}
//---------------------------------------------------------------------------
void TFFTConvert::Convert(float * src, float * dest)
{
//TODO: Add your source code here
for(int i=0;i<Count;i++)
{
Real[i] = src[i];
Imag[i] = 0;
}
Scale();
DoFFT();
Return(dest);
}
//---------------------------------------------------------------------------
void TFFTConvert::Convert(double * src, double * dest,double*onefreq,double & mainfreq,int OneCyclePNumber)
{
//TODO: Add your source code here
for(int i=0;i<Count;i++)
{
Real[i] = src[i];
Imag[i] = 0;
}
Scale();
DoFFT();
Return(dest);
MainImag=Imag[OneCyclePNumber/2];
MainReal=Real[OneCyclePNumber/2];
int imag=0;
if(MainImag>0) imag=1;
if(MainImag==0) imag=0;
if(MainImag<0) imag=-1;
int real=0;
if(MainReal>0) real=1;
if(MainReal==0) real=0;
if(MainReal<0) real=-1;
double angle;
MainImag=FormatFloat("0.000000",MainImag).ToDouble();
MainReal=FormatFloat("0.000000",MainReal).ToDouble();
angle=asin(sqrt(
(MainReal/MainImag)*(MainReal/MainImag)
/(1+(MainReal/MainImag)*(MainReal/MainImag))
)
);
if(real>0&&imag<0)
angle=angle;
if(real>0&&imag>0)
angle=Pi-angle;
if(real<0&&imag>0)
angle=Pi+angle;
if(real<0&&imag<0)
angle=2*Pi-angle;
double max;
max=dest[Count/OneCyclePNumber-2];
for(int i=0;i<4;i++)
max=max>dest[Count/OneCyclePNumber-2+i]?max:dest[Count/OneCyclePNumber-2+i];
for(int i=0;i<Count;i++)
{
onefreq[i]=max/2* sin(2*Pi/OneCyclePNumber*i+angle);
}
}
//------------------------------------------------------------------------------
void TFFTConvert::Convert(double * src, double * dest)
{
//TODO: Add your source code here
for(int i=0;i<Count;i++)
{
Real[i] = src[i];
Imag[i] = 0;
}
Scale();
DoFFT();
Return(dest);
}
//---------------------------------------------------------------------------
void TFFTConvert::Scale()
{
//TODO: Add your source code here
for(int i=0;i<Count;i++)
{
//计算后为峰-峰值
Real[i] /= (Count/4);
Imag[i] /= (Count/4);
}
}
//---------------------------------------------------------------------------
void TFFTConvert::DoFFT()
{
//TODO: Add your source code here
register unsigned int loop, loop1, loop2;
unsigned int i1, i2, i3, i4, y;
double a1, a2, b1, b2, z1, z2;
//初始化
i1 = Count >> 1;
i2 = 1;
for (loop = 0; loop < Power; loop++)
{
i3 = 0;
i4 = i1;
for (loop1 = 0; loop1 < i2; loop1++)
{
y = MapIndex(i3 / (int)i1);
z1 = SIN((y+Count/4)%Count);//cos值
z2 = -SIN(y); //sin值
for (loop2 = i3; loop2 < i4; loop2++)
{
a1 = Real[loop2];
a2 = Imag[loop2];
b1 = z1*Real[loop2+i1] - z2*Imag[loop2+i1];
b2 = z2*Real[loop2+i1] + z1*Imag[loop2+i1];
Real[loop2] = a1 + b1;
Imag[loop2] = a2 + b2;
Real[loop2+i1] = a1 - b1;
Imag[loop2+i1] = a2 - b2;
}
i3 += (i1 << 1);
i4 += (i1 << 1);
}
i1 >>= 1;
i2 <<= 1;
}
}
//---------------------------------------------------------------------------
void TFFTConvert::CreateIndexTable()
{
//TODO: Add your source code here
WORD mask1; //高位
WORD mask2; //低位
for(WORD i=0;i<Count;i++)
{
mask1 = Count/2;
mask2 = 1;
IndexTable[i] = 0;
for(WORD j=0;j<(Power/2.0+0.5);j++)
{
if(mask1&i)
{
IndexTable[i] |= mask2;
}
if(mask2&i)
{
IndexTable[i] |= mask1;
}
mask1 = mask1>>1;
mask2 = mask2<<1;
}
}
}
//---------------------------------------------------------------------------
void TFFTConvert::CreateSinTable()
{
//TODO: Add your source code here
for(int i=0;i<Count;i++)
SinTable[i] = sin(i*2.0*Pi/Count);
}
//---------------------------------------------------------------------------
void TFFTConvert::Return(float * dest)
{
//TODO: Add your source code here
for (int i = 0; i < Count; i++)
{
dest[i] = float(hypot(Real[MapIndex(i)], Imag[MapIndex(i)]));
}
dest[0] /= 4;
dest[Count-1] /= 4;
}
//---------------------------------------------------------------------------
void TFFTConvert::Return(double * dest)
{
//TODO: Add your source code here
for (int i = 0; i < Count; i++)
{
dest[i] = hypot(Real[MapIndex(i)], Imag[MapIndex(i)]);
}
dest[0] /= 4;
dest[Count-1] /= 4;
}
//---------------------------------------------------------------------------