shithub: aubio

Download patch

ref: 60fc05b3fadd7da5957eb8c531bfa882d35e6568
parent: b257b60e3e1004a168b81130924fdd1ab4a9f0c3
parent: f45dd12cc696444320b8360b0c84650e50324e34
author: Paul Brossier <piem@piem.org>
date: Sat Sep 5 08:27:38 EDT 2015

Merge branch 'develop' into notes

--- a/Makefile
+++ b/Makefile
@@ -7,7 +7,7 @@
 	curl https://waf.io/waf-1.8.12 > waf
 	@[ -d wafilb ] || rm -fr waflib
 	@chmod +x waf && ./waf --help > /dev/null
-	@mv .waf-*/waflib . && rm -fr .waf-*
+	@mv .waf*/waflib . && rm -fr .waf-*
 	@sed '/^#==>$$/,$$d' waf > waf2 && mv waf2 waf
 	@chmod +x waf
 
--- a/doc/aubiomfcc.txt
+++ b/doc/aubiomfcc.txt
@@ -1,5 +1,5 @@
 NAME
-  aubiomfcc - a command line tool to compute Mel-frequency Cepstrum Coefficients
+  aubiomfcc - a command line tool to compute Mel-Frequency Cepstrum Coefficients
 
 SYNOPSIS
 
@@ -10,7 +10,11 @@
 
 DESCRIPTION
 
-  aubiomfcc compute the Mel Frequency Cepstrum Coefficients (MFCC).
+  aubiomfcc compute the Mel-Frequency Cepstrum Coefficients (MFCC).
+
+  MFCCs are coefficients that make up for the mel-frequency spectrum, a
+  representation of the short-term power spectrum of a sound. By default, 13
+  coefficents are computed using 40 filters.
 
   When started with an input source (-i/--input), the coefficients are given on
   the console, prefixed by their timestamps in seconds.
--- a/src/aubio.h
+++ b/src/aubio.h
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2003-2013 Paul Brossier <piem@aubio.org>
+  Copyright (C) 2003-2015 Paul Brossier <piem@aubio.org>
 
   This file is part of aubio.
 
@@ -18,18 +18,18 @@
 
 */
 
-/** \mainpage 
- 
+/** \mainpage
+
   \section introduction Introduction
- 
+
   aubio is a library to extract annotations from audio signals: it provides a
   set of functions that take an input audio signal, and output pitch estimates,
   attack times (onset), beat location estimates, and other annotation tasks.
- 
-  \section basics Basics 
- 
+
+  \section basics Basics
+
   All object structures in aubio share the same function prefixes and suffixes:
-  
+
     - \p new_aubio_foo creates the object \p foo
     - \p aubio_foo_do executes the object \p foo
     - \p del_aubio_foo destroys the object \p foo
@@ -37,7 +37,7 @@
   All memory allocation and deallocation take place in the \p new_ and \p del_
   functions. Optionally, more than one \p _do methods are available.
   Additional parameters can be adjusted and observed using:
-  
+
     - \p aubio_foo_get_param, getter function, gets the value of a parameter
     - \p aubio_foo_set_param, setter function, changes the value of a parameter
 
--- a/src/aubio_priv.h
+++ b/src/aubio_priv.h
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2003-2009 Paul Brossier <piem@aubio.org>
+  Copyright (C) 2003-2015 Paul Brossier <piem@aubio.org>
 
   This file is part of aubio.
 
@@ -20,7 +20,7 @@
 
 /** @file
  * Private include file
- * 
+ *
  * This file is for inclusion from _within_ the library only.
  */
 
@@ -29,7 +29,7 @@
 
 /*********************
  *
- * External includes 
+ * External includes
  *
  */
 
@@ -71,7 +71,7 @@
 #include "mathutils.h"
 
 /****
- * 
+ *
  * SYSTEM INTERFACE
  *
  */
@@ -196,10 +196,14 @@
 /* handy shortcuts */
 #define DB2LIN(g) (POW(10.0,(g)*0.05f))
 #define LIN2DB(v) (20.0*LOG10(v))
-#define SQR(_a)   (_a*_a)
+#define SQR(_a)   ((_a)*(_a))
 
-#define MAX(a,b)  ( a > b ? a : b)
-#define MIN(a,b)  ( a < b ? a : b)
+#ifndef MAX
+#define MAX(a,b)  (((a)>(b))?(a):(b))
+#endif /* MAX */
+#ifndef MIN
+#define MIN(a,b)  (((a)<(b))?(a):(b))
+#endif /* MIN */
 
 #define ELEM_SWAP(a,b) { register smpl_t t=(a);(a)=(b);(b)=t; }
 
--- a/src/cvec.h
+++ b/src/cvec.h
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2003-2013 Paul Brossier <piem@aubio.org>
+  Copyright (C) 2003-2015 Paul Brossier <piem@aubio.org>
 
   This file is part of aubio.
 
--- a/src/fmat.h
+++ b/src/fmat.h
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2009-2013 Paul Brossier <piem@aubio.org>
+  Copyright (C) 2009-2015 Paul Brossier <piem@aubio.org>
 
   This file is part of aubio.
 
@@ -62,7 +62,7 @@
 
   \param s vector to read from
   \param channel channel to read from
-  \param position sample position to read from 
+  \param position sample position to read from
 
 */
 smpl_t fmat_get_sample(fmat_t *s, uint_t channel, uint_t position);
@@ -69,10 +69,10 @@
 
 /** write sample value in a buffer
 
-  \param s vector to write to 
+  \param s vector to write to
   \param data value to write in s->data[channel][position]
-  \param channel channel to write to 
-  \param position sample position to write to 
+  \param channel channel to write to
+  \param position sample position to write to
 
 */
 void  fmat_set_sample(fmat_t *s, smpl_t data, uint_t channel, uint_t position);
@@ -101,9 +101,9 @@
 */
 smpl_t ** fmat_get_data(fmat_t *s);
 
-/** print out fmat data 
+/** print out fmat data
 
-  \param s vector to print out 
+  \param s vector to print out
 
 */
 void fmat_print(fmat_t *s);
@@ -116,7 +116,7 @@
 */
 void fmat_set(fmat_t *s, smpl_t val);
 
-/** set all elements to zero 
+/** set all elements to zero
 
   \param s vector to modify
 
@@ -123,7 +123,7 @@
 */
 void fmat_zeros(fmat_t *s);
 
-/** set all elements to ones 
+/** set all elements to ones
 
   \param s vector to modify
 
@@ -148,7 +148,7 @@
 */
 void fmat_weight(fmat_t *s, fmat_t *weight);
 
-/** make a copy of a matrix 
+/** make a copy of a matrix
 
   \param s source vector
   \param t vector to copy to
--- a/src/fvec.c
+++ b/src/fvec.c
@@ -21,6 +21,19 @@
 #include "aubio_priv.h"
 #include "fvec.h"
 
+#ifdef HAVE_ACCELERATE
+#include <Accelerate/Accelerate.h>
+#if !HAVE_AUBIO_DOUBLE
+#define aubio_vDSP_mmov       vDSP_mmov
+#define aubio_vDSP_vmul       vDSP_vmul
+#define aubio_vDSP_vfill      vDSP_vfill
+#else /* HAVE_AUBIO_DOUBLE */
+#define aubio_vDSP_mmov       vDSP_mmovD
+#define aubio_vDSP_vmul       vDSP_vmulD
+#define aubio_vDSP_vfill      vDSP_vfillD
+#endif /* HAVE_AUBIO_DOUBLE */
+#endif
+
 fvec_t * new_fvec( uint_t length) {
   fvec_t * s;
   if ((sint_t)length <= 0) {
@@ -60,18 +73,26 @@
 }
 
 void fvec_set_all (fvec_t *s, smpl_t val) {
+#ifndef HAVE_ACCELERATE
   uint_t j;
   for (j=0; j< s->length; j++) {
     s->data[j] = val;
   }
+#else
+  aubio_vDSP_vfill(&val, s->data, 1, s->length);
+#endif
 }
 
 void fvec_zeros(fvec_t *s) {
-#if HAVE_MEMCPY_HACKS
+#if !defined(HAVE_MEMCPY_HACKS) && !defined(HAVE_ACCELERATE)
+  fvec_set_all (s, 0.);
+#else
+#if defined(HAVE_MEMCPY_HACKS)
   memset(s->data, 0, s->length * sizeof(smpl_t));
 #else
-  fvec_set_all (s, 0.);
+  aubio_vDSP_vclr(s->data, 1, s->length);
 #endif
+#endif
 }
 
 void fvec_ones(fvec_t *s) {
@@ -86,11 +107,15 @@
 }
 
 void fvec_weight(fvec_t *s, fvec_t *weight) {
+#ifndef HAVE_ACCELERATE
   uint_t j;
   uint_t length = MIN(s->length, weight->length);
   for (j=0; j< length; j++) {
     s->data[j] *= weight->data[j];
   }
+#else
+  aubio_vDSP_vmul(s->data, 1, weight->data, 1, s->data, 1, s->length);
+#endif /* HAVE_ACCELERATE */
 }
 
 void fvec_copy(fvec_t *s, fvec_t *t) {
@@ -99,12 +124,16 @@
         s->length, t->length);
     return;
   }
