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

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wwxsdj.html