ref: 729a3c09bf4f4bc7ede032f6af70775adfb525a1
parent: e2981382bde272aa2217c8176f78fcb92f0ae31b
author: Paul Brossier <piem@piem.org>
date: Wed Nov 16 12:29:35 EST 2011
add support for ooura so that aubio can be build without fftw
--- a/configure.ac
+++ b/configure.ac
@@ -173,27 +173,38 @@
dnl Check for fftw3 (required)
dnl if we compile in double precsion, default to fftw3, else fftw3f
+
+AC_ARG_ENABLE(fftw3,
+ AC_HELP_STRING([--enable-fftw3],[compile with fftw3 [[default=auto]]]),
+ [with_fftw3=$enableval],
+ with_fftw3="yes")
+
if test "$with_double_precision" = "yes"; then
default_fftw3f="no"
else
- default_fftw3f="yes"
+ default_fftw3f=$with_fftw3
fi
+
AC_ARG_ENABLE(fftw3f,
AC_HELP_STRING([--enable-fftw3f],[compile with fftw3f [[default=auto]]]),
[with_fftw3f=$enableval],
[with_fftw3f=$default_fftw3f])
+
+# check if we have fftw3f
if test "$with_fftw3f" = "yes"; then
PKG_CHECK_MODULES(FFTWLIB, fftw3f >= 3.0.0, HAVE_FFTW3F=1, HAVE_FFTW3F=0)
else
- PKG_CHECK_MODULES(FFTWLIB, fftw3 >= 3.0.0, HAVE_FFTW3=1)
+# check if we have fftw3
+if test "$with_fftw3" = "yes"; then
+ PKG_CHECK_MODULES(FFTWLIB, fftw3 >= 3.0.0, HAVE_FFTW3=1, HAVE_FFTW3=0)
fi
-if test "${HAVE_FFTW3F}" = "0"; then
- PKG_CHECK_MODULES(FFTWLIB, fftw3 >= 3.0.0, HAVE_FFTW3=1)
fi
+
if test "${HAVE_FFTW3}" = "1"; then
AC_DEFINE(HAVE_FFTW3,1,[Define to enable fftw3 support])
fi
if test "${HAVE_FFTW3F}" = "1"; then
+ AC_DEFINE(HAVE_FFTW3,1,[Define to enable fftw3 support])
AC_DEFINE(HAVE_FFTW3F,1,[Define to enable fftw3f support])
fi
@@ -263,12 +274,12 @@
echo "**************************************************************"
echo "Summary:"
if test "${HAVE_FFTW3F}" = "1"; then
- echo "Fftw3: yes (using fftw3f)"
+ echo "FFT: using fftw3f"
else
if test "${HAVE_FFTW3}" = "1"; then
- echo "Fftw3: yes (not using fftw3f)"
+ echo "Fft: using fftw3"
else
- echo "Fftw3: no (that should not happen)"
+ echo "Fft: using ooura"
fi
fi
if test "${HAVE_SNDFILE}" = "1"; then
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -58,6 +58,7 @@
spectral/mfcc.c \
spectral/phasevoc.c \
spectral/fft.c \
+ spectral/ooura_fft8g.c \
spectral/tss.c \
spectral/specdesc.c \
spectral/statistics.c \
--- a/src/mathutils.c
+++ b/src/mathutils.c
@@ -511,11 +511,11 @@
void
aubio_cleanup (void)
{
-#if HAVE_FFTW3
- fftw_cleanup ();
-#else
-#if HAVE_FFTW3F
+#ifdef HAVE_FFTW3F
fftwf_cleanup ();
+#else
+#ifdef HAVE_FFTW3
+ fftw_cleanup ();
#endif
#endif
}
--- a/src/spectral/fft.c
+++ b/src/spectral/fft.c
@@ -24,6 +24,7 @@
#include "mathutils.h"
#include "spectral/fft.h"
+#ifdef HAVE_FFTW3
/* note that <complex.h> is not included here but only in aubio_priv.h, so that
* c++ projects can still use their own complex definition. */
#include <fftw3.h>
@@ -30,7 +31,7 @@
#include <pthread.h>
#ifdef HAVE_COMPLEX_H
-#if HAVE_FFTW3F
+#ifdef HAVE_FFTW3F
/** fft data type with complex.h and fftw3f */
#define FFTW_TYPE fftwf_complex
#else
@@ -38,7 +39,7 @@
#define FFTW_TYPE fftw_complex
#endif
#else
-#if HAVE_FFTW3F
+#ifdef HAVE_FFTW3F
/** fft data type without complex.h and with fftw3f */
#define FFTW_TYPE float
#else
@@ -50,7 +51,7 @@
/** fft data type */
typedef FFTW_TYPE fft_data_t;
-#if HAVE_FFTW3F
+#ifdef HAVE_FFTW3F
#define fftw_malloc fftwf_malloc
#define fftw_free fftwf_free
#define fftw_execute fftwf_execute
@@ -61,13 +62,13 @@
#define fftw_destroy_plan fftwf_destroy_plan
#endif
-#if HAVE_FFTW3F
-#if HAVE_AUBIO_DOUBLE
+#ifdef HAVE_FFTW3F
+#ifdef HAVE_AUBIO_DOUBLE
#warning "Using aubio in double precision with fftw3 in single precision"
#endif /* HAVE_AUBIO_DOUBLE */
#define real_t float
#else /* HAVE_FFTW3F */
-#if !HAVE_AUBIO_DOUBLE
+#ifndef HAVE_AUBIO_DOUBLE
#warning "Using aubio in single precision with fftw3 in double precision"
#endif /* HAVE_AUBIO_DOUBLE */
#define real_t double
@@ -76,18 +77,32 @@
// a global mutex for FFTW thread safety
pthread_mutex_t aubio_fftw_mutex = PTHREAD_MUTEX_INITIALIZER;
+#endif /* HAVE_FFTW3 */
+
struct _aubio_fft_t {
uint_t winsize;
uint_t fft_size;
+#ifdef HAVE_FFTW3
real_t *in, *out;
fftw_plan pfw, pbw;
fft_data_t * specdata; /* complex spectral data */
+#else
+ double *in, *out;
+ double *w;
+ int *ip;
+#endif /* HAVE_FFTW3 */
fvec_t * compspec;
};
-aubio_fft_t * new_aubio_fft(uint_t winsize) {
+#ifndef HAVE_FFTW3
+// let's use ooura instead
+extern void rdft(int, int, double *, int *, double *);
+#endif
+
+aubio_fft_t * new_aubio_fft (uint_t winsize) {
aubio_fft_t * s = AUBIO_NEW(aubio_fft_t);
uint_t i;
+#ifdef HAVE_FFTW3
s->winsize = winsize;
/* allocate memory */
s->in = AUBIO_ARRAY(real_t,winsize);
@@ -114,6 +129,16 @@
for (i = 0; i < s->fft_size; i++) {
s->specdata[i] = 0.;
}
+#else
+ s->winsize = winsize;
+ s->fft_size = winsize / 2 + 1;
+ s->compspec = new_fvec(winsize);
+ s->in = AUBIO_ARRAY(double, s->fft_size);
+ s->out = AUBIO_ARRAY(double, s->fft_size);
+ s->ip = AUBIO_ARRAY(int , s->fft_size);
+ s->w = AUBIO_ARRAY(double, s->fft_size);
+ s->ip[0] = 0;
+#endif
return s;
}
@@ -120,11 +145,16 @@
void del_aubio_fft(aubio_fft_t * s) {
/* destroy data */
del_fvec(s->compspec);
+#ifdef HAVE_FFTW3
fftw_destroy_plan(s->pfw);
fftw_destroy_plan(s->pbw);
fftw_free(s->specdata);
+#else /* HAVE_FFTW3 */
+ AUBIO_FREE(s->w);
+ AUBIO_FREE(s->ip);
+#endif /* HAVE_FFTW3 */
AUBIO_FREE(s->out);
- AUBIO_FREE(s->in );
+ AUBIO_FREE(s->in);
AUBIO_FREE(s);
}
@@ -139,44 +169,68 @@
}
void aubio_fft_do_complex(aubio_fft_t * s, fvec_t * input, fvec_t * compspec) {
- uint_t j;
- for (j=0; j < s->winsize; j++) {
- s->in[j] = input->data[j];
+ uint_t i;
+ for (i=0; i < s->winsize; i++) {
+ s->in[i] = input->data[i];
}
+#ifdef HAVE_FFTW3
fftw_execute(s->pfw);
#ifdef HAVE_COMPLEX_H
compspec->data[0] = REAL(s->specdata[0]);
- for (j = 1; j < s->fft_size -1 ; j++) {
- compspec->data[j] = REAL(s->specdata[j]);
- compspec->data[compspec->length - j] = IMAG(s->specdata[j]);
+ for (i = 1; i < s->fft_size -1 ; i++) {
+ compspec->data[i] = REAL(s->specdata[i]);
+ compspec->data[compspec->length - i] = IMAG(s->specdata[i]);
}
compspec->data[s->fft_size-1] = REAL(s->specdata[s->fft_size-1]);
-#else
- for (j = 0; j < s->fft_size; j++) {
- compspec->data[j] = s->specdata[j];
+#else /* HAVE_COMPLEX_H */
+ for (i = 0; i < s->fft_size; i++) {
+ compspec->data[i] = s->specdata[i];
}
-#endif
+#endif /* HAVE_COMPLEX_H */
+#else /* HAVE_FFTW3 */
+ rdft(s->winsize, 1, s->in, s->ip, s->w);
+ compspec->data[0] = s->in[0];
+ compspec->data[s->winsize / 2] = s->in[1];
+ for (i = 1; i < s->fft_size - 1; i++) {
+ compspec->data[i] = s->in[2 * i];
+ compspec->data[s->winsize - i] = - s->in[2 * i + 1];
+ }
+#endif /* HAVE_FFTW3 */
}
void aubio_fft_rdo_complex(aubio_fft_t * s, fvec_t * compspec, fvec_t * output) {
- uint_t j;
+ uint_t i;
+#ifdef HAVE_FFTW3
const smpl_t renorm = 1./(smpl_t)s->winsize;
#ifdef HAVE_COMPLEX_H
s->specdata[0] = compspec->data[0];
- for (j=1; j < s->fft_size - 1; j++) {
- s->specdata[j] = compspec->data[j] +
- I * compspec->data[compspec->length - j];
+ for (i=1; i < s->fft_size - 1; i++) {
+ s->specdata[i] = compspec->data[i] +
+ I * compspec->data[compspec->length - i];
}
s->specdata[s->fft_size - 1] = compspec->data[s->fft_size - 1];
#else
- for (j=0; j < s->fft_size; j++) {
- s->specdata[j] = compspec->data[j];
+ for (i=0; i < s->fft_size; i++) {
+ s->specdata[i] = compspec->data[i];
}
#endif
fftw_execute(s->pbw);
- for (j = 0; j < output->length; j++) {
- output->data[j] = s->out[j]*renorm;
+ for (i = 0; i < output->length; i++) {
+ output->data[i] = s->out[i]*renorm;
}
+#else /* HAVE_FFTW3 */
+ smpl_t scale = 2.0 / s->winsize;
+ s->out[0] = compspec->data[0];
+ s->out[1] = compspec->data[s->winsize / 2];
+ for (i = 1; i < s->fft_size - 1; i++) {
+ s->out[2 * i] = compspec->data[i];
+ s->out[2 * i + 1] = - compspec->data[s->winsize - i];
+ }
+ rdft(s->winsize, -1, s->out, s->ip, s->w);
+ for (i=0; i < s->winsize; i++) {
+ output->data[i] = s->out[i] * scale;
+ }
+#endif /* HAVE_FFTW3 */
}
void aubio_fft_get_spectrum(fvec_t * compspec, cvec_t * spectrum) {
@@ -190,15 +244,15 @@
}
void aubio_fft_get_phas(fvec_t * compspec, cvec_t * spectrum) {
- uint_t j;
+ uint_t i;
if (compspec->data[0] < 0) {
spectrum->phas[0] = PI;
} else {
spectrum->phas[0] = 0.;
}
- for (j=1; j < spectrum->length - 1; j++) {
- spectrum->phas[j] = ATAN2(compspec->data[compspec->length-j],
- compspec->data[j]);
+ for (i=1; i < spectrum->length - 1; i++) {
+ spectrum->phas[i] = ATAN2(compspec->data[compspec->length-i],
+ compspec->data[i]);
}
if (compspec->data[compspec->length/2] < 0) {
spectrum->phas[spectrum->length - 1] = PI;
@@ -208,28 +262,28 @@
}
void aubio_fft_get_norm(fvec_t * compspec, cvec_t * spectrum) {
- uint_t j = 0;
+ uint_t i = 0;
spectrum->norm[0] = ABS(compspec->data[0]);
- for (j=1; j < spectrum->length - 1; j++) {
- spectrum->norm[j] = SQRT(SQR(compspec->data[j])
- + SQR(compspec->data[compspec->length - j]) );
+ for (i=1; i < spectrum->length - 1; i++) {
+ spectrum->norm[i] = SQRT(SQR(compspec->data[i])
+ + SQR(compspec->data[compspec->length - i]) );
}
- spectrum->norm[spectrum->length-1] =
+ spectrum->norm[spectrum->length-1] =
ABS(compspec->data[compspec->length/2]);
}
void aubio_fft_get_imag(cvec_t * spectrum, fvec_t * compspec) {
- uint_t j;
- for (j = 1; j < ( compspec->length + 1 ) / 2 /*- 1 + 1*/; j++) {
- compspec->data[compspec->length - j] =
- spectrum->norm[j]*SIN(spectrum->phas[j]);
+ uint_t i;
+ for (i = 1; i < ( compspec->length + 1 ) / 2 /*- 1 + 1*/; i++) {
+ compspec->data[compspec->length - i] =
+ spectrum->norm[i]*SIN(spectrum->phas[i]);
}
}
void aubio_fft_get_real(cvec_t * spectrum, fvec_t * compspec) {
- uint_t j;
- for (j = 0; j < compspec->length / 2 + 1; j++) {
- compspec->data[j] =
- spectrum->norm[j]*COS(spectrum->phas[j]);
+ uint_t i;
+ for (i = 0; i < compspec->length / 2 + 1; i++) {
+ compspec->data[i] =
+ spectrum->norm[i]*COS(spectrum->phas[i]);
}
}
--- a/src/wscript_build
+++ b/src/wscript_build
@@ -1,10 +1,17 @@
+uselib = ['SAMPLERATE']
+if 'HAVE_FFTW3' in conf.get_env():
+ source = bld.path.ant_glob('*.c **/*.c', excl = ['**/ooura_fft8g.c'])
+ uselib += ['FFTW3', 'FFTW3F']
+else:
+ source = bld.path.ant_glob('*.c **/*.c')
+
# build libaubio
-libaubio = bld.new_task_gen(
- features = 'c cshlib',
+bld.shlib(
includes = ['.'],
- source = bld.path.ant_glob('*.c **/*.c'),
+ source = source,
target = 'aubio',
- uselib = ['FFTW3', 'FFTW3F', 'SAMPLERATE'],
+ lib = 'm',
+ uselib = uselib,
vnum = bld.env['LIB_VERSION'])
# install headers, except _priv.h ones
--- a/wscript
+++ b/wscript
@@ -30,6 +30,8 @@
def options(opt):
opt.add_option('--enable-double', action='store_true', default=False,
help='compile aubio in double precision mode')
+ opt.add_option('--disable-fftw', action='store_true', default=False,
+ help='compile with ooura instead of fftw')
opt.add_option('--disable-fftw3f', action='store_true', default=False,
help='compile with fftw3 instead of fftw3f')
opt.add_option('--enable-complex', action='store_true', default=False,
@@ -85,18 +87,23 @@
else:
conf.define('HAVE_AUBIO_DOUBLE', 0)
- # one of fftwf or fftw3f
- if (Options.options.disable_fftw3f == True):
- conf.check_cfg(package = 'fftw3', atleast_version = '3.0.0',
- args = '--cflags --libs')
- else:
- # fftw3f not disabled, take most sensible one according to enable_double
- if (Options.options.enable_double == True):
+ if (Options.options.disable_fftw == False):
+ # one of fftwf or fftw3f
+ if (Options.options.disable_fftw3f == True):
conf.check_cfg(package = 'fftw3', atleast_version = '3.0.0',
args = '--cflags --libs')
else:
- conf.check_cfg(package = 'fftw3f', atleast_version = '3.0.0',
- args = '--cflags --libs')
+ # fftw3f not disabled, take most sensible one according to enable_double
+ if (Options.options.enable_double == True):
+ conf.check_cfg(package = 'fftw3', atleast_version = '3.0.0',
+ args = '--cflags --libs')
+ else:
+ conf.check_cfg(package = 'fftw3f', atleast_version = '3.0.0',
+ args = '--cflags --libs')
+ conf.define('HAVE_FFTW3', 1)
+ else:
+ # fftw disabled, use ooura
+ pass
# optional dependancies
if (Options.options.enable_jack == True):
@@ -191,6 +198,5 @@
# phasevoc-jack also needs jack
if str(target_name).endswith('test-phasevoc-jack.c'):
this_target.includes = ['src', 'examples']
- this_target.use = ['aubio']
this_target.uselib = ['JACK']
this_target.target += ' examples/jackio.c'