changeset 445:7f7a10bcaff1 vampipe

Single or double-precision FFTs (double in the default build), not both
author Chris Cannam
date Thu, 18 Aug 2016 15:06:23 +0100
parents 7bab0c5422f4
children d132b92ec65d
files src/vamp-hostsdk/PluginInputDomainAdapter.cpp src/vamp-sdk/FFT.cpp vamp-sdk/FFT.h
diffstat 3 files changed, 43 insertions(+), 96 deletions(-) [+]
line wrap: on
line diff
--- 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 <string.h>
 #include <limits.h>
 
-// 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 {
 
--- 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);
 }
--- 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;