Linux下简单的FFT实现
Linux下简单的FFT实现
在Linux平台下,从音频接口采回PCM数据,进行FFT变换。最后通过ncurse库,在文本模式下粗糙得对频谱进行实时显示。
整个程序只是作为练手用,代码贴在下面,供自己查阅和大家参考。
Makefile
- all: directshow.o fft.o
- gcc -o spectrum directshow.o fft.o -lm -lcurses
- directshow.o: directshow.c fft.h
- gcc -c directshow.c
- fft.o: fft.c
- gcc -c fft.c
fft.c
- /*******************************************************************************
- * File: fft.c
- * Author: Jerome Wang
- * wangquzhi@gmail.com
- * Last Edit: 2011/01/19
- * Description: void fft(double *DataTimeDomain_r, double *DataTimeDomain_i);
- * Basic funtion used for fft. Two parameters, for the real-part and j-part
- * of the input data. The results are also restored here.
- * Chose the point of fft by define one of these macros:
- * FFT_CONFIG_4
- * FFT_CONFIG_8
- * FFT_CONFIG_128
- *
- * By define FFT_DEBUGE, we can get the debug message indicating the process
- * of the fft processing.
- *******************************************************************************/
- #include <math.h>
- #include <stdio.h>
- #define FFT_CONFIG_128
- /*#define FFT_DEBUGE*/
- #define PI 3.14
- inline void Butterfly(double *a_r, double *a_i, \
- double *b_r, double * b_i,\
- double wx, int N)
- {
- double a_tmp_r = *a_r;
- double a_tmp_i = *a_i;
- double b_tmp_r = *b_r;
- double b_tmp_i = *b_i;
- double wx_tmp_r, wx_tmp_i;
- wx_tmp_r = cos(wx*2*PI/N);
- wx_tmp_i = -sin(wx*2*PI/N);
- *a_r = a_tmp_r + b_tmp_r*wx_tmp_r - b_tmp_i*wx_tmp_i;
- *a_i = a_tmp_i + b_tmp_r*wx_tmp_i + b_tmp_i*wx_tmp_r;
- *b_r = a_tmp_r - b_tmp_r*wx_tmp_r + b_tmp_i*wx_tmp_i;
- *b_i = a_tmp_i - b_tmp_r*wx_tmp_i - b_tmp_i*wx_tmp_r;
- }
- inline int BitReverse(int n, int bits)
- {
- int i = 0;
- int ret = 0;
- for(i = 0; i < bits; i++)
- {
- ret|=((n>>i)&1)<<(bits-i-1);
- }
- return ret;
- }
- void fft(double *DataTimeDomain_r, double *DataTimeDomain_i)
- {
- #ifdef FFT_CONFIG_128
- const int FFT_Pnt = 128;
- /* For 2^7 = 128, 128 points' computation is divided to 7 stages */
- const int FFT_Stg = 7;
- /* In each stage, it contains BttrPerStg butterfly computations */
- const int BttrPerStg = 64;
- #endif
- #ifdef FFT_CONFIG_8
- const int FFT_Pnt = 8;
- const int FFT_Stg = 3;
- const int BttrPerStg = 4;
- #endif
- #ifdef FFT_CONFIG_4
- const int FFT_Pnt = 4;
- const int FFT_Stg = 2;
- const int BttrPerStg = 2;
- #endif
- /* Current Computing Stage, ranges from 0 to (FFT_Stg - 1) */
- int CrrtStg = 0;
- /* Current Butterfly, ranges from 0 to (BttrPerStg - 1) */
- int CrrtBttr = 0;
- int TempPower = 0;
- int BttrPara1 = 0;
- int BttrPara2 = 0;
- int BttrPara3 = 0;
- for(CrrtStg = 0; CrrtStg < FFT_Stg; CrrtStg++)
- {
- #ifdef FFT_DEBUGE
- printf("This is the %dnd Stage:\n", CrrtStg+1);
- #endif
- for(CrrtBttr = 0; CrrtBttr < BttrPerStg; CrrtBttr++)
- {
- TempPower = 1 << CrrtStg;
- BttrPara1 = (CrrtBttr/TempPower)*(TempPower<<1)+CrrtBttr%TempPower;
- BttrPara2 = BttrPara1 + TempPower;
- BttrPara3 = (CrrtBttr % TempPower) * \
- (1 << (BttrPerStg - CrrtStg - 1)) >> 1;
- #ifdef FFT_DEBUGE
- printf("\tNow we perform the butterfly: %d,%d,%d\n", \
- BitReverse(BttrPara1, FFT_Stg),\
- BitReverse(BttrPara2, FFT_Stg),\
- BttrPara3);
- #endif
- Butterfly(DataTimeDomain_r + BitReverse(BttrPara1, FFT_Stg),\
- DataTimeDomain_i + BitReverse(BttrPara1, FFT_Stg),\
- DataTimeDomain_r + BitReverse(BttrPara2, FFT_Stg),\
- DataTimeDomain_i + BitReverse(BttrPara2, FFT_Stg),\
- BttrPara3,\
- FFT_Pnt);
- }
- }
- }
fft.h
- #ifndef FFT_H
- #define FFT_H
- void fft(double *DataTimeDomain_r, double *DataTimeDomain_i);
- #endif
|
评论暂时关闭