-#if HAVE_MEMCPY_HACKS
-  memcpy(t->data, s->data, t->length * sizeof(smpl_t));
-#else
+#if !defined(HAVE_MEMCPY_HACKS) && !defined(HAVE_ACCELERATE)
   uint_t j;
   for (j=0; j< t->length; j++) {
     t->data[j] = s->data[j];
   }
+#else
+#if defined(HAVE_MEMCPY_HACKS)
+  memcpy(t->data, s->data, t->length * sizeof(smpl_t));
+#else
+  aubio_vDSP_mmov(s->data, t->data, 1, s->length, 1, 1);
+#endif
 #endif
 }
--- a/src/fvec.h
+++ b/src/fvec.h
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2003-2013 Paul Brossier <piem@aubio.org>
+  Copyright (C) 2003-2015 Paul Brossier <piem@aubio.org>
 
   This file is part of aubio.
 
@@ -86,7 +86,7 @@
 /** read sample value in a buffer
 
   \param s vector to read from
-  \param position sample position to read from 
+  \param position sample position to read from
 
 */
 smpl_t fvec_get_sample(fvec_t *s, uint_t position);
@@ -93,9 +93,9 @@
 
 /** write sample value in a buffer
 
-  \param s vector to write to 
+  \param s vector to write to
   \param data value to write in s->data[position]
-  \param position sample position to write to 
+  \param position sample position to write to
 
 */
 void  fvec_set_sample(fvec_t *s, smpl_t data, uint_t position);
@@ -107,9 +107,9 @@
 */
 smpl_t * fvec_get_data(fvec_t *s);
 
-/** print out fvec data 
+/** print out fvec data
 
-  \param s vector to print out 
+  \param s vector to print out
 
 */
 void fvec_print(fvec_t *s);
@@ -122,7 +122,7 @@
 */
 void fvec_set_all (fvec_t *s, smpl_t val);
 
-/** set all elements to zero 
+/** set all elements to zero
 
   \param s vector to modify
 
@@ -129,7 +129,7 @@
 */
 void fvec_zeros(fvec_t *s);
 
-/** set all elements to ones 
+/** set all elements to ones
 
   \param s vector to modify
 
--- a/src/io/audio_unit.c
+++ b/src/io/audio_unit.c
@@ -19,7 +19,7 @@
 */
 
 #include "config.h"
-#ifdef TARGET_OS_IPHONE
+#ifdef HAVE_AUDIO_UNIT
 #include "aubio_priv.h"
 
 #include "fvec.h"
@@ -774,4 +774,4 @@
   return (int)err;
 }
 
-#endif /* TARGET_OS_IPHONE */
+#endif /* HAVE_AUDIO_UNIT */
--- a/src/io/sink_sndfile.c
+++ b/src/io/sink_sndfile.c
@@ -33,6 +33,12 @@
 #define MAX_CHANNELS 6
 #define MAX_SIZE 4096
 
+#if !HAVE_AUBIO_DOUBLE
+#define aubio_sf_write_smpl sf_write_float
+#else /* HAVE_AUBIO_DOUBLE */
+#define aubio_sf_write_smpl sf_write_double
+#endif /* HAVE_AUBIO_DOUBLE */
+
 struct _aubio_sink_sndfile_t {
   uint_t samplerate;
   uint_t channels;
@@ -125,7 +131,7 @@
     /* show libsndfile err msg */
     AUBIO_ERR("sink_sndfile: Failed opening %s. %s\n", s->path, sf_strerror (NULL));
     return AUBIO_FAIL;
-  }	
+  }
 
   s->scratch_size = s->max_size*s->channels;
   /* allocate data for de/interleaving reallocated when needed. */
@@ -134,13 +140,13 @@
         s->max_size, s->channels, MAX_CHANNELS * MAX_CHANNELS);
     return AUBIO_FAIL;
   }
-  s->scratch_data = AUBIO_ARRAY(float,s->scratch_size);
+  s->scratch_data = AUBIO_ARRAY(smpl_t,s->scratch_size);
 
   return AUBIO_OK;
 }
 
 void aubio_sink_sndfile_do(aubio_sink_sndfile_t *s, fvec_t * write_data, uint_t write){
-  uint_t i, j,	channels = s->channels;
+  uint_t i, j, channels = s->channels;
   int nsamples = 0;
   smpl_t *pwrite;
   sf_count_t written_frames;
@@ -161,7 +167,7 @@
     }
   }
 
-  written_frames = sf_write_float (s->handle, s->scratch_data, nsamples);
+  written_frames = aubio_sf_write_smpl (s->handle, s->scratch_data, nsamples);
   if (written_frames/channels != write) {
     AUBIO_WRN("sink_sndfile: trying to write %d frames to %s, but only %d could be written\n",
       write, s->path, (uint_t)written_frames);
@@ -170,7 +176,7 @@
 }
 
 void aubio_sink_sndfile_do_multi(aubio_sink_sndfile_t *s, fmat_t * write_data, uint_t write){
-  uint_t i, j,	channels = s->channels;
+  uint_t i, j, channels = s->channels;
   int nsamples = 0;
   smpl_t *pwrite;
   sf_count_t written_frames;
@@ -191,7 +197,7 @@
     }
   }
 
-  written_frames = sf_write_float (s->handle, s->scratch_data, nsamples);
+  written_frames = aubio_sf_write_smpl (s->handle, s->scratch_data, nsamples);
   if (written_frames/channels != write) {
     AUBIO_WRN("sink_sndfile: trying to write %d frames to %s, but only %d could be written\n",
       write, s->path, (uint_t)written_frames);
--- a/src/io/source_avcodec.c
+++ b/src/io/source_avcodec.c
@@ -23,6 +23,9 @@
 
 #ifdef HAVE_LIBAV
 
+// determine whether we use libavformat from ffmpe or libav
+#define FFMPEG_LIBAVFORMAT (LIBAVFORMAT_VERSION_MICRO > 99)
+
 #include <libavcodec/avcodec.h>
 #include <libavformat/avformat.h>
 #include <libavresample/avresample.h>
@@ -100,7 +103,11 @@
   }
 
   // try to make sure max_analyze_duration is big enough for most songs
+#if FFMPEG_LIBAVFORMAT
+  avFormatCtx->max_analyze_duration2 *= 100;
+#else
   avFormatCtx->max_analyze_duration *= 100;
+#endif
 
   // retrieve stream information
   if ( (err = avformat_find_stream_info(avFormatCtx, NULL)) < 0 ) {
--- a/src/io/source_sndfile.c
+++ b/src/io/source_sndfile.c
@@ -90,7 +90,7 @@
     /* show libsndfile err msg */
     AUBIO_ERR("source_sndfile: Failed opening %s: %s\n", s->path, sf_strerror (NULL));
     goto beach;
-  }	
+  }
 
   /* get input specs */
   s->input_samplerate = sfinfo.samplerate;
--- a/src/lvec.h
+++ b/src/lvec.h
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2003-2013 Paul Brossier <piem@aubio.org>
+  Copyright (C) 2003-2015 Paul Brossier <piem@aubio.org>
 
   This file is part of aubio.
 
@@ -61,7 +61,7 @@
 /** read sample value in a buffer
 
   \param s vector to read from
-  \param position sample position to read from 
+  \param position sample position to read from
 
 */
 lsmp_t lvec_get_sample(lvec_t *s, uint_t position);
@@ -68,9 +68,9 @@
 
 /** write sample value in a buffer
 
-  \param s vector to write to 
+  \param s vector to write to
   \param data value to write in s->data[position]
-  \param position sample position to write to 
+  \param position sample position to write to
 
 */
 void  lvec_set_sample(lvec_t *s, lsmp_t data, uint_t position);
