⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 kiss_fft.c

📁 一个开源的sip源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
        scratch[11].r = scratch[0].r + S_MUL(scratch[7].r,yb.r) + S_MUL(scratch[8].r,ya.r);        scratch[11].i = scratch[0].i + S_MUL(scratch[7].i,yb.r) + S_MUL(scratch[8].i,ya.r);        scratch[12].r = - S_MUL(scratch[10].i,yb.i) + S_MUL(scratch[9].i,ya.i);        scratch[12].i = S_MUL(scratch[10].r,yb.i) - S_MUL(scratch[9].r,ya.i);        C_ADD(*Fout2,scratch[11],scratch[12]);        C_SUB(*Fout3,scratch[11],scratch[12]);        ++Fout0;++Fout1;++Fout2;++Fout3;++Fout4;    }}/* perform the butterfly for one stage of a mixed radix FFT */static void kf_bfly_generic(        kiss_fft_cpx * Fout,        const size_t fstride,        const kiss_fft_cfg st,        int m,        int p        ){    int u,k,q1,q;    kiss_fft_cpx * twiddles = st->twiddles;    kiss_fft_cpx t;    kiss_fft_cpx scratchbuf[17];    int Norig = st->nfft;    /*CHECKBUF(scratchbuf,nscratchbuf,p);*/    if (p>17)       speex_error("KissFFT: max radix supported is 17");        for ( u=0; u<m; ++u ) {        k=u;        for ( q1=0 ; q1<p ; ++q1 ) {            scratchbuf[q1] = Fout[ k  ];        if (!st->inverse) {            C_FIXDIV(scratchbuf[q1],p);	}            k += m;        }        k=u;        for ( q1=0 ; q1<p ; ++q1 ) {            int twidx=0;            Fout[ k ] = scratchbuf[0];            for (q=1;q<p;++q ) {                twidx += fstride * k;                if (twidx>=Norig) twidx-=Norig;                C_MUL(t,scratchbuf[q] , twiddles[twidx] );                C_ADDTO( Fout[ k ] ,t);            }            k += m;        }    }}               staticvoid kf_shuffle(         kiss_fft_cpx * Fout,         const kiss_fft_cpx * f,         const size_t fstride,         int in_stride,         int * factors,         const kiss_fft_cfg st            ){   const int p=*factors++; /* the radix  */   const int m=*factors++; /* stage's fft length/p */       /*printf ("fft %d %d %d %d %d %d\n", p*m, m, p, s2, fstride*in_stride, N);*/   if (m==1)   {      int j;      for (j=0;j<p;j++)      {         Fout[j] = *f;         f += fstride*in_stride;      }   } else {      int j;      for (j=0;j<p;j++)      {         kf_shuffle( Fout , f, fstride*p, in_stride, factors,st);         f += fstride*in_stride;         Fout += m;      }   }}staticvoid kf_work(        kiss_fft_cpx * Fout,        const kiss_fft_cpx * f,        const size_t fstride,        int in_stride,        int * factors,        const kiss_fft_cfg st,        int N,        int s2,        int m2        ){   int i;    kiss_fft_cpx * Fout_beg=Fout;    const int p=*factors++; /* the radix  */    const int m=*factors++; /* stage's fft length/p */#if 0    /*printf ("fft %d %d %d %d %d %d\n", p*m, m, p, s2, fstride*in_stride, N);*/    if (m==1)    {    /*   int j;       for (j=0;j<p;j++)       {          Fout[j] = *f;          f += fstride*in_stride;       }*/    } else {       int j;       for (j=0;j<p;j++)       {          kf_work( Fout , f, fstride*p, in_stride, factors,st, N*p, fstride*in_stride, m);          f += fstride*in_stride;          Fout += m;       }    }    Fout=Fout_beg;    switch (p) {        case 2: kf_bfly2(Fout,fstride,st,m); break;        case 3: kf_bfly3(Fout,fstride,st,m); break;         case 4: kf_bfly4(Fout,fstride,st,m); break;        case 5: kf_bfly5(Fout,fstride,st,m); break;         default: kf_bfly_generic(Fout,fstride,st,m,p); break;    }#else    /*printf ("fft %d %d %d %d %d %d %d\n", p*m, m, p, s2, fstride*in_stride, N, m2);*/    if (m==1)     {       /*for (i=0;i<N;i++)       {          int j;          Fout = Fout_beg+i*m2;          const kiss_fft_cpx * f2 = f+i*s2;          for (j=0;j<p;j++)          {             *Fout++ = *f2;             f2 += fstride*in_stride;          }       }*/    }else{       kf_work( Fout , f, fstride*p, in_stride, factors,st, N*p, fstride*in_stride, m);    }                         switch (p) {          case 2: kf_bfly2(Fout,fstride,st,m, N, m2); break;          case 3: for (i=0;i<N;i++){Fout=Fout_beg+i*m2; kf_bfly3(Fout,fstride,st,m);} break;           case 4: kf_bfly4(Fout,fstride,st,m, N, m2); break;          case 5: for (i=0;i<N;i++){Fout=Fout_beg+i*m2; kf_bfly5(Fout,fstride,st,m);} break;           default: for (i=0;i<N;i++){Fout=Fout_beg+i*m2; kf_bfly_generic(Fout,fstride,st,m,p);} break;    }    #endif}/*  facbuf is populated by p1,m1,p2,m2, ...    where     p[i] * m[i] = m[i-1]    m0 = n                  */static void kf_factor(int n,int * facbuf){    int p=4;    /*factor out powers of 4, powers of 2, then any remaining primes */    do {        while (n % p) {            switch (p) {                case 4: p = 2; break;                case 2: p = 3; break;                default: p += 2; break;            }            if (p>32000 || (spx_int32_t)p*(spx_int32_t)p > n)                p = n;          /* no more factors, skip to end */        }        n /= p;        *facbuf++ = p;        *facbuf++ = n;    } while (n > 1);}/* * * User-callable function to allocate all necessary storage space for the fft. * * The return value is a contiguous block of memory, allocated with malloc.  As such, * It can be freed with free(), rather than a kiss_fft-specific function. * */kiss_fft_cfg kiss_fft_alloc(int nfft,int inverse_fft,void * mem,size_t * lenmem ){    kiss_fft_cfg st=NULL;    size_t memneeded = sizeof(struct kiss_fft_state)        + sizeof(kiss_fft_cpx)*(nfft-1); /* twiddle factors*/    if ( lenmem==NULL ) {        st = ( kiss_fft_cfg)KISS_FFT_MALLOC( memneeded );    }else{        if (mem != NULL && *lenmem >= memneeded)            st = (kiss_fft_cfg)mem;        *lenmem = memneeded;    }    if (st) {        int i;        st->nfft=nfft;        st->inverse = inverse_fft;#ifdef FIXED_POINT        for (i=0;i<nfft;++i) {            spx_word32_t phase = i;            if (!st->inverse)                phase = -phase;            kf_cexp2(st->twiddles+i, DIV32(SHL32(phase,17),nfft));        }#else        for (i=0;i<nfft;++i) {           const double pi=3.14159265358979323846264338327;           double phase = ( -2*pi /nfft ) * i;           if (st->inverse)              phase *= -1;           kf_cexp(st->twiddles+i, phase );        }#endif        kf_factor(nfft,st->factors);    }    return st;}    void kiss_fft_stride(kiss_fft_cfg st,const kiss_fft_cpx *fin,kiss_fft_cpx *fout,int in_stride){    if (fin == fout)     {       speex_error("In-place FFT not supported");       /*CHECKBUF(tmpbuf,ntmpbuf,st->nfft);       kf_work(tmpbuf,fin,1,in_stride, st->factors,st);       speex_move(fout,tmpbuf,sizeof(kiss_fft_cpx)*st->nfft);*/    } else {       kf_shuffle( fout, fin, 1,in_stride, st->factors,st);       kf_work( fout, fin, 1,in_stride, st->factors,st, 1, in_stride, 1);    }}void kiss_fft(kiss_fft_cfg cfg,const kiss_fft_cpx *fin,kiss_fft_cpx *fout){    kiss_fft_stride(cfg,fin,fout,1);}

⌨️ 快捷键说明

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