微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

用于ARM上的FFT与IFFT源代码C语言,不依赖特定平台

http://blog.csdn.net/syrchina/article/details/6670517

代码在2011年全国电子大赛结束后(2011年9月3日)发布,多个版本,注释详细。

[cpp]  view plain copy
  1. /******************************************************************************* 
  2. ** 程序名称快速傅里叶变换(FFT)  
  3. ** 程序描述:本程序实现快速傅里叶变换  
  4. ** 程序作者:宋元瑞  
  5. ** 最后修改:2011年4月5日  
  6. *******************************************************************************/  
  7. #include <stdio.h>  
  8. #include <math.h>  
  9.   
  10. #define PI 3.141592653589   //圆周率,12位小数   
  11. #define N 8                 //傅里叶变换的点数   
  12. #define M 3                 //蝶形运算的级数,N = 2^M   
  13. typedef double ElemType;    //原始数据序列的数据类型,可以在这里设置  
  14.   
  15. typedef struct              //定义复数结构体   
  16. {  
  17.     ElemType real,imag;  
  18. }complex;  
  19. complex data[N];            //定义存储单元,原始数据与负数结果均使用之   
  20. ElemType result[N];         //存储FFT后复数结果的模  
  21. //变址   
  22. void ChangeSeat(complex *DataInput)  
  23. {  
  24.     int nextValue,nextM,i,k,j=0;  
  25.     complex temp;  
  26.       
  27.     nextValue=N/2;                  //变址运算,即把自然顺序变成倒位序,采用雷德算法  
  28.     nextM=N-1;  
  29.     for (i=0;i<nextM;i++)  
  30.     {  
  31.         if (i<j)                 //如果i<j,即进行变址  
  32.         {  
  33.             temp=DataInput[j];  
  34.             DataInput[j]=DataInput[i];  
  35.             DataInput[i]=temp;  
  36.         }  
  37.         k=nextValue;                //求j的下一个倒位序  
  38.         while (k<=j)             //如果k<=j,表示j的最高位为1  
  39.         {  
  40.             j=j-k;                  //把最高位变成0  
  41.             k=k/2;                  //k/2,比较次高位,依次类推,逐个比较,直到某个位为0  
  42.         j=j+k;                      //把0改为1  
  43.     }                                         
  44. }  
  45. /* 
  46. //变址  
  47. void ChangeSeat(complex *DataInput) 
  48.     complex Temp[N]; 
  49.     int i,n,New_seat; 
  50.     for(i=0; i<N; i++) 
  51.     { 
  52.         Temp[i].real = DataInput[i].real; 
  53.         Temp[i].imag = DataInput[i].imag; 
  54.     } 
  55.     for(i=0; i<N; i++) 
  56.     { 
  57.         New_seat = 0; 
  58.         for(n=0;n<M;n++) 
  59.         { 
  60.             New_seat = New_seat | (((i>>n) & 0x01) << (M-n-1)); 
  61.         } 
  62.         DataInput[New_seat].real = Temp[i].real; 
  63.         DataInput[New_seat].imag = Temp[i].imag; 
  64. */  
  65. //复数乘法   
  66. complex XX_complex(complex a, complex b)  
  67.     complex temp;  
  68.       
  69.     temp.real = a.real * b.real-a.imag*b.imag;  
  70.     temp.imag = b.imag*a.real + a.imag*b.real;  
  71. return temp;  
  72. }  
  73. //FFT  
  74. void FFT(void)  
  75.     int L=0,B=0,J=0,K=0;  
  76. int step=0;  
  77.     ElemType P=0,T=0;  
  78.     complex W,Temp_XX;  
  79.     //ElemType TempResult[N];  
  80.     ChangeSeat(data);  
  81.     for(L=1; L<=M; L++)  
  82.     {  
  83.         B = 1<<(L-1);//B=2^(L-1)  
  84. for(J=0; J<=B-1; J++)  
  85.             P = (1<<(M-L))*J;//P=2^(M-L) *J   
  86.             step = 1<<L;//2^L  
  87.             for(K=J; K<=N-1; K=K+step)  
  88.             {  
  89.                 W.real =  cos(2*PI*P/N);  
  90.                 W.imag = -sin(2*PI*P/N);  
  91.                   
  92.                 Temp_XX = XX_complex(data[K+B],W);  
  93.                 data[K+B].real = data[K].real - Temp_XX.real;  
  94.                 data[K+B].imag = data[K].imag - Temp_XX.imag;  
  95.                 data[K].real = data[K].real + Temp_XX.real;  
  96.                 data[K].imag = data[K].imag + Temp_XX.imag;  
  97.             }  
  98.         }  
  99.     }  
  100. void IFFT(void)  
  101. int step=0;  
  102.     ElemType P=0,T=0;  
  103.     complex W,Temp_XX;  
  104.     //ElemType TempResult[N];  
  105.     ChangeSeat(data);  
  106. for(L=1; L<=M; L++)  
  107.         B = 1<<(L-1);//B=2^(L-1)  
  108. for(J=0; J<=B-1; J++)  
  109.             P = (1<<(M-L))*J;//P=2^(M-L) *J   
  110.             step = 1<<L;//2^L  
  111.             for(K=J; K<=N-1; K=K+step)  
  112.             {  
  113.                 W.real =  cos(2*PI*P/N);  
  114.                 W.imag =  sin(2*PI*P/N);//逆运算,这里跟FFT符号相反   
  115.                   
  116.                 Temp_XX = XX_complex(data[K+B],W);  
  117.                 data[K+B].real = data[K].real - Temp_XX.real;  
  118.                 data[K+B].imag = data[K].imag - Temp_XX.imag;  
  119.                 data[K].real = data[K].real + Temp_XX.real;  
  120.                 data[K].imag = data[K].imag + Temp_XX.imag;  
  121.             }  
  122.     }  
  123. int main(int argc, char *argv[])  
  124. int i = 0;  
  125. for(i=0; i<N; i++)//制造输入序列   
  126.         data[i].real = sin(2*PI*i/N);  
  127.         printf("%lf ",data[i]);  
  128.     printf("\n\n");  
  129.     FFT();//进行FFT计算   
  130. for(i=0; i<N; i++)  
  131.         {printf("%lf ",sqrt(data[i].real*data[i].real+data[i].imag*data[i].imag));}  
  132.     IFFT();//进行FFT计算   
  133.     printf("\n\n");  
  134. for(i=0; i<N; i++)  
  135.         {printf("%lf ",data[i].real/N);}  
  136.     printf("\n");  
  137. /*for(i=0; i<N; i++) 
  138.         {printf("%lf ",data[i].imag/N);} 
  139.     printf("\n");*/  
  140. /*for(i=0; i<N; i++) 
  141.   
  142. return 0;  
  143. }  


 

copy
    ** 性能提升:修正了IFFT的bug,使用宏定义改变N大小  
  1. ** 程序版本:V6.5 
  2. ** 最后修改:2011年5月16日  
  3. #define PI  3.14159265358979323846264338327950288419716939937510    //圆周率,50位小数   
  4. #define PI2 6.28318530717958647692528676655900576839433879875021  
  5. #define N 1024              //傅里叶变换的点数   
  6. #define M 10                //蝶形运算的级数,N = 2^M   
  7. #define Npart2 512          //创建正弦函数表时取PI的1/2   
  8. #define Npart4 256          //创建正弦函数表时取PI的1/4   
  9. #define FFT_RESULT(x)   (sqrt(data[x].real*data[x].real+data[x].imag*data[x].imag))  
  10. #define IFFT_RESULT(x)  (data[x].real/N)  
  11. float ElemType;     在这里设置  
  12. //定义复数结构体   
  13.     ElemType real,imag;  
  14. }complex;  
  15. complex data[N];            //定义存储单元,原始数据与负数结果均使用之   
  16. ElemType SIN_TABLE[Npart4+1];  
  17. //产生模拟原始数据输入   
  18. void InputData(int i;  
  19.         data[i].real = sin(2*PI*i/N);   //正弦波   
  20.         data[i].imag = 0;  
  21. //创建正弦函数表   
  22. void CREATE_SIN_TABLE(int i=0;   
  23. for(i=0; i<=Npart4; i++)  
  24.         SIN_TABLE[i] = sin(PI*i/Npart2);//SIN_TABLE[i] = sin(PI2*i/N);  
  25. ElemType Sin_find(ElemType x)  
  26. int i = (int)(N*x);  
  27.     i = i>>1;  
  28. if(i>Npart4)//注意:i已经转化为0~N之间的整数了!   
  29.     {//不会超过N/2   
  30.         i = Npart2 - i;//i = i - 2*(i-Npart4);  
  31.     }   
  32. return SIN_TABLE[i];  
  33. ElemType Cos_find(ElemType x)  
  34. if(i<Npart4)         //i = Npart4 - i;  
  35. return SIN_TABLE[Npart4 - i];  
  36.     }   
  37. else//i>Npart4 && i<N/2  
  38.         //i = i - Npart4;  
  39. return -SIN_TABLE[i - Npart4];  
  40. //变址   
  41. void ChangeSeat(complex *DataInput)  
  42.     nextValue=N/2;                  //变址运算,即把自然顺序变成倒位序,采用雷德算法  
  43.     nextM=N-1;  
  44. for (i=0;i<nextM;i++)  
  45.   
  46.             temp=DataInput[j];  
  47.             DataInput[j]=DataInput[i];  
  48.             DataInput[i]=temp;  
  49.         k=nextValue;                //求j的下一个倒位序  
  50.   
  51.             j=j-k;                  //把最高位变成0  
  52.             k=k/2;                  //k/2,比较次高位,依次类推,逐个比较,直到某个位为0  
  53.         j=j+k;                      //把0改为1  
  54.     }                                         
  55. }                                             
  56. //复数乘法   
  57. /*complex XX_complex(complex a, complex b) 
  58.     complex temp; 
  59.      
  60.     temp.real = a.real * b.real-a.imag*b.imag; 
  61.     temp.imag = b.imag*a.real + a.imag*b.real; 
  62.      
  63.     return temp; 
  64. }*/  
  65. //FFT运算函数   
  66. int step=0, KB=0;  
  67. //ElemType P=0;  
  68.     ElemType angle;  
  69.     ChangeSeat(data);//CREATE_SIN_TABLE();  
  70.         step = 1<<L;         B = step>>1;for(J=0; J<B; J++)  
  71.             //P = (1<<(M-L))*J;//P=2^(M-L) *J   
  72.             angle = (double)J/B;            //这里还可以优化   
  73.             W.imag =  -Sin_find(angle);     //用C++该函数课声明为inline   
  74.             W.real =   Cos_find(angle);     //用C++该函数课声明为inline   
  75. //W.real =  cos(angle*PI);  
  76.             //W.imag = -sin(angle*PI);  
  77. for(K=J; K<N; K=K+step)  
  78.                 KB = K + B;  
  79.                 //Temp_XX = XX_complex(data[KB],W);  
  80.                 //用下面两行直接计算复数乘法,省去函数调用开销   
  81.                 Temp_XX.real = data[KB].real * W.real-data[KB].imag*W.imag;  
  82.                 Temp_XX.imag = W.imag*data[KB].real + data[KB].imag*W.real;  
  83.                 data[KB].real = data[K].real - Temp_XX.real;  
  84.                 data[KB].imag = data[K].imag - Temp_XX.imag;  
  85. //IFFT运算函数   
  86.               
  87.             W.imag =   Sin_find(angle);                  W.real =   Cos_find(angle);     //W.real =  cos(angle*PI);  
  88. //W.imag = -sin(angle*PI);  
  89. for(K=J; K<N; K=K+step)  
  90.                 KB = K + B;  
  91.   
  92. //用下面两行直接计算复数乘法,省去函数调用开销   
  93.                 Temp_XX.real = data[KB].real * W.real-data[KB].imag*W.imag;  
  94.                 Temp_XX.imag = W.imag*data[KB].real + data[KB].imag*W.real;  
  95.                 data[KB].real = data[K].real - Temp_XX.real;  
  96.                 data[KB].imag = data[K].imag - Temp_XX.imag;  
  97. //主函数   
  98.     CREATE_SIN_TABLE(); //创建正弦函数表 ,这句只需在程序开始时执行一次   
  99.     InputData();        //输入原始数据 ,此处用公式模拟;实际应用时为AD采样数据   
  100.     FFT();              //进行 FFT计算   
  101.         {printf("%f ",FFT_RESULT(i));}/**/  
  102. //进行 IFFT计算   
  103. copy
    ** 程序名称快速傅里叶变换(FFT) 
  1. ** 程序描述:本程序实现快速傅里叶变换及其逆变换 
  2. ** 性能提升:修正了FFT的bug,变量重新命名,并将 N_FFT改为动态值 
  3. ** 程序版本:V6.6 
  4. ** 程序作者:宋元瑞 
  5. ** 最后修改:2011年5月16日 
  6. #include <stdlib.h>  
  7. #include <math.h>  
  8. //#define OUTPRINT printf  
  9. //#define DEL /##/  
  10. #define RESULT(x) sqrt(data_of_N_FFT[x].real*data_of_N_FFT[x].real+data_of_N_FFT[x].imag*data_of_N_FFT[x].imag)  
  11. #define PI  3.14159265358979323846264338327950288419716939937510    //圆周率,50位小数  
  12. #define PI2 6.28318530717958647692528676655900576839433879875021  
  13. int N_FFT=0;                //傅里叶变换的点数  
  14. int M_of_N_FFT=0;           //蝶形运算的级数,N = 2^M  
  15. int Npart2_of_N_FFT=0;      //创建正弦函数表时取PI的1/2  
  16. int Npart4_of_N_FFT=0;      //创建正弦函数表时取PI的1/4  
  17. //定义复数结构体  
  18. }complex_of_N_FFT,*ptr_complex_of_N_FFT;  
  19. ptr_complex_of_N_FFT data_of_N_FFT=NULL;//开辟存储单元,原始数据与负数结果均使用之  
  20. ElemType* SIN_TABLE_of_N_FFT=NULL;  
  21. //产生模拟原始数据输入  
  22. for (i=0; i<N_FFT; i++)//制造输入序列  
  23.         data_of_N_FFT[i].real = sin(2*PI*i/N_FFT);  //正弦波  
  24.         data_of_N_FFT[i].imag = 0;  
  25.         printf("%f ",data_of_N_FFT[i].real);  
  26. //创建正弦函数  
  27. int i=0;  
  28. for (i=0; i<=Npart4_of_N_FFT; i++)  
  29.         SIN_TABLE_of_N_FFT[i] = sin(PI*i/Npart2_of_N_FFT); ElemType Sin_find(ElemType x)  
  30. int)(N_FFT*x);  
  31.     i = i>>1;  
  32. if (i>Npart4_of_N_FFT)//注意:i已经转化为0~N之间的整数了!  
  33. //不会超过N/2  
  34.         i = Npart2_of_N_FFT - i;return SIN_TABLE_of_N_FFT[i];  
  35. ElemType Cos_find(ElemType x)  
  36. if (i<Npart4_of_N_FFT)return SIN_TABLE_of_N_FFT[Npart4_of_N_FFT - i];  
  37. return -SIN_TABLE_of_N_FFT[i - Npart4_of_N_FFT];  
  38. //变址  
  39. void ChangeSeat(complex_of_N_FFT *DataInput)  
  40.     complex_of_N_FFT temp;  
  41.     nextValue=N_FFT/2;                       nextM=N_FFT-1;  
  42. //复数乘法  
  43.  
  44.  
  45. //FFT运算函数  
  46.     complex_of_N_FFT W,248); line-height:18px">     ChangeSeat(data_of_N_FFT);for (L=1; L<=M_of_N_FFT; L++)  
  47. for (J=0; J<B; J++)  
  48. //P = (1<<(M-L))*J;//P=2^(M-L) *J  
  49. //这里还可以优化  
  50. //用C++该函数课声明为inline  
  51. //用C++该函数课声明为inline  
  52. for (K=J; K<N_FFT; K=K+step)  
  53. //用下面两行直接计算复数乘法,省去函数调用开销  
  54.                 Temp_XX.real = data_of_N_FFT[KB].real * W.real-data_of_N_FFT[KB].imag*W.imag;  
  55.                 Temp_XX.imag = W.imag*data_of_N_FFT[KB].real + data_of_N_FFT[KB].imag*W.real;  
  56.                 data_of_N_FFT[KB].real = data_of_N_FFT[K].real - Temp_XX.real;  
  57.                 data_of_N_FFT[KB].imag = data_of_N_FFT[K].imag - Temp_XX.imag;  
  58.                 data_of_N_FFT[K].real = data_of_N_FFT[K].real + Temp_XX.real;  
  59.                 data_of_N_FFT[K].imag = data_of_N_FFT[K].imag + Temp_XX.imag;  
  60. //IFFT运算函数  
  61. //ElemType P=0;  
  62.     ElemType angle;  
  63.     complex_of_N_FFT W,108); list-style:decimal-leading-zero outside; color:inherit; line-height:18px">     ChangeSeat(data_of_N_FFT);//变址  
  64. //CREATE_SIN_TABLE();  
  65. for (L=1; L<=M_of_N_FFT; L++)  
  66.         step = 1<<L;         B = step>>1;for (J=0; J<B; J++)  
  67. //P = (1<<(M-L))*J;//P=2^(M-L) *J  
  68.             angle = (//这里还可以优化  
  69.             W.imag =   Sin_find(angle);     //初始化FFT程序  
  70. //N_FFT是 FFT的点数,必须是2的次方  
  71. void Init_FFT(int N_of_FFT)  
  72. int i=0;  
  73. int temp_N_FFT=1;  
  74.     N_FFT = N_of_FFT;                   //傅里叶变换的点数 ,必须是 2的次方  
  75.     M_of_N_FFT = 0;                 //蝶形运算的级数,N = 2^M  
  76. for (i=0; temp_N_FFT<N_FFT; i++)  
  77.         temp_N_FFT = 2*temp_N_FFT;  
  78.         M_of_N_FFT++;  
  79.     printf("\n%d\n",M_of_N_FFT);  
  80.     Npart2_of_N_FFT = N_FFT/2;      //创建正弦函数表时取PI的1/2  
  81.     Npart4_of_N_FFT = N_FFT/4;      //创建正弦函数表时取PI的1/4  
  82. //ptr_complex_of_N_FFT data_of_N_FFT=NULL;//开辟存储单元,原始数据与负数结果均使用之  
  83.     data_of_N_FFT = (ptr_complex_of_N_FFT)malloc(N_FFT * sizeof(complex_of_N_FFT));  
  84. //ptr_complex_of_N_FFT SIN_TABLE_of_N_FFT=NULL;  
  85.     SIN_TABLE_of_N_FFT = (ElemType *)malloc((Npart4_of_N_FFT+1) * sizeof(ElemType));  
  86.     CREATE_SIN_TABLE();             //结束 FFT运算,释放相关内存  
  87. void Close_FFT(if (data_of_N_FFT != NULL)  
  88.         free(data_of_N_FFT);          //释放内存  
  89.         data_of_N_FFT = NULL;  
  90. if (SIN_TABLE_of_N_FFT != NULL)  
  91.         free(SIN_TABLE_of_N_FFT);     //释放内存  
  92.         SIN_TABLE_of_N_FFT = NULL;  
  93. //主函数  
  94.     Init_FFT(1024);     //初始化各项参数,此函数只需执行一次  
  95. //输入原始数据  
  96. //进行 FFT计算  
  97. for (i=0; i<N_FFT; i++)  
  98.         printf("%f ",RESULT(i));  
  99.     IFFT();//进行 IFFT计算  
  100. for (i=0; i<N_FFT; i++)  
  101.     Close_FFT();        copy
    ** 模块名称快速傅里叶变换(FFT)  
  1. ** 模块描述:本程序实现快速傅里叶变换  
  2. ** 性能提升:已达到网上同类程序最高速度  
  3. ** 模块版本:V6.0 
  4. ** 模块作者:宋元瑞  
  5. ** 最后修改:2011年5月6日 
  6. **  程序说明: 
  7.     FFT运算输入参数 source_Data(i) 是一个N大小的数组(注意是小括号) 
  8.     FFT运算输出结果 result_Data(i) 是一个N大小的数组(注意是小括号) 
  9. **  调用举例: 
  10. int main(int argc, char *argv[]) 
  11.     int i = 0; 
  12.     ///以下为FFT运算的调用方式  
  13.     FFT_prepare();      //为FFT做好准备,此函数只需程序开始时执行一次即可,切勿写在循环中  
  14.     while(1) 
  15.         for(i=0;i<N_FFT;i++) //输入原始数据  
  16.             {source_Data(i) = sin(2*PI*i/N_FFT);}//注意inputData后面是小括号  
  17.         FFT();              //进行FFT计算  
  18.         //输出结果:XXX =  result_Data(i); 
  19.     } 
  20.     return 0; 
  21. *******************************************************************************/   
  22. #ifndef SYRFFT_H  
  23. //#pragma once  
  24. //#include <stdio.h>  
  25. #define FFT_prepare() CREATE_SIN_TABLE();   //创建正弦函数表   
  26. #define source_Data(i) data_FFT[i].imag     //接收输入数据的数组,大小为N   
  27. #define result_Data(i) sqrt(data_FFT[i].real*data_FFT[i].real+data_FFT[i].imag*data_FFT[i].imag)//FFT结果   
  28. #define PI  3.14159265358979323846264338327950288419716939937510    //圆周率,50位小数   
  29. #define N_FFT 1024              //傅里叶变换的点数   
  30. #define M_of_N_FFT 10               //蝶形运算的级数,N = 2^M   
  31. #define Npart2_of_N_FFT 512         //创建正弦函数表时取PI的1/2   
  32. #define Npart4_of_N_FFT 256         //创建正弦函数表时取PI的1/4   
  33. }complex_of_N_FFT;  
  34. complex_of_N_FFT data_FFT[N_FFT];       //存放要进行FFT运输的数据,运算结果也存放这里   
  35. ElemType SIN_TABLE[Npart4_of_N_FFT+1];  
  36. /* 
  37. void InputData(void) 
  38.     int i; 
  39.     for(i=0; i<N_FFT; i++)       //制造输入序列  
  40.         source_Data(i) = sin(2*PI*i/N_FFT); //模拟输入正弦波  
  41.         //data_FFT[i].imag = sin(2*PI*i/N); //正弦波  
  42.         //printf("%f ",data_FFT[i].imag); 
  43. for(i=0; i<=Npart4_of_N_FFT; i++)  
  44.         SIN_TABLE[i] = sin(PI*i/Npart2_of_N_FFT);int)(N_FFT*x);  
  45. if(i>Npart4_of_N_FFT)if(i<Npart4_of_N_FFT)return SIN_TABLE[Npart4_of_N_FFT - i];  
  46. return -SIN_TABLE[i - Npart4_of_N_FFT];  
  47. //变址前data_FFT[i].imag存储了输入数据,变址后data_FFT[i].real存储了输入数据  
  48. int i,New_seat;  
  49. for(i=0; i<N_FFT; i++)  
  50.         New_seat = 0;  
  51. for(n=0;n<M_of_N_FFT;n++)  
  52.             New_seat = New_seat | (((i>>n) & 0x01) << (M_of_N_FFT-n-1));  
  53.         DataInput[New_seat].real = DataInput[i].imag;  
  54. for(i=0; i<N_FFT; i++)  
  55.         DataInput[i].imag = 0;  
  56. }                                                        
  57. complex_of_N_FFT XX_complex(complex_of_N_FFT a, complex_of_N_FFT b) 
  58.     complex_of_N_FFT temp; 
  59.     ChangeSeat(data_FFT);   for(L=1; L<=M_of_N_FFT; L++)  
  60. for(K=J; K<N_FFT; K=K+step)  
  61. //Temp_XX = XX_complex(data_FFT[KB],108); list-style:decimal-leading-zero outside; color:inherit; line-height:18px">                 Temp_XX.real = data_FFT[KB].real * W.real-data_FFT[KB].imag*W.imag;  
  62.                 Temp_XX.imag = W.imag*data_FFT[KB].real + data_FFT[KB].imag*W.real;  
  63.                 data_FFT[KB].real = data_FFT[K].real - Temp_XX.real;  
  64.                 data_FFT[KB].imag = data_FFT[K].imag - Temp_XX.imag;  
  65.                 data_FFT[K].real = data_FFT[K].real + Temp_XX.real;  
  66.                 data_FFT[K].imag = data_FFT[K].imag + Temp_XX.imag;  
  67. #define SYRFFT_H  
  68. #endif  

 

copy
    ** 程序版本:V6.0 
  1. ** 程序作者:宋元瑞  
  2. ** 最后修改:2011年5月6日 
  3. *******************************************************************************/  
  4. #include "syrFFT_H.h"   //包含FFT运算头文件   
  5. //以下3句为FFT运算的调用函数   
  6.     FFT_prepare();      //为FFT做好准备,此函数只需程序开始时执行一次即可,切勿写在循环中   
  7. //while(1)  
  8. for(i=0;i<N_FFT;i++)//模拟输入   
  9.             {source_Data(i) = sin(2*PI*i/N_FFT);}//注意inputData后面是小括号   
  10.         FFT();  
  11. for(i=0; i<N_FFT; i++)//输出结果   
  12.             {printf("%lf ",result_Data(i));}  
  13.  

    copy

    #ifndef FFT_H  
  1. #include <stdlib.h>  
  2. //傅里叶变换的点数   
  3. //蝶形运算的级数,N = 2^M   
  4. //创建正弦函数表时取PI的1/2   
  5. //创建正弦函数表时取PI的1/4   
  6. //开辟存储单元,原始数据与负数结果均使用之   
  7. //创建正弦函数表   
  8. int i=0;   
  9. for(i=0; i<=Npart4_of_N_FFT; i++)  
  10.         SIN_TABLE_of_N_FFT[i] = sin(PI*i/Npart2_of_N_FFT);//SIN_TABLE[i] = sin(PI2*i/N);  
  11. //注意:i已经转化为0~N之间的整数了!   
  12.     {//不会超过N/2   
  13.         i = Npart2_of_N_FFT - i;//i = i - 2*(i-Npart4);  
  14. return SIN_TABLE_of_N_FFT[i];  
  15. //i = Npart4 - i;  
  16. return SIN_TABLE_of_N_FFT[Npart4_of_N_FFT - i];  
  17. //i>Npart4 && i<N/2  
  18. //i = i - Npart4;  
  19. return -SIN_TABLE_of_N_FFT[i - Npart4_of_N_FFT];  
  20. void ChangeSeat(complex_of_N_FFT *DataInput)  
  21.     complex_of_N_FFT temp;  
  22.     nextValue=N_FFT/2;                       nextM=N_FFT-1;  
  23. }                                             
  24.     complex temp; 
  25.     temp.real = a.real * b.real-a.imag*b.imag; 
  26.     temp.imag = b.imag*a.real + a.imag*b.real; 
  27.     return temp; 
  28. }*/  
  29. //FFT运算函数   
  30. for(L=1; L<=M_of_N_FFT; L++)  
  31. for(J=0; J<B; J++)  
  32. //P = (1<<(M-L))*J;//P=2^(M-L) *J   
  33. //这里还可以优化   
  34.             W.imag =  -Sin_find(angle);     for(K=J; K<N_FFT; K=K+step)  
  35.                 Temp_XX.real = data_of_N_FFT[KB].real * W.real-data_of_N_FFT[KB].imag*W.imag;  
  36.                 Temp_XX.imag = W.imag*data_of_N_FFT[KB].real + data_of_N_FFT[KB].imag*W.real;  
  37.                 data_of_N_FFT[KB].real = data_of_N_FFT[K].real - Temp_XX.real;  
  38.                 data_of_N_FFT[KB].imag = data_of_N_FFT[K].imag - Temp_XX.imag;  
  39.                 data_of_N_FFT[K].real = data_of_N_FFT[K].real + Temp_XX.real;  
  40.                 data_of_N_FFT[K].imag = data_of_N_FFT[K].imag + Temp_XX.imag;  
  41. //IFFT运算函数   
  42.               
  43. //初始化FFT程序   
  44. //N_FFT是 FFT的点数,必须是2的次方   
  45. //傅里叶变换的点数 ,必须是 2的次方   
  46. //蝶形运算的级数,N = 2^M   
  47. for(i=0; temp_N_FFT<N_FFT; i++)  
  48. //printf("\n%d\n",M_of_N_FFT);  
  49. //创建正弦函数表时取PI的1/2   
  50. //创建正弦函数表时取PI的1/4   
  51. //ptr_complex_of_N_FFT data_of_N_FFT=NULL;//开辟存储单元,原始数据与负数结果均使用之   
  52. //结束 FFT运算,释放相关内存   
  53. if(data_of_N_FFT != NULL)  
  54.         free(data_of_N_FFT);                   data_of_N_FFT = NULL;  
  55. if(SIN_TABLE_of_N_FFT != NULL)  
  56.         free(SIN_TABLE_of_N_FFT);              SIN_TABLE_of_N_FFT = NULL;  
  57. #define FFT_H  
  58. #endif  
