搜索
bottom↓
回复: 1

发一个自己用C编的基二FFT函数库 用VC调试和验证的

[复制链接]

出0入0汤圆

发表于 2012-2-18 19:21:18 | 显示全部楼层 |阅读模式

FFT 以及IFFT 在VC下验证的结果 (原文件名:FFTShow.jpg)




此FFT计算需要依赖复数运算库:
DSP_Complex.h


#ifndef __DSP_COMPLEX_H
#define __DSP_COMPLEX_H


typedef   double __ComplexTyp;
typedef struct  dsp_complex{
             __ComplexTyp real;
              __ComplexTyp image;
}DSP_Complex;


/* Add two complex number of A and B result stored in sum*/
void DSP_ComplexADD(DSP_Complex *sum,DSP_Complex *A,DSP_Complex *B);

/*Multiply two complex number of A and B result stored in Mul*/
void DSP_ComplexMUL(DSP_Complex *Mul,DSP_Complex *A,DSP_Complex *B);



#include "DSP_Complex.c"
#endif


DSP_Complex.c

extern void DSP_ComplexADD(DSP_Complex *sum,DSP_Complex *A,DSP_Complex *B)
{
    sum->real=A->real+B->real;
        sum->image=A->image+B->image;
}

extern void DSP_ComplexSUB(DSP_Complex *sub,DSP_Complex *A,DSP_Complex *B)
{
        B->real=-B->real;
        B->image=-B->image;
           sub->real=A->real+B->real;
        sub->image=A->image+B->image;
}

extern void DSP_ComplexMUL(DSP_Complex *Mul,DSP_Complex *A,DSP_Complex *B)
{
          Mul->real=(A->real*B->real)-(A->image*B->image);
        Mul->image=(A->real*B->image)+(A->image*B->real);
}


DSP_FFT.h

#ifndef __DSP_FFT_H
#define __DSP_FFT_H
typedef   double       __RFFTv; //real FFT input data type
typedef   DSP_Complex  __CFFTv; //Image TTF input data type
/*********************************************************************************
Functionaility :2-N based Real number input array FFT with result stored in FFTout
Input:
               __RFFT       *Data          Pointer pointed to the real input array
               int         PointNum        number of element in input array  must to be the integer power of 2
               DSP_Complex *FFTout         Transform result
*********************************************************************************/
void DSP_FFT_1D2N_real(__RFFTv *Data,int PointNum,DSP_Complex *FFTout);

/*********************************************************************************
Functionaility :2-N based complex number input array FFT with result stored in FFTout
Input:
               __CFFTv       *Data          Pointer pointed to the real input array
               int         PointNum        number of element in input array  must to be the integer power of 2
               DSP_Complex *FFTout         Transform result
*********************************************************************************/

void DSP_FFT_1D_Complex(__CFFTv *Data,int PointNum,DSP_Complex *FFTout)

/*********************************************************************************
Functionaility :2-N based complex number input array IFFT with result stored in FFTout
Input:
               __CFFTv       *Data          Pointer pointed to the real input array
               int         PointNum        number of element in input array  must to be the integer power of 2
               DSP_Complex *FFTout         Transform result
*********************************************************************************/

void DSP_IFFT_1D_Complex(__CFFTv *Data,int PointNum,DSP_Complex *FFTout);
#include "DSP_FFT.c"
#endif

DSP_FFT.c

#include <math.h>

#define pi 3.1416


static double __cos(double in)
{
    return cos(in);
}
static double __sin(double in)
{
    return sin(in);
}
static void RDFT_2Point(__RFFTv *dataIn,DSP_Complex *DFTout)
{
       
    DFTout->real  = *dataIn+*(dataIn+1);
        DFTout->image = 0;
        DFTout++;
    DFTout->real  = *dataIn+(*(dataIn+1))*__cos(pi);
        DFTout->image = *(dataIn+1)*-__sin(pi);
}


inline void RExchange(__RFFTv *A, __RFFTv *B)
{
    __RFFTv buf;
        buf=*A;
        *A=*B;
        *B=buf;
}

/*将输入的2 n次方个元素数的数组的奇数下脚标的元素与偶数下脚标的元素分开 偶数在前奇数在后*/
static void RAdjustOrder(__RFFTv *data,int Num)
{
        int i,j,cycle;
    if(Num!=4){
                i=Num/2;
                j=i/2;
        RAdjustOrder(data,i);
        RAdjustOrder(data+i,i);
        for(cycle=0;cycle<j;cycle++){
            RExchange(data+j+cycle,data+i+cycle);
                }
        }
        else{
        RExchange(data+1,data+2);
        }
}


