zoukankan      html  css  js  c++  java
  • FFT

    #include <iostream>
    #include <stdio.h>
    #include <math.h>
    
    //**************************************************************************************
    
    #ifndef M_PI
        #define M_PI 3.14159265358979323846
    #endif
    #define DATA_LEN 64
    #define SAMPLE_FREQ 1000 // Hz
    
    unsigned char sin_data[64] = {0x7F,0x8B,0x98,0xA4,0xB0,0xBB,0xC6,0xD0,0xD9,0xE2,
        0xE9,0xEF,0xF5,0xF9,0xFC,0xFE,0xFE,0xFE,0xFC,0xF9,0xF5,0xEF,0xE9,0xE2,0xD9,0xD0,
        0xC6,0xBB,0xB0,0xA4,0x98,0x8B,0x7F,0x73,0x66,0x5A,0x4E,0x43,0x38,0x2E,0x25,0x1C,
        0x15,0x0F,0x09,0x05,0x02,0x00,0x00,0x00,0x02,0x05,0x09,0x0F,0x15,0x1C,0x25,0x2E,
        0x38,0x43,0x4E,0x5A,0x66,0x73};
    
    typedef struct{
        double r;
        double i;
    } cplx_t;
    
    
    //**************************************************************************************
    
    void cplx_exp(cplx_t *x, cplx_t *r)
    {
        double expx = exp(x->r);
        r->r = expx*cos(x->i);
        r->i = expx*sin(x->i);
    }
    
    // 复数乘法
    void cplx_mul(cplx_t *x, cplx_t *y, cplx_t *r)
    {
        r->r = x->r*y->r-x->i*y->i;
        r->i = x->r*y->i+x->i*y->r;
    }
    
    // 比特反置
    void bit_reverse(cplx_t *x, int N)
    {
        unsigned int i = 0,j = 0,k = 0;
        
        cplx_t tmp;
        
        int bit_num = log(0.0+N)/log(2.0);  // 比特位数
        
        for (i=0; i<N; i++)
        {
            int t = bit_num;
            k=i;
            j=0;
            while (t--)
            {
                j <<= 1;
                j |= k&1;
                k >>= 1;
            }
            if (j>i)
            {
                tmp = x[i];
                x[i] = x[j];
                x[j] = tmp;
            }
        }
    }
    
    
    void fft(cplx_t *x, int N)
    {
        cplx_t u,d,p,W,tmp;
        int i=0,j=0,k=0,l=0;
        
        double M = floor(log(0.0+N)/log(2.0));  // zhiqiu 换底公式
        if (log(0.0+N)/log(2.0)-M > 0)
        {
            printf("The length of x (N) must be a power of two!!!
    ");
            return;
        }
        
        bit_reverse(x,N);
        
        for (i = 0; i < M; i++)
        {
            l = 1<<i;
            for (j = 0; j < N; j += 2*l)
            {
                for (k = 0; k < l; k++)
                {
                    tmp.r = 0.0;
                    tmp.i = -2*M_PI*k/2/l;
                    cplx_exp(&tmp,&W);
                    cplx_mul(&x[j+k+l],&W,&p);
                    u.r = x[j+k].r+p.r;
                    u.i = x[j+k].i+p.i;
                    d.r = x[j+k].r-p.r;
                    d.i = x[j+k].i-p.i;
                    x[j+k] = u;
                    x[j+k+l] = d;
                }
            }
        }
    }
    
    void ifft(cplx_t *x, int N)
    {
        unsigned int i = 0;
        for (i = 0;i < N; i++)
            x[i].i = -x[i].i;
        fft(x,N);
        for (i = 0;i < N; i++)
        {
            x[i].r = x[i].r/(N+0.0);
            x[i].i = -x[i].i/(N+0.0);
        }
    }
    
    
    
    //**************************************************************************************
    
    int main(int argc, const char * argv[])
    {
        int i;
        cplx_t x[DATA_LEN];
        for (i=0;i<DATA_LEN;i++)
        {
            x[i].r = sin_data[i];
            x[i].i = 0;
        }
        
        printf("Before...
    Real		Imag
    ");
        for (i=0; i<DATA_LEN; i++)
            printf("%f	%f
    ",x[i].r,x[i].i);
        
        fft(x, DATA_LEN);
        
        printf("
    After FFT...
    Real		Imag
    ");
        for (i=0; i<DATA_LEN; i++)
            printf("%f	%f
    ",x[i].r,x[i].i);
        
        printf("
    频率		幅度		相位
    ");
        for (i=0; i<DATA_LEN; i++)
        {
            double fudu = sqrt(x[i].r*x[i].r+x[i].i*x[i].i);
            double xiangwei = atan(x[i].i/x[i].r)*180.0/M_PI;
            if (i == 0)
                fudu /= DATA_LEN;
            else
                fudu /= DATA_LEN/2;
            printf("%f	%f	%f
    ", (double)SAMPLE_FREQ/DATA_LEN*i, fudu, xiangwei);
        }
        
        ifft(x, DATA_LEN);
        
        printf("
    After IFFT...
    Real		Imag
    ");
        for (i=0; i<DATA_LEN; i++)
            printf("%f	%f
    ",x[i].r,x[i].i);
        
        return 0;
    }
    
  • 相关阅读:
    Persist Security Info=False是干什么的
    SQL Server windows身份验证和SQL Server身份验证的连接字符串
    SQL Server windows身份验证和SQL Server身份验证的连接字符串
    Entity Framework—配置文件设置
    Entity Framework—配置文件设置
    inner outer
    group by
    SQL Select语句完整的执行顺序(转)
    with check(转)
    三层和MVC
  • 原文地址:https://www.cnblogs.com/SkyPrayer/p/3918863.html
Copyright © 2011-2022 走看看