Index: python/tests/test_fft.py
===================================================================
--- python/tests/test_fft.py	(revision 9ef3c6e531d0b937f18abc3aacd550946c682ace)
+++ python/tests/test_fft.py	(revision 01d4d19410d417789f021eb8b57c7aba6a0b7229)
@@ -143,4 +143,35 @@
         assert_almost_equal ( r[1:], 0)
 
+class aubio_fft_odd_sizes(TestCase):
+
+    def test_reconstruct_with_odd_size(self):
+        win_s = 29
+        self.recontruct(win_s, 'odd sizes not supported')
+
+    def test_reconstruct_with_radix15(self):
+        win_s = 2 ** 4 * 15
+        self.recontruct(win_s, 'radix 15 supported')
+
+    def test_reconstruct_with_radix5(self):
+        win_s = 2 ** 4 * 5
+        self.recontruct(win_s, 'radix 5 supported')
+
+    def test_reconstruct_with_radix3(self):
+        win_s = 2 ** 4 * 3
+        self.recontruct(win_s, 'radix 3 supported')
+
+    def recontruct(self, win_s, skipMessage):
+        try:
+            f = fft(win_s)
+        except RuntimeError:
+            self.skipTest(skipMessage)
+        input_signal = fvec(win_s)
+        input_signal[win_s//2] = 1
+        c = f(input_signal)
+        output_signal = f.rdo(c)
+        assert_almost_equal(input_signal, output_signal)
+
+class aubio_fft_wrong_params(TestCase):
+
     def test_large_input_timegrain(self):
         win_s = 1024
@@ -170,6 +201,4 @@
         with self.assertRaises(ValueError):
             f.rdo(s)
-
-class aubio_fft_wrong_params(TestCase):
 
     def test_wrong_buf_size(self):
@@ -177,13 +206,4 @@
         with self.assertRaises(ValueError):
             fft(win_s)
-
-    def test_buf_size_not_power_of_two(self):
-        # when compiled with fftw3, aubio supports non power of two fft sizes
-        win_s = 320
-        try:
-            with self.assertRaises(RuntimeError):
-                fft(win_s)
-        except AssertionError:
-            self.skipTest('creating aubio.fft with size %d did not fail' % win_s)
 
     def test_buf_size_too_small(self):
Index: src/spectral/fft.c
===================================================================
--- src/spectral/fft.c	(revision 9ef3c6e531d0b937f18abc3aacd550946c682ace)
+++ src/spectral/fft.c	(revision 01d4d19410d417789f021eb8b57c7aba6a0b7229)
@@ -90,9 +90,10 @@
 #define aubio_vDSP_vsadd               vDSP_vsadd
 #define aubio_vDSP_vsmul               vDSP_vsmul
-#define aubio_vDSP_create_fftsetup     vDSP_create_fftsetup
-#define aubio_vDSP_destroy_fftsetup    vDSP_destroy_fftsetup
 #define aubio_DSPComplex               DSPComplex
 #define aubio_DSPSplitComplex          DSPSplitComplex
-#define aubio_FFTSetup                 FFTSetup
+#define aubio_vDSP_DFT_Setup           vDSP_DFT_Setup
+#define aubio_vDSP_DFT_zrop_CreateSetup vDSP_DFT_zrop_CreateSetup
+#define aubio_vDSP_DFT_Execute         vDSP_DFT_Execute
+#define aubio_vDSP_DFT_DestroySetup    vDSP_DFT_DestroySetup
 #define aubio_vvsqrt                   vvsqrtf
 #else
@@ -104,9 +105,10 @@
 #define aubio_vDSP_vsadd               vDSP_vsaddD
 #define aubio_vDSP_vsmul               vDSP_vsmulD
-#define aubio_vDSP_create_fftsetup     vDSP_create_fftsetupD
-#define aubio_vDSP_destroy_fftsetup    vDSP_destroy_fftsetupD
 #define aubio_DSPComplex               DSPDoubleComplex
 #define aubio_DSPSplitComplex          DSPDoubleSplitComplex
-#define aubio_FFTSetup                 FFTSetupD
+#define aubio_vDSP_DFT_Setup           vDSP_DFT_SetupD
+#define aubio_vDSP_DFT_zrop_CreateSetup vDSP_DFT_zrop_CreateSetupD
+#define aubio_vDSP_DFT_Execute         vDSP_DFT_ExecuteD
+#define aubio_vDSP_DFT_DestroySetup    vDSP_DFT_DestroySetupD
 #define aubio_vvsqrt                   vvsqrt
 #endif /* HAVE_AUBIO_DOUBLE */
@@ -153,6 +155,6 @@
 
 #elif defined HAVE_ACCELERATE  // using ACCELERATE
-  int log2fftsize;
-  aubio_FFTSetup fftSetup;
+  aubio_vDSP_DFT_Setup fftSetupFwd;
+  aubio_vDSP_DFT_Setup fftSetupBwd;
   aubio_DSPSplitComplex spec;
   smpl_t *in, *out;
@@ -211,13 +213,30 @@
 
 #elif defined HAVE_ACCELERATE  // using ACCELERATE
+  {
+    uint_t radix = winsize;
+    uint_t order = 0;
+    while ((radix / 2) * 2 == radix) {
+      radix /= 2;
+      order++;
+    }
+    if (order < 4 || (radix != 1 && radix != 3 && radix != 5 && radix != 15)) {
+      AUBIO_ERR("fft: vDSP/Accelerate supports FFT with sizes = "
+          "f * 2 ** n, where n > 4 and f in [1, 3, 5, 15], but requested %d. "
+          "Use the closest power of two, or try recompiling aubio with "
+          "--enable-fftw3.\n", winsize);
+      goto beach;
+    }
+  }
   s->winsize = winsize;
   s->fft_size = winsize;
   s->compspec = new_fvec(winsize);
-  s->log2fftsize = aubio_power_of_two_order(s->fft_size);
   s->in = AUBIO_ARRAY(smpl_t, s->fft_size);
   s->out = AUBIO_ARRAY(smpl_t, s->fft_size);
   s->spec.realp = AUBIO_ARRAY(smpl_t, s->fft_size/2);
   s->spec.imagp = AUBIO_ARRAY(smpl_t, s->fft_size/2);
-  s->fftSetup = aubio_vDSP_create_fftsetup(s->log2fftsize, FFT_RADIX2);
+  s->fftSetupFwd = aubio_vDSP_DFT_zrop_CreateSetup(NULL,
+      s->fft_size, vDSP_DFT_FORWARD);
+  s->fftSetupBwd = aubio_vDSP_DFT_zrop_CreateSetup(s->fftSetupFwd,
+      s->fft_size, vDSP_DFT_INVERSE);
 
 #elif defined HAVE_INTEL_IPP  // using Intel IPP
@@ -293,5 +312,6 @@
   AUBIO_FREE(s->spec.realp);
   AUBIO_FREE(s->spec.imagp);
-  aubio_vDSP_destroy_fftsetup(s->fftSetup);
+  aubio_vDSP_DFT_DestroySetup(s->fftSetupBwd);
+  aubio_vDSP_DFT_DestroySetup(s->fftSetupFwd);
 
 #elif defined HAVE_INTEL_IPP  // using Intel IPP
@@ -351,5 +371,6 @@
   aubio_vDSP_ctoz((aubio_DSPComplex*)s->in, 2, &s->spec, 1, s->fft_size/2);
   // compute the FFT
-  aubio_vDSP_fft_zrip(s->fftSetup, &s->spec, 1, s->log2fftsize, FFT_FORWARD);
+  aubio_vDSP_DFT_Execute(s->fftSetupFwd, s->spec.realp, s->spec.imagp,
+      s->spec.realp, s->spec.imagp);
   // convert from vDSP complex split to [ r0, r1, ..., rN, iN-1, .., i2, i1]
   compspec->data[0] = s->spec.realp[0];
@@ -419,5 +440,6 @@
   aubio_vDSP_ctoz((aubio_DSPComplex*)s->out, 2, &s->spec, 1, s->fft_size/2);
   // compute the FFT
-  aubio_vDSP_fft_zrip(s->fftSetup, &s->spec, 1, s->log2fftsize, FFT_INVERSE);
+  aubio_vDSP_DFT_Execute(s->fftSetupBwd, s->spec.realp, s->spec.imagp,
+      s->spec.realp, s->spec.imagp);
   // convert result to real output
   aubio_vDSP_ztoc(&s->spec, 1, (aubio_DSPComplex*)output->data, 2, s->fft_size/2);
@@ -494,9 +516,20 @@
   }
 #endif
