dsp.c

来自「Linmodem is soft modem source code for e」· C语言 代码 · 共 205 行

C
205
字号
#include "lm.h"s16 cos_tab[COS_TABLE_SIZE];void dsp_init(void){    int i;    for(i=0;i<COS_TABLE_SIZE;i++) {        cos_tab[i] = (int) (cos( 2 * M_PI * i / COS_TABLE_SIZE) * COS_BASE);    }}/* DFT computation with Goertzel algorithm */int compute_DFT(s16 *cos_tab, s16 *sin_tab, s16 *x, int k,int n){    int y_re,y_im,i,j,y_2;    j = 0;#if 0    int s0,s1,s2;    s0 = s1 = 0;    for(i=0;i<n;i++) {        s2 = x[i] + ((cos_tab[j] * s1) >> (COS_BITS-1)) - s0;        s0 = s1;        s1 = s2;        j += k;        if (j >= n) j -= n;    }        y_re = s1 - ((cos_tab[k] * s0) >> COS_BITS);    /* cannot use cos_tab because n is even */    y_im = s1 - ((sin_tab[k] * s0) >> COS_BITS); #else    y_re = y_im = 0;    for(i=0;i<n;i++) {        y_re += cos_tab[j] * x[i];        y_im += sin_tab[j] * x[i];        j += k;        if (j >= n) j -= n;    }    y_re = y_re >> COS_BITS;    y_im = y_im >> COS_BITS;#endif    y_2 = y_re * y_re + y_im * y_im;    return y_2;}/* horrible fft code - only needed to debug or fixed table generation */#define FFT_MAX_SIZE 2048static float norm;static float wfft[FFT_MAX_SIZE];static short tinv[FFT_MAX_SIZE];static int nf = 0, nf2, nf4;int fft_init(int n){    float p,k;    int i,j,a,c, nk;        nf=n;    nf2=nf/2;    nf4=nf/4;    nk=0;    while (n>>=1) nk++;    norm=1/sqrt(nf);        k=0;    p=(2*M_PI)/nf;    for(i=0;i<=nf4;i++) {        wfft[i]=cos(k);        k+=p;    }        for(i=0;i<nf;i++) {        a=i;        c=0;        for(j=0;j<nk;j++) {            c=(c<<1)|(a&1);            a>>=1;        }        tinv[i]= c<=i ? -1 : c;    }        return 0;}/* r = TRUE : reverse FFT */void fft_calc(complex *x,int n, int r){    int i,j,k,l;    complex a,b,c;    complex *p,*q;	    /* auto init of coefficients */    if (n != nf) {        fft_init(n);    }    k=nf2;    l=1;    do {        p=x;        q=x+k;        i=l;        do {            j=0;            do {                a=*p;                b=*q;                p->re=a.re+b.re;                p->im=a.im+b.im;                b.re=a.re-b.re;                b.im=a.im-b.im;                if (j==0) {                    *q=b;                } else if (j==nf4) {                    if (r) {                        q->re=b.im;                        q->im=-b.re;                    } else {                        q->re=-b.im;                        q->im=b.re;                    }                    q->re=-b.im;                    q->im=b.re;                } else if (j<nf4) {                    c.re=wfft[j];                    c.im=wfft[nf4-j];                    if (r) c.im=-c.im;                    q->re=b.re*c.re-b.im*c.im;                    q->im=b.im*c.re+b.re*c.im;                } else {                    c.re=-wfft[nf2-j];                    c.im=wfft[j-nf4];                    if (r) c.im=-c.im;                    q->re=b.re*c.re-b.im*c.im;                    q->im=b.im*c.re+b.re*c.im;                }                p++;                q++;                j+=l;            } while (j<nf2);            p+=k;            q+=k;        } while (--i);        k>>=1;        l<<=1;    } while (k);        for(i=0,p=x;i<nf;i++,p++) {        p->re*=norm;        p->im*=norm;    }        for(i=0,p=x;i<nf;i++,p++) if ((j=tinv[i])!=-1) {        a=*p;        *p=x[j];        x[j]=a;    }}/* hamming window */void calc_hamming(float *ham, int NF){   int i;   for(i=0;i<NF;i++) {      ham[i]=0.54-0.46*cos((2*M_PI*i)/NF);   }}/* slow floating point fft, for testing & init */void slow_fft(complex *output, complex *input, int n, int r){    complex coef[n], a, b, c;    int i,j;    for(i=0;i<n;i++) {        float a;        a = - 2 * M_PI * i / (float) n;        if (r)             a = -a;        coef[i].re = cos(a);        coef[i].im = sin(a);    }        for(i=0;i<n;i++) {        a.re = 0;        a.im = 0;        for(j=0;j<n;j++) {            b = input[j];            c = coef[(j * i) % n];            a.re += b.re*c.re-b.im*c.im;            a.im += b.im*c.re+b.re*c.im;        }        output[i] = a;    }}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?