@@ -82,9 +82,9 @@
 */
 lsmp_t * lvec_get_data(lvec_t *s);
 
-/** print out lvec data 
+/** print out lvec data
 
-  \param s vector to print out 
+  \param s vector to print out
 
 */
 void lvec_print(lvec_t *s);
@@ -97,7 +97,7 @@
 */
 void lvec_set_all(lvec_t *s, smpl_t val);
 
-/** set all elements to zero 
+/** set all elements to zero
 
   \param s vector to modify
 
@@ -104,7 +104,7 @@
 */
 void lvec_zeros(lvec_t *s);
 
-/** set all elements to ones 
+/** set all elements to ones
 
   \param s vector to modify
 
--- a/src/mathutils.c
+++ b/src/mathutils.c
@@ -158,22 +158,39 @@
 smpl_t
 fvec_mean (fvec_t * s)
 {
-  uint_t j;
   smpl_t tmp = 0.0;
+#ifndef HAVE_ACCELERATE
+  uint_t j;
   for (j = 0; j < s->length; j++) {
     tmp += s->data[j];
   }
   return tmp / (smpl_t) (s->length);
+#else
+#if !HAVE_AUBIO_DOUBLE
+  vDSP_meanv(s->data, 1, &tmp, s->length);
+#else /* HAVE_AUBIO_DOUBLE */
+  vDSP_meanvD(s->data, 1, &tmp, s->length);
+#endif /* HAVE_AUBIO_DOUBLE */
+  return tmp;
+#endif /* HAVE_ACCELERATE */
 }
 
 smpl_t
 fvec_sum (fvec_t * s)
 {
-  uint_t j;
   smpl_t tmp = 0.0;
+#ifndef HAVE_ACCELERATE
+  uint_t j;
   for (j = 0; j < s->length; j++) {
     tmp += s->data[j];
   }
+#else
+#if !HAVE_AUBIO_DOUBLE
+  vDSP_sve(s->data, 1, &tmp, s->length);
+#else /* HAVE_AUBIO_DOUBLE */
+  vDSP_sveD(s->data, 1, &tmp, s->length);
+#endif /* HAVE_AUBIO_DOUBLE */
+#endif /* HAVE_ACCELERATE */
   return tmp;
 }
 
--- a/src/mathutils.h
+++ b/src/mathutils.h
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2003-2014 Paul Brossier <piem@aubio.org>
+  Copyright (C) 2003-2015 Paul Brossier <piem@aubio.org>
 
   This file is part of aubio.
 
@@ -82,20 +82,20 @@
 uint_t fvec_max_elem (fvec_t * s);
 
 /** swap the left and right halves of a vector
-  
+
   This function swaps the left part of the signal with the right part of the
 signal. Therefore
 
   \f$ a[0], a[1], ..., a[\frac{N}{2}], a[\frac{N}{2}+1], ..., a[N-1], a[N] \f$
-  
+
   becomes
-  
+
   \f$ a[\frac{N}{2}+1], ..., a[N-1], a[N], a[0], a[1], ..., a[\frac{N}{2}] \f$
 
   This operation, known as 'fftshift' in the Matlab Signal Processing Toolbox,
 can be used before computing the FFT to simplify the phase relationship of the
 resulting spectrum. See Amalia de Götzen's paper referred to above.
-  
+
 */
 void fvec_shift (fvec_t * v);
 
@@ -111,20 +111,20 @@
 /** compute the High Frequency Content of a vector
 
   The High Frequency Content is defined as \f$ \sum_0^{N-1} (k+1) v[k] \f$.
- 
-  \param v vector to get the energy from 
 
+  \param v vector to get the energy from
+
   \return the HFC of v
- 
+
 */
 smpl_t fvec_local_hfc (fvec_t * v);
 
-/** computes the p-norm of a vector 
- 
+/** computes the p-norm of a vector
+
   Computes the p-norm of a vector for \f$ p = \alpha \f$
 
   \f$ L^p = ||x||_p = (|x_1|^p + |x_2|^p + ... + |x_n|^p ) ^ \frac{1}{p} \f$
-  
+
   If p = 1, the result is the Manhattan distance.
 
   If p = 2, the result is the Euclidean distance.
@@ -133,7 +133,7 @@
 input vector.
 
   References:
-  
+
     - <a href="http://en.wikipedia.org/wiki/Lp_space">\f$L^p\f$ space</a> on
   Wikipedia
 
@@ -141,13 +141,13 @@
   \param p order of the computed norm
 
   \return the p-norm of v
- 
+
 */
 smpl_t fvec_alpha_norm (fvec_t * v, smpl_t p);
 
 /**  alpha normalisation
 
-  This function divides all elements of a vector by the p-norm as computed by 
+  This function divides all elements of a vector by the p-norm as computed by
 fvec_alpha_norm().
 
   \param v vector to compute norm from
@@ -165,7 +165,7 @@
 void fvec_add (fvec_t * v, smpl_t c);
 
 /** remove the minimum value of the vector to each elements
-  
+
   \param v vector to remove minimum from
 
 */
@@ -176,14 +176,14 @@
   This function computes the moving median threshold value of at the given
 position of a vector, taking the median among post elements before and up to
 pre elements after pos.
- 
+
   \param v input vector
   \param tmp temporary vector of length post+1+pre
-  \param post length of causal part to take before pos 
+  \param post length of causal part to take before pos
   \param pre length of anti-causal part to take after pos
-  \param pos index to compute threshold for 
+  \param pos index to compute threshold for
 