extern void DSP_FFT_1D_real(__RFFTv *Data,int PointNum,DSP_Complex *FFTout)
{
        int i,cycle;
        double angle;
        DSP_Complex shift,buf1,buf2,*X2;
    if(PointNum==2){
            RDFT_2Point(Data,FFTout);       
        }
        else{
                angle=(2.0*pi)/(double)PointNum;
                i=PointNum/2;
       
        X2=FFTout+i;
        RAdjustOrder(Data,PointNum);
        DSP_FFT_1D_real(Data,i,FFTout);
                DSP_FFT_1D_real(Data+i,i,X2);
        
        for(cycle=0;cycle<i;cycle++,X2++,FFTout++){
                        shift.real=cos(angle*(double)cycle);
                        shift.image=-sin(angle*(double)cycle);
                        DSP_ComplexMUL(&buf1,&shift,X2);
            DSP_ComplexADD(&buf2,FFTout,&buf1);
                        DSP_ComplexSUB(X2,FFTout,&buf1);
                        (FFTout)->image=buf2.image;
                        (FFTout)->real=buf2.real;
                }
        }
}



/****************************************************************************************************************/



static void CDFT_2Point(__CFFTv *dataIn,DSP_Complex *DFTout)
{       
    DSP_Complex buf,W_1;
        DSP_ComplexADD(DFTout,dataIn,dataIn+1);
        DFTout++;
        W_1.real=__cos(pi);
        W_1.image=-__sin(pi);
    DSP_ComplexMUL(&buf,dataIn+1,&W_1);
        DSP_ComplexADD(DFTout,dataIn,&buf);
}


inline void CExchange(__CFFTv *A, __CFFTv *B)
{
    __CFFTv buf;
        buf=*A;
        *A=*B;
        *B=buf;
}

/*将输入的2 n次方个元素数的数组的奇数下脚标的元素与偶数下脚标的元素分开 偶数在前奇数在后*/
static void CAdjustOrder(__CFFTv *data,int Num)
{
        int i,j,cycle;
    if(Num!=4){
                i=Num/2;
                j=i/2;
        CAdjustOrder(data,i);
        CAdjustOrder(data+i,i);
        for(cycle=0;cycle<j;cycle++){
            CExchange(data+j+cycle,data+i+cycle);
                }
        }
        else{
        CExchange(data+1,data+2);
        }
}


extern void DSP_FFT_1D_Complex(__CFFTv *Data,int PointNum,DSP_Complex *FFTout)
{
        int i,cycle;
        double angle;
        DSP_Complex shift,buf1,buf2,*X2;
    if(PointNum==2){
            CDFT_2Point(Data,FFTout);       
        }
        else{
                angle=(2.0*pi)/(double)PointNum;
                i=PointNum/2;
       
        X2=FFTout+i;
        CAdjustOrder(Data,PointNum);
        DSP_FFT_1D_Complex(Data,i,FFTout);
                DSP_FFT_1D_Complex(Data+i,i,X2);
        
        for(cycle=0;cycle<i;cycle++,X2++,FFTout++){
                        shift.real=cos(angle*(double)cycle);
                        shift.image=-sin(angle*(double)cycle);
                        DSP_ComplexMUL(&buf1,&shift,X2);
            DSP_ComplexADD(&buf2,FFTout,&buf1);
                        DSP_ComplexSUB(X2,FFTout,&buf1);
                        (FFTout)->image=buf2.image;
                        (FFTout)->real=buf2.real;
                }
        }
}


extern void DSP_IFFT_1D_Complex(__CFFTv *Data,int PointNum,DSP_Complex *FFTout)
{
        int i;
        __CFFTv *Delegate;
        Delegate=Data;
    for(i=0;i<PointNum;i++,Delegate++)
                Delegate->image=-Delegate->image;
    DSP_FFT_1D_Complex(Data,PointNum,FFTout);
        Delegate=FFTout;
        for(i=0;i<PointNum;i++,Delegate++){
                Delegate->image/=PointNum;
            Delegate->real/=PointNum;
        }
}

阿莫论坛20周年了!感谢大家的支持与爱护!!

一只鸟敢站在脆弱的枝条上歇脚,它依仗的不是枝条不会断,而是自己有翅膀,会飞。

出0入0汤圆

发表于 2012-4-6 10:48:56 | 显示全部楼层
mark 不是蛮懂,先收藏吧。这个事dsp上用的吧
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-6-15 02:07

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表