FFTLib::FFTLib(size_t frame_size) : m_frame_size(frame_size) { m_window = (kiss_fft_scalar *) KISS_FFT_MALLOC(sizeof(kiss_fft_scalar) * frame_size); m_input = (kiss_fft_scalar *) KISS_FFT_MALLOC(sizeof(kiss_fft_scalar) * frame_size); m_output = (kiss_fft_cpx *) KISS_FFT_MALLOC(sizeof(kiss_fft_cpx) * frame_size); PrepareHammingWindow(m_window, m_window + frame_size, 1.0 / INT16_MAX); m_cfg = kiss_fftr_alloc(frame_size, 0, NULL, 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, 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; }
void initialize_fft (int n) { fin = KISS_FFT_MALLOC (n * sizeof (kiss_fft_cpx)); assert(fin != NULL); fout = KISS_FFT_MALLOC (n * sizeof (kiss_fft_cpx)); assert(fout != NULL); cfg_forward = kiss_fft_alloc (n, 0, NULL, NULL); assert(cfg_forward != NULL); cfg_reverse = kiss_fft_alloc (n, 1, NULL, NULL); assert(cfg_reverse != 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; }
/* * * 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; for (i=0;i<nfft;++i) { const double pi=3.141592653589793238462643383279502884197169399375105820974944; double phase = -2*pi*i / nfft; if (st->inverse) phase *= -1; kf_cexp(st->twiddles+i, phase ); } kf_factor(nfft,st->factors); } return st; }
/* * * 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; for (i=0;i<nfft;++i) { double phase = -2*M_PI*i / nfft; if (st->inverse) phase *= -1; kf_cexp(st->twiddles+i, phase ); } kf_factor(nfft,st->factors); } return st; }
std::complex<double> *fft_alloc_complex(size_t n) { #ifdef HAVE_LIBFFTW3 return (std::complex<double>*)(fftw_complex*)fftw_malloc(sizeof(fftw_complex) * n); #else return (std::complex<double>*)KISS_FFT_MALLOC(sizeof(std::complex<double>) * n); #endif }
Tl* Allocate(int iSize, Tc** ioCData, void** ioLData, bool* iMyData) { Tl* data; if (*ioCData) { // Non null - no need to allocate data = (Tl*)*ioCData; *ioLData = 0; *iMyData = false; } else { // Null caller data - need to allocate data = (Tl*)KISS_FFT_MALLOC(iSize*sizeof(Tl)); *ioLData = data; *ioCData = (Tc*)data; *iMyData = true; } assert(data); return data; }
/** * Real to Real transform, a.k.a. cosine transform * Wired to do DFT2 right now. */ void Tracter::Fourier::Init(int iOrder, float** ioIData, float** ioOData) { assert(ioIData); assert(ioOData); assert(iOrder > 0); FourierKiss::sInstanceCount++; assert(mFourierData == 0); mFourierData = new FourierData; FourierData& m = *mFourierData; m.Type = DCT2; m.Order = iOrder; Allocate<float, float>(iOrder*2, ioIData, &m.IData, &m.MyIData); Allocate<float, float>(iOrder, ioOData, &m.OData, &m.MyOData); m.TmpData = (kiss_fft_cpx*)KISS_FFT_MALLOC((iOrder+1)*sizeof(kiss_fft_cpx)); assert(m.TmpData); m.Config = kiss_fftr_alloc(iOrder*2, 0, 0, 0); }
/* * * 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 MS_FIXED_POINT for (i=0;i<nfft;++i) { ms_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; }
int main(int argc, char ** argv) { int k; int nfft[32]; int ndims = 1; int isinverse = 0; int numffts = 1000, i; kiss_fft_cpx * buf; kiss_fft_cpx * bufout; int real = 0; nfft[0] = 1024;// default while (1) { int c = getopt(argc, argv, "n:ix:r"); if (c == -1) break; switch (c) { case 'r': real = 1; break; case 'n': ndims = getdims(nfft, optarg); if (nfft[0] != kiss_fft_next_fast_size(nfft[0])) { int ng = kiss_fft_next_fast_size(nfft[0]); fprintf(stderr, "warning: %d might be a better choice for speed than %d\n", ng, nfft[0]); } break; case 'x': numffts = atoi(optarg); break; case 'i': isinverse = 1; break; } } int nbytes = sizeof(kiss_fft_cpx); for (k = 0; k < ndims; ++k) nbytes *= nfft[k]; #ifdef USE_SIMD numffts /= 4; fprintf(stderr, "since SIMD implementation does 4 ffts at a time, numffts is being reduced to %d\n", numffts); #endif buf = (kiss_fft_cpx*)KISS_FFT_MALLOC(nbytes); bufout = (kiss_fft_cpx*)KISS_FFT_MALLOC(nbytes); memset(buf, 0, nbytes); pstats_init(); if (ndims == 1) { if (real) { kiss_fftr_cfg st = kiss_fftr_alloc(nfft[0] , isinverse , 0, 0); if (isinverse) for (i = 0; i < numffts; ++i) kiss_fftri(st , (kiss_fft_cpx*)buf, (kiss_fft_scalar*)bufout); else for (i = 0; i < numffts; ++i) kiss_fftr(st , (kiss_fft_scalar*)buf, (kiss_fft_cpx*)bufout); free(st); } else { kiss_fft_cfg st = kiss_fft_alloc(nfft[0] , isinverse , 0, 0); for (i = 0; i < numffts; ++i) kiss_fft(st , buf, bufout); free(st); } } else { if (real) { kiss_fftndr_cfg st = kiss_fftndr_alloc(nfft, ndims , isinverse , 0, 0); if (isinverse) for (i = 0; i < numffts; ++i) kiss_fftndri(st , (kiss_fft_cpx*)buf, (kiss_fft_scalar*)bufout); else for (i = 0; i < numffts; ++i) kiss_fftndr(st , (kiss_fft_scalar*)buf, (kiss_fft_cpx*)bufout); free(st); } else { kiss_fftnd_cfg st = kiss_fftnd_alloc(nfft, ndims, isinverse , 0, 0); for (i = 0; i < numffts; ++i) kiss_fftnd(st , buf, bufout); free(st); } } free(buf); free(bufout); fprintf(stderr, "KISS\tnfft="); for (k = 0; k < ndims; ++k) fprintf(stderr, "%d,", nfft[k]); fprintf(stderr, "\tnumffts=%d\n" , numffts); pstats_report(); kiss_fft_cleanup(); return 0; }
kiss_fftnd_cfg kiss_fftnd_alloc(const int *dims,int ndims,int inverse_fft,void*mem,size_t*lenmem) { kiss_fftnd_cfg st = NULL; int i; int dimprod=1; size_t memneeded = sizeof(struct kiss_fftnd_state); size_t n_align; char * ptr; for (i=0;i<ndims;++i) { size_t sublen=0; kiss_fft_alloc (dims[i], inverse_fft, NULL, &sublen); memneeded += sublen; /* st->states[i] */ dimprod *= dims[i]; } memneeded += sizeof(int) * ndims;/* st->dims */ memneeded += sizeof(void*) * ndims;/* st->states */ n_align = 16 - memneeded % 16; /* 16 byte alignment */ memneeded += n_align; memneeded += sizeof(kiss_fft_cpx) * dimprod; /* st->tmpbuf */ if (lenmem == NULL) {/* allocate for the caller*/ st = (kiss_fftnd_cfg) KISS_FFT_MALLOC (memneeded); } else { /* initialize supplied buffer if big enough */ if (*lenmem >= memneeded) st = (kiss_fftnd_cfg) mem; *lenmem = memneeded; /*tell caller how big struct is (or would be) */ } if (!st) return NULL; /*malloc failed or buffer too small */ st->dimprod = dimprod; st->ndims = ndims; ptr=(char*)(st+1); st->states = (kiss_fft_cfg *)ptr; ptr += sizeof(void*) * ndims; st->dims = (int*)ptr; ptr += sizeof(int) * ndims; ptr += n_align; /* 16 byte alignment */ st->tmpbuf = (kiss_fft_cpx*)ptr; ptr += sizeof(kiss_fft_cpx) * dimprod; for (i=0;i<ndims;++i) { size_t len; st->dims[i] = dims[i]; kiss_fft_alloc (st->dims[i], inverse_fft, NULL, &len); st->states[i] = kiss_fft_alloc (st->dims[i], inverse_fft, ptr,&len); ptr += len; } /* Hi there! If you're looking at this particular code, it probably means you've got a brain-dead bounds checker that thinks the above code overwrites the end of the array. It doesn't. -- Mark P.S. The below code might give you some warm fuzzies and help convince you. */ if ( ptr - (char*)st != (int)memneeded ) { fprintf(stderr, "################################################################################\n" "Internal error! Memory allocation miscalculation\n" "################################################################################\n" ); } return st; }