打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
在做软件开发时用的FFT类,后来又改到DSP上了效果还不错
userphoto

2015.04.03

关注

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;
}
//---------------------------------------------------------------------------

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
C++博客 - christanxw的专栏 - 变态之MEMCPY
avr-gcc中关于delay延时函数的应用—AVR单片机,SPI,ADS7816,驱动程...
c语言中memory.h有什么作用
memcpy, memmove的实现
memcpy&memmove的比较
memcpy的用法
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服