# HG changeset patch # User Chris Cannam # Date 1471529183 -3600 # Node ID 7f7a10bcaff1bc7fe37e3280d8241a369e766676 # Parent 7bab0c5422f4b5c8e3637a8b0cd77d8acc5dd3be Single or double-precision FFTs (double in the default build), not both diff -r 7bab0c5422f4 -r 7f7a10bcaff1 src/vamp-hostsdk/PluginInputDomainAdapter.cpp --- a/src/vamp-hostsdk/PluginInputDomainAdapter.cpp Thu Aug 18 14:43:52 2016 +0100 +++ b/src/vamp-hostsdk/PluginInputDomainAdapter.cpp Thu Aug 18 15:06:23 2016 +0100 @@ -49,43 +49,9 @@ #include #include -// Define this symbol in the build if you want to use single-precision -// FFTs in the input domain adapter. The default is to use -// double-precision FFTs. -// -//#define SINGLE_PRECISION_INPUT_DOMAIN_ADAPTER 1 +_VAMP_SDK_HOSTSPACE_BEGIN(PluginInputDomainAdapter.cpp) -// Override C linkage for KissFFT headers. So long as we have already -// included all of the other (system etc) headers KissFFT depends on, -// this should work out OK -#undef __cplusplus - -namespace Kiss { - -#undef KISS_FFT_H -#undef KISS_FTR_H -#undef KISS_FFT__GUTS_H -#undef FIXED_POINT -#undef USE_SIMD -#undef kiss_fft_scalar - -#ifdef SINGLE_PRECISION_INPUT_DOMAIN_ADAPTER -typedef float kiss_fft_scalar; -#define kiss_fft_scalar float -#else -typedef double kiss_fft_scalar; -#define kiss_fft_scalar double -#endif - -inline void free(void *ptr) { ::free(ptr); } -#include "../vamp-sdk/ext/kiss_fft.c" -#include "../vamp-sdk/ext/kiss_fftr.c" - -#undef kiss_fft_scalar // leaving only the namespaced typedef - -} - -_VAMP_SDK_HOSTSPACE_BEGIN(PluginInputDomainAdapter.cpp) +#include "../vamp-sdk/FFTimpl.cpp" namespace Vamp { diff -r 7bab0c5422f4 -r 7f7a10bcaff1 src/vamp-sdk/FFT.cpp --- a/src/vamp-sdk/FFT.cpp Thu Aug 18 14:43:52 2016 +0100 +++ b/src/vamp-sdk/FFT.cpp Thu Aug 18 15:06:23 2016 +0100 @@ -47,36 +47,7 @@ _VAMP_SDK_PLUGSPACE_BEGIN(FFT.cpp) -// Override C linkage for KissFFT headers. So long as we have already -// included all of the other (system etc) headers KissFFT depends on, -// this should work out OK -#undef __cplusplus - -namespace KissSingle { -#undef KISS_FFT_H -#undef KISS_FTR_H -#undef KISS_FFT__GUTS_H -#undef FIXED_POINT -#undef USE_SIMD -#undef kiss_fft_scalar -#define kiss_fft_scalar float -inline void free(void *ptr) { ::free(ptr); } -#include "ext/kiss_fft.c" -#include "ext/kiss_fftr.c" -} - -namespace KissDouble { -#undef KISS_FFT_H -#undef KISS_FTR_H -#undef KISS_FFT__GUTS_H -#undef FIXED_POINT -#undef USE_SIMD -#undef kiss_fft_scalar -#define kiss_fft_scalar double -inline void free(void *ptr) { ::free(ptr); } -#include "ext/kiss_fft.c" -#include "ext/kiss_fftr.c" -} +#include "FFTimpl.cpp" namespace Vamp { @@ -86,9 +57,9 @@ double *ro, double *io) { int n(un); - KissDouble::kiss_fft_cfg c = KissDouble::kiss_fft_alloc(n, false, 0, 0); - KissDouble::kiss_fft_cpx *in = new KissDouble::kiss_fft_cpx[n]; - KissDouble::kiss_fft_cpx *out = new KissDouble::kiss_fft_cpx[n]; + Kiss::kiss_fft_cfg c = Kiss::kiss_fft_alloc(n, false, 0, 0); + Kiss::kiss_fft_cpx *in = new Kiss::kiss_fft_cpx[n]; + Kiss::kiss_fft_cpx *out = new Kiss::kiss_fft_cpx[n]; for (int i = 0; i < n; ++i) { in[i].r = ri[i]; in[i].i = 0; @@ -103,7 +74,7 @@ ro[i] = out[i].r; io[i] = out[i].i; } - KissDouble::kiss_fft_free(c); + Kiss::kiss_fft_free(c); delete[] in; delete[] out; } @@ -114,9 +85,9 @@ double *ro, double *io) { int n(un); - KissDouble::kiss_fft_cfg c = KissDouble::kiss_fft_alloc(n, true, 0, 0); - KissDouble::kiss_fft_cpx *in = new KissDouble::kiss_fft_cpx[n]; - KissDouble::kiss_fft_cpx *out = new KissDouble::kiss_fft_cpx[n]; + Kiss::kiss_fft_cfg c = Kiss::kiss_fft_alloc(n, true, 0, 0); + Kiss::kiss_fft_cpx *in = new Kiss::kiss_fft_cpx[n]; + Kiss::kiss_fft_cpx *out = new Kiss::kiss_fft_cpx[n]; for (int i = 0; i < n; ++i) { in[i].r = ri[i]; in[i].i = 0; @@ -132,7 +103,7 @@ ro[i] = out[i].r * scale; io[i] = out[i].i * scale; } - KissDouble::kiss_fft_free(c); + Kiss::kiss_fft_free(c); delete[] in; delete[] out; } @@ -143,18 +114,26 @@ D(int n) : m_n(n), - m_cf(KissSingle::kiss_fftr_alloc(n, false, 0, 0)), - m_ci(KissSingle::kiss_fftr_alloc(n, true, 0, 0)), - m_freq(new KissSingle::kiss_fft_cpx[n/2+1]) { } + m_cf(Kiss::kiss_fftr_alloc(n, false, 0, 0)), + m_ci(Kiss::kiss_fftr_alloc(n, true, 0, 0)), + m_ri(new Kiss::kiss_fft_scalar[m_n]), + m_ro(new Kiss::kiss_fft_scalar[m_n]), + m_freq(new Kiss::kiss_fft_cpx[n/2+1]) { } ~D() { - KissSingle::kiss_fftr_free(m_cf); - KissSingle::kiss_fftr_free(m_ci); + Kiss::kiss_fftr_free(m_cf); + Kiss::kiss_fftr_free(m_ci); + delete[] m_ri; + delete[] m_ro; delete[] m_freq; } - void forward(const float *ri, float *co) { - KissSingle::kiss_fftr(m_cf, ri, m_freq); + void forward(const double *ri, double *co) { + for (int i = 0; i < m_n; ++i) { + // in case kiss_fft_scalar is float + m_ri[i] = ri[i]; + } + Kiss::kiss_fftr(m_cf, m_ri, m_freq); int hs = m_n/2 + 1; for (int i = 0; i < hs; ++i) { co[i*2] = m_freq[i].r; @@ -162,24 +141,26 @@ } } - void inverse(const float *ci, float *ro) { + void inverse(const double *ci, double *ro) { int hs = m_n/2 + 1; for (int i = 0; i < hs; ++i) { m_freq[i].r = ci[i*2]; m_freq[i].i = ci[i*2+1]; } - KissSingle::kiss_fftri(m_ci, m_freq, ro); + Kiss::kiss_fftri(m_ci, m_freq, m_ro); double scale = 1.0 / double(m_n); for (int i = 0; i < m_n; ++i) { - ro[i] *= scale; + ro[i] = m_ro[i] * scale; } } private: int m_n; - KissSingle::kiss_fftr_cfg m_cf; - KissSingle::kiss_fftr_cfg m_ci; - KissSingle::kiss_fft_cpx *m_freq; + Kiss::kiss_fftr_cfg m_cf; + Kiss::kiss_fftr_cfg m_ci; + Kiss::kiss_fft_scalar *m_ri; + Kiss::kiss_fft_scalar *m_ro; + Kiss::kiss_fft_cpx *m_freq; }; FFTReal::FFTReal(unsigned int n) : @@ -193,13 +174,13 @@ } void -FFTReal::forward(const float *ri, float *co) +FFTReal::forward(const double *ri, double *co) { m_d->forward(ri, co); } void -FFTReal::inverse(const float *ci, float *ro) +FFTReal::inverse(const double *ci, double *ro) { m_d->inverse(ci, ro); } diff -r 7bab0c5422f4 -r 7f7a10bcaff1 vamp-sdk/FFT.h --- a/vamp-sdk/FFT.h Thu Aug 18 14:43:52 2016 +0100 +++ b/vamp-sdk/FFT.h Thu Aug 18 15:06:23 2016 +0100 @@ -45,9 +45,9 @@ /** * A simple FFT implementation provided for convenience of plugin * authors. This class provides one-shot (i.e. fixed table state is - * recalculated every time) double precision complex-complex + * recalculated every time) double-precision complex-complex * transforms. For repeated transforms from real time-domain data, use - * a FFTReal object instead. + * an FFTReal object instead. * * The forward transform is unscaled; the inverse transform is scaled * by 1/n. @@ -92,9 +92,9 @@ /** * A simple FFT implementation provided for convenience of plugin - * authors. This class provides transforms between real - * single-precision time-domain and complex single-precision - * frequency-domain data. + * authors. This class provides transforms between double-precision + * real time-domain and double-precision complex frequency-domain + * data. * * The forward transform is unscaled; the inverse transform is scaled * by 1/n. @@ -117,7 +117,7 @@ * co must point to enough space to receive an interleaved complex * output array of size n/2+1. */ - void forward(const float *ri, float *co); + void forward(const double *ri, double *co); /** * Calculate an inverse transform of size n. @@ -128,7 +128,7 @@ * of size n. The output is scaled by 1/n and only the real part * is returned. */ - void inverse(const float *ci, float *ro); + void inverse(const double *ci, double *ro); private: class D;