static void compute_bitrev_table( int Fout, opus_int16 *f, const size_t fstride, int in_stride, opus_int16 * factors, const kiss_fft_state *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++) { *f = Fout+j; f += fstride*in_stride; } } else { int j; for (j=0;j<p;j++) { compute_bitrev_table( Fout , f, fstride*p, in_stride, factors,st); f += fstride*in_stride; Fout += m; } } }
/* * * Allocates all necessary storage space for the fft and ifft. * The return value is a contiguous block of memory. As such, * It can be freed with free(). * */ kiss_fft_state *opus_fft_alloc_twiddles(int nfft,void * mem,size_t * lenmem, const kiss_fft_state *base, int arch) { kiss_fft_state *st=NULL; size_t memneeded = sizeof(struct kiss_fft_state); /* twiddle factors*/ if ( lenmem==NULL ) { st = ( kiss_fft_state*)KISS_FFT_MALLOC( memneeded ); }else{ if (mem != NULL && *lenmem >= memneeded) st = (kiss_fft_state*)mem; *lenmem = memneeded; } if (st) { opus_int16 *bitrev; kiss_twiddle_cpx *twiddles; st->nfft=nfft; #ifdef FIXED_POINT st->scale_shift = celt_ilog2(st->nfft); if (st->nfft == 1<<st->scale_shift) st->scale = Q15ONE; else st->scale = (1073741824+st->nfft/2)/st->nfft>>(15-st->scale_shift); #else st->scale = 1.f/nfft; #endif if (base != NULL) { st->twiddles = base->twiddles; st->shift = 0; while (st->shift < 32 && nfft<<st->shift != base->nfft) st->shift++; if (st->shift>=32) goto fail; } else { st->twiddles = twiddles = (kiss_twiddle_cpx*)KISS_FFT_MALLOC(sizeof(kiss_twiddle_cpx)*nfft); compute_twiddles(twiddles, nfft); st->shift = -1; } if (!kf_factor(nfft,st->factors)) { goto fail; } /* bitrev */ st->bitrev = bitrev = (opus_int16*)KISS_FFT_MALLOC(sizeof(opus_int16)*nfft); if (st->bitrev==NULL) goto fail; compute_bitrev_table(0, bitrev, 1,1, st->factors,st); /* Initialize architecture specific fft parameters */ if (opus_fft_alloc_arch(st, arch)) goto fail; } return st; fail: opus_fft_free(st, arch); return NULL; }
/* * * Allocates all necessary storage space for the fft and ifft. * The return value is a contiguous block of memory. As such, * It can be freed with free(). * */ kiss_fft_state *opus_fft_alloc_twiddles(int nfft,void * mem,size_t * lenmem, const kiss_fft_state *base) { kiss_fft_state *st=NULL; size_t memneeded = sizeof(struct kiss_fft_state); /* twiddle factors*/ if ( lenmem==NULL ) { st = ( kiss_fft_state*)KISS_FFT_MALLOC( memneeded ); }else{ if (mem != NULL && *lenmem >= memneeded) st = (kiss_fft_state*)mem; *lenmem = memneeded; } if (st) { opus_int16 *bitrev; kiss_twiddle_cpx *twiddles; st->nfft=nfft; #ifndef FIXED_POINT st->scale = 1.f/nfft; #endif if (base != NULL) { st->twiddles = base->twiddles; st->shift = 0; while (nfft<<st->shift != base->nfft && st->shift < 32) st->shift++; if (st->shift>=32) goto fail; } else { st->twiddles = twiddles = (kiss_twiddle_cpx*)KISS_FFT_MALLOC(sizeof(kiss_twiddle_cpx)*nfft); compute_twiddles(twiddles, nfft); st->shift = -1; } if (!kf_factor(nfft,st->factors)) { goto fail; } /* bitrev */ st->bitrev = bitrev = (opus_int16*)KISS_FFT_MALLOC(sizeof(opus_int16)*nfft); if (st->bitrev==NULL) goto fail; compute_bitrev_table(0, bitrev, 1,1, st->factors,st); } return st; fail: opus_fft_free(st); return NULL; }