-  \return moving median threshold value 
+  \return moving median threshold value
 
 */
 smpl_t fvec_moving_thres (fvec_t * v, fvec_t * tmp, uint_t post, uint_t pre,
@@ -196,13 +196,13 @@
 
   \param v input vector
   \param tmp temporary vector of length post+1+pre
-  \param post length of causal part to take before pos 
+  \param post length of causal part to take before pos
   \param pre length of anti-causal part to take after pos
 
 */
 void fvec_adapt_thres (fvec_t * v, fvec_t * tmp, uint_t post, uint_t pre);
 
-/** returns the median of a vector 
+/** returns the median of a vector
 
   The QuickSelect routine is based on the algorithm described in "Numerical
 recipes in C", Second Edition, Cambridge University Press, 1992, Section 8.5,
@@ -215,7 +215,7 @@
   \param v vector to get median from
 
   \return the median of v
- 
+
 */
 smpl_t fvec_median (fvec_t * v);
 
@@ -248,13 +248,13 @@
 smpl_t fvec_quadratic_peak_mag (fvec_t * x, smpl_t p);
 
 /** Quadratic interpolation using Lagrange polynomial.
- 
+
   Inspired from ``Comparison of interpolation algorithms in real-time sound
-processing'', Vladimir Arnost, 
-  
-  \param s0,s1,s2 are 3 consecutive samples of a curve 
+processing'', Vladimir Arnost,
+
+  \param s0,s1,s2 are 3 consecutive samples of a curve
   \param pf is the floating point index [0;2]
- 
+
   \return \f$ s0 + (pf/2.)*((pf-3.)*s0-2.*(pf-2.)*s1+(pf-1.)*s2); \f$
 
 */
--- a/src/musicutils.h
+++ b/src/musicutils.h
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2003-2013 Paul Brossier <piem@aubio.org>
+  Copyright (C) 2003-2015 Paul Brossier <piem@aubio.org>
 
   This file is part of aubio.
 
@@ -29,11 +29,11 @@
 extern "C" {
 #endif
 
-/** create window 
+/** create window
 
   \param window_type type of the window to create
   \param size length of the window to create (see fvec_set_window())
- 
+
 */
 fvec_t *new_aubio_window (char_t * window_type, uint_t size);
 
@@ -49,7 +49,7 @@
   "default" is equivalent to "hanningz".
 
   References:
-    
+
     - <a href="http://en.wikipedia.org/wiki/Window_function">Window
 function</a> on Wikipedia
     - Amalia de Götzen, Nicolas Bernardini, and Daniel Arfib. Traditional (?)
@@ -68,7 +68,7 @@
 range \f$ [-\pi, \pi] \f$.
 
   \param phase unwrapped phase to map to the unit circle
-  
+
   \return equivalent phase wrapped to the unit circle
 
 */
@@ -93,7 +93,7 @@
 smpl_t aubio_miditofreq (smpl_t midi);
 
 /** clean up cached memory at the end of program
- 
+
   This function should be used at the end of programs to purge all cached
   memory. So far it is only useful to clean FFTW's cache.
 
@@ -137,7 +137,7 @@
 smpl_t aubio_db_spl (fvec_t * v);
 
 /** check if buffer level in dB SPL is under a given threshold
- 
+
   \param v vector to get level from
   \param threshold threshold in dB SPL
 
--- a/src/onset/onset.c
+++ b/src/onset/onset.c
@@ -67,11 +67,16 @@
       }
     }
   } else {
-    // we are at the beginning of the file, and we don't find silence
-    if (o->total_frames <= o->delay && o->last_onset < o ->minioi && aubio_silence_detection(input, o->silence) == 0) {
-      //AUBIO_DBG ("beginning of file is not silent, marking as onset\n");
-      isonset = o->delay / o->hop_size;
-      o->last_onset = o->delay;
+    // we are at the beginning of the file
+    if (o->total_frames <= o->delay) {
+      // and we don't find silence
+      if (aubio_silence_detection(input, o->silence) == 0) {
+        uint_t new_onset = o->total_frames;
+        if (o->total_frames == 0 || o->last_onset + o->minioi < new_onset) {
+          isonset = o->delay / o->hop_size;
+          o->last_onset = o->total_frames + o->delay;
+        }
+      }
     }
   }
   onset->data[0] = isonset;
--- a/src/onset/peakpicker.h
+++ b/src/onset/peakpicker.h
@@ -18,12 +18,12 @@
 
 */
 
-/** \file 
- 
+/** \file
+
   Peak picking utilities function
 
   \example onset/test-peakpicker.c
-  
+
 */
 
 #ifndef _AUBIO_PEAKPICK_H
--- a/src/pitch/pitchyinfft.h
+++ b/src/pitch/pitchyinfft.h
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2003-2013 Paul Brossier <piem@aubio.org>
+  Copyright (C) 2003-2015 Paul Brossier <piem@aubio.org>
 
   This file is part of aubio.
 
@@ -19,14 +19,14 @@
 */
 
 /** \file
- 
+
   Pitch detection using a spectral implementation of the YIN algorithm
-  
+
   This algorithm was derived from the YIN algorithm. In this implementation, a
   Fourier transform is used to compute a tapered square difference function,
   which allows spectral weighting. Because the difference function is tapered,
   the selection of the period is simplified.
- 
+
   Paul Brossier, [Automatic annotation of musical audio for interactive
   systems](http://aubio.org/phd/), Chapter 3, Pitch Analysis, PhD thesis,
   Centre for Digital music, Queen Mary University of London, London, UK, 2006.
@@ -45,40 +45,40 @@
 /** pitch detection object */
 typedef struct _aubio_pitchyinfft_t aubio_pitchyinfft_t;
 
-/** execute pitch detection on an input buffer 
- 
+/** execute pitch detection on an input buffer
+
   \param o pitch detection object as returned by new_aubio_pitchyinfft
   \param samples_in input signal vector (length as specified at creation time)
   \param cands_out pitch period candidates, in samples
- 
+
 */
 void aubio_pitchyinfft_do (aubio_pitchyinfft_t * o, fvec_t * samples_in, fvec_t * cands_out);
 /** creation of the pitch detection object
- 
+
   \param samplerate samplerate of the input signal
-  \param buf_size size of the input buffer to analyse 
- 
+  \param buf_size size of the input buffer to analyse
+
 */
 aubio_pitchyinfft_t *new_aubio_pitchyinfft (uint_t samplerate, uint_t buf_size);
 /** deletion of the pitch detection object
- 
+
   \param o pitch detection object as returned by new_aubio_pitchyinfft()
- 
+
 */
 void del_aubio_pitchyinfft (aubio_pitchyinfft_t * o);
 
-/** get tolerance parameter for YIN algorithm 
-  
-  \param o YIN pitch detection object 
+/** get tolerance parameter for YIN algorithm
 
+  \param o YIN pitch detection object
+
   \return tolerance parameter for minima selection [default 0.15]
 
 */
 smpl_t aubio_pitchyinfft_get_tolerance (aubio_pitchyinfft_t * o);
 
-/** set tolerance parameter for YIN algorithm 
-  
-  \param o YIN pitch detection object 
+/** set tolerance parameter for YIN algorithm
+
+  \param o YIN pitch detection object
   \param tol tolerance parameter for minima selection [default 0.15]
 
 */
--- a/src/spectral/fft.c
+++ b/src/spectral/fft.c
@@ -66,12 +66,12 @@
 #if HAVE_AUBIO_DOUBLE
 #warning "Using aubio in double precision with fftw3 in single precision"
 #endif /* HAVE_AUBIO_DOUBLE */
-#define real_t float 
+#define real_t float
 #else /* HAVE_FFTW3F */
 #if !HAVE_AUBIO_DOUBLE
 #warning "Using aubio in single precision with fftw3 in double precision"
 #endif /* HAVE_AUBIO_DOUBLE */
-#define real_t double 
+#define real_t double
 #endif /* HAVE_FFTW3F */
 
 // a global mutex for FFTW thread safety
@@ -82,6 +82,36 @@
 // https://developer.apple.com/library/mac/#documentation/Accelerate/Reference/vDSPRef/Reference/reference.html
 #include <Accelerate/Accelerate.h>
 
+#if !HAVE_AUBIO_DOUBLE
+#define aubio_vDSP_ctoz                vDSP_ctoz
+#define aubio_vDSP_fft_zrip            vDSP_fft_zrip
+#define aubio_vDSP_ztoc                vDSP_ztoc
+#define aubio_vDSP_zvmags              vDSP_zvmags
+#define aubio_vDSP_zvphas              vDSP_zvphas
+#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_vvsqrt                   vvsqrtf
+#else
+#define aubio_vDSP_ctoz                vDSP_ctozD
+#define aubio_vDSP_fft_zrip            vDSP_fft_zripD
+#define aubio_vDSP_ztoc                vDSP_ztocD
+#define aubio_vDSP_zvmags              vDSP_zvmagsD
+#define aubio_vDSP_zvphas              vDSP_zvphasD
+#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_vvsqrt                   vvsqrt
+#endif /* HAVE_AUBIO_DOUBLE */
+
 #else                         // using OOURA
 // let's use ooura instead
 extern void rdft(int, int, smpl_t *, int *, smpl_t *);
@@ -95,19 +125,13 @@
 #ifdef HAVE_FFTW3             // using FFTW3
   real_t *in, *out;
   fftw_plan pfw, pbw;
-  fft_data_t * specdata;     /* complex spectral data */
+  fft_data_t * specdata;      /* complex spectral data */
 #else
 #ifdef HAVE_ACCELERATE        // using ACCELERATE
   int log2fftsize;
-#if !HAVE_AUBIO_DOUBLE
-  FFTSetup fftSetup;
-  DSPSplitComplex spec;
-  float *in, *out;
-#else
-  FFTSetupD fftSetup;
-  DSPDoubleSplitComplex spec;
-  double *in, *out;
-#endif
+  aubio_FFTSetup fftSetup;
+  aubio_DSPSplitComplex spec;
+  smpl_t *in, *out;
 #else                         // using OOURA
   smpl_t *in, *out;
   smpl_t *w;
@@ -119,6 +143,10 @@
 
 aubio_fft_t * new_aubio_fft (uint_t winsize) {
   aubio_fft_t * s = AUBIO_NEW(aubio_fft_t);
+  if ((sint_t)winsize < 1) {
+    AUBIO_ERR("fft: got winsize %d, but can not be < 1\n", winsize);
+    goto beach;
+  }
 #ifdef HAVE_FFTW3
   uint_t i;
   s->winsize  = winsize;
@@ -153,20 +181,17 @@
   s->fft_size = winsize;
   s->compspec = new_fvec(winsize);
   s->log2fftsize = (uint_t)log2f(s->fft_size);
-#if !HAVE_AUBIO_DOUBLE
-  s->in = AUBIO_ARRAY(float, s->fft_size);
-  s->out = AUBIO_ARRAY(float, s->fft_size);
-  s->spec.realp = AUBIO_ARRAY(float, s->fft_size/2);
-  s->spec.imagp = AUBIO_ARRAY(float, s->fft_size/2);
-  s->fftSetup = vDSP_create_fftsetup(s->log2fftsize, FFT_RADIX2);
-#else
-  s->in = AUBIO_ARRAY(double, s->fft_size);
-  s->out = AUBIO_ARRAY(double, s->fft_size);
-  s->spec.realp = AUBIO_ARRAY(double, s->fft_size/2);
-  s->spec.imagp = AUBIO_ARRAY(double, s->fft_size/2);
-  s->fftSetup = vDSP_create_fftsetupD(s->log2fftsize, FFT_RADIX2);
-#endif
+  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);
 #else                         // using OOURA
+  if (aubio_is_power_of_two(winsize) != 1) {
+    AUBIO_ERR("fft: can only create with sizes power of two,"
+              " requested %d\n", winsize);
+    goto beach;
+  }
   s->winsize = winsize;
   s->fft_size = winsize / 2 + 1;
   s->compspec = new_fvec(winsize);
@@ -178,6 +203,9 @@
 #endif /* HAVE_ACCELERATE */
 #endif /* HAVE_FFTW3 */
   return s;
+beach:
+  AUBIO_FREE(s);
+  return NULL;
 }
 
 void del_aubio_fft(aubio_fft_t * s) {
@@ -191,11 +219,7 @@
 #ifdef HAVE_ACCELERATE        // using ACCELERATE
   AUBIO_FREE(s->spec.realp);
   AUBIO_FREE(s->spec.imagp);
-#if !HAVE_AUBIO_DOUBLE
-  vDSP_destroy_fftsetup(s->fftSetup);
-#else
-  vDSP_destroy_fftsetupD(s->fftSetup);
-#endif
+  aubio_vDSP_destroy_fftsetup(s->fftSetup);
 #else                         // using OOURA
   AUBIO_FREE(s->w);
   AUBIO_FREE(s->ip);
@@ -218,9 +242,13 @@
 
 void aubio_fft_do_complex(aubio_fft_t * s, fvec_t * input, fvec_t * compspec) {
   uint_t i;
+#ifndef HAVE_MEMCPY_HACKS
   for (i=0; i < s->winsize; i++) {
     s->in[i] = input->data[i];
   }
+#else
+  memcpy(s->in, input->data, s->winsize * sizeof(smpl_t));
+#endif /* HAVE_MEMCPY_HACKS */
 #ifdef HAVE_FFTW3             // using FFTW3
   fftw_execute(s->pfw);
 #ifdef HAVE_COMPLEX_H
@@ -237,17 +265,10 @@
 #endif /* HAVE_COMPLEX_H */
 #else /* HAVE_FFTW3 */
 #ifdef HAVE_ACCELERATE        // using ACCELERATE
-#if !HAVE_AUBIO_DOUBLE
   // convert real data to even/odd format used in vDSP
-  vDSP_ctoz((DSPComplex*)s->in, 2, &s->spec, 1, s->fft_size/2);
+  aubio_vDSP_ctoz((aubio_DSPComplex*)s->in, 2, &s->spec, 1, s->fft_size/2);
   // compute the FFT
-  vDSP_fft_zrip(s->fftSetup, &s->spec, 1, s->log2fftsize, FFT_FORWARD);
-#else
-  // convert real data to even/odd format used in vDSP
-  vDSP_ctozD((DSPDoubleComplex*)s->in, 2, &s->spec, 1, s->fft_size/2);
-  // compute the FFT
-  vDSP_fft_zripD(s->fftSetup, &s->spec, 1, s->log2fftsize, FFT_FORWARD);
-#endif
+  aubio_vDSP_fft_zrip(s->fftSetup, &s->spec, 1, s->log2fftsize, FFT_FORWARD);
   // convert from vDSP complex split to [ r0, r1, ..., rN, iN-1, .., i2, i1]
   compspec->data[0] = s->spec.realp[0];
   compspec->data[s->fft_size / 2] = s->spec.imagp[0];
@@ -257,11 +278,7 @@
   }
   // apply scaling
   smpl_t scale = 1./2.;
-#if !HAVE_AUBIO_DOUBLE
-  vDSP_vsmul(compspec->data, 1, &scale, compspec->data, 1, s->fft_size);
-#else
-  vDSP_vsmulD(compspec->data, 1, &scale, compspec->data, 1, s->fft_size);
-#endif
+  aubio_vDSP_vsmul(compspec->data, 1, &scale, compspec->data, 1, s->fft_size);
 #else                         // using OOURA
   rdft(s->winsize, 1, s->in, s->ip, s->w);
   compspec->data[0] = s->in[0];
@@ -304,27 +321,15 @@
     s->out[2 * i] = compspec->data[i];
     s->out[2 * i + 1] = compspec->data[s->winsize - i];
   }
-#if !HAVE_AUBIO_DOUBLE
   // convert to split complex format used in vDSP
-  vDSP_ctoz((DSPComplex*)s->out, 2, &s->spec, 1, s->fft_size/2);
+  aubio_vDSP_ctoz((aubio_DSPComplex*)s->out, 2, &s->spec, 1, s->fft_size/2);
   // compute the FFT
-  vDSP_fft_zrip(s->fftSetup, &s->spec, 1, s->log2fftsize, FFT_INVERSE);
+  aubio_vDSP_fft_zrip(s->fftSetup, &s->spec, 1, s->log2fftsize, FFT_INVERSE);
   // convert result to real output
-  vDSP_ztoc(&s->spec, 1, (DSPComplex*)output->data, 2, s->fft_size/2);
+  aubio_vDSP_ztoc(&s->spec, 1, (aubio_DSPComplex*)output->data, 2, s->fft_size/2);
   // apply scaling
   smpl_t scale = 1.0 / s->winsize;
-  vDSP_vsmul(output->data, 1, &scale, output->data, 1, s->fft_size);
-#else
-  // convert to split complex format used in vDSP
-  vDSP_ctozD((DSPDoubleComplex*)s->out, 2, &s->spec, 1, s->fft_size/2);
-  // compute the FFT
-  vDSP_fft_zripD(s->fftSetup, &s->spec, 1, s->log2fftsize, FFT_INVERSE);
-  // convert result to real output
-  vDSP_ztocD(&s->spec, 1, (DSPDoubleComplex*)output->data, 2, s->fft_size/2);
-  // apply scaling
-  smpl_t scale = 1.0 / s->winsize;
-  vDSP_vsmulD(output->data, 1, &scale, output->data, 1, s->fft_size);
-#endif
+  aubio_vDSP_vsmul(output->data, 1, &scale, output->data, 1, s->fft_size);
 #else                         // using OOURA
   smpl_t scale = 2.0 / s->winsize;
   s->out[0] = compspec->data[0];
@@ -391,7 +396,7 @@
 void aubio_fft_get_real(cvec_t * spectrum, fvec_t * compspec) {
   uint_t i;
   for (i = 0; i < compspec->length / 2 + 1; i++) {
-    compspec->data[i] = 
+    compspec->data[i] =
       spectrum->norm[i]*COS(spectrum->phas[i]);
   }
 }
--- a/src/spectral/fft.h
+++ b/src/spectral/fft.h
@@ -18,7 +18,7 @@
 
 */
 
-/** \file 
+/** \file
 
   Fast Fourier Transform
 
@@ -39,7 +39,7 @@
 #endif
 
 /** FFT object
- 
+
   This object computes forward and backward FFTs.
 
 */
@@ -51,7 +51,7 @@
 
 */
 aubio_fft_t * new_aubio_fft (uint_t size);
-/** delete FFT object 
+/** delete FFT object
 
   \param s fft object as returned by new_aubio_fft
 
@@ -61,8 +61,8 @@
 /** compute forward FFT
 
   \param s fft object as returned by new_aubio_fft
-  \param input input signal 
-  \param spectrum output spectrum 
+  \param input input signal
+  \param spectrum output spectrum
 
 */
 void aubio_fft_do (aubio_fft_t *s, fvec_t * input, cvec_t * spectrum);
@@ -69,8 +69,8 @@
 /** compute backward (inverse) FFT
 
   \param s fft object as returned by new_aubio_fft
-  \param spectrum input spectrum 
-  \param output output signal 
+  \param spectrum input spectrum
+  \param output output signal
 
 */
 void aubio_fft_rdo (aubio_fft_t *s, cvec_t * spectrum, fvec_t * output);
@@ -78,7 +78,7 @@
 /** compute forward FFT
 
   \param s fft object as returned by new_aubio_fft
-  \param input real input signal 
+  \param input real input signal
   \param compspec complex output fft real/imag
 
 */
@@ -86,53 +86,53 @@
 /** compute backward (inverse) FFT from real/imag
 
   \param s fft object as returned by new_aubio_fft
-  \param compspec real/imag input fft array 
-  \param output real output array 
+  \param compspec real/imag input fft array
+  \param output real output array
 
 */
 void aubio_fft_rdo_complex (aubio_fft_t *s, fvec_t * compspec, fvec_t * output);
 
-/** convert real/imag spectrum to norm/phas spectrum 
+/** convert real/imag spectrum to norm/phas spectrum
 
-  \param compspec real/imag input fft array 
-  \param spectrum cvec norm/phas output array 
+  \param compspec real/imag input fft array
+  \param spectrum cvec norm/phas output array
 
 */
 void aubio_fft_get_spectrum(fvec_t * compspec, cvec_t * spectrum);
-/** convert real/imag spectrum to norm/phas spectrum 
+/** convert real/imag spectrum to norm/phas spectrum
 
-  \param compspec real/imag input fft array 
-  \param spectrum cvec norm/phas output array 
+  \param compspec real/imag input fft array
+  \param spectrum cvec norm/phas output array
 
 */
 void aubio_fft_get_realimag(cvec_t * spectrum, fvec_t * compspec);
 
-/** compute phas spectrum from real/imag parts 
+/** compute phas spectrum from real/imag parts
 
-  \param compspec real/imag input fft array 
-  \param spectrum cvec norm/phas output array 
+  \param compspec real/imag input fft array
+  \param spectrum cvec norm/phas output array
 
 */
 void aubio_fft_get_phas(fvec_t * compspec, cvec_t * spectrum);
-/** compute imaginary part from the norm/phas cvec 
+/** compute imaginary part from the norm/phas cvec
 
-  \param spectrum norm/phas input array 
-  \param compspec real/imag output fft array 
+  \param spectrum norm/phas input array
+  \param compspec real/imag output fft array
 
 */
 void aubio_fft_get_imag(cvec_t * spectrum, fvec_t * compspec);
 
-/** compute norm component from real/imag parts 
+/** compute norm component from real/imag parts
 
-  \param compspec real/imag input fft array 
-  \param spectrum cvec norm/phas output array 
+  \param compspec real/imag input fft array
+  \param spectrum cvec norm/phas output array
 
 */
 void aubio_fft_get_norm(fvec_t * compspec, cvec_t * spectrum);
-/** compute real part from norm/phas components 
+/** compute real part from norm/phas components
 
-  \param spectrum norm/phas input array 
-  \param compspec real/imag output fft array 
+  \param spectrum norm/phas input array
+  \param compspec real/imag output fft array
 
 */
 void aubio_fft_get_real(cvec_t * spectrum, fvec_t * compspec);
--- a/src/spectral/filterbank_mel.h
+++ b/src/spectral/filterbank_mel.h
@@ -58,7 +58,7 @@
   \param samplerate audio sampling rate
 
   The filter coefficients are built according to Malcolm Slaney's Auditory
-  Toolbox, available at http://cobweb.ecn.purdue.edu/~malcolm/interval/1998-010/
+  Toolbox, available at http://engineering.purdue.edu/~malcolm/interval/1998-010/
   (see file mfcc.m).
 
 */
--- a/src/spectral/mfcc.h
+++ b/src/spectral/mfcc.h
@@ -21,7 +21,14 @@
 
 /** \file
 
-  Mel-frequency cepstrum coefficients object
+  Mel-Frequency Cepstrum Coefficients object
+
+  This object computes MFCC coefficients on an input cvec_t.
+
+  The implementation follows the specifications established by Malcolm Slaney
+  in its Auditory Toolbox, available online (see file mfcc.m).
+
+  http://engineering.ecn.purdue.edu/~malcolm/interval/1998-010/
 
   \example spectral/test-mfcc.c
 
--- a/src/spectral/phasevoc.h
+++ b/src/spectral/phasevoc.h
@@ -56,7 +56,7 @@
 void del_aubio_pvoc(aubio_pvoc_t *pv);
 
 /** compute spectral frame
-  
+
   This function accepts an input vector of size [hop_s]. The
   analysis buffer is rotated and filled with the new data. After windowing of
   this signal window, the Fourier transform is computed and returned in
@@ -63,7 +63,7 @@
   fftgrain as two vectors, magnitude and phase.
 
   \param pv phase vocoder object as returned by new_aubio_pvoc
-  \param in new input signal (hop_s long) 
+  \param in new input signal (hop_s long)
   \param fftgrain output spectral frame
 
 */
@@ -74,10 +74,10 @@
   [buf_s] and computes its inverse Fourier transform. Overlap-add
   synthesis is then computed using the previously synthetised frames, and the
   output stored in out.
-  
+
   \param pv phase vocoder object as returned by new_aubio_pvoc
   \param fftgrain input spectral frame
-  \param out output signal (hop_s long) 
+  \param out output signal (hop_s long)
 
 */
 void aubio_pvoc_rdo(aubio_pvoc_t *pv, cvec_t * fftgrain, fvec_t *out);
@@ -97,6 +97,6 @@
 
 #ifdef __cplusplus
 }
-#endif 
+#endif
 
 #endif /* _AUBIO_PHASEVOC_H */
--- a/src/spectral/tss.h
+++ b/src/spectral/tss.h
@@ -62,7 +62,7 @@
 void del_aubio_tss (aubio_tss_t * o);
 
 /** split input into transient and steady states components
- 
+
   \param o tss object as returned by new_aubio_tss()
   \param input input spectral frame
   \param trans output transient components
@@ -72,8 +72,8 @@
 void aubio_tss_do (aubio_tss_t * o, cvec_t * input, cvec_t * trans,
     cvec_t * stead);
 
-/** set transient / steady state separation threshold 
- 
+/** set transient / steady state separation threshold
+
   \param o tss object as returned by new_aubio_tss()
   \param thrs new threshold value
 
@@ -81,7 +81,7 @@
 uint_t aubio_tss_set_threshold (aubio_tss_t * o, smpl_t thrs);
 
 /** set parameter a, defaults to 3
- 
+
   \param o tss object as returned by new_aubio_tss()
   \param alpha new value for alpha parameter
 
@@ -89,7 +89,7 @@
 uint_t aubio_tss_set_alpha (aubio_tss_t * o, smpl_t alpha);
 
 /** set parameter b, defaults to 3
- 
+
   \param o tss object as returned by new_aubio_tss()
   \param beta new value for beta parameter
 
--- a/src/tempo/beattracking.c
+++ b/src/tempo/beattracking.c
@@ -135,8 +135,8 @@
   //number of harmonics in shift invariant comb filterbank
   uint_t numelem = 4;
 
-  smpl_t phase;                 // beat alignment (step - lastbeat) 
-  smpl_t beat;                  // beat position 
+  smpl_t phase;                 // beat alignment (step - lastbeat)
+  smpl_t beat;                  // beat position
   smpl_t bp;                    // beat period
   uint_t a, b;                  // used to build shift invariant comb filterbank
   uint_t kmax;                  // number of elements used to find beat phase
@@ -226,7 +226,7 @@
   i = 1;
   beat = bp - phase;
 
-  // AUBIO_DBG ("bp: %f, phase: %f, lastbeat: %f, step: %d, winlen: %d\n", 
+  // AUBIO_DBG ("bp: %f, phase: %f, lastbeat: %f, step: %d, winlen: %d\n",
   //    bp, phase, bt->lastbeat, step, winlen);
 
   /* the next beat will be earlier than 60% of the tempo period
@@ -318,7 +318,7 @@
     gp = 0;
   }
 
-  //now look for step change - i.e. a difference between gp and rp that 
+  //now look for step change - i.e. a difference between gp and rp that
   // is greater than 2*constthresh - always true in first case, since gp = 0
   if (counter == 0) {
     if (ABS (gp - rp) > 2. * bt->g_var) {
@@ -341,7 +341,7 @@
       counter = 2;              // let it look next time
     }
   } else if (counter > 0) {
-    //if counter doesn't = 1, 
+    //if counter doesn't = 1,
     counter = counter - 1;
   }
 
--- a/src/tempo/beattracking.h
+++ b/src/tempo/beattracking.h
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2003-2013 Matthew Davies and Paul Brossier <piem@aubio.org>
+  Copyright (C) 2003-2015 Matthew Davies and Paul Brossier <piem@aubio.org>
 
   This file is part of aubio.
 
@@ -34,7 +34,7 @@
   Engeeniring Society 118th Convention, Barcelona, Spain, May 2005.
 
   \example tempo/test-beattracking.c
-  
+
 */
 #ifndef _AUBIO_BEATTRACKING_H
 #define _AUBIO_BEATTRACKING_H