copy
    ** 程序描述:本程序实现快速傅里叶变换及其逆变换  
  1. ** 性能提升:修正了FFT的bug  
  2. #include "jxust_fft6_6.h"  
  3. //产生模拟原始数据输入 ,在实际应用时替换为AD采样数据   
  4. //输入采样数据   
  5. //主函数 ,示例如何调用FFT运算   
  6. char *argv[])  
  7. int i = 0;  
  8.     Init_FFT(1024);     //①初始化各项参数,此函数只需执行一次 ; 参数为FFT的点数,必须为2的次方   
  9.     InputData();        //②输入原始数据 ,此处在实际应用时替换为AD采样数据   
  10.     FFT();              //③进行 FFT计算   
  11. //for(i=0; i<N_FFT; i++)//④输出FFT频谱结果  sqrt(data_of_N_FFT[i].real*data_of_N_FFT[i].real+data_of_N_FFT[i].imag*data_of_N_FFT[i].imag)  
  12. //{printf("%f ",RESULT(i));}  
  13. //for(i=0; i<N_FFT; i++)//(可选步骤)⑤输出 IFFT结果 ,滤波时会用到;暂时不用   
  14.   
  15.     Close_FFT();    //结束 FFT运算,释放相关内存 ;此函数在彻底结束FFT运算后调用,   
  16. return 0;  
  17. }  

