d@0: //---------------------------------------------------------------------------------------------------------------------- d@0: /** d@0: \author André Bergner d@0: \date Feb/2013 d@0: d@0: \class FFTW d@0: d@0: Encapsulates the FFT of lib-fftw d@0: d@0: (c) Copyright NATIVE INSTRUMENTS, Berlin, Germany d@0: ALL RIGHTS RESERVED d@0: */ d@0: //---------------------------------------------------------------------------------------------------------------------- d@0: d@0: #pragma once d@0: d@0: #include "fftw3.h" d@0: #include d@0: #include d@0: #include d@0: //#include d@0: d@0: d@0: d@0: class FFTW d@0: { d@0: d@0: public: d@0: fftwf_plan m_plan; d@0: unsigned m_iFFTSize; d@0: d@0: FFTW(); d@0: FFTW( unsigned fftLength ) d@0: { d@0: m_iFFTSize = fftLength; d@0: d@0: float* tempInput = new float[fftLength]; d@0: memset(tempInput,0, fftLength * sizeof(float)); d@0: float* tempReal = new float[fftLength]; d@0: memset(tempReal,0, fftLength * sizeof(float)); d@0: float* tempImag = new float[fftLength]; d@0: memset(tempImag,0, fftLength * sizeof(float)); d@0: fftwf_iodim dim; d@0: dim.n = fftLength; d@0: dim.is = 1; d@0: dim.os = 1; d@0: m_plan = fftwf_plan_guru_split_dft_r2c( 1, &dim, 0, NULL, tempInput, tempReal, tempImag, FFTW_ESTIMATE ); d@0: delete[] tempInput; d@0: tempInput = nullptr; d@0: delete[] tempReal; d@0: tempReal = nullptr; d@0: delete[] tempImag; d@0: tempImag = nullptr; d@0: } d@0: d@0: d@0: ~FFTW() d@0: { d@0: if(m_plan != NULL) d@0: { d@0: fftwf_destroy_plan( m_plan ); d@0: } d@0: } d@0: d@0: d@0: void process( const float* input , float* realPart , float* imagPart ) d@0: { d@0: float* nonConstInput = const_cast(input); // fftw does not take const input even though the data not be manipulated! d@0: d@0: fftwf_execute_split_dft_r2c( m_plan, nonConstInput, realPart, imagPart); d@0: d@0: //Multiply results by 2 to match the iOS output d@0: for(size_t i = 0; i < m_iFFTSize; i++) d@0: { d@0: realPart[i] *= 2.f; d@0: imagPart[i] *= 2.f; d@0: } d@0: } d@0: d@0: }; d@0: