日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

FFT算法的完整DSP实现

發布時間:2025/5/22 编程问答 22 豆豆
生活随笔 收集整理的這篇文章主要介紹了 FFT算法的完整DSP实现 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

傅里葉變換或者FFT的理論參考:

[1]?http://www.dspguide.com/ch12/2.htm

? ? ??The Scientist and Engineer's Guide to?Digital Signal Processing, ??By Steven W. Smith, Ph.D.

[2]?http://blog.csdn.net/v_JULY_v/article/details/6196862,可當作[1]的中文參考

[3] 任意一本數字信號處理教材,上面都有詳細的推導DCT求解轉換為FFT求解的過程

[4] TI文檔:基于TMS320C64x+DSP的FFT實現。 使用baidu/google可以搜索到。

另外,FFT的開源代碼可參考:

[1] FFTW:?http://www.fftw.org/?最快,最好的開源FFT。

[2] FFTReal:?http://ldesoras.free.fr/prod.html#src_fftreal?輕量級FFT算法實現

[3] KISS FFT:?http://sourceforge.net/projects/kissfft/ 簡單易用的FFT的C語言實現


1. 有關FFT理論的一點小小解釋

關于FFT這里只想提到兩點:

(1)DFT變換對的表達式(必須記住



? ? ? ? ? —— 稱旋轉因子


(2)FFT用途——目標只有一個,加速DFT的計算效率。

DFT計算X(k)需要N^2次復數乘法和N(N-1)次復數加法;FFT將N^2的計算量降為。


FFT其實是很難的東西,即使常年在這個領域下打拼的科學家也未必能很好的寫出FFT的算法。”——摘自參考上面提供的參考文獻[1]

因此,我們不必太過糾結于細節,當明白FFT理論后,將已有的算法挪過來用就OK了,不必為閉著教材寫不出FFT而郁悶不堪。


FFT的BASIC程序偽代碼如下:


IFFT的BASIC程序偽代碼如下(IFFT通過調用FFT計算):


FFT算法的流程圖如下圖,總結為3過程3循環:

(1)3過程:單點時域分解(倒位序過程) + 單點時域計算單點頻譜 + 頻域合成

(2)3循環:外循環——分解次數,中循環——sub-DFT運算,內循環——2點蝶形算法


分解過程或者說倒位序的獲得參考下圖理解:

2. FFT的DSP實現

下面為本人使用C語言實現的FFT及IFFT算法實例,能計算任意以2為對數底的采樣點數的FFT,算法參考上面給的流程圖。

[cpp] view plaincopy print?
  • /*?
  • ?*?zx_fft.h?
  • ?*?
  • ?*??Created?on:?2013-8-5?
  • ?*??????Author:?monkeyzx?
  • ?*/??
  • ??
  • #ifndef?ZX_FFT_H_??
  • #define?ZX_FFT_H_??
  • ??
  • typedef?float??????????FFT_TYPE;??
  • ??
  • #ifndef?PI??
  • #define?PI?????????????(3.14159265f)??
  • #endif??
  • ??
  • typedef?struct?complex_st?{??
  • ????FFT_TYPE?real;??
  • ????FFT_TYPE?img;??
  • }?complex;??
  • ??
  • int?fft(complex?*x,?int?N);??
  • int?ifft(complex?*x,?int?N);??
  • void?zx_fft(void);??
  • ??
  • #endif?/*?ZX_FFT_H_?*/??
  • /** zx_fft.h** Created on: 2013-8-5* Author: monkeyzx*/#ifndef ZX_FFT_H_ #define ZX_FFT_H_typedef float FFT_TYPE;#ifndef PI #define PI (3.14159265f) #endiftypedef struct complex_st {FFT_TYPE real;FFT_TYPE img; } complex;int fft(complex *x, int N); int ifft(complex *x, int N); void zx_fft(void);#endif /* ZX_FFT_H_ */
    [cpp] view plaincopy print?
  • /*?
  • ?*?zx_fft.c?
  • ?*?
  • ?*?Implementation?of?Fast?Fourier?Transform(FFT)?
  • ?*?and?reversal?Fast?Fourier?Transform(IFFT)?
  • ?*?
  • ?*??Created?on:?2013-8-5?
  • ?*??????Author:?monkeyzx?
  • ?*/??
  • ??
  • #include?"zx_fft.h"??
  • #include?<math.h>??
  • #include?<stdlib.h>??
  • ??
  • /*?
  • ?*?Bit?Reverse?
  • ?*?===?Input?===?
  • ?*?x?:?complex?numbers?
  • ?*?n?:?nodes?of?FFT.?@N?should?be?power?of?2,?that?is?2^(*)?
  • ?*?l?:?count?by?bit?of?binary?format,?@l=CEIL{log2(n)}?
  • ?*?===?Output?===?
  • ?*?r?:?results?after?reversed.?
  • ?*?Note:?I?use?a?local?variable?@temp?that?result?@r?can?be?set?
  • ?*?to?@x?and?won't?overlap.?
  • ?*/??
  • static?void?BitReverse(complex?*x,?complex?*r,?int?n,?int?l)??
  • {??
  • ????int?i?=?0;??
  • ????int?j?=?0;??
  • ????short?stk?=?0;??
  • ????static?complex?*temp?=?0;??
  • ??
  • ????temp?=?(complex?*)malloc(sizeof(complex)?*?n);??
  • ????if?(!temp)?{??
  • ????????return;??
  • ????}??
  • ??
  • ????for(i=0;?i<n;?i++)?{??
  • ????????stk?=?0;??
  • ????????j?=?0;??
  • ????????do?{??
  • ????????????stk?|=?(i>>(j++))?&?0x01;??
  • ????????????if(j<l)??
  • ????????????{??
  • ????????????????stk?<<=?1;??
  • ????????????}??
  • ????????}while(j<l);??
  • ??
  • ????????if(stk?<?n)?{?????????????/*?滿足倒位序輸出?*/??
  • ????????????temp[stk]?=?x[i];??
  • ????????}??
  • ????}??
  • ????/*?copy?@temp?to?@r?*/??
  • ????for?(i=0;?i<n;?i++)?{??
  • ????????r[i]?=?temp[i];??
  • ????}??
  • ????free(temp);??
  • }??
  • ??
  • /*?
  • ?*?FFT?Algorithm?
  • ?*?===?Inputs?===?
  • ?*?x?:?complex?numbers?
  • ?*?N?:?nodes?of?FFT.?@N?should?be?power?of?2,?that?is?2^(*)?
  • ?*?===?Output?===?
  • ?*?the?@x?contains?the?result?of?FFT?algorithm,?so?the?original?data?
  • ?*?in?@x?is?destroyed,?please?store?them?before?using?FFT.?
  • ?*/??
  • int?fft(complex?*x,?int?N)??
  • {??
  • ????int?i,j,l,ip;??
  • ????static?int?M?=?0;??
  • ????static?int?le,le2;??
  • ????static?FFT_TYPE?sR,sI,tR,tI,uR,uI;??
  • ??
  • ????M?=?(int)(log(N)?/?log(2));??
  • ??
  • ????/*?
  • ?????*?bit?reversal?sorting?
  • ?????*/??
  • ????BitReverse(x,x,N,M);??
  • ??
  • ????/*?
  • ?????*?For?Loops?
  • ?????*/??
  • ????for?(l=1;?l<=M;?l++)?{???/*?loop?for?ceil{log2(N)}?*/??
  • ????????le?=?(int)pow(2,l);??
  • ????????le2?=?(int)(le?/?2);??
  • ????????uR?=?1;??
  • ????????uI?=?0;??
  • ????????sR?=?cos(PI?/?le2);??
  • ????????sI?=?-sin(PI?/?le2);??
  • ????????for?(j=1;?j<=le2;?j++)?{???/*?loop?for?each?sub?DFT?*/??
  • ????????????//jm1?=?j?-?1;??
  • ????????????for?(i=j-1;?i<=N-1;?i+=le)?{??/*?loop?for?each?butterfly?*/??
  • ????????????????ip?=?i?+?le2;??
  • ????????????????tR?=?x[ip].real?*?uR?-?x[ip].img?*?uI;??
  • ????????????????tI?=?x[ip].real?*?uI?+?x[ip].img?*?uR;??
  • ????????????????x[ip].real?=?x[i].real?-?tR;??
  • ????????????????x[ip].img?=?x[i].img?-?tI;??
  • ????????????????x[i].real?+=?tR;??
  • ????????????????x[i].img?+=?tI;??
  • ????????????}??/*?Next?i?*/??
  • ????????????tR?=?uR;??
  • ????????????uR?=?tR?*?sR?-?uI?*?sI;??
  • ????????????uI?=?tR?*?sI?+?uI?*sR;??
  • ????????}?/*?Next?j?*/??
  • ????}?/*?Next?l?*/??
  • ??
  • ????return?0;??
  • }??
  • ??
  • /*?
  • ?*?Inverse?FFT?Algorithm?
  • ?*?===?Inputs?===?
  • ?*?x?:?complex?numbers?
  • ?*?N?:?nodes?of?FFT.?@N?should?be?power?of?2,?that?is?2^(*)?
  • ?*?===?Output?===?
  • ?*?the?@x?contains?the?result?of?FFT?algorithm,?so?the?original?data?
  • ?*?in?@x?is?destroyed,?please?store?them?before?using?FFT.?
  • ?*/??
  • int?ifft(complex?*x,?int?N)??
  • {??
  • ????int?k?=?0;??
  • ??
  • ????for?(k=0;?k<=N-1;?k++)?{??
  • ????????x[k].img?=?-x[k].img;??
  • ????}??
  • ??
  • ????fft(x,?N);????/*?using?FFT?*/??
  • ??
  • ????for?(k=0;?k<=N-1;?k++)?{??
  • ????????x[k].real?=?x[k].real?/?N;??
  • ????????x[k].img?=?-x[k].img?/?N;??
  • ????}??
  • ??
  • ????return?0;??
  • }??
  • ??
  • /*?
  • ?*?Code?below?is?an?example?of?using?FFT?and?IFFT.?
  • ?*/??
  • #define??SAMPLE_NODES??????????????(128)??
  • complex?x[SAMPLE_NODES];??
  • int?INPUT[SAMPLE_NODES];??
  • int?OUTPUT[SAMPLE_NODES];??
  • ??
  • static?void?MakeInput()??
  • {??
  • ????int?i;??
  • ??
  • ????for?(?i=0;i<SAMPLE_NODES;i++?)??
  • ????{??
  • ????????x[i].real?=?sin(PI*2*i/SAMPLE_NODES);??
  • ????????x[i].img?=?0.0f;??
  • ????????INPUT[i]=sin(PI*2*i/SAMPLE_NODES)*1024;??
  • ????}??
  • }??
  • ??
  • static?void?MakeOutput()??
  • {??
  • ????int?i;??
  • ??
  • ????for?(?i=0;i<SAMPLE_NODES;i++?)??
  • ????{??
  • ????????OUTPUT[i]?=?sqrt(x[i].real*x[i].real?+?x[i].img*x[i].img)*1024;??
  • ????}??
  • }??
  • ??
  • void?zx_fft(void)??
  • {??
  • ????MakeInput();??
  • ??
  • ????fft(x,128);??
  • ????MakeOutput();??
  • ??
  • ????ifft(x,128);??
  • ????MakeOutput();??
  • }??
  • /** zx_fft.c** Implementation of Fast Fourier Transform(FFT)* and reversal Fast Fourier Transform(IFFT)** Created on: 2013-8-5* Author: monkeyzx*/#include "zx_fft.h" #include <math.h> #include <stdlib.h>/** Bit Reverse* === Input ===* x : complex numbers* n : nodes of FFT. @N should be power of 2, that is 2^(*)* l : count by bit of binary format, @l=CEIL{log2(n)}* === Output ===* r : results after reversed.* Note: I use a local variable @temp that result @r can be set* to @x and won't overlap.*/ static void BitReverse(complex *x, complex *r, int n, int l) {int i = 0;int j = 0;short stk = 0;static complex *temp = 0;temp = (complex *)malloc(sizeof(complex) * n);if (!temp) {return;}for(i=0; i<n; i++) {stk = 0;j = 0;do {stk |= (i>>(j++)) & 0x01;if(j<l){stk <<= 1;}}while(j<l);if(stk < n) { /* 滿足倒位序輸出 */temp[stk] = x[i];}}/* copy @temp to @r */for (i=0; i<n; i++) {r[i] = temp[i];}free(temp); }/** FFT Algorithm* === Inputs ===* x : complex numbers* N : nodes of FFT. @N should be power of 2, that is 2^(*)* === Output ===* the @x contains the result of FFT algorithm, so the original data* in @x is destroyed, please store them before using FFT.*/ int fft(complex *x, int N) {int i,j,l,ip;static int M = 0;static int le,le2;static FFT_TYPE sR,sI,tR,tI,uR,uI;M = (int)(log(N) / log(2));/** bit reversal sorting*/BitReverse(x,x,N,M);/** For Loops*/for (l=1; l<=M; l++) { /* loop for ceil{log2(N)} */le = (int)pow(2,l);le2 = (int)(le / 2);uR = 1;uI = 0;sR = cos(PI / le2);sI = -sin(PI / le2);for (j=1; j<=le2; j++) { /* loop for each sub DFT *///jm1 = j - 1;for (i=j-1; i<=N-1; i+=le) { /* loop for each butterfly */ip = i + le2;tR = x[ip].real * uR - x[ip].img * uI;tI = x[ip].real * uI + x[ip].img * uR;x[ip].real = x[i].real - tR;x[ip].img = x[i].img - tI;x[i].real += tR;x[i].img += tI;} /* Next i */tR = uR;uR = tR * sR - uI * sI;uI = tR * sI + uI *sR;} /* Next j */} /* Next l */return 0; }/** Inverse FFT Algorithm* === Inputs ===* x : complex numbers* N : nodes of FFT. @N should be power of 2, that is 2^(*)* === Output ===* the @x contains the result of FFT algorithm, so the original data* in @x is destroyed, please store them before using FFT.*/ int ifft(complex *x, int N) {int k = 0;for (k=0; k<=N-1; k++) {x[k].img = -x[k].img;}fft(x, N); /* using FFT */for (k=0; k<=N-1; k++) {x[k].real = x[k].real / N;x[k].img = -x[k].img / N;}return 0; }/** Code below is an example of using FFT and IFFT.*/ #define SAMPLE_NODES (128) complex x[SAMPLE_NODES]; int INPUT[SAMPLE_NODES]; int OUTPUT[SAMPLE_NODES];static void MakeInput() {int i;for ( i=0;i<SAMPLE_NODES;i++ ){x[i].real = sin(PI*2*i/SAMPLE_NODES);x[i].img = 0.0f;INPUT[i]=sin(PI*2*i/SAMPLE_NODES)*1024;} }static void MakeOutput() {int i;for ( i=0;i<SAMPLE_NODES;i++ ){OUTPUT[i] = sqrt(x[i].real*x[i].real + x[i].img*x[i].img)*1024;} }void zx_fft(void) {MakeInput();fft(x,128);MakeOutput();ifft(x,128);MakeOutput(); }
    程序在TMS320C6713上實驗,主函數中調用zx_fft()函數即可。

    FFT的采樣點數為128,輸入信號的實數域為正弦信號,虛數域為0,數據精度定義FFT_TYPE為float類型,MakeInput和MakeOutput函數分別用于產生輸入數據INPUT和輸出數據OUTPUT的函數,便于使用CCS 的Graph功能繪制波形圖。這里調試時使用CCS v5中的Tools -> Graph功能得到下面的波形圖(怎么用自己琢磨,不會的使用CCS 的Help)。

    輸入波形


    輸入信號的頻域幅值表示


    FFT運算結果


    對FFT運算結果逆變換(IFFT)



    如何檢驗運算結果是否正確呢?有幾種方法:

    (1)使用matlab驗證,下面為相同情況的matlab圖形驗證代碼

    [cpp] view plaincopy print?
  • SAMPLE_NODES?=?128;??
  • i?=?1:SAMPLE_NODES;??
  • x?=?sin(pi*2*i?/?SAMPLE_NODES);??
  • ??
  • subplot(2,2,1);?plot(x);title('Inputs');??
  • axis([0?128?-1?1]);??
  • ??
  • y?=?fft(x,?SAMPLE_NODES);??
  • subplot(2,2,2);?plot(abs(y));title('FFT');??
  • axis([0?128?0?80]);??
  • ??
  • z?=?ifft(y,?SAMPLE_NODES);??
  • subplot(2,2,3);?plot(abs(z));title('IFFT');??
  • axis([0?128?0?1]);??
  • SAMPLE_NODES = 128; i = 1:SAMPLE_NODES; x = sin(pi*2*i / SAMPLE_NODES);subplot(2,2,1); plot(x);title('Inputs'); axis([0 128 -1 1]);y = fft(x, SAMPLE_NODES); subplot(2,2,2); plot(abs(y));title('FFT'); axis([0 128 0 80]);z = ifft(y, SAMPLE_NODES); subplot(2,2,3); plot(abs(z));title('IFFT'); axis([0 128 0 1]);

    (2)使用IFFT驗證:輸入信號的FFT獲得的信號再IFFT,則的到的信號與原信號相同

    可能大家發現輸入信號上面的最后IFFT的信號似乎不同,這是因為FFT和IFFT存在精度截斷誤差(也叫數據截斷噪聲,意思就是說,我們使用的float數據類型數據位數有限,沒法完全保留原始信號的信息)。因此,IFFT之后是復數(數據截斷噪聲引入了虛數域,只不過值很小),所以在繪圖時使用了計算幅值的方法,

    C代碼中:

    [cpp] view plaincopy print?
  • OUTPUT[i]?=?sqrt(x[i].real*x[i].real?+?x[i].img*x[i].img)*1024;??
  • OUTPUT[i] = sqrt(x[i].real*x[i].real + x[i].img*x[i].img)*1024;

    matlab代碼中:

    [cpp] view plaincopy print?
  • subplot(2,2,3);?plot(abs(z));title('IFFT');??
  • subplot(2,2,3); plot(abs(z));title('IFFT');

    所以IFFT的結果將sin函數的負y軸數據翻到了正y軸。另外,在CCS v5的圖形中我們將顯示信號的幅度放大了1024倍便于觀察,而matlab中沒有放大。


    =================

    更正 更正 。。。

    =================

    上面程序中的BitReverse函數由于使用了malloc函數,當要分配的n比較大時,在DSP上運行會出現一定的問題,因此改用偽代碼中提供的倒位序方法更可靠。

    修正后的完整FFT代碼文件粘貼如下,在實際的DSP項目中測試通過,可直接拷貝復用。

    [cpp] view plaincopy print?
  • /*?
  • ?*?zx_fft.h?
  • ?*?
  • ?*??Created?on:?2013-8-5?
  • ?*??????Author:?monkeyzx?
  • ?*/??
  • ??
  • #ifndef?_ZX_FFT_H??
  • #define?_ZX_FFT_H??
  • ??
  • #include?"../Headers/Global.h"??
  • ??
  • #define?TYPE_FFT_E?????float????/*?Type?is?the?same?with?COMPLEX?member?*/???????
  • ??
  • #ifndef?PI??
  • #define?PI?????????????(3.14159265f)??
  • #endif??
  • ??
  • typedef?COMPLEX?TYPE_FFT;??/*?Define?COMPLEX?in?Config.h?*/??
  • ??
  • extern?int?fft(TYPE_FFT?*x,?int?N);??
  • extern?int?ifft(TYPE_FFT?*x,?int?N);??
  • ??
  • #endif?/*?ZX_FFT_H_?*/??
  • /** zx_fft.h** Created on: 2013-8-5* Author: monkeyzx*/#ifndef _ZX_FFT_H #define _ZX_FFT_H#include "../Headers/Global.h"#define TYPE_FFT_E float /* Type is the same with COMPLEX member */ #ifndef PI #define PI (3.14159265f) #endiftypedef COMPLEX TYPE_FFT; /* Define COMPLEX in Config.h */extern int fft(TYPE_FFT *x, int N); extern int ifft(TYPE_FFT *x, int N);#endif /* ZX_FFT_H_ */
    [cpp] view plaincopy print?
  • /*?
  • ?*?zx_fft.c?
  • ?*?
  • ?*?Implementation?of?Fast?Fourier?Transform(FFT)?
  • ?*?and?reversal?Fast?Fourier?Transform(IFFT)?
  • ?*??
  • ?*??Created?on:?2013-8-5?
  • ?*??????Author:?monkeyzx?
  • ?*?
  • ?*?TEST?OK?2014.01.14?
  • ?*?==?2014.01.14?
  • ?*???Replace?@BitReverse(x,x,N,M)?by?refrence?to??
  • ?*???<The?Scientist?and?Engineer's?Guide?to?Digital?Signal?Processing>?
  • ?*/??
  • ??
  • #include?"zx_fft.h"??
  • ??
  • /*?
  • ?*?FFT?Algorithm?
  • ?*?===?Inputs?===?
  • ?*?x?:?complex?numbers?
  • ?*?N?:?nodes?of?FFT.?@N?should?be?power?of?2,?that?is?2^(*)?
  • ?*?===?Output?===?
  • ?*?the?@x?contains?the?result?of?FFT?algorithm,?so?the?original?data?
  • ?*?in?@x?is?destroyed,?please?store?them?before?using?FFT.?
  • ?*/??
  • int?fft(TYPE_FFT?*x,?int?N)??
  • {??
  • ????int?i,j,l,k,ip;??
  • ????static?int?M?=?0;??
  • ????static?int?le,le2;??
  • ????static?TYPE_FFT_E?sR,sI,tR,tI,uR,uI;??
  • ??
  • ????M?=?(int)(log(N)?/?log(2));??
  • ??
  • ????/*?
  • ?????*?bit?reversal?sorting?
  • ?????*/??
  • ????l?=?N?/?2;??
  • ????j?=?l;??
  • ????//BitReverse(x,x,N,M);??
  • ????for?(i=1;?i<=N-2;?i++)?{??
  • ????????if?(i?<?j)?{??
  • ????????????tR?=?x[j].real;??
  • ????????????tI?=?x[j].imag;??
  • ????????????x[j].real?=?x[i].real;??
  • ????????????x[j].imag?=?x[i].imag;??
  • ????????????x[i].real?=?tR;??
  • ????????????x[i].imag?=?tI;??
  • ????????}??
  • ????????k?=?l;??
  • ????????while?(k?<=?j)?{??
  • ????????????j?=?j?-?k;??
  • ????????????k?=?k?/?2;??
  • ????????}??
  • ????????j?=?j?+?k;??
  • ????}??
  • ??
  • ????/*?
  • ?????*?For?Loops?
  • ?????*/??
  • ????for?(l=1;?l<=M;?l++)?{???/*?loop?for?ceil{log2(N)}?*/??
  • ????????le?=?(int)pow(2,l);??
  • ????????le2?=?(int)(le?/?2);??
  • ????????uR?=?1;??
  • ????????uI?=?0;??
  • ????????sR?=?cos(PI?/?le2);??
  • ????????sI?=?-sin(PI?/?le2);??
  • ????????for?(j=1;?j<=le2;?j++)?{???/*?loop?for?each?sub?DFT?*/??
  • ????????????//jm1?=?j?-?1;??
  • ????????????for?(i=j-1;?i<=N-1;?i+=le)?{??/*?loop?for?each?butterfly?*/??
  • ????????????????ip?=?i?+?le2;??
  • ????????????????tR?=?x[ip].real?*?uR?-?x[ip].imag?*?uI;??
  • ????????????????tI?=?x[ip].real?*?uI?+?x[ip].imag?*?uR;??
  • ????????????????x[ip].real?=?x[i].real?-?tR;??
  • ????????????????x[ip].imag?=?x[i].imag?-?tI;??
  • ????????????????x[i].real?+=?tR;??
  • ????????????????x[i].imag?+=?tI;??
  • ????????????}??/*?Next?i?*/??
  • ????????????tR?=?uR;??
  • ????????????uR?=?tR?*?sR?-?uI?*?sI;??
  • ????????????uI?=?tR?*?sI?+?uI?*sR;??
  • ????????}?/*?Next?j?*/??
  • ????}?/*?Next?l?*/??
  • ??
  • ????return?0;??
  • }??
  • ??
  • /*?
  • ?*?Inverse?FFT?Algorithm?
  • ?*?===?Inputs?===?
  • ?*?x?:?complex?numbers?
  • ?*?N?:?nodes?of?FFT.?@N?should?be?power?of?2,?that?is?2^(*)?
  • ?*?===?Output?===?
  • ?*?the?@x?contains?the?result?of?FFT?algorithm,?so?the?original?data?
  • ?*?in?@x?is?destroyed,?please?store?them?before?using?FFT.?
  • ?*/??
  • int?ifft(TYPE_FFT?*x,?int?N)??
  • {??
  • ????int?k?=?0;??
  • ??
  • ????for?(k=0;?k<=N-1;?k++)?{??
  • ????????x[k].imag?=?-x[k].imag;??
  • ????}??
  • ??
  • ????fft(x,?N);????/*?using?FFT?*/??
  • ??
  • ????for?(k=0;?k<=N-1;?k++)?{??
  • ????????x[k].real?=?x[k].real?/?N;??
  • ????????x[k].imag?=?-x[k].imag?/?N;??
  • ????}??
  • ??
  • ????return?0;??
  • }??
  • /** zx_fft.c** Implementation of Fast Fourier Transform(FFT)* and reversal Fast Fourier Transform(IFFT)* * Created on: 2013-8-5* Author: monkeyzx** TEST OK 2014.01.14* == 2014.01.14* Replace @BitReverse(x,x,N,M) by refrence to * <The Scientist and Engineer's Guide to Digital Signal Processing>*/#include "zx_fft.h"/** FFT Algorithm* === Inputs ===* x : complex numbers* N : nodes of FFT. @N should be power of 2, that is 2^(*)* === Output ===* the @x contains the result of FFT algorithm, so the original data* in @x is destroyed, please store them before using FFT.*/ int fft(TYPE_FFT *x, int N) {int i,j,l,k,ip;static int M = 0;static int le,le2;static TYPE_FFT_E sR,sI,tR,tI,uR,uI;M = (int)(log(N) / log(2));/** bit reversal sorting*/l = N / 2;j = l;//BitReverse(x,x,N,M);for (i=1; i<=N-2; i++) {if (i < j) {tR = x[j].real;tI = x[j].imag;x[j].real = x[i].real;x[j].imag = x[i].imag;x[i].real = tR;x[i].imag = tI;}k = l;while (k <= j) {j = j - k;k = k / 2;}j = j + k;}/** For Loops*/for (l=1; l<=M; l++) { /* loop for ceil{log2(N)} */le = (int)pow(2,l);le2 = (int)(le / 2);uR = 1;uI = 0;sR = cos(PI / le2);sI = -sin(PI / le2);for (j=1; j<=le2; j++) { /* loop for each sub DFT *///jm1 = j - 1;for (i=j-1; i<=N-1; i+=le) { /* loop for each butterfly */ip = i + le2;tR = x[ip].real * uR - x[ip].imag * uI;tI = x[ip].real * uI + x[ip].imag * uR;x[ip].real = x[i].real - tR;x[ip].imag = x[i].imag - tI;x[i].real += tR;x[i].imag += tI;} /* Next i */tR = uR;uR = tR * sR - uI * sI;uI = tR * sI + uI *sR;} /* Next j */} /* Next l */return 0; }/** Inverse FFT Algorithm* === Inputs ===* x : complex numbers* N : nodes of FFT. @N should be power of 2, that is 2^(*)* === Output ===* the @x contains the result of FFT algorithm, so the original data* in @x is destroyed, please store them before using FFT.*/ int ifft(TYPE_FFT *x, int N) {int k = 0;for (k=0; k<=N-1; k++) {x[k].imag = -x[k].imag;}fft(x, N); /* using FFT */for (k=0; k<=N-1; k++) {x[k].real = x[k].real / N;x[k].imag = -x[k].imag / N;}return 0; }
    另外,可能還需要您在其它頭文件中定義COMPLEX的復數類型

    [cpp] view plaincopy print?
  • typedef?struct?{??
  • ????float?real;??
  • ????float?imag;??
  • }?COMPLEX;??
  • typedef struct {float real;float imag; } COMPLEX;


    =====================

    增加:FFT頻譜結果顯示

    =====================

    [plain] view plaincopy print?
  • clc;??
  • clear;??
  • ??
  • %?Read?a?real?audio?signal??
  • [fname,pname]=uigetfile(...??
  • ????{'*.wav';'*.*'},...??
  • ????'Input?wav?File');??
  • [x?fs?nbits]?=?wavread(fullfile(pname,fname));??
  • ??
  • %?Window??
  • %?N?=?1024;??
  • N?=?size(x,1);??
  • x?=?x(1:N,?1);??
  • ??
  • %?FFT??
  • y?=?fft(x);??
  • %?頻率對稱,取N/2??
  • y?=?y(1:N/2);??
  • ??
  • %?FFT頻率與物理頻率轉換??
  • x1?=?1:N/2;??
  • x2?=?(1:N/2)*fs/(N/2);??%?/1000表示KHz??
  • log_x2?=?log2(x2);??
  • ??
  • %?plot??
  • figure,??
  • subplot(2,2,1);plot(x);??
  • xlabel('Time/N');ylabel('Mag');grid?on??
  • title('原始信號');??
  • subplot(2,2,2);plot(x1,?abs(y));??
  • xlabel('Freq/N');ylabel('Mag');grid?on??
  • title('FFT信號/橫坐標為點數');??
  • subplot(2,2,3);plot(x2,abs(y));??
  • xlabel('Freq/Hz');ylabel('Mag');grid?on??
  • title('FFT信號/橫坐標為物理頻率');??
  • subplot(2,2,4);plot(log_x2,abs(y));??
  • xlabel('Freq/log2(Hz)');ylabel('Mag');grid?on??
  • title('FFT信號/橫坐標為物理頻率取log');??
  • ??
  • %?更常見是將幅值取log??
  • y?=?log2(abs(y));??
  • figure,??
  • plot(x2,y);??
  • xlabel('Freq/Hz');ylabel('Mag/log2');grid?on??
  • title('幅值取log2');??
  • clc; clear;% Read a real audio signal [fname,pname]=uigetfile(...{'*.wav';'*.*'},...'Input wav File'); [x fs nbits] = wavread(fullfile(pname,fname));% Window % N = 1024; N = size(x,1); x = x(1:N, 1);% FFT y = fft(x); % 頻率對稱,取N/2 y = y(1:N/2);% FFT頻率與物理頻率轉換 x1 = 1:N/2; x2 = (1:N/2)*fs/(N/2); % /1000表示KHz log_x2 = log2(x2);% plot figure, subplot(2,2,1);plot(x); xlabel('Time/N');ylabel('Mag');grid on title('原始信號'); subplot(2,2,2);plot(x1, abs(y)); xlabel('Freq/N');ylabel('Mag');grid on title('FFT信號/橫坐標為點數'); subplot(2,2,3);plot(x2,abs(y)); xlabel('Freq/Hz');ylabel('Mag');grid on title('FFT信號/橫坐標為物理頻率'); subplot(2,2,4);plot(log_x2,abs(y)); xlabel('Freq/log2(Hz)');ylabel('Mag');grid on title('FFT信號/橫坐標為物理頻率取log');% 更常見是將幅值取log y = log2(abs(y)); figure, plot(x2,y); xlabel('Freq/Hz');ylabel('Mag/log2');grid on title('幅值取log2');




    最終部分優化的源代碼我放在https://github.com/xiahouzuoxin/fft。


    總結

    以上是生活随笔為你收集整理的FFT算法的完整DSP实现的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。