@@ -49,7 +49,7 @@
 /** create beat tracking object
 
   \param winlen length of the onset detection window
-  \param hop_size number of onset detection samples [512] 
+  \param hop_size number of onset detection samples [512]
   \param samplerate samplerate of the input signal
 
 */
@@ -56,12 +56,12 @@
 aubio_beattracking_t * new_aubio_beattracking(uint_t winlen, uint_t hop_size,
     uint_t samplerate);
 
-/** track the beat 
+/** track the beat
 
   \param bt beat tracking object
   \param dfframes current input detection function frame, smoothed by
-  adaptive median threshold. 
-  \param out stored detected beat locations 
+  adaptive median threshold.
+  \param out stored detected beat locations
 
 */
 void aubio_beattracking_do (aubio_beattracking_t * bt, fvec_t * dfframes,
@@ -77,7 +77,7 @@
 */
 smpl_t aubio_beattracking_get_bpm(aubio_beattracking_t * bt);
 
-/** get current tempo confidence 
+/** get current tempo confidence
 
   \param bt beat tracking object
 
--- a/src/temporal/a_weighting.h
+++ b/src/temporal/a_weighting.h
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2003-2013 Paul Brossier <piem@aubio.org>
+  Copyright (C) 2003-2015 Paul Brossier <piem@aubio.org>
 
   This file is part of aubio.
 
@@ -24,18 +24,18 @@
 /** \file
 
   A-weighting filter coefficients
-  
+
   This file creates an A-weighting digital filter, which reduces low and high
   frequencies and enhance the middle ones to reflect the ability of the human
   hearing.
-  
+
   The implementation is based on the following standard:
 
     - IEC/CD 1672: Electroacoustics-Sound Level Meters, IEC, Geneva, Nov.  1996,
   for A- and C-weighting filters.
-  
+
   See also:
-  
+
     - <a href="http://en.wikipedia.org/wiki/A-weighting">A-Weighting on
   Wikipedia</a>
     - <a href="http://en.wikipedia.org/wiki/Weighting_filter">Weighting filter on
@@ -42,7 +42,7 @@
   Wikipedia</a>
     - <a href="http://www.mathworks.com/matlabcentral/fileexchange/69">Christophe
   Couvreur's 'octave' toolbox</a>
-  
+
   The coefficients in this file have been computed using Christophe Couvreur's
   scripts in octave 3.0 (debian package 1:3.0.5-6+b2 with octave-signal
   1.0.9-1+b1 on i386), with <pre> [b, a] = adsign(1/Fs) </pre> for various
@@ -62,7 +62,7 @@
 
 /** create new A-design filter
 
-  \param samplerate sampling frequency of the signal to filter. Should be one of 
+  \param samplerate sampling frequency of the signal to filter. Should be one of
   8000, 11025, 16000, 22050, 24000, 32000, 44100, 48000, 88200, 96000, and
   192000 Hz
 
@@ -74,7 +74,7 @@
 /** set feedback and feedforward coefficients of a A-weighting filter
 
   \param f filter object to get coefficients from
-  \param samplerate sampling frequency of the signal to filter. Should be one of 
+  \param samplerate sampling frequency of the signal to filter. Should be one of
   8000, 11025, 16000, 22050, 24000, 32000, 44100, 48000, 88200, 96000, and
   192000 Hz
 
--- a/src/temporal/biquad.h
+++ b/src/temporal/biquad.h
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2003-2013 Paul Brossier <piem@aubio.org>
+  Copyright (C) 2003-2015 Paul Brossier <piem@aubio.org>
 
   This file is part of aubio.
 
@@ -21,12 +21,12 @@
 #ifndef _AUBIO_FILTER_BIQUAD_H
 #define _AUBIO_FILTER_BIQUAD_H
 
-/** \file 
+/** \file
 
   Second order Infinite Impulse Response filter
 
   This file implements a normalised biquad filter (second order IIR):
- 
+
   \f$ y[n] = b_0 x[n] + b_1 x[n-1] + b_2 x[n-2] - a_1 y[n-1] - a_2 y[n-2] \f$
 
   The filtfilt version runs the filter twice, forward and backward, to
--- a/src/temporal/c_weighting.h
+++ b/src/temporal/c_weighting.h
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2003-2013 Paul Brossier <piem@aubio.org>
+  Copyright (C) 2003-2015 Paul Brossier <piem@aubio.org>
 
   This file is part of aubio.
 
@@ -24,18 +24,18 @@
 /** \file
 
   C-weighting filter coefficients
-  
+
   This file creates a C-weighting digital filter, which reduces low and high
   frequencies and enhance the middle ones to reflect the ability of the human
   hearing.
-  
+
   The implementation is based on the following standard:
 
     - IEC/CD 1672: Electroacoustics-Sound Level Meters, IEC, Geneva, Nov.  1996,
   for A- and C-weighting filters.
-  
+
   See also:
-  
+
     - <a href="http://en.wikipedia.org/wiki/A-weighting">A-Weighting on
   Wikipedia</a>
     - <a href="http://en.wikipedia.org/wiki/Weighting_filter">Weighting filter on
@@ -42,7 +42,7 @@
   Wikipedia</a>
     - <a href="http://www.mathworks.com/matlabcentral/fileexchange/69">Christophe
   Couvreur's 'octave' toolbox</a>
-  
+
   The coefficients in this file have been computed using Christophe Couvreur's
   scripts in octave 3.0 (debian package 1:3.0.5-6+b2 with octave-signal
   1.0.9-1+b1 on i386), with <pre> [b, a] = cdsign(1/Fs) </pre> for various
@@ -62,7 +62,7 @@
 
 /** create new C-design filter
 
-  \param samplerate sampling frequency of the signal to filter. Should be one of 
+  \param samplerate sampling frequency of the signal to filter. Should be one of
   8000, 11025, 16000, 22050, 24000, 32000, 44100, 48000, 88200, 96000, and
   192000 Hz
 
@@ -74,7 +74,7 @@
 /** set feedback and feedforward coefficients of a C-weighting filter
 
   \param f filter object to get coefficients from
-  \param samplerate sampling frequency of the signal to filter. Should be one of 
+  \param samplerate sampling frequency of the signal to filter. Should be one of
   8000, 11025, 16000, 22050, 24000, 32000, 44100, 48000, 88200, 96000, and
   192000 Hz
 
--- a/src/temporal/filter.h
+++ b/src/temporal/filter.h
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2003-2013 Paul Brossier <piem@aubio.org>
+  Copyright (C) 2003-2015 Paul Brossier <piem@aubio.org>
 
   This file is part of aubio.
 
@@ -21,14 +21,14 @@
 #ifndef _AUBIO_FILTER_H
 #define _AUBIO_FILTER_H
 
-/** \file 
+/** \file
 
   Digital filter
 
   This object stores a digital filter of order \f$n\f$.
   It contains the following data:
-    - \f$ n*1 b_i \f$ feedforward coefficients 
-    - \f$ n*1 a_i \f$ feedback coefficients 
+    - \f$ n*1 b_i \f$ feedforward coefficients
+    - \f$ n*1 a_i \f$ feedback coefficients
     - \f$ n*c x_i \f$ input signal
     - \f$ n*c y_i \f$ output signal
 
@@ -40,7 +40,7 @@
 
   The function aubio_filter_do_outplace() computes the following output signal
   \f$ y[n] \f$ from the input signal \f$ x[n] \f$:
- 
+
   \f{eqnarray*}{
      y[n] = b_0 x[n] & + & b_1 x[n-1] + b_2 x[n-2] + ... + b_P x[n-P] \\
                      & - & a_1 y[n-1] - a_2 y[n-2] - ... - a_P y[n-P] \\
@@ -53,13 +53,13 @@
   forward then backward, to compensate with the phase shifting of the forward
   operation.
 
-  Some convenience functions are provided: 
+  Some convenience functions are provided:
     - new_aubio_filter_a_weighting() and aubio_filter_set_a_weighting(),
     - new_aubio_filter_c_weighting() and aubio_filter_set_c_weighting().
     - new_aubio_filter_biquad() and aubio_filter_set_biquad().
 
   \example temporal/test-filter.c
- 
+
 */
 
 #ifdef __cplusplus
@@ -163,7 +163,7 @@
 aubio_filter_t *new_aubio_filter (uint_t order);
 
 /** delete a filter object
- 
+
   \param f filter object to delete
 
 */
--- a/src/temporal/resampler.h
+++ b/src/temporal/resampler.h
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2003-2013 Paul Brossier <piem@aubio.org>
+  Copyright (C) 2003-2015 Paul Brossier <piem@aubio.org>
 
   This file is part of aubio.
 
@@ -22,12 +22,12 @@
 #define _AUBIO_RESAMPLER_H
 
 /** \file
- 
+
  Resampling object
 
  This object resamples an input vector into an output vector using
  libsamplerate. See http://www.mega-nerd.com/SRC/
- 
+
 */
 
 #ifdef __cplusplus
@@ -37,9 +37,9 @@
 /** resampler object */
 typedef struct _aubio_resampler_t aubio_resampler_t;
 
-/** create resampler object 
+/** create resampler object
 
-  \param ratio output_sample_rate / input_sample_rate 
+  \param ratio output_sample_rate / input_sample_rate
   \param type libsamplerate resampling type, see http://www.mega-nerd.com/SRC/api_misc.html#Converters
 
 */
--- a/src/types.h
+++ b/src/types.h
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2003-2013 Paul Brossier <piem@aubio.org>
+  Copyright (C) 2003-2015 Paul Brossier <piem@aubio.org>
 
   This file is part of aubio.
 
@@ -22,9 +22,9 @@
 #define _AUBIO__TYPES_H
 
 /** \file
- 
+
   Definition of data types used in aubio
- 
+
 */
 
 #ifdef __cplusplus
--- a/src/utils/parameter.h
+++ b/src/utils/parameter.h
@@ -60,7 +60,7 @@
 */
 uint_t aubio_parameter_set_target_value ( aubio_parameter_t * param, smpl_t value );
 
-/** get next parameter 
+/** get next parameter
 
   \param param parameter, created by ::new_aubio_parameter
 
--- a/src/utils/scale.h
+++ b/src/utils/scale.h
@@ -20,13 +20,13 @@
 
 /** \file
 
- Vector scaling function 
- 
+ Vector scaling function
+
  This object, inspired from the scale object in FTS, the jMax engine, scales
  the values of a vector according to an affine function defined as follow:
- 
- \f$ y = (x - ilow)*(ohig-olow)/(ihig-ilow) + olow \f$ 
- 
+
+ \f$ y = (x - ilow)*(ohig-olow)/(ihig-ilow) + olow \f$
+
 */
 #ifndef _AUBIO_SCALE_H
 #define _AUBIO_SCALE_H
@@ -39,7 +39,7 @@
 typedef struct _aubio_scale_t aubio_scale_t;
 
 /** create a scale object
- 
+
   \param flow lower value of output function
   \param fhig higher value of output function
   \param ilow lower value of input function
@@ -48,7 +48,7 @@
 */
 aubio_scale_t * new_aubio_scale(smpl_t flow, smpl_t fhig,
     smpl_t ilow, smpl_t ihig);
-/** delete a scale object 
+/** delete a scale object
 
   \param s scale object as returned by new_aubio_scale
 
@@ -75,6 +75,6 @@
 
 #ifdef __cplusplus
 }
-#endif 
+#endif
 
 #endif /* _AUBIO_SCALE_H */
--- a/src/vecutils.h
+++ b/src/vecutils.h
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2009-2013 Paul Brossier <piem@aubio.org>
+  Copyright (C) 2009-2015 Paul Brossier <piem@aubio.org>
 
   This file is part of aubio.
 
--- a/tests/src/spectral/test-fft.c
+++ b/tests/src/spectral/test-fft.c
@@ -2,6 +2,7 @@
 
 int main (void)
 {
+  int return_code = 0;
   uint_t i, n_iters = 100; // number of iterations
   uint_t win_s = 500; // window size
   fvec_t * in = new_fvec (win_s); // input buffer
@@ -10,6 +11,11 @@
   // create fft object
   aubio_fft_t * fft = new_aubio_fft(win_s);
 
+  if (!fft) {
+    return_code = 1;
+    goto beach;
+  }
+
   // fill input with some data
   in->data[0] = 1;
   in->data[1] = 2;
@@ -33,9 +39,10 @@
   // cleam up
   //fvec_print(out);
   del_aubio_fft(fft);
+beach:
   del_fvec(in);
   del_cvec(fftgrain);
   del_fvec(out);
   aubio_cleanup();
-  return 0;
+  return return_code;
 }
--- a/tests/src/test-delnull.c
+++ b/tests/src/test-delnull.c
@@ -1,13 +1,24 @@
 #include <stdlib.h>
 #include "aubio.h"
 
-// Because aubio does not check for double free, this program will crash.
-// Programs that call these functions should check for null pointers.
+// When creating an aubio object, the user should check whether the object is
+// set NULL, indicating the creation failed and the object was not allocated.
 
 int main (void)
 {
-  del_fvec(NULL);
-  del_lvec(NULL);
-  del_cvec(NULL);
-  return 0;
+  uint_t return_code = 0;
+  fvec_t *f = new_fvec(-12);
+  cvec_t *c = new_cvec(-12);
+  lvec_t *l = new_lvec(-12);
+  aubio_fft_t *fft = new_aubio_fft(-12);
+  if (f != NULL) {
+    return_code = 1;
+  } else if (c != NULL) {
+    return_code = 2;
+  } else if (l != NULL) {
+    return_code = 3;
+  } else if (fft != NULL) {
+    return_code = 3;
+  }
+  return return_code;
 }
--- a/wscript
+++ b/wscript
@@ -75,6 +75,12 @@
     add_option_enable_disable(ctx, 'fat', default = False,
             help_str = 'build fat binaries (darwin only)',
             help_disable_str = 'do not build fat binaries (default)')
+    add_option_enable_disable(ctx, 'accelerate', default = None,
+            help_str = 'use Accelerate framework (darwin only) (auto)',
+            help_disable_str = 'do not use Accelerate framework')
+    add_option_enable_disable(ctx, 'apple-audio', default = None,
+            help_str = 'use CoreFoundation (darwin only) (auto)',
+            help_disable_str = 'do not use CoreFoundation framework')
 
     ctx.add_option('--with-target-platform', type='string',
             help='set target platform for cross-compilation', dest='target_platform')
@@ -110,15 +116,20 @@
         ctx.env.LINKFLAGS += ['-arch', 'i386', '-arch', 'x86_64']
 
     if target_platform in [ 'darwin', 'ios', 'iosimulator']:
-        ctx.env.FRAMEWORK = ['CoreFoundation', 'AudioToolbox', 'Accelerate']
-        ctx.define('HAVE_SOURCE_APPLE_AUDIO', 1)
-        ctx.define('HAVE_SINK_APPLE_AUDIO', 1)
-        ctx.define('HAVE_ACCELERATE', 1)
+        if (ctx.options.enable_apple_audio != False):
+            ctx.env.FRAMEWORK += ['CoreFoundation', 'AudioToolbox']
+            ctx.define('HAVE_SOURCE_APPLE_AUDIO', 1)
+            ctx.define('HAVE_SINK_APPLE_AUDIO', 1)
+        if (ctx.options.enable_accelerate != False):
+            ctx.define('HAVE_ACCELERATE', 1)
+            ctx.env.FRAMEWORK += ['Accelerate']
 
     if target_platform in [ 'ios', 'iosimulator' ]:
-        ctx.define('TARGET_OS_IPHONE', 1)
         MINSDKVER="6.1"
         ctx.env.CFLAGS += ['-std=c99']
+        if (ctx.options.enable_audio_unit != False):
+            ctx.define('HAVE_AUDIO_UNIT', 1)
+            #ctx.env.FRAMEWORK += ['CoreFoundation', 'AudioToolbox']
         if target_platform == 'ios':
             DEVROOT = "/Applications/Xcode.app/Contents"
             DEVROOT += "/Developer/Platforms/iPhoneOS.platform/Developer"
@@ -238,7 +249,7 @@
         ctx.check_cfg(package = 'libavresample', atleast_version = '1.0.1',
                 args = '--cflags --libs', uselib_store = 'AVRESAMPLE',
                 mandatory = ctx.options.enable_avcodec)
-        if all ( 'HAVE_' + i in ctx.env.define_key
+        if all ( 'HAVE_' + i in ctx.env
                 for i in ['AVCODEC', 'AVFORMAT', 'AVUTIL', 'AVRESAMPLE'] ):
             ctx.define('HAVE_LIBAV', 1)
             ctx.msg('Checking for all libav libraries', 'yes')
--