-  if (compspec->data[compspec->length/2] < 0) {
-    spectrum->phas[spectrum->length - 1] = PI;
+#ifdef HAVE_FFTW3
+  // for even length only, make sure last element is 0 or PI
+  if (2 * (compspec->length / 2) == compspec->length) {
+#endif
+    if (compspec->data[compspec->length/2] < 0) {
+      spectrum->phas[spectrum->length - 1] = PI;
+    } else {
+      spectrum->phas[spectrum->length - 1] = 0.;
+    }
+#ifdef HAVE_FFTW3
   } else {
-    spectrum->phas[spectrum->length - 1] = 0.;
-  }
+    i = spectrum->length - 1;
+    spectrum->phas[i] = ATAN2(compspec->data[compspec->length-i],
+        compspec->data[i]);
+  }
+#endif
 }
 
@@ -508,6 +541,17 @@
         + SQR(compspec->data[compspec->length - i]) );
   }
-  spectrum->norm[spectrum->length-1] =
-    ABS(compspec->data[compspec->length/2]);
+#ifdef HAVE_FFTW3
+  // for even length, make sure last element is > 0
+  if (2 * (compspec->length / 2) == compspec->length) {
+#endif
+    spectrum->norm[spectrum->length-1] =
+      ABS(compspec->data[compspec->length/2]);
+#ifdef HAVE_FFTW3
+  } else {
+    i = spectrum->length - 1;
+    spectrum->norm[i] = SQRT(SQR(compspec->data[i])
+        + SQR(compspec->data[compspec->length - i]) );
+  }
+#endif
 }
 
