40#ifdef SAF_USE_APPLE_ACCELERATE
41# include "AvailabilityVersions.h"
48typedef struct _saf_stft_data {
49 int winsize, hopsize, fftsize, nCHin, nCHout, nBands;
51 int numOvrlpAddBlocks, bufferlength, nPrevHops;
52 float* window, *insig_rect_win, *insig_win, *outsig_win;
53 float** overlapAddBuffer;
55 float_complex* tmp_fft;
61typedef struct _saf_rfft_data {
65#if defined(SAF_USE_FFTW)
70 fftwf_complex* fwd_bufferFD;
71 fftwf_complex* bwd_bufferFD;
72#elif defined(SAF_USE_INTEL_IPP)
74 int specSize, specBufferSize, bufferSize, log2n;
75 IppsDFTSpec_R_32f* hDFTspec;
76 IppsFFTSpec_R_32f* hFFTspec;
80#elif defined(SAF_USE_APPLE_ACCELERATE)
81# ifdef SAF_USE_INTERLEAVED_VDSP
82 vDSP_DFT_Interleaved_Setup DFT_fwd;
83 vDSP_DFT_Interleaved_Setup DFT_bwd;
85 vDSP_DFT_Setup DFT_fwd;
86 vDSP_DFT_Setup DFT_bwd;
87 DSPSplitComplex VDSP_split;
88 DSPSplitComplex VDSP_split_tmp;
90#elif defined(SAF_USE_INTEL_MKL_LP64) || defined(SAF_USE_INTEL_MKL_ILP64)
91 DFTI_DESCRIPTOR_HANDLE MKL_FFT_Handle;
92 MKL_LONG input_strides[2], output_strides[2], Status;
95 kiss_fftr_cfg kissFFThandle_fwd;
96 kiss_fftr_cfg kissFFThandle_bkw;
101typedef struct _saf_fft_data {
105#if defined(SAF_USE_FFTW)
108 fftwf_complex* fwd_bufferTD;
109 fftwf_complex* bwd_bufferTD;
110 fftwf_complex* fwd_bufferFD;
111 fftwf_complex* bwd_bufferFD;
112#elif defined(SAF_USE_INTEL_IPP)
114 int specSize, specBufferSize, bufferSize, log2n;
115 IppsDFTSpec_C_32fc* hDFTspec;
116 IppsFFTSpec_C_32fc* hFFTspec;
120#elif defined(SAF_USE_APPLE_ACCELERATE)
121# ifdef SAF_USE_INTERLEAVED_VDSP
122 vDSP_DFT_Interleaved_Setup DFT_fwd;
123 vDSP_DFT_Interleaved_Setup DFT_bwd;
125 vDSP_DFT_Setup DFT_fwd;
126 vDSP_DFT_Setup DFT_bwd;
127 DSPSplitComplex VDSP_split;
128 DSPSplitComplex VDSP_split_tmp;
130#elif defined(SAF_USE_INTEL_MKL_LP64) || defined(SAF_USE_INTEL_MKL_ILP64)
131 DFTI_DESCRIPTOR_HANDLE MKL_FFT_Handle;
135 kiss_fft_cfg kissFFThandle_fwd;
136 kiss_fft_cfg kissFFThandle_bkw;
153 for(k=0; k<fftSize/2+1; k++)
154 freqVector[k] = (
float)k * fs/(float)fftSize;
167 int i, y_len, fftSize, nBins;
169 float_complex* H, *X, *Y;
173 y_len = x_len + h_len - 1;
174 fftSize = (int)((
float)
nextpow2(y_len)+0.5f);
176 h0 =
calloc1d(fftSize,
sizeof(
float));
177 x0 =
calloc1d(fftSize,
sizeof(
float));
178 y0 =
malloc1d(fftSize *
sizeof(
float));
179 H =
malloc1d(nBins*
sizeof(float_complex));
180 X =
malloc1d(nBins*
sizeof(float_complex));
181 Y =
malloc1d(nBins*
sizeof(float_complex));
185 for(i=0; i<nCH; i++){
187 memcpy(h0, &h[i*h_len], h_len*
sizeof(
float));
188 memcpy(x0, &x[i*x_len], x_len*
sizeof(
float));
197 memcpy(&y[i*y_len], y0, y_len*
sizeof(
float));
223 y_tmp =
malloc1d(nCH*(x_len+h_len-1)*
sizeof(
float));
224 fftconv(x, h, x_len, h_len, nCH, y_tmp);
226 memcpy(&y[i*x_len], &y_tmp[i*(x_len+h_len-1)], x_len*
sizeof(
float));
237#if defined(SAF_USE_INTEL_IPP) && 0
238 IppsHilbertSpec* ippSpec;
243 saf_assert(!ippsHilbertGetSize_32f32fc(x_len, ippAlgHintNone, &ippSpecSize, &ippBufferSize),
"IPP error!");
244 ippSpec = (IppsHilbertSpec*)ippsMalloc_8u(ippSpecSize);
245 buffer = ippsMalloc_8u(ippBufferSize);
246 saf_assert(!ippsHilbertInit_32f32fc(x_len, ippAlgHintNone, ippSpec, buffer),
"IPP error!");
247 saf_assert(!ippsHilbert_32f32fc(x, (Ipp32fc*)y, ippSpec, buffer),
"IPP error!");
253 float_complex *xfft, *h, *xhfft;
257 xfft =
malloc1d(x_len*
sizeof(float_complex));
258 h =
malloc1d(x_len*
sizeof(float_complex));
259 xhfft =
malloc1d(x_len*
sizeof(float_complex));
265 memset(h, 0,
sizeof(float_complex)*x_len);
268 h[0] = cmplxf(1.0f, 0.0f);
269 h[x_len/2] = cmplxf(1.0f, 0.0f);
270 for(i=1;i<x_len/2;i++)
271 h[i] = cmplxf(2.0f, 0.0f);
274 saf_assert(x_len % 2 == 0,
"Uneven lengths are not supported by saf_fft");
276 h[0] = cmplxf(1.0f, 0.0f);
277 for(i=1;i<(x_len+1)/2;i++)
278 h[i] = cmplxf(2.0f, 0.0f);
299 void **
const phSTFT,
312 h->winsize = winsize;
313 h->hopsize = hopsize;
314 h->nBands = winsize+1;
315 h->FDformat = FDformat;
318 h->fftsize = 2*winsize;
320 h->insig_rect_win =
calloc1d(h->fftsize,
sizeof(
float));
321 h->insig_win =
calloc1d(h->fftsize,
sizeof(
float));
324 h->tmp_fft =
malloc1d(h->nBands *
sizeof(float_complex));
325 h->outsig_win =
malloc1d(h->fftsize*
sizeof(
float));
326 h->nPrevHops = winsize/hopsize-1;
328 h->prev_inhops = (
float***)
calloc3d(h->nPrevHops, nCHin, hopsize,
sizeof(
float));
330 h->prev_inhops = NULL;
336 h->window =
malloc1d(winsize*
sizeof(
float));
341 h->numOvrlpAddBlocks = winsize/hopsize;
342 h->bufferlength = h->numOvrlpAddBlocks * (h->fftsize);
343 h->overlapAddBuffer = (
float**)
calloc2d(nCHout, h->bufferlength,
sizeof(
float));
355 free(h->overlapAddBuffer);
356 free(h->insig_rect_win);
359 free(h->prev_inhops);
371 float_complex*** dataFD
376 int ch, j, nHops, t, band, idx, hIdx;
378 saf_assert(framesize % h->hopsize == 0,
"framesize must be multiple of hopsize");
379 nHops = framesize/h->hopsize;
383 if(h->winsize==h->hopsize){
384 for (t = 0; t<nHops; t++){
385 for(ch=0; ch < h->nCHin; ch++){
387 memcpy(h->insig_rect_win, &dataTD[ch][t*(h->hopsize)], h->winsize*
sizeof(
float));
397 for(band=0; band<h->nBands; band++)
398 dataFD[band][ch][t] = h->tmp_fft[band];
407 for (t = 0; t<nHops; t++){
408 for(ch=0; ch < h->nCHin; ch++){
411 while (hIdx < h->winsize){
412 memcpy(&(h->insig_rect_win[hIdx]), h->prev_inhops[0][ch], h->hopsize*
sizeof(
float));
413 for(j=0; j< h->nPrevHops-1; j++)
414 memcpy(h->prev_inhops[j][ch], h->prev_inhops[j+1][ch], h->hopsize*
sizeof(
float));
415 memcpy(h->prev_inhops[h->nPrevHops-1][ch], &dataTD[ch][idx], h->hopsize*
sizeof(
float));
418 utility_svvmul(h->insig_rect_win, h->window, h->winsize, h->insig_win);
428 for(band=0; band<h->nBands; band++)
429 dataFD[band][ch][t] = h->tmp_fft[band];
441 float_complex*** dataFD,
447 int t, ch, nHops, band;
449 saf_assert(framesize % h->hopsize == 0,
"framesize must be multiple of hopsize");
450 nHops = framesize/h->hopsize;
452 for (t = 0; t<nHops; t++){
453 for(ch=0; ch < h->nCHout; ch++){
455 memcpy(h->overlapAddBuffer[ch], h->overlapAddBuffer[ch] + h->hopsize, (h->numOvrlpAddBlocks-1)*(h->hopsize)*
sizeof(
float));
458 memset(h->overlapAddBuffer[ch] + (h->numOvrlpAddBlocks-1)*(h->hopsize), 0, h->hopsize*
sizeof(
float));
466 for(band=0; band<h->nBands; band++)
467 h->tmp_fft[band] = dataFD[band][ch][t];
473 cblas_saxpy(h->fftsize, 1.0f, h->outsig_win, 1, h->overlapAddBuffer[ch], 1);
474 memcpy(dataTD[ch] + t*(h->hopsize), h->overlapAddBuffer[ch], h->hopsize*
sizeof(
float));
486 memset(
FLATTEN3D(h->prev_inhops), 0, h->nPrevHops * (h->nCHin) * (h->hopsize) *
sizeof(
float));
487 memset(
FLATTEN2D(h->overlapAddBuffer), 0, h->nCHout * (h->bufferlength) *
sizeof(
float));
500 if(new_nCHin != h->nCHin && h->nPrevHops > 0){
503 h->prev_inhops = (
float***)
realloc3d_r((
void***)h->prev_inhops, h->nPrevHops, new_nCHin, h->hopsize,
504 h->nPrevHops, h->nCHin, h->hopsize,
sizeof(float));
506 for(i=0; i< h->nPrevHops; i++)
507 for(ch=h->nCHin; ch<new_nCHin; ch++)
508 memset(h->prev_inhops[i][ch], 0, h->hopsize *
sizeof(
float));
510 h->nCHin = new_nCHin;
513 if(new_nCHout != h->nCHout){
516 h->overlapAddBuffer = (
float**)
realloc2d_r((
void**)h->overlapAddBuffer, new_nCHout, h->bufferlength,
517 h->nCHout, h->bufferlength,
sizeof(float));
519 for(ch=h->nCHout; ch<new_nCHout; ch++)
520 memset(h->overlapAddBuffer[ch], 0, h->bufferlength *
sizeof(
float));
522 h->nCHout = new_nCHout;
541 h->Scale = 1.0f/(float)N;
542 saf_assert(N>=2 &&
ISEVEN(N),
"Only even (non zero) FFT sizes are supported");
543 h->useKissFFT_FLAG = 0;
544#if defined(SAF_USE_FFTW)
545 h->fwd_bufferTD =
malloc1d(h->N*
sizeof(
float));
546 h->bwd_bufferTD =
malloc1d(h->N*
sizeof(
float));
547 h->fwd_bufferFD =
malloc1d((h->N/2+1)*
sizeof(fftwf_complex));
548 h->bwd_bufferFD =
malloc1d((h->N/2+1)*
sizeof(fftwf_complex));
549 h->p_fwd = fftwf_plan_dft_r2c_1d(h->N, h->fwd_bufferTD, h->fwd_bufferFD, FFTW_ESTIMATE);
550 h->p_bwd = fftwf_plan_dft_c2r_1d(h->N, h->bwd_bufferFD, h->bwd_bufferTD, FFTW_ESTIMATE);
551#elif defined(SAF_USE_INTEL_IPP)
553 if((
int)(log2f((
float)N)+1.0f) == (
int)(log2f((
float)N))){
554 h->useIPPfft_FLAG = 1;
555 h->log2n = (int)(log2f((
float)N)+0.1f);
556 ippsFFTGetSize_R_32f(h->log2n, IPP_FFT_DIV_INV_BY_N, ippAlgHintNone, &(h->specSize), &(h->specBufferSize), &(h->bufferSize));
558 h->memSpec = (Ipp8u*) ippMalloc(h->specSize);
559 h->buffer = (Ipp8u*) ippMalloc(h->bufferSize);
560 h->memInit = (Ipp8u*) ippMalloc(h->specBufferSize);
561 ippsFFTInit_R_32f(&(h->hFFTspec), h->log2n, IPP_FFT_DIV_INV_BY_N, ippAlgHintNone, h->memSpec, h->memInit);
564 h->useIPPfft_FLAG = 0;
565 ippsDFTGetSize_R_32f(N, IPP_FFT_DIV_INV_BY_N, ippAlgHintNone, &(h->specSize), &(h->specBufferSize), &(h->bufferSize));
566 h->hDFTspec = (IppsDFTSpec_R_32f*) ippMalloc(h->specSize);
567 h->buffer = (Ipp8u*) ippMalloc(h->bufferSize);
568 h->memInit = (Ipp8u*) ippMalloc(h->specBufferSize);
569 ippsDFTInit_R_32f(N, IPP_FFT_DIV_INV_BY_N, ippAlgHintNone, h->hDFTspec, h->memInit);
573#elif defined(SAF_USE_APPLE_ACCELERATE)
574# ifdef SAF_USE_INTERLEAVED_VDSP
575 h->DFT_fwd = vDSP_DFT_Interleaved_CreateSetup(0, N, vDSP_DFT_FORWARD, vDSP_DFT_Interleaved_RealtoComplex);
576 h->DFT_bwd = vDSP_DFT_Interleaved_CreateSetup(0, N, vDSP_DFT_INVERSE, vDSP_DFT_Interleaved_RealtoComplex);
578 h->DFT_fwd = vDSP_DFT_zrop_CreateSetup(0, N, vDSP_DFT_FORWARD);
579 h->DFT_bwd = vDSP_DFT_zrop_CreateSetup(0, N, vDSP_DFT_INVERSE);
581 if(h->DFT_fwd==0 || h->DFT_bwd==0)
582 h->useKissFFT_FLAG = 1;
585 saf_assert(h->DFT_fwd!=0 && h->DFT_bwd!=0,
"Failed to create vDSP DFT");
586# ifndef SAF_USE_INTERLEAVED_VDSP
587 h->VDSP_split_tmp.realp =
malloc1d((h->N/2)*
sizeof(
float));
588 h->VDSP_split_tmp.imagp =
malloc1d((h->N/2)*
sizeof(
float));
589 h->VDSP_split.realp =
malloc1d((h->N/2)*
sizeof(
float));
590 h->VDSP_split.imagp =
malloc1d((h->N/2)*
sizeof(
float));
593#elif defined(SAF_USE_INTEL_MKL_LP64) || defined(SAF_USE_INTEL_MKL_ILP64)
594 h->MKL_FFT_Handle = 0;
595 h->Status = DftiCreateDescriptor(&(h->MKL_FFT_Handle), DFTI_SINGLE, DFTI_REAL, 1, h->N);
596 h->Status = DftiSetValue(h->MKL_FFT_Handle, DFTI_PLACEMENT, DFTI_NOT_INPLACE);
600 h->Status = DftiSetValue(h->MKL_FFT_Handle, DFTI_CONJUGATE_EVEN_STORAGE, DFTI_COMPLEX_COMPLEX);
602 h->Status = DftiSetValue(h->MKL_FFT_Handle, DFTI_BACKWARD_SCALE, h->Scale);
604 h->Status = DftiCommitDescriptor(h->MKL_FFT_Handle);
607 h->useKissFFT_FLAG = 1;
610 if(h->useKissFFT_FLAG){
611 h->kissFFThandle_fwd = kiss_fftr_alloc(h->N, 0, NULL, NULL);
612 h->kissFFThandle_bkw = kiss_fftr_alloc(h->N, 1, NULL, NULL);
623#if defined(SAF_USE_FFTW)
624 free(h->fwd_bufferTD);
625 free(h->bwd_bufferTD);
626 free(h->fwd_bufferFD);
627 free(h->bwd_bufferFD);
628 fftwf_destroy_plan(h->p_bwd);
629 fftwf_destroy_plan(h->p_fwd);
630#elif defined(SAF_USE_INTEL_IPP)
631 if(h->useIPPfft_FLAG){
637 ippFree(h->hDFTspec);
641#elif defined(SAF_USE_APPLE_ACCELERATE)
642 if(!h->useKissFFT_FLAG){
643# ifdef SAF_USE_INTERLEAVED_VDSP
644 vDSP_DFT_Interleaved_DestroySetup(h->DFT_fwd);
645 vDSP_DFT_Interleaved_DestroySetup(h->DFT_bwd);
647 vDSP_DFT_DestroySetup(h->DFT_fwd);
648 vDSP_DFT_DestroySetup(h->DFT_bwd);
649 free(h->VDSP_split_tmp.realp);
650 free(h->VDSP_split_tmp.imagp);
651 free(h->VDSP_split.realp);
652 free(h->VDSP_split.imagp);
655#elif defined(SAF_USE_INTEL_MKL_LP64) || defined(SAF_USE_INTEL_MKL_ILP64)
656 h->Status = DftiFreeDescriptor(&(h->MKL_FFT_Handle));
658 if(h->useKissFFT_FLAG){
659 kiss_fftr_free(h->kissFFThandle_fwd);
660 kiss_fftr_free(h->kissFFThandle_bkw);
673 float_complex* outputFD
678#if defined(SAF_USE_FFTW)
679 cblas_scopy(h->N, inputTD, 1, h->fwd_bufferTD, 1);
680 fftwf_execute(h->p_fwd);
681 cblas_ccopy(h->N/2+1, h->fwd_bufferFD, 1, outputFD, 1);
682#elif defined(SAF_USE_INTEL_IPP)
683 if(h->useIPPfft_FLAG)
684 ippsFFTFwd_RToCCS_32f((Ipp32f*)inputTD, (Ipp32f*)outputFD, h->hFFTspec, h->buffer);
686 ippsDFTFwd_RToCCS_32f((Ipp32f*)inputTD, (Ipp32f*)outputFD, h->hDFTspec, h->buffer);
687#elif defined(SAF_USE_APPLE_ACCELERATE)
688 if(!h->useKissFFT_FLAG){
689# ifdef SAF_USE_INTERLEAVED_VDSP
692 vDSP_ctoz((DSPComplex*)inputTD, 2, &(h->VDSP_split_tmp), 1, (h->N)/2);
693 vDSP_DFT_Execute(h->DFT_fwd, h->VDSP_split_tmp.realp, h->VDSP_split_tmp.imagp, h->VDSP_split.realp, h->VDSP_split.imagp);
695 outputFD[0] = cmplxf(h->VDSP_split.realp[0], 0.0f);
696 cblas_scopy(h->N/2-1, &h->VDSP_split.realp[1], 1, &((
float*)(outputFD))[2], 2);
697 cblas_scopy(h->N/2-1, &h->VDSP_split.imagp[1], 1, &((
float*)(outputFD))[3], 2);
700 outputFD[h->N/2] = cmplxf(h->VDSP_split.imagp[0], 0.0f);
705 cblas_sscal(2*(h->N/2+1), 0.5f, (
float*)outputFD, 1);
707#elif defined(SAF_USE_INTEL_MKL_LP64) || defined(SAF_USE_INTEL_MKL_ILP64)
708 h->Status = DftiComputeForward(h->MKL_FFT_Handle, inputTD, outputFD);
710 if(h->useKissFFT_FLAG)
711 kiss_fftr(h->kissFFThandle_fwd, inputTD, (
kiss_fft_cpx*)outputFD);
717 float_complex* inputFD,
723#if defined(SAF_USE_FFTW)
724 cblas_ccopy(h->N/2+1, inputFD, 1, h->bwd_bufferFD, 1);
725 fftwf_execute(h->p_bwd);
726 cblas_scopy(h->N, h->bwd_bufferTD, 1, outputTD, 1);
727 cblas_sscal(h->N, h->Scale, outputTD, 1);
728#elif defined(SAF_USE_INTEL_IPP)
729 if(h->useIPPfft_FLAG)
730 ippsFFTInv_CCSToR_32f((Ipp32f*)inputFD, (Ipp32f*)outputTD, h->hFFTspec, h->buffer);
732 ippsDFTInv_CCSToR_32f((Ipp32f*)inputFD, (Ipp32f*)outputTD, h->hDFTspec, h->buffer);
733#elif defined(SAF_USE_APPLE_ACCELERATE)
734 if(!h->useKissFFT_FLAG){
735# ifdef SAF_USE_INTERLEAVED_VDSP
738 h->VDSP_split_tmp.realp[0] = crealf(inputFD[0]);
739 h->VDSP_split_tmp.imagp[0] = crealf(inputFD[h->N/2]);
740 cblas_scopy(h->N/2-1, &((
float*)(inputFD))[2], 2, &h->VDSP_split_tmp.realp[1], 1);
741 cblas_scopy(h->N/2-1, &((
float*)(inputFD))[3], 2, &h->VDSP_split_tmp.imagp[1], 1);
742 vDSP_DFT_Execute(h->DFT_bwd, h->VDSP_split_tmp.realp, h->VDSP_split_tmp.imagp, h->VDSP_split.realp, h->VDSP_split.imagp);
743 vDSP_ztoc(&(h->VDSP_split), 1, (DSPComplex*)outputTD, 2, (h->N)/2);
744 vDSP_vsmul(outputTD, 1, &(h->Scale), outputTD, 1, h->N);
747#elif defined(SAF_USE_INTEL_MKL_LP64) || defined(SAF_USE_INTEL_MKL_ILP64)
748 h->Status = DftiComputeBackward(h->MKL_FFT_Handle, inputFD, outputTD);
750 if(h->useKissFFT_FLAG){
751 kiss_fftri(h->kissFFThandle_bkw, (
kiss_fft_cpx*)inputFD, outputTD);
752 cblas_sscal(h->N, 1.0f/(
float)(h->N), outputTD, 1);
771 h->Scale = 1.0f/(float)N;
772 saf_assert(N>=2,
"Only even (non zero) FFT sizes are supported");
773 h->useKissFFT_FLAG = 0;
774#if defined(SAF_USE_FFTW)
775 h->fwd_bufferTD =
malloc1d(h->N*
sizeof(fftwf_complex));
776 h->bwd_bufferTD =
malloc1d(h->N*
sizeof(fftwf_complex));
777 h->fwd_bufferFD =
malloc1d(h->N*
sizeof(fftwf_complex));
778 h->bwd_bufferFD =
malloc1d(h->N*
sizeof(fftwf_complex));
779 h->p_fwd = fftwf_plan_dft_1d(h->N, h->fwd_bufferTD, h->fwd_bufferFD, FFTW_FORWARD, FFTW_ESTIMATE);
780 h->p_bwd = fftwf_plan_dft_1d(h->N, h->bwd_bufferFD, h->bwd_bufferTD, FFTW_BACKWARD, FFTW_ESTIMATE);
781#elif defined(SAF_USE_INTEL_IPP)
783 if((
int)(log2f((
float)N) + 1.0f) == (
int)(log2f((
float)N))){
784 h->useIPPfft_FLAG = 1;
785 h->log2n = (int)(log2f((
float)N)+0.1f);
786 ippsFFTGetSize_C_32fc(h->log2n, IPP_FFT_DIV_INV_BY_N, ippAlgHintNone, &(h->specSize), &(h->specBufferSize), &(h->bufferSize));
788 h->memSpec = (Ipp8u*)ippMalloc(h->specSize);
789 h->buffer = (Ipp8u*)ippMalloc(h->bufferSize);
790 h->memInit = (Ipp8u*)ippMalloc(h->specBufferSize);
791 ippsFFTInit_C_32fc(&(h->hFFTspec), h->log2n, IPP_FFT_DIV_INV_BY_N, ippAlgHintNone, h->memSpec, h->memInit);
794 h->useIPPfft_FLAG = 0;
795 ippsDFTGetSize_C_32fc(N, IPP_FFT_DIV_INV_BY_N, ippAlgHintNone, &(h->specSize), &(h->specBufferSize), &(h->bufferSize));
796 h->hDFTspec = (IppsDFTSpec_C_32fc*)ippMalloc(h->specSize);
797 h->buffer = (Ipp8u*)ippMalloc(h->bufferSize);
798 h->memInit = (Ipp8u*)ippMalloc(h->specBufferSize);
799 ippsDFTInit_C_32fc(N, IPP_FFT_DIV_INV_BY_N, ippAlgHintNone, h->hDFTspec, h->memInit);
803#elif defined(SAF_USE_APPLE_ACCELERATE)
804# ifdef SAF_USE_INTERLEAVED_VDSP
805 h->DFT_fwd = vDSP_DFT_Interleaved_CreateSetup(0, N, vDSP_DFT_FORWARD, vDSP_DFT_Interleaved_RealtoComplex);
806 h->DFT_bwd = vDSP_DFT_Interleaved_CreateSetup(0, N, vDSP_DFT_INVERSE, vDSP_DFT_Interleaved_RealtoComplex);
808 h->DFT_fwd = vDSP_DFT_zop_CreateSetup(0, N, vDSP_DFT_FORWARD);
809 h->DFT_bwd = vDSP_DFT_zop_CreateSetup(0, N, vDSP_DFT_INVERSE);
811 if(h->DFT_fwd==0 || h->DFT_bwd==0)
812 h->useKissFFT_FLAG = 1;
815 saf_assert(h->DFT_fwd!=0 && h->DFT_bwd!=0,
"Failed to create vDSP DFT");
816# ifndef SAF_USE_INTERLEAVED_VDSP
817 h->VDSP_split_tmp.realp =
malloc1d((h->N)*
sizeof(
float));
818 h->VDSP_split_tmp.imagp =
malloc1d((h->N)*
sizeof(
float));
819 h->VDSP_split.realp =
malloc1d((h->N)*
sizeof(
float));
820 h->VDSP_split.imagp =
malloc1d((h->N)*
sizeof(
float));
823#elif defined(SAF_USE_INTEL_MKL_LP64) || defined(SAF_USE_INTEL_MKL_ILP64)
824 h->MKL_FFT_Handle = 0;
825 h->Status = DftiCreateDescriptor( &(h->MKL_FFT_Handle), DFTI_SINGLE,
826 DFTI_COMPLEX, 1, h->N);
827 h->Status = DftiSetValue(h->MKL_FFT_Handle, DFTI_PLACEMENT, DFTI_NOT_INPLACE);
829 h->Status = DftiSetValue(h->MKL_FFT_Handle, DFTI_BACKWARD_SCALE, h->Scale);
831 h->Status = DftiCommitDescriptor(h->MKL_FFT_Handle);
834 h->useKissFFT_FLAG = 1;
837 if(h->useKissFFT_FLAG){
851#if defined(SAF_USE_FFTW)
852 free(h->fwd_bufferTD);
853 free(h->bwd_bufferTD);
854 free(h->fwd_bufferFD);
855 free(h->bwd_bufferFD);
856 fftwf_destroy_plan(h->p_bwd);
857 fftwf_destroy_plan(h->p_fwd);
858#elif defined(SAF_USE_INTEL_IPP)
859 if(h->useIPPfft_FLAG){
865 ippFree(h->hDFTspec);
869#elif defined(SAF_USE_APPLE_ACCELERATE)
870 if(!h->useKissFFT_FLAG){
871# ifdef SAF_USE_INTERLEAVED_VDSP
872 vDSP_DFT_Interleaved_DestroySetup(h->DFT_fwd);
873 vDSP_DFT_Interleaved_DestroySetup(h->DFT_bwd);
875 vDSP_DFT_DestroySetup(h->DFT_fwd);
876 vDSP_DFT_DestroySetup(h->DFT_bwd);
877 free(h->VDSP_split_tmp.realp);
878 free(h->VDSP_split_tmp.imagp);
879 free(h->VDSP_split.realp);
880 free(h->VDSP_split.imagp);
883#elif defined(SAF_USE_INTEL_MKL_LP64) || defined(SAF_USE_INTEL_MKL_ILP64)
884 h->Status = DftiFreeDescriptor(&(h->MKL_FFT_Handle));
886 if(h->useKissFFT_FLAG){
887 kiss_fft_free(h->kissFFThandle_fwd);
888 kiss_fft_free(h->kissFFThandle_bkw);
900 float_complex* inputTD,
901 float_complex* outputFD
906#if defined(SAF_USE_FFTW)
907 cblas_ccopy(h->N, inputTD, 1, h->fwd_bufferTD, 1);
908 fftwf_execute(h->p_fwd);
909 cblas_ccopy(h->N, h->fwd_bufferFD, 1, outputFD, 1);
910#elif defined(SAF_USE_INTEL_IPP)
911 if(h->useIPPfft_FLAG)
912 ippsFFTFwd_CToC_32fc((Ipp32fc*)inputTD, (Ipp32fc*)outputFD, h->hFFTspec, h->buffer);
914 ippsDFTFwd_CToC_32fc((Ipp32fc*)inputTD, (Ipp32fc*)outputFD, h->hDFTspec, h->buffer);
915#elif defined(SAF_USE_APPLE_ACCELERATE)
916 if(!h->useKissFFT_FLAG){
917# ifdef SAF_USE_INTERLEAVED_VDSP
920 cblas_scopy(h->N, &((
float*)(inputTD))[0], 2, h->VDSP_split_tmp.realp, 1);
921 cblas_scopy(h->N, &((
float*)(inputTD))[1], 2, h->VDSP_split_tmp.imagp, 1);
922 vDSP_DFT_Execute(h->DFT_fwd, h->VDSP_split_tmp.realp, h->VDSP_split_tmp.imagp, h->VDSP_split.realp, h->VDSP_split.imagp);
923 cblas_scopy(h->N, h->VDSP_split.realp, 1, &((
float*)(outputFD))[0], 2);
924 cblas_scopy(h->N, h->VDSP_split.imagp, 1, &((
float*)(outputFD))[1], 2);
927#elif defined(SAF_USE_INTEL_MKL_LP64) || defined(SAF_USE_INTEL_MKL_ILP64)
928 h->Status = DftiComputeForward(h->MKL_FFT_Handle, inputTD, outputFD);
930 if(h->useKissFFT_FLAG)
937 float_complex* inputFD,
938 float_complex* outputTD
943#if defined(SAF_USE_FFTW)
944 cblas_ccopy(h->N, inputFD, 1, h->bwd_bufferFD, 1);
945 fftwf_execute(h->p_bwd);
946 cblas_ccopy(h->N, h->bwd_bufferTD, 1, outputTD, 1);
947 cblas_sscal(2 * h->N, h->Scale, (
float*)outputTD, 1);
948#elif defined(SAF_USE_INTEL_IPP)
949 if(h->useIPPfft_FLAG)
950 ippsFFTInv_CToC_32fc((Ipp32fc*)inputFD, (Ipp32fc*)outputTD, h->hFFTspec, h->buffer);
952 ippsDFTInv_CToC_32fc((Ipp32fc*)inputFD, (Ipp32fc*)outputTD, h->hDFTspec, h->buffer);
953#elif defined(SAF_USE_APPLE_ACCELERATE)
954 if(!h->useKissFFT_FLAG){
955# ifdef SAF_USE_INTERLEAVED_VDSP
958 cblas_scopy(h->N, &((
float*)(inputFD))[0], 2, h->VDSP_split_tmp.realp, 1);
959 cblas_scopy(h->N, &((
float*)(inputFD))[1], 2, h->VDSP_split_tmp.imagp, 1);
960 vDSP_DFT_Execute(h->DFT_bwd, h->VDSP_split_tmp.realp, h->VDSP_split_tmp.imagp, h->VDSP_split.realp, h->VDSP_split.imagp);
961 cblas_scopy(h->N, h->VDSP_split.realp, 1, &((
float*)(outputTD))[0], 2);
962 cblas_scopy(h->N, h->VDSP_split.imagp, 1, &((
float*)(outputTD))[1], 2);
963 cblas_sscal(2*(h->N), 1.0f/(
float)(h->N), (
float*)outputTD, 1);
966#elif defined(SAF_USE_INTEL_MKL_LP64) || defined(SAF_USE_INTEL_MKL_ILP64)
967 h->Status = DftiComputeBackward(h->MKL_FFT_Handle, inputFD, outputTD);
969 if(h->useKissFFT_FLAG){
971 cblas_sscal(2*(h->N), 1.0f/(
float)(h->N), (
float*)outputTD, 1);
#define saf_print_error(message)
Macro to print a error message along with the filename and line number.
void fftfilt(float *x, float *h, int x_len, int h_len, int nCH, float *y)
FFT-based convolution for FIR filters.
void saf_stft_backward(void *const hSTFT, float_complex ***dataFD, int framesize, float **dataTD)
Performs the backward-STFT operation for the current frame.
#define saf_assert(x, message)
Macro to make an assertion, along with a string explaining its purpose.
void saf_stft_forward(void *const hSTFT, float **dataTD, int framesize, float_complex ***dataFD)
Performs the forward-STFT operation for the current frame.
void utility_cvvmul(const float_complex *a, const float_complex *b, const int len, float_complex *c)
Single-precision, complex, element-wise vector-vector multiplication i.e.
void utility_svvmul(const float *a, const float *b, const int len, float *c)
Single-precision, element-wise vector-vector multiplication i.e.
void fftconv(float *x, float *h, int x_len, int h_len, int nCH, float *y)
FFT-based convolution of signal 'x' with filter 'h'.
SAF_STFT_FDDATA_FORMAT
Options for how the frequency domain data is permuted when using saf_stft.
void saf_fft_backward(void *const hFFT, float_complex *inputFD, float_complex *outputTD)
Performs the backward-FFT operation; use for complex to complex transformations.
void saf_fft_create(void **const phFFT, int N)
Creates an instance of saf_fft; complex<->complex FFT.
void saf_stft_channelChange(void *const hSTFT, int new_nCHin, int new_nCHout)
Changes the number of input/output channels.
void hilbert(float_complex *x, int x_len, float_complex *y)
Computes the discrete-time analytic signal via the Hilbert transform [1].
void saf_rfft_create(void **const phFFT, int N)
Creates an instance of saf_rfft; real<->half-complex (conjugate-symmetric) FFT.
void getWindowingFunction(WINDOWING_FUNCTION_TYPES type, int winlength, float *win)
Computes the weights of a specific windowing function.
void saf_fft_forward(void *const hFFT, float_complex *inputTD, float_complex *outputFD)
Performs the forward-FFT operation; use for complex to complex transformations.
void saf_rfft_forward(void *const hFFT, float *inputTD, float_complex *outputFD)
Performs the forward-FFT operation; use for real to complex (conjugate symmetric) transformations.
void getUniformFreqVector(int fftSize, float fs, float *freqVector)
Calculates the frequencies (in Hz) of uniformly spaced bins, for a given FFT size and sampling rate.
void saf_rfft_backward(void *const hFFT, float_complex *inputFD, float *outputTD)
Performs the backward-FFT operation; use for complex (conjugate symmetric) to real transformations.
void saf_rfft_destroy(void **const phFFT)
Destroys an instance of saf_rfft.
void saf_stft_destroy(void **const phSTFT)
Destroys an instance of saf_stft.
#define ISEVEN(n)
Returns 1 if "n" is even valued, and 0 if it is not.
int nextpow2(int numsamp)
A simple function which returns the next power of 2.
void saf_stft_flushBuffers(void *const hSTFT)
Flushes the internal buffers with zeros.
void saf_fft_destroy(void **const phFFT)
Destroys an instance of saf_fft.
void saf_stft_create(void **const phSTFT, int winsize, int hopsize, int nCHin, int nCHout, SAF_STFT_FDDATA_FORMAT FDformat)
Creates an instance of saf_stft.
@ WINDOWING_FUNCTION_HANN
Hann.
@ SAF_STFT_TIME_CH_BANDS
nTimeHops x nChannels x nBands
@ SAF_STFT_BANDS_CH_TIME
nBands x nChannels x nTimeHops
void kiss_fft(kiss_fft_cfg cfg, const kiss_fft_cpx *fin, kiss_fft_cpx *fout)
kiss_fft(cfg,in_out_buf)
kiss_fft_cfg kiss_fft_alloc(int nfft, int inverse_fft, void *mem, size_t *lenmem)
kiss_fft_alloc
void * malloc1d(size_t dim1_data_size)
1-D malloc (same as malloc, but with error checking)
void * calloc1d(size_t dim1, size_t data_size)
1-D calloc (same as calloc, but with error checking)
void *** realloc3d_r(void ***ptr, size_t new_dim1, size_t new_dim2, size_t new_dim3, size_t prev_dim1, size_t prev_dim2, size_t prev_dim3, size_t data_size)
3-D realloc which does retain previous data order
void ** realloc2d_r(void **ptr, size_t new_dim1, size_t new_dim2, size_t prev_dim1, size_t prev_dim2, size_t data_size)
2-D realloc which does retain previous data order
void ** calloc2d(size_t dim1, size_t dim2, size_t data_size)
2-D calloc (contiguously allocated, so use free() as usual to deallocate)
void *** calloc3d(size_t dim1, size_t dim2, size_t dim3, size_t data_size)
3-D calloc (contiguously allocated, so use free() as usual to deallocate)
#define FLATTEN2D(A)
Use this macro when passing a 2-D dynamic multi-dimensional array to memset, memcpy or any other func...
#define FLATTEN3D(A)
Use this macro when passing a 3-D dynamic multi-dimensional array to memset, memcpy or any other func...
Include header for SAF externals.
Main header for the utilities module (SAF_UTILITIES_MODULE)
Complex data type used by kissFFT.
Data structure for complex-complex FFT transforms.
Data structure for real-(half)complex FFT transforms.
Data structure for short-time Fourier transform.