diff --git a/OOps/fftlib.c b/OOps/fftlib.c index 7c9d4eeb09c..7b60f4f2390 100644 --- a/OOps/fftlib.c +++ b/OOps/fftlib.c @@ -3353,15 +3353,6 @@ void csoundRealFFTMult(CSOUND *csound, MYFLT *outbuf, New FFT interface VL, 2016 */ -typedef struct _FFT_SETUP{ - int N, M; - void *setup; - MYFLT *buffer; - int lib; - int d; -} CSOUND_FFT_SETUP; - - static void pffft_execute(CSOUND_FFT_SETUP *setup, MYFLT *sig) { @@ -3448,6 +3439,10 @@ int setupDispose(CSOUND *csound, void *pp){ return OK; } +int isPowTwo(int N) { + return ((N != 0) && !(N & (N - 1))); +} + void *csoundRealFFT2Setup(CSOUND *csound, int FFTsize, int d){ @@ -3498,6 +3493,7 @@ void *csoundRealFFT2Setup(CSOUND *csound, csound->RegisterResetCallback(csound, (void*) setup, (int (*)(CSOUND *, void *)) setupDispose); + setup->p2 = isPowTwo(FFTsize); return (void *) setup; } diff --git a/include/csoundCore.h b/include/csoundCore.h index 26b1f5f9356..530e6a5cd3d 100644 --- a/include/csoundCore.h +++ b/include/csoundCore.h @@ -935,6 +935,19 @@ typedef struct NAME__ { } ENGINE_STATE; + /** + * Nen FFT interface + */ + typedef struct _FFT_SETUP{ + int N, M; + void *setup; + MYFLT *buffer; + int lib; + int d; + int p2; + } CSOUND_FFT_SETUP; + + /** * plugin module info */ diff --git a/include/plugin.h b/include/plugin.h index 1ce29493805..0d181256ba3 100644 --- a/include/plugin.h +++ b/include/plugin.h @@ -43,6 +43,8 @@ enum thread { i = 1, k = 2, ik = 3, a = 4, ia = 5, ika = 7 }; */ enum fsig_format { pvs = 0, polar, complex, tracks }; +typedef CSOUND_FFT_SETUP* fftp; + /** Csound Engine object. */ class Csound : CSOUND { @@ -163,18 +165,39 @@ class Csound : CSOUND { direction: FFT_FWD or FFT_INV \n returns a handle to the FFT setup. */ - void *rfft_setup(uint32_t size, uint32_t direction) { - return RealFFT2Setup(this, size, direction); + fftp fft_setup(uint32_t size, uint32_t direction) { + return (fftp) RealFFT2Setup(this, size, direction); } /** FFT operation, in-place, but also returning a pointer to std::complex to the transformed data memory. */ - std::complex *rfft(void *setup, MYFLT *data) { - RealFFT2(this, setup, data); + std::complex *rfft(fftp setup, MYFLT *data) { + if(!setup->p2) { + if(setup->d == FFT_FWD) + RealFFTnp2(this, data, setup->N); + else + InverseRealFFTnp2(this, data, setup->N); + } + else + RealFFT2(this, setup, data); return reinterpret_cast *>(data); } + + /** FFT operation for complex data, in-place, but also + returning a pointer to std::complex + to the transformed data memory. + */ + std::complex *fft(fftp setup, std::complex *data) { + MYFLT *fdata = reinterpret_cast(data); + if(setup->d == FFT_FWD) + ComplexFFT(this,fdata,setup->N); + else + ComplexFFT(this,fdata,setup->N); + return reinterpret_cast*>(fdata); + } + }; /** One-dimensional array container