copy

    #ifndef SYRFFT_6_55_H  
  1. #define FFT_RESULT(x)   (sqrt(data_of_N_FFT[x].real*data_of_N_FFT[x].real+data_of_N_FFT[x].imag*data_of_N_FFT[x].imag))  
  2. #define IFFT_RESULT(x)  (data_of_N_FFT[x].real/N_FFT)  
  3. #define N_FFT           1024        //傅里叶变换的点数   
  4. #define M_of_N_FFT      10          //蝶形运算的级数,N = 2^M   
  5. #define Npart2_of_N_FFT 512         //创建正弦函数表时取PI的1/2   
  6. #define Npart4_of_N_FFT 256         //创建正弦函数表时取PI的1/4   
  7. }complex_of_N_FFT,*ptr_complex_of_N_FFT;  
  8. complex_of_N_FFT data_of_N_FFT[N_FFT];           ElemType SIN_TABLE_of_N_FFT[Npart4_of_N_FFT+1];  
  9. int)(N_FFT*x);     i = i>>1;// i = i / 2;  
  10. if(i>Npart4_of_N_FFT)  
  11. //根据FFT相关公式,sin()参数不会超过PI, 即i不会超过N/2   
  12. if(i < Npart4_of_N_FFT )   
  13.     { else //i > Npart4 && i < N/2   
  14. //初始化FFT程序   
  15. void Init_FFT()  
  16. //结束 FFT运算,释放相关内存   
  17. #define SYRFFT_6_55_H  
  18. #endif  

copy

    ** 程序版本:V6.55 
  1. ** 最后修改:2011年5月22日  
  2. #include "syrFFT_6_55.h"   
  3.   
  4. int i;  
  5. //制造输入序列   
  6.         data_of_N_FFT[i].real = sin(2*PI*i/N_FFT);  //输入采样数据   
  7.         data_of_N_FFT[i].imag = 0;  
  8. //主函数 ,示例如何调用FFT运算   
  9.     Init_FFT();         //①初始化各项参数,此函数只需执行一次 ; 修改FFT的点数去头文件的宏定义处修改   
  10.   
  11. //③进行 FFT计算   
  12. //for(i=0; i<N_FFT; i++)//④输出FFT频谱结果  sqrt(data_of_N_FFT[i].real*data_of_N_FFT[i].real+data_of_N_FFT[i].imag*data_of_N_FFT[i].imag)  
  13.   
  14. //进行 IFFT计算   
  15. //for(i=0; i<N_FFT; i++)//(可选步骤)⑤输出 IFFT结果 ,滤波时会用到;暂时不用   
  16.   
  17. //结束 FFT运算,此版本此句无用,可不写   
  18. }  

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。

相关推荐