=Norig) twidx-=Norig;
+ C_MUL(t,scratch[q] , twiddles[twidx] );
+ C_ADDTO( Fout[ k ] ,t);
+ }
+ k += m;
+ }
+ }
+ KISS_FFT_TMP_FREE(scratch);
+}
+
+static
+void kf_work(
+ kiss_fft_cpx * Fout,
+ const kiss_fft_cpx * f,
+ const size_t fstride,
+ int in_stride,
+ int * factors,
+ const kiss_fft_cfg st
+ )
+{
+ kiss_fft_cpx * Fout_beg=Fout;
+ const int p=*factors++; /* the radix */
+ const int m=*factors++; /* stage's fft length/p */
+ const kiss_fft_cpx * Fout_end = Fout + p*m;
+
+#ifdef _OPENMP
+ // use openmp extensions at the
+ // top-level (not recursive)
+ if (fstride==1 && p<=5)
+ {
+ int k;
+
+ // execute the p different work units in different threads
+# pragma omp parallel for
+ for (k=0;k floor_sqrt)
+ p = n; /* no more factors, skip to end */
+ }
+ n /= p;
+ *facbuf++ = p;
+ *facbuf++ = n;
+ } while (n > 1);
+}
+
+/*
+ *
+ * User-callable function to allocate all necessary storage space for the fft.
+ *
+ * The return value is a contiguous block of memory, allocated with malloc. As such,
+ * It can be freed with free(), rather than a kiss_fft-specific function.
+ * */
+kiss_fft_cfg kiss_fft_alloc(int nfft,int inverse_fft,void * mem,size_t * lenmem )
+{
+ kiss_fft_cfg st=NULL;
+ size_t memneeded = sizeof(struct kiss_fft_state)
+ + sizeof(kiss_fft_cpx)*(nfft-1); /* twiddle factors*/
+
+ if ( lenmem==NULL ) {
+ st = ( kiss_fft_cfg)KISS_FFT_MALLOC( memneeded );
+ }else{
+ if (mem != NULL && *lenmem >= memneeded)
+ st = (kiss_fft_cfg)mem;
+ *lenmem = memneeded;
+ }
+ if (st) {
+ int i;
+ st->nfft=nfft;
+ st->inverse = inverse_fft;
+
+ for (i=0;iinverse)
+ phase *= -1;
+ kf_cexp(st->twiddles+i, phase );
+ }
+
+ kf_factor(nfft,st->factors);
+ }
+ return st;
+}
+
+
+void kiss_fft_stride(kiss_fft_cfg st,const kiss_fft_cpx *fin,kiss_fft_cpx *fout,int in_stride)
+{
+ if (fin == fout) {
+ //NOTE: this is not really an in-place FFT algorithm.
+ //It just performs an out-of-place FFT into a temp buffer
+ kiss_fft_cpx * tmpbuf = (kiss_fft_cpx*)KISS_FFT_TMP_ALLOC( sizeof(kiss_fft_cpx)*st->nfft);
+ kf_work(tmpbuf,fin,1,in_stride, st->factors,st);
+ memcpy(fout,tmpbuf,sizeof(kiss_fft_cpx)*st->nfft);
+ KISS_FFT_TMP_FREE(tmpbuf);
+ }else{
+ kf_work( fout, fin, 1,in_stride, st->factors,st );
+ }
+}
+
+void kiss_fft(kiss_fft_cfg cfg,const kiss_fft_cpx *fin,kiss_fft_cpx *fout)
+{
+ kiss_fft_stride(cfg,fin,fout,1);
+}
+
+
+void kiss_fft_cleanup(void)
+{
+ // nothing needed any more
+}
+
+int kiss_fft_next_fast_size(int n)
+{
+ while(1) {
+ int m=n;
+ while ( (m%2) == 0 ) m/=2;
+ while ( (m%3) == 0 ) m/=3;
+ while ( (m%5) == 0 ) m/=5;
+ if (m<=1)
+ break; /* n is completely factorable by twos, threes, and fives */
+ n++;
+ }
+ return n;
+}
diff --git a/src/dep/gist/libs/kiss_fft130/kiss_fft.h b/src/dep/gist/libs/kiss_fft130/kiss_fft.h
new file mode 100644
index 0000000..64c50f4
--- /dev/null
+++ b/src/dep/gist/libs/kiss_fft130/kiss_fft.h
@@ -0,0 +1,124 @@
+#ifndef KISS_FFT_H
+#define KISS_FFT_H
+
+#include
+#include
+#include
+#include
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ ATTENTION!
+ If you would like a :
+ -- a utility that will handle the caching of fft objects
+ -- real-only (no imaginary time component ) FFT
+ -- a multi-dimensional FFT
+ -- a command-line utility to perform ffts
+ -- a command-line utility to perform fast-convolution filtering
+
+ Then see kfc.h kiss_fftr.h kiss_fftnd.h fftutil.c kiss_fastfir.c
+ in the tools/ directory.
+*/
+
+#ifdef USE_SIMD
+# include
+# define kiss_fft_scalar __m128
+#define KISS_FFT_MALLOC(nbytes) _mm_malloc(nbytes,16)
+#define KISS_FFT_FREE _mm_free
+#else
+#define KISS_FFT_MALLOC malloc
+#define KISS_FFT_FREE free
+#endif
+
+
+#ifdef FIXED_POINT
+#include
+# if (FIXED_POINT == 32)
+# define kiss_fft_scalar int32_t
+# else
+# define kiss_fft_scalar int16_t
+# endif
+#else
+# ifndef kiss_fft_scalar
+/* default is float */
+# define kiss_fft_scalar float
+# endif
+#endif
+
+typedef struct {
+ kiss_fft_scalar r;
+ kiss_fft_scalar i;
+}kiss_fft_cpx;
+
+typedef struct kiss_fft_state* kiss_fft_cfg;
+
+/*
+ * kiss_fft_alloc
+ *
+ * Initialize a FFT (or IFFT) algorithm's cfg/state buffer.
+ *
+ * typical usage: kiss_fft_cfg mycfg=kiss_fft_alloc(1024,0,NULL,NULL);
+ *
+ * The return value from fft_alloc is a cfg buffer used internally
+ * by the fft routine or NULL.
+ *
+ * If lenmem is NULL, then kiss_fft_alloc will allocate a cfg buffer using malloc.
+ * The returned value should be free()d when done to avoid memory leaks.
+ *
+ * The state can be placed in a user supplied buffer 'mem':
+ * If lenmem is not NULL and mem is not NULL and *lenmem is large enough,
+ * then the function places the cfg in mem and the size used in *lenmem
+ * and returns mem.
+ *
+ * If lenmem is not NULL and ( mem is NULL or *lenmem is not large enough),
+ * then the function returns NULL and places the minimum cfg
+ * buffer size in *lenmem.
+ * */
+
+kiss_fft_cfg kiss_fft_alloc(int nfft,int inverse_fft,void * mem,size_t * lenmem);
+
+/*
+ * kiss_fft(cfg,in_out_buf)
+ *
+ * Perform an FFT on a complex input buffer.
+ * for a forward FFT,
+ * fin should be f[0] , f[1] , ... ,f[nfft-1]
+ * fout will be F[0] , F[1] , ... ,F[nfft-1]
+ * Note that each element is complex and can be accessed like
+ f[k].r and f[k].i
+ * */
+void kiss_fft(kiss_fft_cfg cfg,const kiss_fft_cpx *fin,kiss_fft_cpx *fout);
+
+/*
+ A more generic version of the above function. It reads its input from every Nth sample.
+ * */
+void kiss_fft_stride(kiss_fft_cfg cfg,const kiss_fft_cpx *fin,kiss_fft_cpx *fout,int fin_stride);
+
+/* If kiss_fft_alloc allocated a buffer, it is one contiguous
+ buffer and can be simply free()d when no longer needed*/
+#define kiss_fft_free free
+
+/*
+ Cleans up some memory that gets managed internally. Not necessary to call, but it might clean up
+ your compiler output to call this before you exit.
+*/
+void kiss_fft_cleanup(void);
+
+
+/*
+ * Returns the smallest integer k, such that k>=n and k has only "fast" factors (2,3,5)
+ */
+int kiss_fft_next_fast_size(int n);
+
+/* for real ffts, we need an even size */
+#define kiss_fftr_next_fast_size_real(n) \
+ (kiss_fft_next_fast_size( ((n)+1)>>1)<<1)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/src/dep/gist/libs/kiss_fft130/kissfft.hh b/src/dep/gist/libs/kiss_fft130/kissfft.hh
new file mode 100644
index 0000000..a586cb1
--- /dev/null
+++ b/src/dep/gist/libs/kiss_fft130/kissfft.hh
@@ -0,0 +1,299 @@
+#ifndef KISSFFT_CLASS_HH
+#include
+#include
+
+namespace kissfft_utils {
+
+template
+struct traits
+{
+ typedef T_scalar scalar_type;
+ typedef std::complex cpx_type;
+ void fill_twiddles( std::complex * dst ,int nfft,bool inverse)
+ {
+ T_scalar phinc = (inverse?2:-2)* acos( (T_scalar) -1) / nfft;
+ for (int i=0;i(0,i*phinc) );
+ }
+
+ void prepare(
+ std::vector< std::complex > & dst,
+ int nfft,bool inverse,
+ std::vector & stageRadix,
+ std::vector & stageRemainder )
+ {
+ _twiddles.resize(nfft);
+ fill_twiddles( &_twiddles[0],nfft,inverse);
+ dst = _twiddles;
+
+ //factorize
+ //start factoring out 4's, then 2's, then 3,5,7,9,...
+ int n= nfft;
+ int p=4;
+ do {
+ while (n % p) {
+ switch (p) {
+ case 4: p = 2; break;
+ case 2: p = 3; break;
+ default: p += 2; break;
+ }
+ if (p*p>n)
+ p=n;// no more factors
+ }
+ n /= p;
+ stageRadix.push_back(p);
+ stageRemainder.push_back(n);
+ }while(n>1);
+ }
+ std::vector _twiddles;
+
+
+ const cpx_type twiddle(int i) { return _twiddles[i]; }
+};
+
+}
+
+template
+ >
+class kissfft
+{
+ public:
+ typedef T_traits traits_type;
+ typedef typename traits_type::scalar_type scalar_type;
+ typedef typename traits_type::cpx_type cpx_type;
+
+ kissfft(int nfft,bool inverse,const traits_type & traits=traits_type() )
+ :_nfft(nfft),_inverse(inverse),_traits(traits)
+ {
+ _traits.prepare(_twiddles, _nfft,_inverse ,_stageRadix, _stageRemainder);
+ }
+
+ void transform(const cpx_type * src , cpx_type * dst)
+ {
+ kf_work(0, dst, src, 1,1);
+ }
+
+ private:
+ void kf_work( int stage,cpx_type * Fout, const cpx_type * f, size_t fstride,size_t in_stride)
+ {
+ int p = _stageRadix[stage];
+ int m = _stageRemainder[stage];
+ cpx_type * Fout_beg = Fout;
+ cpx_type * Fout_end = Fout + p*m;
+
+ if (m==1) {
+ do{
+ *Fout = *f;
+ f += fstride*in_stride;
+ }while(++Fout != Fout_end );
+ }else{
+ do{
+ // recursive call:
+ // DFT of size m*p performed by doing
+ // p instances of smaller DFTs of size m,
+ // each one takes a decimated version of the input
+ kf_work(stage+1, Fout , f, fstride*p,in_stride);
+ f += fstride*in_stride;
+ }while( (Fout += m) != Fout_end );
+ }
+
+ Fout=Fout_beg;
+
+ // recombine the p smaller DFTs
+ switch (p) {
+ case 2: kf_bfly2(Fout,fstride,m); break;
+ case 3: kf_bfly3(Fout,fstride,m); break;
+ case 4: kf_bfly4(Fout,fstride,m); break;
+ case 5: kf_bfly5(Fout,fstride,m); break;
+ default: kf_bfly_generic(Fout,fstride,m,p); break;
+ }
+ }
+
+ // these were #define macros in the original kiss_fft
+ void C_ADD( cpx_type & c,const cpx_type & a,const cpx_type & b) { c=a+b;}
+ void C_MUL( cpx_type & c,const cpx_type & a,const cpx_type & b) { c=a*b;}
+ void C_SUB( cpx_type & c,const cpx_type & a,const cpx_type & b) { c=a-b;}
+ void C_ADDTO( cpx_type & c,const cpx_type & a) { c+=a;}
+ void C_FIXDIV( cpx_type & ,int ) {} // NO-OP for float types
+ scalar_type S_MUL( const scalar_type & a,const scalar_type & b) { return a*b;}
+ scalar_type HALF_OF( const scalar_type & a) { return a*.5;}
+ void C_MULBYSCALAR(cpx_type & c,const scalar_type & a) {c*=a;}
+
+ void kf_bfly2( cpx_type * Fout, const size_t fstride, int m)
+ {
+ for (int k=0;kreal() - HALF_OF(scratch[3].real() ) , Fout->imag() - HALF_OF(scratch[3].imag() ) );
+
+ C_MULBYSCALAR( scratch[0] , epi3.imag() );
+
+ C_ADDTO(*Fout,scratch[3]);
+
+ Fout[m2] = cpx_type( Fout[m].real() + scratch[0].imag() , Fout[m].imag() - scratch[0].real() );
+
+ C_ADDTO( Fout[m] , cpx_type( -scratch[0].imag(),scratch[0].real() ) );
+ ++Fout;
+ }while(--k);
+ }
+
+ void kf_bfly5( cpx_type * Fout, const size_t fstride, const size_t m)
+ {
+ cpx_type *Fout0,*Fout1,*Fout2,*Fout3,*Fout4;
+ size_t u;
+ cpx_type scratch[13];
+ cpx_type * twiddles = &_twiddles[0];
+ cpx_type *tw;
+ cpx_type ya,yb;
+ ya = twiddles[fstride*m];
+ yb = twiddles[fstride*2*m];
+
+ Fout0=Fout;
+ Fout1=Fout0+m;
+ Fout2=Fout0+2*m;
+ Fout3=Fout0+3*m;
+ Fout4=Fout0+4*m;
+
+ tw=twiddles;
+ for ( u=0; u=Norig) twidx-=Norig;
+ C_MUL(t,scratchbuf[q] , twiddles[twidx] );
+ C_ADDTO( Fout[ k ] ,t);
+ }
+ k += m;
+ }
+ }
+ }
+
+ int _nfft;
+ bool _inverse;
+ std::vector _twiddles;
+ std::vector _stageRadix;
+ std::vector _stageRemainder;
+ traits_type _traits;
+};
+#endif
diff --git a/src/dep/gist/logo.png b/src/dep/gist/logo.png
new file mode 100644
index 0000000..a3a75a6
Binary files /dev/null and b/src/dep/gist/logo.png differ
diff --git a/src/dep/gist/python-module/GistPythonModule.cpp b/src/dep/gist/python-module/GistPythonModule.cpp
new file mode 100644
index 0000000..866933c
--- /dev/null
+++ b/src/dep/gist/python-module/GistPythonModule.cpp
@@ -0,0 +1,324 @@
+#include
+#include
+#include
+#include
+#include "../src/Gist.h"
+
+//=======================================================================
+/** The Gist module */
+Gist gist (512, 44100);
+
+//=======================================================================
+static PyObject* setAudioFrameSize (PyObject *dummy, PyObject *args)
+{
+ int audioFrameSize;
+
+ if (!PyArg_ParseTuple(args, "i", &audioFrameSize))
+ {
+ return NULL;
+ }
+
+ gist.setAudioFrameSize (audioFrameSize);
+
+ return Py_BuildValue("");
+}
+
+//=======================================================================
+static PyObject* setSamplingFrequency (PyObject *dummy, PyObject *args)
+{
+ int samplingFrequency;
+
+ if (!PyArg_ParseTuple(args, "i", &samplingFrequency))
+ {
+ return NULL;
+ }
+
+ gist.setSamplingFrequency (samplingFrequency);
+
+ return Py_BuildValue("");
+}
+
+//=======================================================================
+static PyObject* getAudioFrameSize (PyObject *dummy, PyObject *args)
+{
+ return PyInt_FromLong((long) gist.getAudioFrameSize());
+}
+
+//=======================================================================
+static PyObject* getSamplingFrequency (PyObject *dummy, PyObject *args)
+{
+ return PyInt_FromLong((long) gist.getSamplingFrequency());
+}
+
+//=======================================================================
+static PyObject * processFrame (PyObject *dummy, PyObject *args)
+{
+ PyObject *arg1 = NULL;
+ PyObject *arr1 = NULL;
+
+ if (!PyArg_ParseTuple (args, "O", &arg1))
+ {
+ return NULL;
+ }
+
+ arr1 = PyArray_FROM_OTF (arg1, NPY_DOUBLE, NPY_IN_ARRAY);
+ if (arr1 == NULL)
+ {
+ return NULL;
+ }
+
+ double* audioFrame = (double*) PyArray_DATA(arr1);
+ long audioFrameSize = (int) PyArray_Size ((PyObject*)arr1);
+
+ if (audioFrameSize != gist.getAudioFrameSize())
+ {
+ PyErr_SetString (PyExc_ValueError, "You are passing an audio frame with a different size to the frame size set in Gist. Use gist.getAudioFrameSize() to find out what is being used and change it with gist.setAudioFrameSize(frameSize)");
+ return NULL;
+ }
+
+ gist.processAudioFrame (audioFrame, (unsigned long) audioFrameSize);
+
+ Py_DECREF (arr1);
+
+ return Py_BuildValue("");
+}
+
+//=======================================================================//
+//=================== CORE TIME DOMAIN FEATURES ========================//
+//=======================================================================//
+
+//=======================================================================
+static PyObject * rootMeanSquare (PyObject *dummy, PyObject *args)
+{
+ double rms = gist.rootMeanSquare();
+
+ return PyFloat_FromDouble (rms);
+}
+
+//=======================================================================
+static PyObject * peakEnergy (PyObject *dummy, PyObject *args)
+{
+ double p = gist.peakEnergy();
+
+ return PyFloat_FromDouble (p);
+}
+
+//=======================================================================
+static PyObject * zeroCrossingRate (PyObject *dummy, PyObject *args)
+{
+ double zcr = gist.zeroCrossingRate();
+
+ return PyFloat_FromDouble (zcr);
+}
+
+//=======================================================================//
+//================= CORE FREQUENCY DOMAIN FEATURES ======================//
+//=======================================================================//
+
+//=======================================================================
+static PyObject * spectralCentroid (PyObject *dummy, PyObject *args)
+{
+ double sc = gist.spectralCentroid();
+
+ return PyFloat_FromDouble (sc);
+}
+
+//=======================================================================
+static PyObject * spectralCrest (PyObject *dummy, PyObject *args)
+{
+ double sc = gist.spectralCrest();
+
+ return PyFloat_FromDouble (sc);
+}
+
+//=======================================================================
+static PyObject * spectralFlatness (PyObject *dummy, PyObject *args)
+{
+ double sf = gist.spectralFlatness();
+
+ return PyFloat_FromDouble (sf);
+}
+
+//=======================================================================
+static PyObject * spectralRolloff (PyObject *dummy, PyObject *args)
+{
+ double sr = gist.spectralRolloff();
+
+ return PyFloat_FromDouble (sr);
+}
+
+//=======================================================================
+static PyObject * spectralKurtosis (PyObject *dummy, PyObject *args)
+{
+ double sk = gist.spectralKurtosis();
+
+ return PyFloat_FromDouble (sk);
+}
+
+//=======================================================================//
+//==================== ONSET DETECTION FUNCTIONS ========================//
+//=======================================================================//
+
+//=======================================================================
+static PyObject * energyDifference (PyObject *dummy, PyObject *args)
+{
+ double ed = gist.energyDifference();
+
+ return PyFloat_FromDouble (ed);
+}
+
+//=======================================================================
+static PyObject * spectralDifference (PyObject *dummy, PyObject *args)
+{
+ double sd = gist.spectralDifference();
+
+ return PyFloat_FromDouble (sd);
+}
+
+//=======================================================================
+static PyObject * spectralDifferenceHWR (PyObject *dummy, PyObject *args)
+{
+ double sdhwr = gist.spectralDifferenceHWR();
+
+ return PyFloat_FromDouble (sdhwr);
+}
+
+//=======================================================================
+static PyObject * complexSpectralDifference (PyObject *dummy, PyObject *args)
+{
+ double csd = gist.complexSpectralDifference();
+
+ return PyFloat_FromDouble (csd);
+}
+
+//=======================================================================
+static PyObject * highFrequencyContent (PyObject *dummy, PyObject *args)
+{
+ double hfc = gist.highFrequencyContent();
+
+ return PyFloat_FromDouble (hfc);
+}
+
+//=======================================================================//
+//============================== PITCH ==================================//
+//=======================================================================//
+
+//=======================================================================
+static PyObject * pitch (PyObject *dummy, PyObject *args)
+{
+ double p = gist.pitch();
+
+ return PyFloat_FromDouble (p);
+}
+
+//=======================================================================//
+//============================= SPECTRA =================================//
+//=======================================================================//
+
+//=======================================================================
+static PyObject * magnitudeSpectrum (PyObject *dummy, PyObject *args)
+{
+ std::vector magnitudeSpectrum = gist.getMagnitudeSpectrum();
+
+ int numDimensions = 1;
+ npy_intp numElements = magnitudeSpectrum.size();
+
+ PyObject* c = PyArray_SimpleNew (numDimensions, &numElements, NPY_DOUBLE);
+ void* arrayData = PyArray_DATA ( (PyArrayObject*)c);
+ memcpy (arrayData, &magnitudeSpectrum[0], PyArray_ITEMSIZE((PyArrayObject*) c) * numElements);
+
+ return c;
+}
+
+//=======================================================================
+static PyObject * melFrequencySpectrum (PyObject *dummy, PyObject *args)
+{
+ const std::vector& melFrequencySpectrum = gist.getMelFrequencySpectrum();
+
+ int numDimensions = 1;
+ npy_intp numElements = melFrequencySpectrum.size();
+
+ PyObject* c = PyArray_SimpleNew (numDimensions, &numElements, NPY_DOUBLE);
+ void* arrayData = PyArray_DATA ( (PyArrayObject*)c);
+ memcpy (arrayData, &melFrequencySpectrum[0], PyArray_ITEMSIZE((PyArrayObject*) c) * numElements);
+
+ return c;
+}
+
+//=======================================================================
+static PyObject * mfccs (PyObject *dummy, PyObject *args)
+{
+ const std::vector& mfccs = gist.getMelFrequencyCepstralCoefficients();
+
+ int numDimensions = 1;
+ npy_intp numElements = mfccs.size();
+
+ PyObject* c = PyArray_SimpleNew (numDimensions, &numElements, NPY_DOUBLE);
+ void* arrayData = PyArray_DATA ( (PyArrayObject*)c);
+ memcpy (arrayData, &mfccs[0], PyArray_ITEMSIZE((PyArrayObject*) c) * numElements);
+
+ return c;
+}
+
+//=======================================================================
+static PyMethodDef gist_methods[] = {
+
+ /** Configuration methods */
+ {"setAudioFrameSize", setAudioFrameSize, METH_VARARGS, "Set the audio frame size to be used"},
+ {"getAudioFrameSize", getAudioFrameSize, METH_VARARGS, "Get the audio frame size currently being used"},
+ {"setSamplingFrequency", setSamplingFrequency, METH_VARARGS, "Set the audio sampling frequency to be used"},
+ {"getSamplingFrequency", getSamplingFrequency, METH_VARARGS, "Get the audio sampling frequency currently being used"},
+
+ {"processFrame", processFrame, METH_VARARGS, "Process a single audio frame"},
+
+ /** Core Time Domain Features */
+ {"rms", rootMeanSquare, METH_VARARGS, "Return the RMS of the most recent audio frame"},
+ {"peakEnergy", peakEnergy, METH_VARARGS, "Return the peak energy of the most recent audio frame"},
+ {"zeroCrossingRate", zeroCrossingRate, METH_VARARGS, "Return the zero crossing rate of the most recent audio frame"},
+
+ /** Core Frequency Domain Features */
+ {"spectralCentroid", spectralCentroid, METH_VARARGS, "Return the spectral centroid of the most recent audio frame"},
+ {"spectralCrest", spectralCrest, METH_VARARGS, "Return the spectral crest of the most recent audio frame"},
+ {"spectralFlatness", spectralFlatness, METH_VARARGS, "Return the spectral flatness of the most recent audio frame"},
+ {"spectralRolloff", spectralRolloff, METH_VARARGS, "Return the spectral rolloff of the most recent audio frame"},
+ {"spectralKurtosis", spectralKurtosis, METH_VARARGS, "Return the spectral kurtosis of the most recent audio frame"},
+
+ /** Onset Detection Functions */
+ {"energyDifference", energyDifference, METH_VARARGS, "Return the energy difference onset detection function of the most recent audio frame"},
+ {"spectralDifference", spectralDifference, METH_VARARGS, "Return the spectral difference onset detection function of the most recent audio frame"},
+ {"spectralDifferenceHWR", spectralDifferenceHWR, METH_VARARGS, "Return the spectral difference (half-wave rectified) onset detection function of the most recent audio frame"},
+ {"complexSpectralDifference", complexSpectralDifference, METH_VARARGS, "Return the complex spectral difference onset detection function of the most recent audio frame"},
+ {"highFrequencyContent", highFrequencyContent, METH_VARARGS, "Return the high frequency content onset detection function of the most recent audio frame"},
+
+ /** Pitch */
+ {"pitch", pitch, METH_VARARGS, "Return the monophonic pitch estimate the most recent audio frame"},
+
+ /** Spectra */
+ {"magnitudeSpectrum", magnitudeSpectrum, METH_VARARGS, "Return the magnitude spectrum for the most recent audio frame"},
+ {"melFrequencySpectrum", melFrequencySpectrum, METH_VARARGS, "Return the mel-frequency spectrum for the most recent audio frame"},
+ {"mfccs", mfccs, METH_VARARGS, "Return the mel-frequency cepstral coefficients for the most recent audio frame"},
+
+ {NULL, NULL, 0, NULL} /* Sentinel */
+};
+
+
+
+//=======================================================================
+PyMODINIT_FUNC initgist (void)
+{
+ (void)Py_InitModule("gist", gist_methods);
+ import_array();
+}
+
+//=======================================================================
+int main (int argc, char *argv[])
+{
+ /* Pass argv[0] to the Python interpreter */
+ Py_SetProgramName(argv[0]);
+
+ /* Initialize the Python interpreter. Required. */
+ Py_Initialize();
+
+ /* Add a static module */
+ initgist();
+}
diff --git a/src/dep/gist/python-module/INSTALL.md b/src/dep/gist/python-module/INSTALL.md
new file mode 100644
index 0000000..901c12a
--- /dev/null
+++ b/src/dep/gist/python-module/INSTALL.md
@@ -0,0 +1,25 @@
+Gist - Python Module
+=================================
+
+See the main Gist README for other information including usage and license information. If it hasn't been included with these files, you can find it at:
+
+[https://github.com/adamstark/Gist](https://github.com/adamstark/Gist)
+
+Python Module Installation
+--------------------------
+
+On the command line, type:
+
+ python setup.py build
+
+and then:
+
+ python setup.py install
+
+You may need to prefix the second command with 'sudo', depending upon your system configuration.
+
+
+Python Module Usage
+-------------------
+
+Please see the file `example.py` for usage examples
\ No newline at end of file
diff --git a/src/dep/gist/python-module/example.py b/src/dep/gist/python-module/example.py
new file mode 100644
index 0000000..f0ceee0
--- /dev/null
+++ b/src/dep/gist/python-module/example.py
@@ -0,0 +1,84 @@
+import numpy as np
+
+# ================================
+# import the gist module
+import gist
+
+# ====================== Setting up ===================
+
+# Commented out for now
+
+# Get the sampling frequency
+#fs = gist.getSamplingFrequency()
+
+# Set the sampling frequency
+#gist.setSamplingFrequency (48000)
+
+# Set the audio frame size that the module expects
+#gist.setAudioFrameSize (512)
+
+# ====================== Extracting Features ===================
+
+# This example shows how to get features from a single audio frame
+
+# Create an arbitrary sin wave as an audio frame
+audioFrame = np.sin (np.arange((512.)) * np.pi / 180. * 4 )
+
+# Process the audio frame
+gist.processFrame (audioFrame)
+
+# Now we extract features and print them out...
+
+# ====================== Core Time Domain Features ===================
+
+print ""
+print "--- CORE TIME DOMAIN FEATURES ---"
+print ""
+print "RMS:", gist.rms()
+print "Peak Energy:", gist.peakEnergy()
+print "Zero Crossing Rate:", gist.zeroCrossingRate()
+print ""
+
+# ====================== Core Frequency Domain Features ===================
+
+print "--- CORE FREQUENCY DOMAIN FEATURES ---"
+print ""
+print "Spectral Centroid: ", gist.spectralCentroid()
+print "Spectral Crest:", gist.spectralCrest()
+print "Spectral Flatness:", gist.spectralFlatness()
+print "Spectral Rolloff:", gist.spectralRolloff()
+print "Spectral Kurtosis:", gist.spectralKurtosis()
+print ""
+
+# ========================= Onset Detection Functions =======================
+
+print "--- ONSET DETECTION FUNCTIONS ---"
+print ""
+print "Energy Difference:", gist.energyDifference()
+print "Spectral Difference:", gist.spectralDifference()
+print "Spectral Difference (half-wave rectified):", gist.spectralDifferenceHWR()
+print "Complex Spectral Difference:", gist.complexSpectralDifference()
+print "High Frequency Content:", gist.highFrequencyContent()
+print ""
+
+# ========================= Pitch =======================
+
+print "--- PITCH ---"
+print ""
+print "Pitch:", gist.pitch()
+print ""
+
+# ======================= Spectra ========================
+
+print "--- SPECTRA ---"
+print ""
+magnitudeSpectrum = gist.magnitudeSpectrum()
+print "Magnitude Spectrum has", magnitudeSpectrum.size, "samples"
+
+melFrequencySpectrum = gist.melFrequencySpectrum()
+print "Mel-Frequency Spectrum has", melFrequencySpectrum.size, "samples"
+
+mfccs = gist.mfccs()
+print "MFCCs has", mfccs.size, "samples"
+
+
diff --git a/src/dep/gist/python-module/setup.py b/src/dep/gist/python-module/setup.py
new file mode 100644
index 0000000..402974d
--- /dev/null
+++ b/src/dep/gist/python-module/setup.py
@@ -0,0 +1,26 @@
+# setup.py
+# build command : python setup.py build build_ext --inplace
+from numpy.distutils.core import setup, Extension
+import os, numpy
+
+name = 'gist'
+sources = [
+'GistPythonModule.cpp',
+'../src/Gist.cpp',
+'../src/core/CoreFrequencyDomainFeatures.cpp',
+'../src/core/CoreTimeDomainFeatures.cpp',
+'../src/mfcc/MFCC.cpp',
+'../src/onset-detection-functions/OnsetDetectionFunction.cpp',
+'../src/pitch/Yin.cpp',
+'../src/fft/WindowFunctions.cpp'
+]
+
+include_dirs = [
+ numpy.get_include(),'/usr/local/include'
+ ]
+
+setup( name = 'Gist',
+ include_dirs = include_dirs,
+ ext_modules = [Extension(name, sources,libraries = ['fftw3'],library_dirs = ['/usr/local/lib'],define_macros=[
+ ('USE_FFTW', None)],)]
+ )
\ No newline at end of file
diff --git a/src/dep/gist/src/Gist.cpp b/src/dep/gist/src/Gist.cpp
new file mode 100644
index 0000000..847160b
--- /dev/null
+++ b/src/dep/gist/src/Gist.cpp
@@ -0,0 +1,366 @@
+//=======================================================================
+/** @file Gist.cpp
+ * @brief Implementation for all relevant parts of the 'Gist' audio analysis library
+ * @author Adam Stark
+ * @copyright Copyright (C) 2013 Adam Stark
+ *
+ * This file is part of the 'Gist' audio analysis library
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+//=======================================================================
+
+#include "Gist.h"
+#include
+
+//=======================================================================
+template
+Gist::Gist (int audioFrameSize, int fs, WindowType windowType_)
+ : fftConfigured (false),
+ onsetDetectionFunction (audioFrameSize),
+ yin (fs),
+ mfcc (audioFrameSize, fs),
+ windowType (windowType_)
+{
+ samplingFrequency = fs;
+ setAudioFrameSize (audioFrameSize);
+}
+
+//=======================================================================
+template
+Gist::~Gist()
+{
+ if (fftConfigured)
+ {
+ freeFFT();
+ }
+}
+
+//=======================================================================
+template
+void Gist::setAudioFrameSize (int audioFrameSize)
+{
+ frameSize = audioFrameSize;
+
+ audioFrame.resize (frameSize);
+
+ windowFunction = WindowFunctions::createWindow (audioFrameSize, windowType);
+
+ fftReal.resize (frameSize);
+ fftImag.resize (frameSize);
+ magnitudeSpectrum.resize (frameSize / 2);
+
+ configureFFT();
+
+ onsetDetectionFunction.setFrameSize (frameSize);
+ mfcc.setFrameSize (frameSize);
+}
+
+//=======================================================================
+template
+void Gist::setSamplingFrequency (int fs)
+{
+ samplingFrequency = fs;
+ yin.setSamplingFrequency (samplingFrequency);
+ mfcc.setSamplingFrequency (samplingFrequency);
+}
+
+//=======================================================================
+template
+int Gist::getAudioFrameSize()
+{
+ return frameSize;
+}
+
+//=======================================================================
+template
+int Gist::getSamplingFrequency()
+{
+ return samplingFrequency;
+}
+
+//=======================================================================
+template
+void Gist::processAudioFrame (const std::vector& a)
+{
+ // you are passing an audio frame of a different size to the
+ // audio frame size setup in Gist
+ assert (a.size() == audioFrame.size());
+
+ std::copy (a.begin(), a.end(), audioFrame.begin());
+ performFFT();
+}
+
+//=======================================================================
+template
+void Gist::processAudioFrame (const T* frame, int numSamples)
+{
+ // you are passing an audio frame of a different size to the
+ // audio frame size setup in Gist
+ assert (numSamples == audioFrame.size());
+
+ for (int i = 0; i < audioFrame.size(); i++)
+ audioFrame[i] = frame[i];
+
+ performFFT();
+}
+
+//=======================================================================
+template
+const std::vector& Gist::getMagnitudeSpectrum()
+{
+ return magnitudeSpectrum;
+}
+
+//=======================================================================
+template
+T Gist::rootMeanSquare()
+{
+ return coreTimeDomainFeatures.rootMeanSquare (audioFrame);
+}
+
+//=======================================================================
+template
+T Gist::peakEnergy()
+{
+ return coreTimeDomainFeatures.peakEnergy (audioFrame);
+}
+
+//=======================================================================
+template
+T Gist::zeroCrossingRate()
+{
+ return coreTimeDomainFeatures.zeroCrossingRate (audioFrame);
+}
+
+//=======================================================================
+template
+T Gist::spectralCentroid()
+{
+ return coreFrequencyDomainFeatures.spectralCentroid (magnitudeSpectrum);
+}
+
+//=======================================================================
+template
+T Gist::spectralCrest()
+{
+ return coreFrequencyDomainFeatures.spectralCrest (magnitudeSpectrum);
+}
+
+//=======================================================================
+template
+T Gist::spectralFlatness()
+{
+ return coreFrequencyDomainFeatures.spectralFlatness (magnitudeSpectrum);
+}
+
+//=======================================================================
+template
+T Gist::spectralRolloff()
+{
+ return coreFrequencyDomainFeatures.spectralRolloff (magnitudeSpectrum);
+}
+
+//=======================================================================
+template
+T Gist::spectralKurtosis()
+{
+ return coreFrequencyDomainFeatures.spectralKurtosis (magnitudeSpectrum);
+}
+
+//=======================================================================
+template
+T Gist::energyDifference()
+{
+ return onsetDetectionFunction.energyDifference (audioFrame);
+}
+
+//=======================================================================
+template
+T Gist::spectralDifference()
+{
+ return onsetDetectionFunction.spectralDifference (magnitudeSpectrum);
+}
+
+//=======================================================================
+template
+T Gist::spectralDifferenceHWR()
+{
+ return onsetDetectionFunction.spectralDifferenceHWR (magnitudeSpectrum);
+}
+
+//=======================================================================
+template
+T Gist::complexSpectralDifference()
+{
+ return onsetDetectionFunction.complexSpectralDifference (fftReal, fftImag);
+}
+
+//=======================================================================
+template
+T Gist::highFrequencyContent()
+{
+ return onsetDetectionFunction.highFrequencyContent (magnitudeSpectrum);
+}
+
+//=======================================================================
+template
+T Gist::pitch()
+{
+ return yin.pitchYin (audioFrame);
+}
+
+//=======================================================================
+template
+const std::vector& Gist::getMelFrequencySpectrum()
+{
+ mfcc.calculateMelFrequencySpectrum (magnitudeSpectrum);
+ return mfcc.melSpectrum;
+}
+
+//=======================================================================
+template
+const std::vector& Gist::getMelFrequencyCepstralCoefficients()
+{
+ mfcc.calculateMelFrequencyCepstralCoefficients (magnitudeSpectrum);
+ return mfcc.MFCCs;
+}
+
+//=======================================================================
+template
+void Gist::configureFFT()
+{
+ if (fftConfigured)
+ {
+ freeFFT();
+ }
+
+#ifdef USE_FFTW
+ // ------------------------------------------------------
+ // initialise the fft time and frequency domain audio frame arrays
+ fftIn = (fftw_complex*)fftw_malloc (sizeof (fftw_complex) * frameSize); // complex array to hold fft data
+ fftOut = (fftw_complex*)fftw_malloc (sizeof (fftw_complex) * frameSize); // complex array to hold fft data
+
+ // FFT plan initialisation
+ p = fftw_plan_dft_1d (frameSize, fftIn, fftOut, FFTW_FORWARD, FFTW_ESTIMATE);
+#endif /* END USE_FFTW */
+
+#ifdef USE_KISS_FFT
+ // ------------------------------------------------------
+ // initialise the fft time and frequency domain audio frame arrays
+ fftIn = new kiss_fft_cpx[frameSize];
+ fftOut = new kiss_fft_cpx[frameSize];
+ cfg = kiss_fft_alloc (frameSize, 0, 0, 0);
+#endif /* END USE_KISS_FFT */
+
+#ifdef USE_ACCELERATE_FFT
+ accelerateFFT.setAudioFrameSize (frameSize);
+#endif
+
+ fftConfigured = true;
+}
+
+//=======================================================================
+template
+void Gist::freeFFT()
+{
+#ifdef USE_FFTW
+ // destroy fft plan
+ fftw_destroy_plan (p);
+
+ fftw_free (fftIn);
+ fftw_free (fftOut);
+#endif
+
+#ifdef USE_KISS_FFT
+ // free the Kiss FFT configuration
+ free (cfg);
+
+ delete[] fftIn;
+ delete[] fftOut;
+#endif
+}
+
+//=======================================================================
+template
+void Gist::performFFT()
+{
+#ifdef USE_FFTW
+ // copy samples from audio frame
+ for (int i = 0; i < frameSize; i++)
+ {
+ fftIn[i][0] = (double)(audioFrame[i] * windowFunction[i]);
+ fftIn[i][1] = (double)0.0;
+ }
+
+ // perform the FFT
+ fftw_execute (p);
+
+ // store real and imaginary parts of FFT
+ for (int i = 0; i < frameSize; i++)
+ {
+ fftReal[i] = (T)fftOut[i][0];
+ fftImag[i] = (T)fftOut[i][1];
+ }
+#endif
+
+#ifdef USE_KISS_FFT
+ for (int i = 0; i < frameSize; i++)
+ {
+ fftIn[i].r = (double)(audioFrame[i] * windowFunction[i]);
+ fftIn[i].i = 0.0;
+ }
+
+ // execute kiss fft
+ kiss_fft (cfg, fftIn, fftOut);
+
+ // store real and imaginary parts of FFT
+ for (int i = 0; i < frameSize; i++)
+ {
+ fftReal[i] = (T)fftOut[i].r;
+ fftImag[i] = (T)fftOut[i].i;
+ }
+#endif
+
+#ifdef USE_ACCELERATE_FFT
+
+ T inputFrame[frameSize];
+ T outputReal[frameSize];
+ T outputImag[frameSize];
+
+ for (int i = 0; i < frameSize; i++)
+ {
+ inputFrame[i] = audioFrame[i] * windowFunction[i];
+ }
+
+ accelerateFFT.performFFT (inputFrame, outputReal, outputImag);
+
+ for (int i = 0; i < frameSize; i++)
+ {
+ fftReal[i] = outputReal[i];
+ fftImag[i] = outputImag[i];
+ }
+
+#endif
+
+ // calculate the magnitude spectrum
+ for (int i = 0; i < frameSize / 2; i++)
+ {
+ magnitudeSpectrum[i] = sqrt ((fftReal[i] * fftReal[i]) + (fftImag[i] * fftImag[i]));
+ }
+}
+
+//===========================================================
+template class Gist;
+template class Gist;
diff --git a/src/dep/gist/src/Gist.h b/src/dep/gist/src/Gist.h
new file mode 100644
index 0000000..771e334
--- /dev/null
+++ b/src/dep/gist/src/Gist.h
@@ -0,0 +1,226 @@
+//=======================================================================
+/** @file Gist.h
+ * @brief Includes all relevant parts of the 'Gist' audio analysis library
+ * @author Adam Stark
+ * @copyright Copyright (C) 2013 Adam Stark
+ *
+ * This file is part of the 'Gist' audio analysis library
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+//=======================================================================
+
+#ifndef __GISTHEADER__
+#define __GISTHEADER__
+
+//=======================================================================
+// core
+#include "core/CoreTimeDomainFeatures.h"
+#include "core/CoreFrequencyDomainFeatures.h"
+
+// onset detection functions
+#include "onset-detection-functions/OnsetDetectionFunction.h"
+
+// pitch detection
+#include "pitch/Yin.h"
+
+// MFCC
+#include "mfcc/MFCC.h"
+
+//=======================================================================
+// fft
+
+#ifdef USE_FFTW
+#include "fftw3.h"
+#endif
+
+#ifdef USE_KISS_FFT
+#include "kiss_fft.h"
+#endif
+
+#ifdef USE_ACCELERATE_FFT
+#include "fft/AccelerateFFT.h"
+#endif
+
+#include "fft/WindowFunctions.h"
+
+//=======================================================================
+/** Class for all performing all Gist audio analyses */
+template
+class Gist
+{
+public:
+
+ //=======================================================================
+ /** Constructor
+ * @param audioFrameSize the input audio frame size
+ * @param fs the input audio sample rate
+ * @param windowType the type of window function to use
+ */
+ Gist (int audioFrameSize, int fs, WindowType windowType = HanningWindow);
+
+ /** Destructor */
+ ~Gist();
+
+ //=======================================================================
+ /** Set the audio frame size.
+ * @param frameSize_ the frame size to use
+ */
+ void setAudioFrameSize (int audioFrameSize);
+
+ /** Set the sampling frequency of input audio
+ * @param fs the sampling frequency
+ */
+ void setSamplingFrequency (int fs);
+
+ //=======================================================================
+ /** @Returns the audio frame size currently being used */
+ int getAudioFrameSize();
+
+ /** @Returns the audio sampling frequency being used for analysis */
+ int getSamplingFrequency();
+
+ //=======================================================================
+ /** Process an audio frame
+ * @param audioFrame a vector containing audio samples
+ */
+ void processAudioFrame (const std::vector& audioFrame_);
+
+ /** Process an audio frame
+ * @param frame a pointer to an array containing the audio frame
+ * @param numSamples the number of samples in the audio frame
+ */
+ void processAudioFrame (const T* frame, int numSamples);
+
+ /** Gist automatically calculates the magnitude spectrum when processAudioFrame() is called, this function returns it.
+ @returns the current magnitude spectrum */
+ const std::vector& getMagnitudeSpectrum();
+
+ //================= CORE TIME DOMAIN FEATURES =================
+
+ /** @Returns the root mean square (RMS) of the currently stored audio frame */
+ T rootMeanSquare();
+
+ /** @Returns the peak energy of the currently stored audio frame */
+ T peakEnergy();
+
+ /** @Returns the zero crossing rate of the currently stored audio frame */
+ T zeroCrossingRate();
+
+ //=============== CORE FREQUENCY DOMAIN FEATURES ==============
+
+ /** @Returns the spectral centroid from the magnitude spectrum */
+ T spectralCentroid();
+
+ /** @Returns the spectral crest */
+ T spectralCrest();
+
+ /** @Returns the spectral flatness of the magnitude spectrum */
+ T spectralFlatness();
+
+ /** @Returns the spectral rolloff of the magnitude spectrum */
+ T spectralRolloff();
+
+ /** @Returns the spectral kurtosis of the magnitude spectrum */
+ T spectralKurtosis();
+
+ //================= ONSET DETECTION FUNCTIONS =================
+
+ /** @Returns the energy difference onset detection function sample for the magnitude spectrum frame */
+ T energyDifference();
+
+ /** @Returns the spectral difference onset detection function sample for the magnitude spectrum frame */
+ T spectralDifference();
+
+ /** @Returns the half wave rectified complex spectral difference onset detection function sample for the magnitude spectrum frame */
+ T spectralDifferenceHWR();
+
+ /** @Returns the complex spectral difference onset detection function sample for the magnitude spectrum frame */
+ T complexSpectralDifference();
+
+ /** @Returns the high frequency content onset detection function sample for the magnitude spectrum frame */
+ T highFrequencyContent();
+
+ //=========================== PITCH ============================
+
+ /** @Returns a monophonic pitch estimate according to the Yin algorithm */
+ T pitch();
+
+ //=========================== MFCCs =============================
+
+ /** Calculates the Mel Frequency Spectrum */
+ const std::vector& getMelFrequencySpectrum();
+
+ /** Calculates the Mel-frequency Cepstral Coefficients */
+ const std::vector& getMelFrequencyCepstralCoefficients();
+
+private:
+ //=======================================================================
+
+ /** Configure the FFT implementation given the audio frame size) */
+ void configureFFT();
+
+ /** Free all FFT-related data */
+ void freeFFT();
+
+ /** perform the FFT on the current audio frame */
+ void performFFT();
+
+ //=======================================================================
+
+#ifdef USE_FFTW
+ fftw_plan p; /**< fftw plan */
+ fftw_complex* fftIn; /**< to hold complex fft values for input */
+ fftw_complex* fftOut; /**< to hold complex fft values for output */
+#endif
+
+#ifdef USE_KISS_FFT
+ kiss_fft_cfg cfg; /**< Kiss FFT configuration */
+ kiss_fft_cpx* fftIn; /**< FFT input samples, in complex form */
+ kiss_fft_cpx* fftOut; /**< FFT output samples, in complex form */
+#endif
+
+#ifdef USE_ACCELERATE_FFT
+ AccelerateFFT accelerateFFT;
+#endif
+
+ int frameSize; /**< The audio frame size */
+ int samplingFrequency; /**< The sampling frequency used for analysis */
+ WindowType windowType; /**< The window type used in FFT analysis */
+
+ std::vector audioFrame; /**< The current audio frame */
+ std::vector windowFunction; /**< The window function used in FFT processing */
+ std::vector fftReal; /**< The real part of the FFT for the current audio frame */
+ std::vector fftImag; /**< The imaginary part of the FFT for the current audio frame */
+ std::vector magnitudeSpectrum; /**< The magnitude spectrum of the current audio frame */
+
+ bool fftConfigured;
+
+ /** object to compute core time domain features */
+ CoreTimeDomainFeatures coreTimeDomainFeatures;
+
+ /** object to compute core frequency domain features */
+ CoreFrequencyDomainFeatures coreFrequencyDomainFeatures;
+
+ /** object to compute onset detection functions */
+ OnsetDetectionFunction onsetDetectionFunction;
+
+ /** object to compute pitch estimates via the Yin algorithm */
+ Yin yin;
+
+ /** object to compute MFCCs and mel-frequency specta */
+ MFCC mfcc;
+};
+
+#endif
diff --git a/src/dep/gist/src/core/CoreFrequencyDomainFeatures.cpp b/src/dep/gist/src/core/CoreFrequencyDomainFeatures.cpp
new file mode 100644
index 0000000..c613511
--- /dev/null
+++ b/src/dep/gist/src/core/CoreFrequencyDomainFeatures.cpp
@@ -0,0 +1,198 @@
+//=======================================================================
+/** @file CoreFrequencyDomainFeatures.cpp
+ * @brief Implementations of common frequency domain audio features
+ * @author Adam Stark
+ * @copyright Copyright (C) 2013 Adam Stark
+ *
+ * This file is part of the 'Gist' audio analysis library
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+//=======================================================================
+
+#include "CoreFrequencyDomainFeatures.h"
+
+//===========================================================
+template
+CoreFrequencyDomainFeatures::CoreFrequencyDomainFeatures()
+{
+}
+
+//===========================================================
+template
+T CoreFrequencyDomainFeatures::spectralCentroid (const std::vector& magnitudeSpectrum)
+{
+ // to hold sum of amplitudes
+ T sumAmplitudes = 0.0;
+
+ // to hold sum of weighted amplitudes
+ T sumWeightedAmplitudes = 0.0;
+
+ // for each bin in the first half of the magnitude spectrum
+ for (int i = 0; i < magnitudeSpectrum.size(); i++)
+ {
+ // sum amplitudes
+ sumAmplitudes += magnitudeSpectrum[i];
+
+ // sum amplitudes weighted by the bin number
+ sumWeightedAmplitudes += magnitudeSpectrum[i] * i;
+ }
+
+ // if the sum of amplitudes is larger than zero (it should be if the buffer wasn't
+ // all zeros)
+ if (sumAmplitudes > 0)
+ {
+ // the spectral centroid is the sum of weighted amplitudes divided by the sum of amplitdues
+ return sumWeightedAmplitudes / sumAmplitudes;
+ }
+ else // to be safe just return zero
+ {
+ return 0.0;
+ }
+}
+
+//===========================================================
+template
+T CoreFrequencyDomainFeatures::spectralFlatness (const std::vector& magnitudeSpectrum)
+{
+ double sumVal = 0.0;
+ double logSumVal = 0.0;
+ double N = (double)magnitudeSpectrum.size();
+
+ T flatness;
+
+ for (int i = 0; i < magnitudeSpectrum.size(); i++)
+ {
+ // add one to stop zero values making it always zero
+ double v = (double)(1 + magnitudeSpectrum[i]);
+
+ sumVal += v;
+ logSumVal += log (v);
+ }
+
+ sumVal = sumVal / N;
+ logSumVal = logSumVal / N;
+
+ if (sumVal > 0)
+ {
+ flatness = (T)(exp (logSumVal) / sumVal);
+ }
+ else
+ {
+ flatness = 0.0;
+ }
+
+ return flatness;
+}
+
+//===========================================================
+template
+T CoreFrequencyDomainFeatures::spectralCrest (const std::vector& magnitudeSpectrum)
+{
+ T sumVal = 0.0;
+ T maxVal = 0.0;
+ T N = (T)magnitudeSpectrum.size();
+
+ for (int i = 0; i < magnitudeSpectrum.size(); i++)
+ {
+ T v = magnitudeSpectrum[i] * magnitudeSpectrum[i];
+ sumVal += v;
+
+ if (v > maxVal)
+ {
+ maxVal = v;
+ }
+ }
+
+ T spectralCrest;
+
+ if (sumVal > 0)
+ {
+ T meanVal = sumVal / N;
+
+ spectralCrest = maxVal / meanVal;
+ }
+ else
+ {
+ // this is a ratio so we return 1.0 if the buffer is just zeros
+ spectralCrest = 1.0;
+ }
+
+ return spectralCrest;
+}
+
+//===========================================================
+template
+T CoreFrequencyDomainFeatures::spectralRolloff (const std::vector& magnitudeSpectrum, T percentile)
+{
+ T sumOfMagnitudeSpectrum = std::accumulate (magnitudeSpectrum.begin(), magnitudeSpectrum.end(), 0);
+ T threshold = sumOfMagnitudeSpectrum * percentile;
+
+ T cumulativeSum = 0;
+ int index = 0;
+
+ for (int i = 0; i < magnitudeSpectrum.size();i++)
+ {
+ cumulativeSum += magnitudeSpectrum[i];
+
+ if (cumulativeSum > threshold)
+ {
+ index = i;
+ break;
+ }
+ }
+
+ T spectralRolloff = ((T)index) / ((T)magnitudeSpectrum.size());
+
+ return spectralRolloff;
+}
+
+//===========================================================
+template
+T CoreFrequencyDomainFeatures::spectralKurtosis (const std::vector& magnitudeSpectrum)
+{
+ // https://en.wikipedia.org/wiki/Kurtosis#Sample_kurtosis
+
+ T sumOfMagnitudeSpectrum = std::accumulate (magnitudeSpectrum.begin(), magnitudeSpectrum.end(), 0);
+
+ T mean = sumOfMagnitudeSpectrum / (T)magnitudeSpectrum.size();
+
+ T moment2 = 0;
+ T moment4 = 0;
+
+ for (int i = 0; i < magnitudeSpectrum.size(); i++)
+ {
+ T difference = magnitudeSpectrum[i] - mean;
+ T squaredDifference = difference*difference;
+
+ moment2 += squaredDifference;
+ moment4 += squaredDifference*squaredDifference;
+ }
+
+ moment2 = moment2 / (T)magnitudeSpectrum.size();
+ moment4 = moment4 / (T)magnitudeSpectrum.size();
+
+ if (moment2 == 0)
+ {
+ return -3.;
+ }
+ else
+ {
+ return (moment4 / (moment2*moment2)) - 3.;
+ }
+}
+
+//===========================================================
+template class CoreFrequencyDomainFeatures;
+template class CoreFrequencyDomainFeatures;
diff --git a/src/dep/gist/src/core/CoreFrequencyDomainFeatures.h b/src/dep/gist/src/core/CoreFrequencyDomainFeatures.h
new file mode 100644
index 0000000..99db215
--- /dev/null
+++ b/src/dep/gist/src/core/CoreFrequencyDomainFeatures.h
@@ -0,0 +1,86 @@
+//=======================================================================
+/** @file CoreFrequencyDomainFeatures.h
+ * @brief Implementations of common frequency domain audio features
+ * @author Adam Stark
+ * @copyright Copyright (C) 2013 Adam Stark
+ *
+ * This file is part of the 'Gist' audio analysis library
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+//=======================================================================
+
+#ifndef __GIST__COREFREQUENCYDOMAINFEATURES__
+#define __GIST__COREFREQUENCYDOMAINFEATURES__
+
+#include
+#include
+#include
+
+/** template class for calculating common frequency domain
+ * audio features. Instantiations of the class should be
+ * of either 'float' or 'double' types and no others */
+template
+class CoreFrequencyDomainFeatures
+{
+public:
+ /** constructor */
+ CoreFrequencyDomainFeatures();
+
+ //===========================================================
+ /** calculates the spectral centroid given the first half of the magnitude spectrum
+ of an audio signal. Do not pass the whole (i.e. mirrored) magnitude spectrum into
+ this function or you will always get the middle index as the spectral centroid
+ @param magnitudeSpectrum the first half of the magnitude spectrum (i.e. not mirrored)
+ @returns the spectral centroid as an index value
+ */
+ T spectralCentroid (const std::vector& magnitudeSpectrum);
+
+ //===========================================================
+ /** calculates the spectral flatness given the first half of the magnitude spectrum
+ of an audio signal.
+ @param magnitudeSpectrum the first half of the magnitude spectrum (i.e. not mirrored)
+ @returns the spectral flatness
+ */
+ T spectralFlatness (const std::vector& magnitudeSpectrum);
+
+ //===========================================================
+ /** calculates the spectral crest given the first half of the magnitude spectrum
+ of an audio signal.
+ @param magnitudeSpectrum the first half of the magnitude spectrum (i.e. not mirrored)
+ @returns the spectral crest
+ */
+ T spectralCrest (const std::vector& magnitudeSpectrum);
+
+ //===========================================================
+ /** calculates the spectral rolloff given the first half of the magnitude spectrum
+ of an audio signal.
+ @param magnitudeSpectrum the first half of the magnitude spectrum (i.e. not mirrored)
+ @param percentile the rolloff threshold
+ @returns the spectral rolloff
+ */
+ T spectralRolloff (const std::vector& magnitudeSpectrum, T percentile = 0.85);
+
+ //===========================================================
+ /** calculates the spectral kurtosis given the first half of the magnitude spectrum
+ of an audio signal.
+ @param magnitudeSpectrum the first half of the magnitude spectrum (i.e. not mirrored)
+ @returns the spectral kurtosis
+ */
+ T spectralKurtosis (const std::vector& magnitudeSpectrum);
+
+
+};
+
+#endif
diff --git a/src/dep/gist/src/core/CoreTimeDomainFeatures.cpp b/src/dep/gist/src/core/CoreTimeDomainFeatures.cpp
new file mode 100644
index 0000000..22d4a89
--- /dev/null
+++ b/src/dep/gist/src/core/CoreTimeDomainFeatures.cpp
@@ -0,0 +1,103 @@
+//=======================================================================
+/** @file CoreTimeDomainFeatures.cpp
+ * @brief Implementations of common time domain audio features
+ * @author Adam Stark
+ * @copyright Copyright (C) 2013 Adam Stark
+ *
+ * This file is part of the 'Gist' audio analysis library
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+//=======================================================================
+
+#include "CoreTimeDomainFeatures.h"
+
+//===========================================================
+template
+CoreTimeDomainFeatures::CoreTimeDomainFeatures()
+{
+}
+
+//===========================================================
+template
+T CoreTimeDomainFeatures::rootMeanSquare (const std::vector& buffer)
+{
+ // create variable to hold the sum
+ T sum = 0;
+
+ // sum the squared samples
+ for (int i = 0; i < buffer.size(); i++)
+ {
+ sum += pow (buffer[i], 2);
+ }
+
+ // return the square root of the mean of squared samples
+ return sqrt (sum / ((T)buffer.size()));
+}
+
+//===========================================================
+template
+T CoreTimeDomainFeatures::peakEnergy (const std::vector& buffer)
+{
+ // create variable with very small value to hold the peak value
+ T peak = -10000.0;
+
+ // for each audio sample
+ for (int i = 0; i < buffer.size(); i++)
+ {
+ // store the absolute value of the sample
+ T absSample = fabs (buffer[i]);
+
+ // if the absolute value is larger than the peak
+ if (absSample > peak)
+ {
+ // the peak takes on the sample value
+ peak = absSample;
+ }
+ }
+
+ // return the peak value
+ return peak;
+}
+
+//===========================================================
+template
+T CoreTimeDomainFeatures::zeroCrossingRate (const std::vector& buffer)
+{
+ // create a variable to hold the zero crossing rate
+ T zcr = 0;
+
+ // for each audio sample, starting from the second one
+ for (int i = 1; i < buffer.size(); i++)
+ {
+ // initialise two booleans indicating whether or not
+ // the current and previous sample are positive
+ bool current = (buffer[i] > 0);
+ bool previous = (buffer[i - 1] > 0);
+
+ // if the sign is different
+ if (current != previous)
+ {
+ // add one to the zero crossing rate
+ zcr = zcr + 1.0;
+ }
+ }
+
+ // return the zero crossing rate
+ return zcr;
+}
+
+//===========================================================
+template class CoreTimeDomainFeatures;
+template class CoreTimeDomainFeatures;
diff --git a/src/dep/gist/src/core/CoreTimeDomainFeatures.h b/src/dep/gist/src/core/CoreTimeDomainFeatures.h
new file mode 100644
index 0000000..958cd3a
--- /dev/null
+++ b/src/dep/gist/src/core/CoreTimeDomainFeatures.h
@@ -0,0 +1,64 @@
+//=======================================================================
+/** @file CoreTimeDomainFeatures.h
+ * @brief Implementations of common time domain audio features
+ * @author Adam Stark
+ * @copyright Copyright (C) 2013 Adam Stark
+ *
+ * This file is part of the 'Gist' audio analysis library
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+//=======================================================================
+
+#ifndef __GIST__CORETIMEDOMAINFEATURES__
+#define __GIST__CORETIMEDOMAINFEATURES__
+
+#include
+#include
+
+/** template class for calculating common time domain
+ * audio features. Instantiations of the class should be
+ * of either 'float' or 'double' types and no others */
+template
+class CoreTimeDomainFeatures
+{
+public:
+ /** constructor */
+ CoreTimeDomainFeatures();
+
+ //===========================================================
+ /** calculates the Root Mean Square (RMS) of an audio buffer
+ * in vector format
+ * @param buffer a time domain buffer containing audio samples
+ * @returns the RMS value
+ */
+ T rootMeanSquare (const std::vector& buffer);
+
+ //===========================================================
+ /** calculates the peak energy (max absolute value) in a time
+ * domain audio signal buffer in vector format
+ * @param buffer a time domain buffer containing audio samples
+ * @returns the peak energy value
+ */
+ T peakEnergy (const std::vector& buffer);
+
+ //===========================================================
+ /** calculates the zero crossing rate of a time domain audio signal buffer
+ * @param buffer a time domain buffer containing audio samples
+ * @returns the zero crossing rate
+ */
+ T zeroCrossingRate (const std::vector& buffer);
+};
+
+#endif
diff --git a/src/dep/gist/src/fft/AccelerateFFT.cpp b/src/dep/gist/src/fft/AccelerateFFT.cpp
new file mode 100644
index 0000000..055d1b5
--- /dev/null
+++ b/src/dep/gist/src/fft/AccelerateFFT.cpp
@@ -0,0 +1,178 @@
+// //=======================================================================
+// /** @file AccelerateFFT.cpp
+// * @brief Performs the FFT using the Apple Accelerate Framework
+// * @author Adam Stark
+// * @copyright Copyright (C) 2013 Adam Stark
+// *
+// * This file is part of the 'Gist' audio analysis library
+// *
+// * This program is free software: you can redistribute it and/or modify
+// * it under the terms of the GNU General Public License as published by
+// * the Free Software Foundation, either version 3 of the License, or
+// * (at your option) any later version.
+// *
+// * This program is distributed in the hope that it will be useful,
+// * but WITHOUT ANY WARRANTY; without even the implied warranty of
+// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// * GNU General Public License for more details.
+// *
+// * You should have received a copy of the GNU General Public License
+// * along with this program. If not, see .
+// */
+// //=======================================================================
+//
+// #include "AccelerateFFT.h"
+// #include
+//
+// //=======================================================================
+// template
+// AccelerateFFT::AccelerateFFT()
+// {
+// complexSplit.realp = nullptr;
+// complexSplit.imagp = nullptr;
+// doubleComplexSplit.realp = nullptr;
+// doubleComplexSplit.imagp = nullptr;
+//
+// configured = false;
+// }
+//
+//
+// //=======================================================================
+// template <>
+// void AccelerateFFT::setAudioFrameSize (int frameSize)
+// {
+// fftSize = frameSize;
+// fftSizeOver2 = fftSize / 2;
+// log2n = log2f (fftSize);
+//
+// if (configured)
+// {
+// free (complexSplit.realp);
+// free (complexSplit.imagp);
+// vDSP_destroy_fftsetup (fftSetupFloat);
+// }
+//
+// complexSplit.realp = (float*)malloc (fftSize * sizeof (float));
+// complexSplit.imagp = (float*)malloc (fftSize * sizeof (float));
+//
+// fftSetupFloat = vDSP_create_fftsetup (log2n, FFT_RADIX2);
+//
+// if (fftSetupFloat == nullptr)
+// {
+// // couldn't set up FFT
+// assert (false);
+// }
+//
+// configured = true;
+// }
+//
+// //=======================================================================
+// template <>
+// void AccelerateFFT::setAudioFrameSize (int frameSize)
+// {
+// fftSize = frameSize;
+// fftSizeOver2 = fftSize / 2;
+// log2n = log2f (fftSize);
+//
+// if (configured)
+// {
+// free (doubleComplexSplit.realp);
+// free (doubleComplexSplit.imagp);
+// vDSP_destroy_fftsetupD (fftSetupDouble);
+// }
+//
+// doubleComplexSplit.realp = (double*)malloc (fftSize * sizeof (double));
+// doubleComplexSplit.imagp = (double*)malloc (fftSize * sizeof (double));
+//
+// fftSetupDouble = vDSP_create_fftsetupD (log2n, FFT_RADIX2);
+//
+// if (fftSetupDouble == nullptr)
+// {
+// // couldn't set up FFT
+// assert (false);
+// }
+//
+// configured = true;
+// }
+//
+// //=======================================================================
+// template <>
+// AccelerateFFT::~AccelerateFFT()
+// {
+// free (complexSplit.realp);
+// free (complexSplit.imagp);
+// vDSP_destroy_fftsetup (fftSetupFloat);
+// }
+//
+// //=======================================================================
+// template <>
+// AccelerateFFT::~AccelerateFFT()
+// {
+// free (doubleComplexSplit.realp);
+// free (doubleComplexSplit.imagp);
+// vDSP_destroy_fftsetupD (fftSetupDouble);
+// }
+//
+// //=======================================================================
+// template <>
+// void AccelerateFFT