找回密碼
 立即注冊(cè)

QQ登錄

只需一步,快速開(kāi)始

搜索
查看: 2612|回復(fù): 0
打印 上一主題 下一主題
收起左側(cè)

C語(yǔ)言寫(xiě)的FFT代碼

[復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
ID:996634 發(fā)表于 2021-12-26 17:19 | 只看該作者 回帖獎(jiǎng)勵(lì) |倒序?yàn)g覽 |閱讀模式
/*   新手上路還望見(jiàn)諒。  *
  1. #include <stdio.h>
  2. #include <math.h>
  3. #include <stdlib.h>

  4. #define   N     8     //64  輸入樣本總數(shù)
  5. #define    M     3   //DFT運(yùn)算層數(shù)     //2^m=N  
  6. #define    PI    3.1415926

  7. float   twiddle[N/2] = {1.0, 0.707, 0.0, -0.707};
  8. float   x_r[N] = {1, 1, 1, 1, 0, 0, 0, 0};  //輸入數(shù)據(jù),此處設(shè)為8個(gè)
  9. float   x_i[N];                         //N=8


  10. /**
  11. * 初始化輸出虛部
  12. */
  13. static void fft_init( void )
  14. {
  15.     int i;
  16.     for(i=0; i<N; i++)   x_i[i] = 0.0;
  17. }

  18. /**
  19. * 反轉(zhuǎn)算法.將時(shí)域信號(hào)重新排序.
  20. * 這個(gè)算法有改進(jìn)的空間
  21. */
  22. static void bitrev( void )
  23. {
  24.     int    p=1, q, i;
  25.     int    bit_rev[ N ];  
  26.     float   xx_r[ N ];   
  27.    
  28.     bit_rev[ 0 ] = 0;
  29.     while( p < N )
  30.     {
  31.        for(q=0; q<p; q++)  
  32.        {
  33.            bit_rev[ q ]     = bit_rev[ q ] * 2;
  34.            bit_rev[ q + p ] = bit_rev[ q ] + 1;
  35.        }
  36.        p *= 2;
  37.     }
  38.    
  39.     for(i=0; i<N; i++)   xx_r[ i ] = x_r[ i ];   
  40.    
  41.     for(i=0; i<N; i++)   x_r[i] = xx_r[ bit_rev[i] ];
  42. }

  43. void fft( void )
  44. {   fp = fopen("log2.txt", "a+");//此處
  45.     int     cur_layer, gr_num, i, k, p;        //cur_layer代表正要計(jì)算的當(dāng)前層,gr_num代表當(dāng)前層的顆粒數(shù)
  46.     float   tmp_real, tmp_imag, temp;   // 臨時(shí)變量, 記錄實(shí)部
  47.     float   tw1, tw2;// 旋轉(zhuǎn)因子,tw1為旋轉(zhuǎn)因子的實(shí)部cos部分, tw2為旋轉(zhuǎn)因子的虛部sin部分.
  48.       
  49.     int    step;      // 步進(jìn)
  50.     int    sample_num;   // 顆粒的樣本總數(shù)(各層不同, 因?yàn)楦鲗宇w粒的輸入不同)
  51.    
  52.     /* 對(duì)層循環(huán) */
  53.     for(cur_layer=1; cur_layer<=M; cur_layer++)
  54.     {      
  55.        /* 求當(dāng)前層擁有多少個(gè)顆粒(gr_num) */
  56.        gr_num = 1;
  57.        i = M - cur_layer;
  58.        while(i > 0)
  59.        {
  60.            i--;
  61.            gr_num *= 2;
  62.        }
  63.       
  64.        /* 每個(gè)顆粒的輸入樣本數(shù)N' */
  65.        sample_num    = (int)pow(2, cur_layer);
  66.        /* 步進(jìn). 步進(jìn)是N'/2 */
  67.        step       = sample_num/2;
  68.       
  69.        /*  */
  70.        k = 0;
  71.       
  72.        /* 對(duì)顆粒進(jìn)行循環(huán) */
  73.        for(i=0; i<gr_num; i++)
  74.        {
  75.            /*
  76.             * 對(duì)樣本點(diǎn)進(jìn)行循環(huán), 注意上限和步進(jìn)
  77.             */
  78.            for(p=0; p<sample_num/2; p++)
  79.            {   
  80.               // 旋轉(zhuǎn)因子, 需要優(yōu)化...   
  81.               tw1 = cos(2*PI*p/pow(2, cur_layer));
  82.               tw2 = -sin(2*PI*p/pow(2, cur_layer));
  83.               
  84.               tmp_real = x_r[k+p];
  85.               tmp_imag = x_i[k+p];
  86.               temp = x_r[k+p+step];
  87.               
  88.               /* 蝶形算法 */
  89.               x_r[k+p]   = tmp_real + ( tw1*x_r[k+p+step] - tw2*x_i[k+p+step] );
  90.               x_i[k+p]   = tmp_imag + ( tw2*x_r[k+p+step] + tw1*x_i[k+p+step] );
  91.               /* X[k] = A(k)+WB(k)
  92.                * X[k+N/2] = A(k)-WB(k) 的性質(zhì)可以優(yōu)化這里*/
  93.               /*旋轉(zhuǎn)因子, 需要優(yōu)化...
  94.               tw1 = cos(2*PI*(p+step)/pow(2, cur_layer));
  95.               tw2 = -sin(2*PI*(p+step)/pow(2, cur_layer));
  96.               x_r[k+p+step] = tmp_real + ( tw1*temp - tw2*x_i[k+p+step] );
  97.               x_i[k+p+step] = tmp_imag + ( tw2*temp + tw1*x_i[k+p+step] );*/
  98.         x_r[k+p+step]   = tmp_real - ( tw1* temp - tw2*x_i[k+p+step] );
  99.               x_i[k+p+step]   = tmp_imag - ( tw2* temp + tw1*x_i[k+p+step] );
  100.               
  101.               printf("k=%d, x_r[k]=%f, x_i[k]=%f\n", k+p, x_r[k+p], x_i[k+p]);
  102.               printf("k=%d, x_r[k]=%f, x_i[k]=%f\n", k+p+step, x_r[k+p+step], x_i[k+p+step]);
  103.            }
  104.            /* 開(kāi)跳!:) */
  105.            k += 2*step;
  106.        }   
  107.     }
  108. }

  109. void display( void )
  110. {
  111.     printf("\n\n");
  112.     int   i;  
  113.     for(i=0; i<N; i++)
  114.        printf("%f\t%f\n", x_r[i], x_i[i]);
  115. }

  116. int main( void )
  117. {
  118.     fft_init( );                //初始化
  119.     bitrev( );                //將輸入直接按FFT計(jì)算要求排序,如8點(diǎn)FFT計(jì)算,排序?yàn)閤[0]、x[4]、x[2]、x[6]、x[1]、x[5]、x[3]、x[7]
  120.     fft( );                        //進(jìn)行FFT計(jì)算
  121.     display( );                //顯示計(jì)算結(jié)果
  122.    
  123.     system( "pause" );
  124.     return 1;
  125. }

復(fù)制代碼

評(píng)分

參與人數(shù) 1黑幣 +10 收起 理由
admin + 10 共享資料的黑幣獎(jiǎng)勵(lì)!

查看全部評(píng)分

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏2 分享淘帖 頂 踩
回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

手機(jī)版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表