ref: bcf38fe01822c610831591851df8abd76bfaacf7
parent: 2d8cffabb484b5bee7d4d44c8f753d95ca841d03
author: Paul Brossier <[email protected]>
date: Sat Nov 24 16:08:04 EST 2007
src/: move tempo files to src/tempo, continue moving pitch and onset files
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -10,19 +10,19 @@
hist.h \
scale.h \
resample.h \
- onset/onsetdetection.h \
tss.h \
- peakpick.h \
biquad.h \
- pitchdetection.h \
+ pitch/pitchdetection.h \
pitch/pitchmcomb.h \
pitch/pitchyin.h \
pitch/pitchschmitt.h \
pitch/pitchfcomb.h \
pitch/pitchyinfft.h \
- beattracking.h \
- onset.h \
- tempo.h \
+ onset/onset.h \
+ onset/onsetdetection.h \
+ onset/peakpick.h \
+ tempo/tempo.h \
+ tempo/beattracking.h \
filter.h \
filterbank.h \
mfcc.h
@@ -48,16 +48,12 @@
scale.h \
resample.c \
resample.h \
- onset/onsetdetection.c \
- onset/onsetdetection.h \
tss.c \
tss.h \
- peakpick.c \
- peakpick.h \
biquad.c \
biquad.h \
- pitchdetection.c \
- pitchdetection.h \
+ pitch/pitchdetection.c \
+ pitch/pitchdetection.h \
pitch/pitchmcomb.c \
pitch/pitchmcomb.h \
pitch/pitchyin.c \
@@ -68,12 +64,16 @@
pitch/pitchfcomb.h \
pitch/pitchyinfft.c \
pitch/pitchyinfft.h \
- beattracking.c \
- beattracking.h \
- onset.c \
- onset.h \
- tempo.c \
- tempo.h \
+ onset/onset.c \
+ onset/onset.h \
+ onset/onsetdetection.c \
+ onset/onsetdetection.h \
+ onset/peakpick.c \
+ onset/peakpick.h \
+ tempo/tempo.c \
+ tempo/tempo.h \
+ tempo/beattracking.c \
+ tempo/beattracking.h \
filter.c \
filter.h \
filterbank.c \
--- a/src/aubio.h
+++ b/src/aubio.h
@@ -66,19 +66,19 @@
#include "hist.h"
#include "tss.h"
#include "resample.h"
-#include "peakpick.h"
#include "biquad.h"
#include "filter.h"
-#include "pitchdetection.h"
+#include "pitch/pitchdetection.h"
#include "pitch/pitchmcomb.h"
#include "pitch/pitchyin.h"
#include "pitch/pitchyinfft.h"
#include "pitch/pitchschmitt.h"
#include "pitch/pitchfcomb.h"
-#include "beattracking.h"
-#include "onset/detection.h"
-#include "onset.h"
-#include "tempo.h"
+#include "onset/onsetdetection.h"
+#include "onset/onset.h"
+#include "onset/peakpick.h"
+#include "tempo/beattracking.h"
+#include "tempo/tempo.h"
#include "filterbank.h"
#include "mfcc.h"
--- a/src/beattracking.c
+++ /dev/null
@@ -1,467 +1,0 @@
-/*
- Copyright (C) 2005 Matthew Davies and Paul Brossier
-
- 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 2 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, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-*/
-
-#include "aubio_priv.h"
-#include "sample.h"
-#include "mathutils.h"
-#include "beattracking.h"
-
-uint_t fvec_gettimesig(smpl_t * acf, uint_t acflen, uint_t gp);
-void aubio_beattracking_checkstate(aubio_beattracking_t * bt);
-smpl_t fvec_getperiod(aubio_beattracking_t * bt);
-
-struct _aubio_beattracking_t {
- fvec_t * rwv; /** rayleigh weight vector - rayleigh distribution function */
- fvec_t * gwv; /** rayleigh weight vector - rayleigh distribution function */
- fvec_t * dfwv; /** detection function weighting - exponential curve */
- fvec_t * dfrev; /** reversed onset detection function */
- fvec_t * acf; /** vector for autocorrelation function (of current detection function frame) */
- fvec_t * acfout; /** store result of passing acf through s.i.c.f.b. */
- fvec_t * phwv; /** beat expectation alignment weighting */
- fvec_t * phout;
- uint_t timesig; /** time signature of input, set to zero until context dependent model activated */
- uint_t step;
- fvec_t * locacf; /** vector to store harmonics of filterbank of acf */
- fvec_t * inds; /** vector for max index outputs for each harmonic */
- uint_t rayparam; /** Rayleigh parameter */
- uint_t lastbeat;
- sint_t counter;
- uint_t flagstep;
- smpl_t g_var;
- uint_t gp;
- uint_t bp;
- uint_t rp;
- uint_t rp1;
- uint_t rp2;
-};
-
-aubio_beattracking_t * new_aubio_beattracking(uint_t winlen,
- uint_t channels) {
-
- aubio_beattracking_t * p = AUBIO_NEW(aubio_beattracking_t);
- uint_t i = 0;
- /* parameter for rayleigh weight vector - sets preferred tempo to
- * 120bpm [43] */
- smpl_t rayparam = 48./512. * winlen;
- smpl_t dfwvnorm = EXP((LOG(2.0)/rayparam)*(winlen+2));
- /** length over which beat period is found [128] */
- uint_t laglen = winlen/4;
- /** step increment - both in detection function samples -i.e. 11.6ms or
- * 1 onset frame [128] */
- uint_t step = winlen/4; /* 1.5 seconds */
-
- uint_t maxnumelem = 4; /* max number of index output */
- p->lastbeat = 0;
- p->counter = 0;
- p->flagstep = 0;
- p->g_var = 3.901; // constthresh empirically derived!
- p->rp = 1;
- p->gp = 0;
-
- p->rayparam = rayparam;
- p->step = step;
- p->rwv = new_fvec(laglen,channels);
- p->gwv = new_fvec(laglen,channels);
- p->dfwv = new_fvec(winlen,channels);
- p->dfrev = new_fvec(winlen,channels);
- p->acf = new_fvec(winlen,channels);
- p->acfout = new_fvec(laglen,channels);
- p->phwv = new_fvec(2*laglen,channels);
- p->phout = new_fvec(winlen,channels);
-
- p->timesig = 0;
-
- p->inds = new_fvec(maxnumelem,channels);
- p->locacf = new_fvec(winlen,channels);
-
- /* exponential weighting, dfwv = 0.5 when i = 43 */
- for (i=0;i<winlen;i++) {
- p->dfwv->data[0][i] = (EXP((LOG(2.0)/rayparam)*(i+1)))
- / dfwvnorm;
- }
-
- for (i=0;i<(laglen);i++){
- p->rwv->data[0][i] = ((smpl_t)(i+1.) / SQR((smpl_t)rayparam)) *
- EXP((-SQR((smpl_t)(i+1.)) / (2.*SQR((smpl_t)rayparam))));
- }
-
- return p;
-
-}
-
-void del_aubio_beattracking(aubio_beattracking_t * p) {
- del_fvec(p->rwv);
- del_fvec(p->gwv);
- del_fvec(p->dfwv);
- del_fvec(p->dfrev);
- del_fvec(p->acf);
- del_fvec(p->acfout);
- del_fvec(p->phwv);
- del_fvec(p->phout);
- del_fvec(p->locacf);
- del_fvec(p->inds);
- AUBIO_FREE(p);
-}
-
-
-void aubio_beattracking_do(aubio_beattracking_t * bt, fvec_t * dfframe, fvec_t * output) {
-
- uint_t i,k;
- /* current beat period value found using gaussian weighting (from context dependent model) */
- uint_t step = bt->step;
- uint_t laglen = bt->rwv->length;
- uint_t winlen = bt->dfwv->length;
- smpl_t * phout = bt->phout->data[0];
- smpl_t * phwv = bt->phwv->data[0];
- smpl_t * dfrev = bt->dfrev->data[0];
- smpl_t * dfwv = bt->dfwv->data[0];
- smpl_t * rwv = bt->rwv->data[0];
- smpl_t * acfout = bt->acfout->data[0];
- smpl_t * acf = bt->acf->data[0];
- uint_t maxindex = 0;
- //number of harmonics in shift invariant comb filterbank
- uint_t numelem = 4;
-
- //smpl_t myperiod = 0.;
- //smpl_t * out = output->data[0];
-
- //parameters for making s.i.c.f.b.
- uint_t a,b;
- //beat alignment
- uint_t phase;
- uint_t kmax;
- sint_t beat;
- uint_t bp;
-
- for (i = 0; i < winlen; i++){
- dfrev[winlen-1-i] = 0.;
- dfrev[winlen-1-i] = dfframe->data[0][i]*dfwv[i];
- }
-
- /* find autocorrelation function */
- aubio_autocorr(dfframe,bt->acf);
- /*
- for (i = 0; i < winlen; i++){
- AUBIO_DBG("%f,",acf[i]);
- }
- AUBIO_DBG("\n");
- */
-
- /* get acfout - assume Rayleigh weightvector only */
- /* if timesig is unknown, use metrically unbiased version of filterbank */
- if(!bt->timesig)
- numelem = 4;
- // AUBIO_DBG("using unbiased filterbank, timesig: %d\n", timesig);
- else
- numelem = bt->timesig;
- // AUBIO_DBG("using biased filterbank, timesig: %d\n", timesig);
-
- /* first and last output values are left intentionally as zero */
- for (i=0; i < bt->acfout->length; i++)
- acfout[i] = 0.;
-
- for(i=1;i<laglen-1;i++){
- for (a=1; a<=numelem; a++){
- for(b=(1-a); b<a; b++){
- acfout[i] += acf[a*(i+1)+b-1]
- * 1./(2.*a-1.)*rwv[i];
- }
- }
- }
-
- /* find non-zero Rayleigh period */
- maxindex = vec_max_elem(bt->acfout);
- bt->rp = maxindex ? maxindex : 1;
- //rp = (maxindex==127) ? 43 : maxindex; //rayparam
- bt->rp = (maxindex==bt->acfout->length-1) ? bt->rayparam : maxindex; //rayparam
-
- // get float period
- //myperiod = fvec_getperiod(bt);
- //AUBIO_DBG("\nrp = %d myperiod = %f\n",bt->rp,myperiod);
- //AUBIO_DBG("accurate tempo is %f bpm\n",5168./myperiod);
-
- /* activate biased filterbank */
- aubio_beattracking_checkstate(bt);
- bp = bt->bp;
- /* end of biased filterbank */
-
- /* initialize output */
- for(i=0;i<bt->phout->length;i++) {phout[i] = 0.;}
-
- /* deliberate integer operation, could be set to 3 max eventually */
- kmax = winlen/bp;
-
- for(i=0;i<bp;i++){
- phout[i] = 0.;
- for(k=0;k<kmax;k++){
- phout[i] += dfrev[i+bp*k] * phwv[i];
- }
- }
-
- /* find Rayleigh period */
- maxindex = vec_max_elem(bt->phout);
- if (maxindex == winlen-1) maxindex = 0;
- phase = 1 + maxindex;
-
- /* debug */
- //AUBIO_DBG("beat period = %d, rp1 = %d, rp2 = %d\n", bp, rp1, rp2);
- //AUBIO_DBG("rp = %d, gp = %d, phase = %d\n", bt->rp, bt->gp, phase);
-
- /* reset output */
- for (i = 0; i < laglen; i++)
- output->data[0][i] = 0.;
-
- i = 1;
- beat = bp - phase;
- /* start counting the beats */
- if(beat >= 0)
- {
- output->data[0][i] = (smpl_t)beat;
- i++;
- }
-
- while( beat+bp < step )
- {
- beat += bp;
- output->data[0][i] = (smpl_t)beat;
- i++;
- }
-
- bt->lastbeat = beat;
- /* store the number of beat found in this frame as the first element */
- output->data[0][0] = i;
-}
-
-uint_t fvec_gettimesig(smpl_t * acf, uint_t acflen, uint_t gp){
- sint_t k = 0;
- smpl_t three_energy = 0., four_energy = 0.;
- if( acflen > 6 * gp + 2 ){
- for(k=-2;k<2;k++){
- three_energy += acf[3*gp+k];
- four_energy += acf[4*gp+k];
- }
- }
- else{ /*Expanded to be more accurate in time sig estimation*/
- for(k=-2;k<2;k++){
- three_energy += acf[3*gp+k]+acf[6*gp+k];
- four_energy += acf[4*gp+k]+acf[2*gp+k];
- }
- }
- return (three_energy > four_energy) ? 3 : 4;
-}
-
-smpl_t fvec_getperiod(aubio_beattracking_t * bt){
- /*function to make a more accurate beat period measurement.*/
-
- smpl_t period = 0.;
- smpl_t maxval = 0.;
- uint_t numelem = 4;
-
- sint_t a,b;
- uint_t i,j;
- uint_t acfmi = bt->rp; //acfout max index
- uint_t maxind = 0;
-
- if(!bt->timesig)
- numelem = 4;
- else
- numelem = bt->timesig;
-
- for (i=0;i<numelem;i++) // initialize
- bt->inds->data[0][i] = 0.;
-
- for (i=0;i<bt->locacf->length;i++) // initialize
- bt->locacf->data[0][i] = 0.;
-
- // get appropriate acf elements from acf and store in locacf
- for (a=1;a<=4;a++){
- for(b=(1-a);b<a;b++){
- bt->locacf->data[0][a*(acfmi)+b-1] =
- bt->acf->data[0][a*(acfmi)+b-1];
- }
- }
-
- for(i=0;i<numelem;i++){
-
- maxind = 0;
- maxval = 0.0;
-
- for (j=0;j<(acfmi*(i+1)+(i)); j++){
- if(bt->locacf->data[0][j]>maxval){
- maxval = bt->locacf->data[0][j];
- maxind = j;
- }
- //bt->locacf->data[0][maxind] = 0.;
- bt->locacf->data[0][j] = 0.;
- }
- //AUBIO_DBG("\n maxind is %d\n",maxind);
- bt->inds->data[0][i] = maxind;
-
- }
-
- for (i=0;i<numelem;i++){
- period += bt->inds->data[0][i]/(i+1.);}
-
- period = period/numelem;
-
- return (period);
-}
-
-
-void aubio_beattracking_checkstate(aubio_beattracking_t * bt) {
- uint_t i,j,a,b;
- uint_t flagconst = 0;
- sint_t counter = bt->counter;
- uint_t flagstep = bt->flagstep;
- uint_t gp = bt->gp;
- uint_t bp = bt->bp;
- uint_t rp = bt->rp;
- uint_t rp1 = bt->rp1;
- uint_t rp2 = bt->rp2;
- uint_t laglen = bt->rwv->length;
- uint_t acflen = bt->acf->length;
- uint_t step = bt->step;
- smpl_t * acf = bt->acf->data[0];
- smpl_t * acfout = bt->acfout->data[0];
- smpl_t * gwv = bt->gwv->data[0];
- smpl_t * phwv = bt->phwv->data[0];
-
- if (gp) {
- // doshiftfbank again only if context dependent model is in operation
- //acfout = doshiftfbank(acf,gwv,timesig,laglen,acfout);
- //don't need acfout now, so can reuse vector
- // gwv is, in first loop, definitely all zeros, but will have
- // proper values when context dependent model is activated
- for (i=0; i < bt->acfout->length; i++)
- acfout[i] = 0.;
- for(i=1;i<laglen-1;i++){
- for (a=1;a<=bt->timesig;a++){
- for(b=(1-a);b<a;b++){
- acfout[i] += acf[a*(i+1)+b-1]
- * 1. * gwv[i];
- }
- }
- }
- gp = vec_max_elem(bt->acfout);
- /*
- while(gp<32) gp =gp*2;
- while(gp>64) gp = gp/2;
- */
- } else {
- //still only using general model
- gp = 0;
- }
-
- //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) {
- flagstep = 1; // have observed step change.
- counter = 3; // setup 3 frame counter
- } else {
- flagstep = 0;
- }
- }
-
- //i.e. 3rd frame after flagstep initially set
- if (counter==1 && flagstep==1) {
- //check for consistency between previous beatperiod values
- if(ABS(2.*rp - rp1 -rp2) < bt->g_var) {
- //if true, can activate context dependent model
- flagconst = 1;
- counter = 0; // reset counter and flagstep
- } else {
- //if not consistent, then don't flag consistency!
- flagconst = 0;
- counter = 2; // let it look next time
- }
- } else if (counter > 0) {
- //if counter doesn't = 1,
- counter = counter-1;
- }
-
- rp2 = rp1; rp1 = rp;
-
- if (flagconst) {
- /* first run of new hypothesis */
- gp = rp;
- bt->timesig = fvec_gettimesig(acf,acflen, gp);
- for(j=0;j<laglen;j++)
- gwv[j] = EXP(-.5*SQR((smpl_t)(j+1.-gp))/SQR(bt->g_var));
- flagconst = 0;
- bp = gp;
- /* flat phase weighting */
- for(j=0;j<2*laglen;j++) {phwv[j] = 1.;}
- } else if (bt->timesig) {
- /* context dependant model */
- bp = gp;
- /* gaussian phase weighting */
- if (step > bt->lastbeat) {
- for(j=0;j<2*laglen;j++) {
- phwv[j] = EXP(-.5*SQR((smpl_t)(1.+j-step+bt->lastbeat))/(bp/8.));
- }
- } else {
- //AUBIO_DBG("NOT using phase weighting as step is %d and lastbeat %d \n",
- // step,bt->lastbeat);
- for(j=0;j<2*laglen;j++) {phwv[j] = 1.;}
- }
- } else {
- /* initial state */
- bp = rp;
- /* flat phase weighting */
- for(j=0;j<2*laglen;j++) {phwv[j] = 1.;}
- }
-
- /* do some further checks on the final bp value */
-
- /* if tempo is > 206 bpm, half it */
- while (bp < 25) {
- //AUBIO_DBG("warning, doubling the beat period from %d\n", bp);
- //AUBIO_DBG("warning, halving the tempo from %f\n", 60.*samplerate/hopsize/bp);
- bp = bp*2;
- }
-
- //AUBIO_DBG("tempo:\t%3.5f bpm | ", 5168./bp);
-
- /* smoothing */
- //bp = (uint_t) (0.8 * (smpl_t)bp + 0.2 * (smpl_t)bp2);
- //AUBIO_DBG("tempo:\t%3.5f bpm smoothed | bp2 %d | bp %d | ", 5168./bp, bp2, bp);
- //bp2 = bp;
- //AUBIO_DBG("time signature: %d \n", bt->timesig);
- bt->counter = counter;
- bt->flagstep = flagstep;
- bt->gp = gp;
- bt->bp = bp;
- bt->rp1 = rp1;
- bt->rp2 = rp2;
-
-}
-
-smpl_t aubio_beattracking_get_bpm(aubio_beattracking_t * bt) {
- if (bt->timesig != 0 && bt->counter == 0 && bt->flagstep == 0) {
- return 5168. / (smpl_t)bt->gp;
- } else {
- return 0.;
- }
-}
-
-smpl_t aubio_beattracking_get_confidence(aubio_beattracking_t * bt) {
- if (bt->gp) return vec_max(bt->acfout);
- else return 0.;
-}
--- a/src/beattracking.h
+++ /dev/null
@@ -1,91 +1,0 @@
-/*
- Copyright (C) 2003 Matthew Davies and Paul Brossier
-
- 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 2 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, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-*/
-
-/** \file
-
- Beat tracking using a context dependant model
-
- This file implement the causal beat tracking algorithm designed by Matthew
- Davies and described in the following articles:
-
- Matthew E. P. Davies and Mark D. Plumbley. Causal tempo tracking of audio.
- In Proceedings of the International Symposium on Music Information Retrieval
- (ISMIR), pages 164169, Barcelona, Spain, 2004.
-
- Matthew E. P. Davies, Paul Brossier, and Mark D. Plumbley. Beat tracking
- towards automatic musical accompaniment. In Proceedings of the Audio
- Engeeniring Society 118th Convention, Barcelona, Spain, May 2005.
-
-*/
-#ifndef BEATTRACKING_H
-#define BEATTRACKING_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/** beat tracking object */
-typedef struct _aubio_beattracking_t aubio_beattracking_t;
-
-/** create beat tracking object
-
- \param winlen: frame size [512]
- \param channels number (not functionnal) [1]
-
-*/
-aubio_beattracking_t * new_aubio_beattracking(uint_t winlen, uint_t channels);
-/** 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
-
-*/
-void aubio_beattracking_do(aubio_beattracking_t * bt, fvec_t * dfframes, fvec_t * out);
-/** get current tempo in bpm
-
- \param bt beat tracking object
-
- Returns the currently observed tempo, in beats per minutes, or 0 if no
- consistent value is found.
-
-*/
-smpl_t aubio_beattracking_get_bpm(aubio_beattracking_t * bt);
-/** get current tempo confidence
-
- \param bt beat tracking object
-
- Returns the confidence with which the tempo has been observed, 0 if no
- consistent value is found.
-
-*/
-smpl_t aubio_beattracking_get_confidence(aubio_beattracking_t * bt);
-/** delete beat tracking object
-
- \param p beat tracking object
-
-*/
-void del_aubio_beattracking(aubio_beattracking_t * p);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* BEATTRACKING_H */
--- a/src/onset.c
+++ /dev/null
@@ -1,119 +1,0 @@
-/*
- Copyright (C) 2006 Paul Brossier
-
- 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 2 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, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-*/
-
-#include "aubio_priv.h"
-#include "sample.h"
-#include "onset/detection.h"
-#include "phasevoc.h"
-#include "peakpick.h"
-#include "mathutils.h"
-#include "onset.h"
-
-/** structure to store object state */
-struct _aubio_onset_t {
- aubio_pvoc_t * pv; /**< phase vocoder */
- aubio_onsetdetection_t * od; /**< onset detection */
- aubio_pickpeak_t * pp; /**< peak picker */
- cvec_t * fftgrain; /**< phase vocoder output */
- fvec_t * of; /**< onset detection function */
- smpl_t threshold; /**< onset peak picking threshold */
- smpl_t silence; /**< silence threhsold */
- uint_t minioi; /**< minimum inter onset interval */
- uint_t wasonset; /**< number of frames since last onset */
-};
-
-/* execute onset detection function on iput buffer */
-void aubio_onset(aubio_onset_t *o, fvec_t * input, fvec_t * onset)
-{
- uint_t isonset = 0;
- uint_t wasonset = o->wasonset;
- aubio_pvoc_do (o->pv,input, o->fftgrain);
- aubio_onsetdetection(o->od,o->fftgrain, o->of);
- /*if (usedoubled) {
- aubio_onsetdetection(o2,fftgrain, onset2);
- onset->data[0][0] *= onset2->data[0][0];
- }*/
- isonset = aubio_peakpick_pimrt(o->of,o->pp);
- if (isonset) {
- if (aubio_silence_detection(input, o->silence)==1) {
- isonset = 0;
- wasonset++;
- } else {
- if (wasonset > o->minioi) {
- wasonset = 0;
- } else {
- isonset = 0;
- wasonset++;
- }
- }
- } else {
- wasonset++;
- }
- o->wasonset = wasonset;
- onset->data[0][0] = isonset;
- return;
-}
-
-void aubio_onset_set_silence(aubio_onset_t * o, smpl_t silence) {
- o->silence = silence;
- return;
-}
-
-void aubio_onset_set_threshold(aubio_onset_t * o, smpl_t threshold) {
- o->threshold = threshold;
- aubio_peakpicker_set_threshold(o->pp, o->threshold);
- return;
-}
-
-void aubio_onset_set_minioi(aubio_onset_t * o, uint_t minioi) {
- o->minioi = minioi;
- return;
-}
-
-/* Allocate memory for an onset detection */
-aubio_onset_t * new_aubio_onset (aubio_onsetdetection_type type_onset,
- uint_t buf_size, uint_t hop_size, uint_t channels)
-{
- aubio_onset_t * o = AUBIO_NEW(aubio_onset_t);
- /** set some default parameter */
- o->threshold = 0.3;
- o->minioi = 4;
- o->silence = -70;
- o->wasonset = 0;
- o->pv = new_aubio_pvoc(buf_size, hop_size, channels);
- o->pp = new_aubio_peakpicker(o->threshold);
- o->od = new_aubio_onsetdetection(type_onset,buf_size,channels);
- o->fftgrain = new_cvec(buf_size,channels);
- o->of = new_fvec(1, channels);
- /*if (usedoubled) {
- o2 = new_aubio_onsetdetection(type_onset2,buffer_size,channels);
- onset2 = new_fvec(1 , channels);
- }*/
- return o;
-}
-
-void del_aubio_onset (aubio_onset_t *o)
-{
- del_aubio_onsetdetection(o->od);
- del_aubio_peakpicker(o->pp);
- del_aubio_pvoc(o->pv);
- del_fvec(o->of);
- del_cvec(o->fftgrain);
- AUBIO_FREE(o);
-}
--- a/src/onset.h
+++ /dev/null
@@ -1,102 +1,0 @@
-/*
- Copyright (C) 2006 Paul Brossier
-
- 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 2 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, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-*/
-
-/** \file
-
- Onset detection driver
-
- The following routines compute the onset detection function and detect peaks
- in these functions. When onsets are found above a given silence threshold,
- and after a minimum inter-onset interval, the output vector returned by
- aubio_onset is filled with 1. Otherwise, the output vector remains 0.
-
- The peak-picking threshold, the silence threshold, and the minimum
- inter-onset interval can be adjusted during the execution of the aubio_onset
- routine using the corresponding functions.
-
-*/
-
-
-#ifndef ONSET_H
-#define ONSET_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/** onset detection object */
-typedef struct _aubio_onset_t aubio_onset_t;
-
-/** create onset detection object
-
- \param type_onset onset detection type as specified in onsetdetection.h
- \param buf_size buffer size for phase vocoder
- \param hop_size hop size for phase vocoder
- \param channels number of channels
-
-*/
-aubio_onset_t * new_aubio_onset (aubio_onsetdetection_type type_onset,
- uint_t buf_size, uint_t hop_size, uint_t channels);
-
-/** execute onset detection
-
- \param o onset detection object as returned by new_aubio_onset
- \param input new audio vector of length hop_size
- \param onset output vector, 1 if onset is found, 0 otherwise
-
-*/
-void aubio_onset(aubio_onset_t *o, fvec_t * input, fvec_t * onset);
-
-/** set onset detection silence threshold
-
- \param o onset detection object as returned by new_aubio_onset
- \param silence new silence detection threshold
-
-*/
-void aubio_onset_set_silence(aubio_onset_t * o, smpl_t silence);
-
-/** set onset detection peak picking threshold
-
- \param o onset detection object as returned by new_aubio_onset
- \param threshold new peak-picking threshold
-
-*/
-void aubio_onset_set_threshold(aubio_onset_t * o, smpl_t threshold);
-
-/** set minimum inter onset interval
-
- \param o onset detection object as returned by new_aubio_onset
- \param minioi minimum number of frames between onsets (in multiple of
- hop_size/samplerare)
-
-*/
-void aubio_onset_set_minioi(aubio_onset_t * o, uint_t minioi);
-
-/** delete onset detection object
-
- \param o onset detection object to delete
-
-*/
-void del_aubio_onset(aubio_onset_t * o);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* ONSET_H */
--- /dev/null
+++ b/src/onset/onset.c
@@ -1,0 +1,119 @@
+/*
+ Copyright (C) 2006 Paul Brossier
+
+ 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 2 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, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#include "aubio_priv.h"
+#include "sample.h"
+#include "onset/onsetdetection.h"
+#include "phasevoc.h"
+#include "peakpick.h"
+#include "mathutils.h"
+#include "onset.h"
+
+/** structure to store object state */
+struct _aubio_onset_t {
+ aubio_pvoc_t * pv; /**< phase vocoder */
+ aubio_onsetdetection_t * od; /**< onset detection */
+ aubio_pickpeak_t * pp; /**< peak picker */
+ cvec_t * fftgrain; /**< phase vocoder output */
+ fvec_t * of; /**< onset detection function */
+ smpl_t threshold; /**< onset peak picking threshold */
+ smpl_t silence; /**< silence threhsold */
+ uint_t minioi; /**< minimum inter onset interval */
+ uint_t wasonset; /**< number of frames since last onset */
+};
+
+/* execute onset detection function on iput buffer */
+void aubio_onset(aubio_onset_t *o, fvec_t * input, fvec_t * onset)
+{
+ uint_t isonset = 0;
+ uint_t wasonset = o->wasonset;
+ aubio_pvoc_do (o->pv,input, o->fftgrain);
+ aubio_onsetdetection(o->od,o->fftgrain, o->of);
+ /*if (usedoubled) {
+ aubio_onsetdetection(o2,fftgrain, onset2);
+ onset->data[0][0] *= onset2->data[0][0];
+ }*/
+ isonset = aubio_peakpick_pimrt(o->of,o->pp);
+ if (isonset) {
+ if (aubio_silence_detection(input, o->silence)==1) {
+ isonset = 0;
+ wasonset++;
+ } else {
+ if (wasonset > o->minioi) {
+ wasonset = 0;
+ } else {
+ isonset = 0;
+ wasonset++;
+ }
+ }
+ } else {
+ wasonset++;
+ }
+ o->wasonset = wasonset;
+ onset->data[0][0] = isonset;
+ return;
+}
+
+void aubio_onset_set_silence(aubio_onset_t * o, smpl_t silence) {
+ o->silence = silence;
+ return;
+}
+
+void aubio_onset_set_threshold(aubio_onset_t * o, smpl_t threshold) {
+ o->threshold = threshold;
+ aubio_peakpicker_set_threshold(o->pp, o->threshold);
+ return;
+}
+
+void aubio_onset_set_minioi(aubio_onset_t * o, uint_t minioi) {
+ o->minioi = minioi;
+ return;
+}
+
+/* Allocate memory for an onset detection */
+aubio_onset_t * new_aubio_onset (aubio_onsetdetection_type type_onset,
+ uint_t buf_size, uint_t hop_size, uint_t channels)
+{
+ aubio_onset_t * o = AUBIO_NEW(aubio_onset_t);
+ /** set some default parameter */
+ o->threshold = 0.3;
+ o->minioi = 4;
+ o->silence = -70;
+ o->wasonset = 0;
+ o->pv = new_aubio_pvoc(buf_size, hop_size, channels);
+ o->pp = new_aubio_peakpicker(o->threshold);
+ o->od = new_aubio_onsetdetection(type_onset,buf_size,channels);
+ o->fftgrain = new_cvec(buf_size,channels);
+ o->of = new_fvec(1, channels);
+ /*if (usedoubled) {
+ o2 = new_aubio_onsetdetection(type_onset2,buffer_size,channels);
+ onset2 = new_fvec(1 , channels);
+ }*/
+ return o;
+}
+
+void del_aubio_onset (aubio_onset_t *o)
+{
+ del_aubio_onsetdetection(o->od);
+ del_aubio_peakpicker(o->pp);
+ del_aubio_pvoc(o->pv);
+ del_fvec(o->of);
+ del_cvec(o->fftgrain);
+ AUBIO_FREE(o);
+}
--- /dev/null
+++ b/src/onset/onset.h
@@ -1,0 +1,102 @@
+/*
+ Copyright (C) 2006 Paul Brossier
+
+ 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 2 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, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+/** \file
+
+ Onset detection driver
+
+ The following routines compute the onset detection function and detect peaks
+ in these functions. When onsets are found above a given silence threshold,
+ and after a minimum inter-onset interval, the output vector returned by
+ aubio_onset is filled with 1. Otherwise, the output vector remains 0.
+
+ The peak-picking threshold, the silence threshold, and the minimum
+ inter-onset interval can be adjusted during the execution of the aubio_onset
+ routine using the corresponding functions.
+
+*/
+
+
+#ifndef ONSET_H
+#define ONSET_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** onset detection object */
+typedef struct _aubio_onset_t aubio_onset_t;
+
+/** create onset detection object
+
+ \param type_onset onset detection type as specified in onsetdetection.h
+ \param buf_size buffer size for phase vocoder
+ \param hop_size hop size for phase vocoder
+ \param channels number of channels
+
+*/
+aubio_onset_t * new_aubio_onset (aubio_onsetdetection_type type_onset,
+ uint_t buf_size, uint_t hop_size, uint_t channels);
+
+/** execute onset detection
+
+ \param o onset detection object as returned by new_aubio_onset
+ \param input new audio vector of length hop_size
+ \param onset output vector, 1 if onset is found, 0 otherwise
+
+*/
+void aubio_onset(aubio_onset_t *o, fvec_t * input, fvec_t * onset);
+
+/** set onset detection silence threshold
+
+ \param o onset detection object as returned by new_aubio_onset
+ \param silence new silence detection threshold
+
+*/
+void aubio_onset_set_silence(aubio_onset_t * o, smpl_t silence);
+
+/** set onset detection peak picking threshold
+
+ \param o onset detection object as returned by new_aubio_onset
+ \param threshold new peak-picking threshold
+
+*/
+void aubio_onset_set_threshold(aubio_onset_t * o, smpl_t threshold);
+
+/** set minimum inter onset interval
+
+ \param o onset detection object as returned by new_aubio_onset
+ \param minioi minimum number of frames between onsets (in multiple of
+ hop_size/samplerare)
+
+*/
+void aubio_onset_set_minioi(aubio_onset_t * o, uint_t minioi);
+
+/** delete onset detection object
+
+ \param o onset detection object to delete
+
+*/
+void del_aubio_onset(aubio_onset_t * o);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* ONSET_H */
--- /dev/null
+++ b/src/onset/peakpick.c
@@ -1,0 +1,184 @@
+/*
+ Copyright (C) 2003 Paul Brossier
+
+ 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 2 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, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#include "aubio_priv.h"
+#include "sample.h"
+#include "mathutils.h"
+#include "biquad.h"
+#include "peakpick.h"
+
+/* peak picking parameters, default values in brackets
+ *
+ * [<----post----|--pre-->]
+ * .................|.............
+ * time-> ^now
+ */
+struct _aubio_pickpeak_t {
+ /** thresh: offset threshold [0.033 or 0.01] */
+ smpl_t threshold;
+ /** win_post: median filter window length (causal part) [8] */
+ uint_t win_post;
+ /** pre: median filter window (anti-causal part) [post-1] */
+ uint_t win_pre;
+ /** threshfn: name or handle of fn for computing adaptive threshold [median] */
+ aubio_thresholdfn_t thresholdfn;
+ /** picker: name or handle of fn for picking event times [peakpick] */
+ aubio_pickerfn_t pickerfn;
+
+ /** biquad lowpass filter */
+ aubio_biquad_t * biquad;
+ /** original onsets */
+ fvec_t * onset_keep;
+ /** modified onsets */
+ fvec_t * onset_proc;
+ /** peak picked window [3] */
+ fvec_t * onset_peek;
+ /** scratch pad for biquad and median */
+ fvec_t * scratch;
+
+ /** \bug should be used to calculate filter coefficients */
+ /* cutoff: low-pass filter cutoff [0.34, 1] */
+ /* smpl_t cutoff; */
+
+ /* not used anymore */
+ /* time precision [512/44100 winlength/samplerate, fs/buffer_size */
+ /* smpl_t tau; */
+ /* alpha: normalisation exponent [9] */
+ /* smpl_t alpha; */
+};
+
+
+/** modified version for real time, moving mean adaptive threshold this method
+ * is slightly more permissive than the offline one, and yelds to an increase
+ * of false positives. best */
+uint_t aubio_peakpick_pimrt(fvec_t * onset, aubio_pickpeak_t * p) {
+ fvec_t * onset_keep = (fvec_t *)p->onset_keep;
+ fvec_t * onset_proc = (fvec_t *)p->onset_proc;
+ fvec_t * onset_peek = (fvec_t *)p->onset_peek;
+ fvec_t * scratch = (fvec_t *)p->scratch;
+ smpl_t mean = 0., median = 0.;
+ uint_t length = p->win_post + p->win_pre + 1;
+ uint_t i = 0, j;
+
+ /* store onset in onset_keep */
+ /* shift all elements but last, then write last */
+ /* for (i=0;i<channels;i++) { */
+ for (j=0;j<length-1;j++) {
+ onset_keep->data[i][j] = onset_keep->data[i][j+1];
+ onset_proc->data[i][j] = onset_keep->data[i][j];
+ }
+ onset_keep->data[i][length-1] = onset->data[i][0];
+ onset_proc->data[i][length-1] = onset->data[i][0];
+ /* } */
+
+ /* filter onset_proc */
+ /** \bug filtfilt calculated post+pre times, should be only once !? */
+ aubio_biquad_do_filtfilt(p->biquad,onset_proc,scratch);
+
+ /* calculate mean and median for onset_proc */
+ /* for (i=0;i<onset_proc->channels;i++) { */
+ mean = vec_mean(onset_proc);
+ /* copy to scratch */
+ for (j = 0; j < length; j++)
+ scratch->data[i][j] = onset_proc->data[i][j];
+ median = p->thresholdfn(scratch);
+ /* } */
+
+ /* for (i=0;i<onset->channels;i++) { */
+ /* shift peek array */
+ for (j=0;j<3-1;j++)
+ onset_peek->data[i][j] = onset_peek->data[i][j+1];
+ /* calculate new peek value */
+ onset_peek->data[i][2] =
+ onset_proc->data[i][p->win_post] - median - mean * p->threshold;
+ /* } */
+ //AUBIO_DBG("%f\n", onset_peek->data[0][2]);
+ return (p->pickerfn)(onset_peek,1);
+}
+
+/** this method returns the current value in the pick peaking buffer
+ * after smoothing
+ */
+smpl_t aubio_peakpick_pimrt_getval(aubio_pickpeak_t * p)
+{
+ uint_t i = 0;
+ return p->onset_peek->data[i][1];
+}
+
+/** function added by Miguel Ramirez to return the onset detection amplitude in peakval */
+uint_t aubio_peakpick_pimrt_wt(fvec_t * onset, aubio_pickpeak_t * p, smpl_t* peakval)
+{
+ uint_t isonset = 0;
+ isonset = aubio_peakpick_pimrt(onset,p);
+
+ //if ( isonset && peakval != NULL )
+ if ( peakval != NULL )
+ *peakval = aubio_peakpick_pimrt_getval(p);
+
+ return isonset;
+}
+
+void aubio_peakpicker_set_threshold(aubio_pickpeak_t * p, smpl_t threshold) {
+ p->threshold = threshold;
+ return;
+}
+
+smpl_t aubio_peakpicker_get_threshold(aubio_pickpeak_t * p) {
+ return p->threshold;
+}
+
+void aubio_peakpicker_set_thresholdfn(aubio_pickpeak_t * p, aubio_thresholdfn_t thresholdfn) {
+ p->thresholdfn = thresholdfn;
+ return;
+}
+
+aubio_thresholdfn_t aubio_peakpicker_get_thresholdfn(aubio_pickpeak_t * p) {
+ return (aubio_thresholdfn_t) (p->thresholdfn);
+}
+
+aubio_pickpeak_t * new_aubio_peakpicker(smpl_t threshold) {
+ aubio_pickpeak_t * t = AUBIO_NEW(aubio_pickpeak_t);
+ t->threshold = 0.1; /* 0.0668; 0.33; 0.082; 0.033; */
+ if (threshold > 0. && threshold < 10.)
+ t->threshold = threshold;
+ t->win_post = 5;
+ t->win_pre = 1;
+
+ t->thresholdfn = (aubio_thresholdfn_t)(vec_median); /* (vec_mean); */
+ t->pickerfn = (aubio_pickerfn_t)(vec_peakpick);
+
+ t->scratch = new_fvec(t->win_post+t->win_pre+1,1);
+ t->onset_keep = new_fvec(t->win_post+t->win_pre+1,1);
+ t->onset_proc = new_fvec(t->win_post+t->win_pre+1,1);
+ t->onset_peek = new_fvec(3,1);
+
+ /* cutoff: low-pass filter cutoff [0.34, 1] */
+ /* t->cutoff=0.34; */
+ t->biquad = new_aubio_biquad(0.1600,0.3200,0.1600,-0.5949,0.2348);
+ return t;
+}
+
+void del_aubio_peakpicker(aubio_pickpeak_t * p) {
+ del_aubio_biquad(p->biquad);
+ del_fvec(p->onset_keep);
+ del_fvec(p->onset_proc);
+ del_fvec(p->onset_peek);
+ del_fvec(p->scratch);
+ AUBIO_FREE(p);
+}
--- /dev/null
+++ b/src/onset/peakpick.h
@@ -1,0 +1,64 @@
+/*
+ Copyright (C) 2003 Paul Brossier
+
+ 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 2 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, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+/** \file
+ * peak picking utilities function
+ *
+ * \todo check/fix peak picking
+ */
+
+#ifndef PEAKPICK_H
+#define PEAKPICK_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** function pointer to thresholding function */
+typedef smpl_t (*aubio_thresholdfn_t)(fvec_t *input);
+/** function pointer to peak-picking function */
+typedef uint_t (*aubio_pickerfn_t)(fvec_t *input, uint_t pos);
+/** peak-picker structure */
+typedef struct _aubio_pickpeak_t aubio_pickpeak_t;
+
+/** peak-picker creation function */
+aubio_pickpeak_t * new_aubio_peakpicker(smpl_t threshold);
+/** real time peak picking function */
+uint_t aubio_peakpick_pimrt(fvec_t * DF, aubio_pickpeak_t * p);
+/** function added by Miguel Ramirez to return the onset detection amplitude in peakval */
+uint_t aubio_peakpick_pimrt_wt( fvec_t* DF, aubio_pickpeak_t* p, smpl_t* peakval );
+/** get current peak value */
+smpl_t aubio_peakpick_pimrt_getval(aubio_pickpeak_t * p);
+/** destroy peak picker structure */
+void del_aubio_peakpicker(aubio_pickpeak_t * p);
+
+/** set peak picking threshold */
+void aubio_peakpicker_set_threshold(aubio_pickpeak_t * p, smpl_t threshold);
+/** get peak picking threshold */
+smpl_t aubio_peakpicker_get_threshold(aubio_pickpeak_t * p);
+/** set peak picker thresholding function */
+void aubio_peakpicker_set_thresholdfn(aubio_pickpeak_t * p, aubio_thresholdfn_t thresholdfn);
+/** get peak picker thresholding function */
+aubio_thresholdfn_t aubio_peakpicker_get_thresholdfn(aubio_pickpeak_t * p);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* PEAKPICK_H */
--- a/src/peakpick.c
+++ /dev/null
@@ -1,184 +1,0 @@
-/*
- Copyright (C) 2003 Paul Brossier
-
- 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 2 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, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-*/
-
-#include "aubio_priv.h"
-#include "sample.h"
-#include "mathutils.h"
-#include "biquad.h"
-#include "peakpick.h"
-
-/* peak picking parameters, default values in brackets
- *
- * [<----post----|--pre-->]
- * .................|.............
- * time-> ^now
- */
-struct _aubio_pickpeak_t {
- /** thresh: offset threshold [0.033 or 0.01] */
- smpl_t threshold;
- /** win_post: median filter window length (causal part) [8] */
- uint_t win_post;
- /** pre: median filter window (anti-causal part) [post-1] */
- uint_t win_pre;
- /** threshfn: name or handle of fn for computing adaptive threshold [median] */
- aubio_thresholdfn_t thresholdfn;
- /** picker: name or handle of fn for picking event times [peakpick] */
- aubio_pickerfn_t pickerfn;
-
- /** biquad lowpass filter */
- aubio_biquad_t * biquad;
- /** original onsets */
- fvec_t * onset_keep;
- /** modified onsets */
- fvec_t * onset_proc;
- /** peak picked window [3] */
- fvec_t * onset_peek;
- /** scratch pad for biquad and median */
- fvec_t * scratch;
-
- /** \bug should be used to calculate filter coefficients */
- /* cutoff: low-pass filter cutoff [0.34, 1] */
- /* smpl_t cutoff; */
-
- /* not used anymore */
- /* time precision [512/44100 winlength/samplerate, fs/buffer_size */
- /* smpl_t tau; */
- /* alpha: normalisation exponent [9] */
- /* smpl_t alpha; */
-};
-
-
-/** modified version for real time, moving mean adaptive threshold this method
- * is slightly more permissive than the offline one, and yelds to an increase
- * of false positives. best */
-uint_t aubio_peakpick_pimrt(fvec_t * onset, aubio_pickpeak_t * p) {
- fvec_t * onset_keep = (fvec_t *)p->onset_keep;
- fvec_t * onset_proc = (fvec_t *)p->onset_proc;
- fvec_t * onset_peek = (fvec_t *)p->onset_peek;
- fvec_t * scratch = (fvec_t *)p->scratch;
- smpl_t mean = 0., median = 0.;
- uint_t length = p->win_post + p->win_pre + 1;
- uint_t i = 0, j;
-
- /* store onset in onset_keep */
- /* shift all elements but last, then write last */
- /* for (i=0;i<channels;i++) { */
- for (j=0;j<length-1;j++) {
- onset_keep->data[i][j] = onset_keep->data[i][j+1];
- onset_proc->data[i][j] = onset_keep->data[i][j];
- }
- onset_keep->data[i][length-1] = onset->data[i][0];
- onset_proc->data[i][length-1] = onset->data[i][0];
- /* } */
-
- /* filter onset_proc */
- /** \bug filtfilt calculated post+pre times, should be only once !? */
- aubio_biquad_do_filtfilt(p->biquad,onset_proc,scratch);
-
- /* calculate mean and median for onset_proc */
- /* for (i=0;i<onset_proc->channels;i++) { */
- mean = vec_mean(onset_proc);
- /* copy to scratch */
- for (j = 0; j < length; j++)
- scratch->data[i][j] = onset_proc->data[i][j];
- median = p->thresholdfn(scratch);
- /* } */
-
- /* for (i=0;i<onset->channels;i++) { */
- /* shift peek array */
- for (j=0;j<3-1;j++)
- onset_peek->data[i][j] = onset_peek->data[i][j+1];
- /* calculate new peek value */
- onset_peek->data[i][2] =
- onset_proc->data[i][p->win_post] - median - mean * p->threshold;
- /* } */
- //AUBIO_DBG("%f\n", onset_peek->data[0][2]);
- return (p->pickerfn)(onset_peek,1);
-}
-
-/** this method returns the current value in the pick peaking buffer
- * after smoothing
- */
-smpl_t aubio_peakpick_pimrt_getval(aubio_pickpeak_t * p)
-{
- uint_t i = 0;
- return p->onset_peek->data[i][1];
-}
-
-/** function added by Miguel Ramirez to return the onset detection amplitude in peakval */
-uint_t aubio_peakpick_pimrt_wt(fvec_t * onset, aubio_pickpeak_t * p, smpl_t* peakval)
-{
- uint_t isonset = 0;
- isonset = aubio_peakpick_pimrt(onset,p);
-
- //if ( isonset && peakval != NULL )
- if ( peakval != NULL )
- *peakval = aubio_peakpick_pimrt_getval(p);
-
- return isonset;
-}
-
-void aubio_peakpicker_set_threshold(aubio_pickpeak_t * p, smpl_t threshold) {
- p->threshold = threshold;
- return;
-}
-
-smpl_t aubio_peakpicker_get_threshold(aubio_pickpeak_t * p) {
- return p->threshold;
-}
-
-void aubio_peakpicker_set_thresholdfn(aubio_pickpeak_t * p, aubio_thresholdfn_t thresholdfn) {
- p->thresholdfn = thresholdfn;
- return;
-}
-
-aubio_thresholdfn_t aubio_peakpicker_get_thresholdfn(aubio_pickpeak_t * p) {
- return (aubio_thresholdfn_t) (p->thresholdfn);
-}
-
-aubio_pickpeak_t * new_aubio_peakpicker(smpl_t threshold) {
- aubio_pickpeak_t * t = AUBIO_NEW(aubio_pickpeak_t);
- t->threshold = 0.1; /* 0.0668; 0.33; 0.082; 0.033; */
- if (threshold > 0. && threshold < 10.)
- t->threshold = threshold;
- t->win_post = 5;
- t->win_pre = 1;
-
- t->thresholdfn = (aubio_thresholdfn_t)(vec_median); /* (vec_mean); */
- t->pickerfn = (aubio_pickerfn_t)(vec_peakpick);
-
- t->scratch = new_fvec(t->win_post+t->win_pre+1,1);
- t->onset_keep = new_fvec(t->win_post+t->win_pre+1,1);
- t->onset_proc = new_fvec(t->win_post+t->win_pre+1,1);
- t->onset_peek = new_fvec(3,1);
-
- /* cutoff: low-pass filter cutoff [0.34, 1] */
- /* t->cutoff=0.34; */
- t->biquad = new_aubio_biquad(0.1600,0.3200,0.1600,-0.5949,0.2348);
- return t;
-}
-
-void del_aubio_peakpicker(aubio_pickpeak_t * p) {
- del_aubio_biquad(p->biquad);
- del_fvec(p->onset_keep);
- del_fvec(p->onset_proc);
- del_fvec(p->onset_peek);
- del_fvec(p->scratch);
- AUBIO_FREE(p);
-}
--- a/src/peakpick.h
+++ /dev/null
@@ -1,64 +1,0 @@
-/*
- Copyright (C) 2003 Paul Brossier
-
- 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 2 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, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-*/
-
-/** \file
- * peak picking utilities function
- *
- * \todo check/fix peak picking
- */
-
-#ifndef PEAKPICK_H
-#define PEAKPICK_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/** function pointer to thresholding function */
-typedef smpl_t (*aubio_thresholdfn_t)(fvec_t *input);
-/** function pointer to peak-picking function */
-typedef uint_t (*aubio_pickerfn_t)(fvec_t *input, uint_t pos);
-/** peak-picker structure */
-typedef struct _aubio_pickpeak_t aubio_pickpeak_t;
-
-/** peak-picker creation function */
-aubio_pickpeak_t * new_aubio_peakpicker(smpl_t threshold);
-/** real time peak picking function */
-uint_t aubio_peakpick_pimrt(fvec_t * DF, aubio_pickpeak_t * p);
-/** function added by Miguel Ramirez to return the onset detection amplitude in peakval */
-uint_t aubio_peakpick_pimrt_wt( fvec_t* DF, aubio_pickpeak_t* p, smpl_t* peakval );
-/** get current peak value */
-smpl_t aubio_peakpick_pimrt_getval(aubio_pickpeak_t * p);
-/** destroy peak picker structure */
-void del_aubio_peakpicker(aubio_pickpeak_t * p);
-
-/** set peak picking threshold */
-void aubio_peakpicker_set_threshold(aubio_pickpeak_t * p, smpl_t threshold);
-/** get peak picking threshold */
-smpl_t aubio_peakpicker_get_threshold(aubio_pickpeak_t * p);
-/** set peak picker thresholding function */
-void aubio_peakpicker_set_thresholdfn(aubio_pickpeak_t * p, aubio_thresholdfn_t thresholdfn);
-/** get peak picker thresholding function */
-aubio_thresholdfn_t aubio_peakpicker_get_thresholdfn(aubio_pickpeak_t * p);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* PEAKPICK_H */
--- /dev/null
+++ b/src/pitch/pitchdetection.c
@@ -1,0 +1,246 @@
+/*
+ Copyright (C) 2003 Paul Brossier
+
+ 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 2 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, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include "aubio_priv.h"
+#include "sample.h"
+#include "phasevoc.h"
+#include "mathutils.h"
+#include "filter.h"
+#include "pitch/pitchmcomb.h"
+#include "pitch/pitchyin.h"
+#include "pitch/pitchfcomb.h"
+#include "pitch/pitchschmitt.h"
+#include "pitch/pitchyinfft.h"
+#include "pitchdetection.h"
+
+typedef smpl_t (*aubio_pitchdetection_func_t)
+ (aubio_pitchdetection_t *p, fvec_t * ibuf);
+typedef smpl_t (*aubio_pitchdetection_conv_t)
+ (smpl_t value, uint_t srate, uint_t bufsize);
+
+void aubio_pitchdetection_slideblock(aubio_pitchdetection_t *p, fvec_t *ibuf);
+
+smpl_t aubio_pitchdetection_mcomb (aubio_pitchdetection_t *p, fvec_t *ibuf);
+smpl_t aubio_pitchdetection_yin (aubio_pitchdetection_t *p, fvec_t *ibuf);
+smpl_t aubio_pitchdetection_schmitt (aubio_pitchdetection_t *p, fvec_t *ibuf);
+smpl_t aubio_pitchdetection_fcomb (aubio_pitchdetection_t *p, fvec_t *ibuf);
+smpl_t aubio_pitchdetection_yinfft (aubio_pitchdetection_t *p, fvec_t *ibuf);
+
+/** generic pitch detection structure */
+struct _aubio_pitchdetection_t {
+ aubio_pitchdetection_type type; /**< pitch detection mode */
+ aubio_pitchdetection_mode mode; /**< pitch detection output mode */
+ uint_t srate; /**< samplerate */
+ uint_t bufsize; /**< buffer size */
+ aubio_pitchmcomb_t * mcomb; /**< mcomb object */
+ aubio_pitchfcomb_t * fcomb; /**< fcomb object */
+ aubio_pitchschmitt_t * schmitt; /**< schmitt object */
+ aubio_pitchyinfft_t * yinfft; /**< yinfft object */
+ aubio_filter_t * filter; /**< filter */
+ aubio_pvoc_t * pv; /**< phase vocoder for mcomb */
+ cvec_t * fftgrain; /**< spectral frame for mcomb */
+ fvec_t * buf; /**< temporary buffer for yin */
+ fvec_t * yin; /**< yin function */
+ smpl_t yinthres; /**< yin peak picking threshold parameter */
+ aubio_pitchdetection_func_t callback; /**< pointer to current pitch detection method */
+ aubio_pitchdetection_conv_t freqconv; /**< pointer to current pitch conversion method */
+};
+
+/* convenience wrapper function for frequency unit conversions
+ * should probably be rewritten with #defines */
+smpl_t freqconvbin(smpl_t f,uint_t srate,uint_t bufsize);
+smpl_t freqconvbin(smpl_t f,uint_t srate,uint_t bufsize){
+ return aubio_freqtobin(f,srate,bufsize);
+}
+
+smpl_t freqconvmidi(smpl_t f,uint_t srate,uint_t bufsize);
+smpl_t freqconvmidi(smpl_t f,uint_t srate UNUSED,uint_t bufsize UNUSED){
+ return aubio_freqtomidi(f);
+}
+
+smpl_t freqconvpass(smpl_t f,uint_t srate,uint_t bufsize);
+smpl_t freqconvpass(smpl_t f,uint_t srate UNUSED,uint_t bufsize UNUSED){
+ return f;
+}
+
+aubio_pitchdetection_t * new_aubio_pitchdetection(uint_t bufsize,
+ uint_t hopsize,
+ uint_t channels,
+ uint_t samplerate,
+ aubio_pitchdetection_type type,
+ aubio_pitchdetection_mode mode)
+{
+ aubio_pitchdetection_t *p = AUBIO_NEW(aubio_pitchdetection_t);
+ p->srate = samplerate;
+ p->type = type;
+ p->mode = mode;
+ p->bufsize = bufsize;
+ switch(p->type) {
+ case aubio_pitch_yin:
+ p->buf = new_fvec(bufsize,channels);
+ p->yin = new_fvec(bufsize/2,channels);
+ p->callback = aubio_pitchdetection_yin;
+ p->yinthres = 0.15;
+ break;
+ case aubio_pitch_mcomb:
+ p->pv = new_aubio_pvoc(bufsize, hopsize, channels);
+ p->fftgrain = new_cvec(bufsize, channels);
+ p->mcomb = new_aubio_pitchmcomb(bufsize,hopsize,channels,samplerate);
+ p->filter = new_aubio_cdsgn_filter(samplerate);
+ p->callback = aubio_pitchdetection_mcomb;
+ break;
+ case aubio_pitch_fcomb:
+ p->buf = new_fvec(bufsize,channels);
+ p->fcomb = new_aubio_pitchfcomb(bufsize,hopsize,samplerate);
+ p->callback = aubio_pitchdetection_fcomb;
+ break;
+ case aubio_pitch_schmitt:
+ p->buf = new_fvec(bufsize,channels);
+ p->schmitt = new_aubio_pitchschmitt(bufsize,samplerate);
+ p->callback = aubio_pitchdetection_schmitt;
+ break;
+ case aubio_pitch_yinfft:
+ p->buf = new_fvec(bufsize,channels);
+ p->yinfft = new_aubio_pitchyinfft(bufsize);
+ p->callback = aubio_pitchdetection_yinfft;
+ p->yinthres = 0.85;
+ break;
+ default:
+ break;
+ }
+ switch(p->mode) {
+ case aubio_pitchm_freq:
+ p->freqconv = freqconvpass;
+ break;
+ case aubio_pitchm_midi:
+ p->freqconv = freqconvmidi;
+ break;
+ case aubio_pitchm_cent:
+ /* bug: not implemented */
+ p->freqconv = freqconvmidi;
+ break;
+ case aubio_pitchm_bin:
+ p->freqconv = freqconvbin;
+ break;
+ default:
+ break;
+ }
+ return p;
+}
+
+void del_aubio_pitchdetection(aubio_pitchdetection_t * p) {
+ switch(p->type) {
+ case aubio_pitch_yin:
+ del_fvec(p->yin);
+ del_fvec(p->buf);
+ break;
+ case aubio_pitch_mcomb:
+ del_aubio_pvoc(p->pv);
+ del_cvec(p->fftgrain);
+ del_aubio_filter(p->filter);
+ del_aubio_pitchmcomb(p->mcomb);
+ break;
+ case aubio_pitch_schmitt:
+ del_fvec(p->buf);
+ del_aubio_pitchschmitt(p->schmitt);
+ break;
+ case aubio_pitch_fcomb:
+ del_fvec(p->buf);
+ del_aubio_pitchfcomb(p->fcomb);
+ break;
+ case aubio_pitch_yinfft:
+ del_fvec(p->buf);
+ del_aubio_pitchyinfft(p->yinfft);
+ break;
+ default:
+ break;
+ }
+ AUBIO_FREE(p);
+}
+
+void aubio_pitchdetection_slideblock(aubio_pitchdetection_t *p, fvec_t *ibuf){
+ uint_t i,j = 0, overlap_size = 0;
+ overlap_size = p->buf->length-ibuf->length;
+ for (i=0;i<p->buf->channels;i++){
+ for (j=0;j<overlap_size;j++){
+ p->buf->data[i][j] = p->buf->data[i][j+ibuf->length];
+ }
+ }
+ for (i=0;i<ibuf->channels;i++){
+ for (j=0;j<ibuf->length;j++){
+ p->buf->data[i][j+overlap_size] = ibuf->data[i][j];
+ }
+ }
+}
+
+void aubio_pitchdetection_set_yinthresh(aubio_pitchdetection_t *p, smpl_t thres) {
+ p->yinthres = thres;
+}
+
+smpl_t aubio_pitchdetection(aubio_pitchdetection_t *p, fvec_t * ibuf) {
+ return p->freqconv(p->callback(p,ibuf),p->srate,p->bufsize);
+}
+
+smpl_t aubio_pitchdetection_mcomb(aubio_pitchdetection_t *p, fvec_t *ibuf) {
+ smpl_t pitch = 0.;
+ aubio_filter_do(p->filter,ibuf);
+ aubio_pvoc_do(p->pv,ibuf,p->fftgrain);
+ pitch = aubio_pitchmcomb_detect(p->mcomb,p->fftgrain);
+ /** \bug should move the >0 check within aubio_bintofreq */
+ if (pitch>0.) {
+ pitch = aubio_bintofreq(pitch,p->srate,p->bufsize);
+ } else {
+ pitch = 0.;
+ }
+ return pitch;
+}
+
+smpl_t aubio_pitchdetection_yin(aubio_pitchdetection_t *p, fvec_t *ibuf) {
+ smpl_t pitch = 0.;
+ aubio_pitchdetection_slideblock(p,ibuf);
+ pitch = aubio_pitchyin_getpitchfast(p->buf,p->yin, p->yinthres);
+ if (pitch>0) {
+ pitch = p->srate/(pitch+0.);
+ } else {
+ pitch = 0.;
+ }
+ return pitch;
+}
+
+
+smpl_t aubio_pitchdetection_yinfft(aubio_pitchdetection_t *p, fvec_t *ibuf){
+ smpl_t pitch = 0.;
+ aubio_pitchdetection_slideblock(p,ibuf);
+ pitch = aubio_pitchyinfft_detect(p->yinfft,p->buf,p->yinthres);
+ if (pitch>0) {
+ pitch = p->srate/(pitch+0.);
+ } else {
+ pitch = 0.;
+ }
+ return pitch;
+}
+
+smpl_t aubio_pitchdetection_fcomb(aubio_pitchdetection_t *p, fvec_t *ibuf){
+ aubio_pitchdetection_slideblock(p,ibuf);
+ return aubio_pitchfcomb_detect(p->fcomb,p->buf);
+}
+
+smpl_t aubio_pitchdetection_schmitt(aubio_pitchdetection_t *p, fvec_t *ibuf){
+ aubio_pitchdetection_slideblock(p,ibuf);
+ return aubio_pitchschmitt_detect(p->schmitt,p->buf);
+}
--- /dev/null
+++ b/src/pitch/pitchdetection.h
@@ -1,0 +1,98 @@
+/*
+ Copyright (C) 2003 Paul Brossier
+
+ 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 2 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, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef PITCHAUTOTCORR_H
+#define PITCHAUTOTCORR_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** \file
+
+ Generic method for pitch detection
+
+ This file creates the objects required for the computation of the selected
+ pitch detection algorithm and output the results, in midi note or Hz.
+
+*/
+
+/** pitch detection algorithm */
+typedef enum {
+ aubio_pitch_yin, /**< YIN algorithm */
+ aubio_pitch_mcomb, /**< Multi-comb filter */
+ aubio_pitch_schmitt, /**< Schmitt trigger */
+ aubio_pitch_fcomb, /**< Fast comb filter */
+ aubio_pitch_yinfft /**< Spectral YIN */
+} aubio_pitchdetection_type;
+
+/** pitch detection output mode */
+typedef enum {
+ aubio_pitchm_freq, /**< Frequency (Hz) */
+ aubio_pitchm_midi, /**< MIDI note (0.,127) */
+ aubio_pitchm_cent, /**< Cent */
+ aubio_pitchm_bin /**< Frequency bin (0,bufsize) */
+} aubio_pitchdetection_mode;
+
+/** pitch detection object */
+typedef struct _aubio_pitchdetection_t aubio_pitchdetection_t;
+
+/** execute pitch detection on an input signal frame
+
+ \param p pitch detection object as returned by new_aubio_pitchdetection
+ \param ibuf input signal of length hopsize
+
+*/
+smpl_t aubio_pitchdetection(aubio_pitchdetection_t * p, fvec_t * ibuf);
+
+/** change yin or yinfft tolerance threshold
+
+ default is 0.15 for yin and 0.85 for yinfft
+
+*/
+void aubio_pitchdetection_set_yinthresh(aubio_pitchdetection_t *p, smpl_t thres);
+
+/** deletion of the pitch detection object
+
+ \param p pitch detection object as returned by new_aubio_pitchdetection
+
+*/
+void del_aubio_pitchdetection(aubio_pitchdetection_t * p);
+
+/** creation of the pitch detection object
+
+ \param bufsize size of the input buffer to analyse
+ \param hopsize step size between two consecutive analysis instant
+ \param channels number of channels to analyse
+ \param samplerate sampling rate of the signal
+ \param type set pitch detection algorithm
+ \param mode set pitch units for output
+
+*/
+aubio_pitchdetection_t * new_aubio_pitchdetection(uint_t bufsize,
+ uint_t hopsize,
+ uint_t channels,
+ uint_t samplerate,
+ aubio_pitchdetection_type type,
+ aubio_pitchdetection_mode mode);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /*PITCHDETECTION_H*/
--- a/src/pitchdetection.c
+++ /dev/null
@@ -1,246 +1,0 @@
-/*
- Copyright (C) 2003 Paul Brossier
-
- 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 2 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, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include "aubio_priv.h"
-#include "sample.h"
-#include "phasevoc.h"
-#include "mathutils.h"
-#include "filter.h"
-#include "pitch/pitchmcomb.h"
-#include "pitch/pitchyin.h"
-#include "pitch/pitchfcomb.h"
-#include "pitch/pitchschmitt.h"
-#include "pitch/pitchyinfft.h"
-#include "pitchdetection.h"
-
-typedef smpl_t (*aubio_pitchdetection_func_t)
- (aubio_pitchdetection_t *p, fvec_t * ibuf);
-typedef smpl_t (*aubio_pitchdetection_conv_t)
- (smpl_t value, uint_t srate, uint_t bufsize);
-
-void aubio_pitchdetection_slideblock(aubio_pitchdetection_t *p, fvec_t *ibuf);
-
-smpl_t aubio_pitchdetection_mcomb (aubio_pitchdetection_t *p, fvec_t *ibuf);
-smpl_t aubio_pitchdetection_yin (aubio_pitchdetection_t *p, fvec_t *ibuf);
-smpl_t aubio_pitchdetection_schmitt (aubio_pitchdetection_t *p, fvec_t *ibuf);
-smpl_t aubio_pitchdetection_fcomb (aubio_pitchdetection_t *p, fvec_t *ibuf);
-smpl_t aubio_pitchdetection_yinfft (aubio_pitchdetection_t *p, fvec_t *ibuf);
-
-/** generic pitch detection structure */
-struct _aubio_pitchdetection_t {
- aubio_pitchdetection_type type; /**< pitch detection mode */
- aubio_pitchdetection_mode mode; /**< pitch detection output mode */
- uint_t srate; /**< samplerate */
- uint_t bufsize; /**< buffer size */
- aubio_pitchmcomb_t * mcomb; /**< mcomb object */
- aubio_pitchfcomb_t * fcomb; /**< fcomb object */
- aubio_pitchschmitt_t * schmitt; /**< schmitt object */
- aubio_pitchyinfft_t * yinfft; /**< yinfft object */
- aubio_filter_t * filter; /**< filter */
- aubio_pvoc_t * pv; /**< phase vocoder for mcomb */
- cvec_t * fftgrain; /**< spectral frame for mcomb */
- fvec_t * buf; /**< temporary buffer for yin */
- fvec_t * yin; /**< yin function */
- smpl_t yinthres; /**< yin peak picking threshold parameter */
- aubio_pitchdetection_func_t callback; /**< pointer to current pitch detection method */
- aubio_pitchdetection_conv_t freqconv; /**< pointer to current pitch conversion method */
-};
-
-/* convenience wrapper function for frequency unit conversions
- * should probably be rewritten with #defines */
-smpl_t freqconvbin(smpl_t f,uint_t srate,uint_t bufsize);
-smpl_t freqconvbin(smpl_t f,uint_t srate,uint_t bufsize){
- return aubio_freqtobin(f,srate,bufsize);
-}
-
-smpl_t freqconvmidi(smpl_t f,uint_t srate,uint_t bufsize);
-smpl_t freqconvmidi(smpl_t f,uint_t srate UNUSED,uint_t bufsize UNUSED){
- return aubio_freqtomidi(f);
-}
-
-smpl_t freqconvpass(smpl_t f,uint_t srate,uint_t bufsize);
-smpl_t freqconvpass(smpl_t f,uint_t srate UNUSED,uint_t bufsize UNUSED){
- return f;
-}
-
-aubio_pitchdetection_t * new_aubio_pitchdetection(uint_t bufsize,
- uint_t hopsize,
- uint_t channels,
- uint_t samplerate,
- aubio_pitchdetection_type type,
- aubio_pitchdetection_mode mode)
-{
- aubio_pitchdetection_t *p = AUBIO_NEW(aubio_pitchdetection_t);
- p->srate = samplerate;
- p->type = type;
- p->mode = mode;
- p->bufsize = bufsize;
- switch(p->type) {
- case aubio_pitch_yin:
- p->buf = new_fvec(bufsize,channels);
- p->yin = new_fvec(bufsize/2,channels);
- p->callback = aubio_pitchdetection_yin;
- p->yinthres = 0.15;
- break;
- case aubio_pitch_mcomb:
- p->pv = new_aubio_pvoc(bufsize, hopsize, channels);
- p->fftgrain = new_cvec(bufsize, channels);
- p->mcomb = new_aubio_pitchmcomb(bufsize,hopsize,channels,samplerate);
- p->filter = new_aubio_cdsgn_filter(samplerate);
- p->callback = aubio_pitchdetection_mcomb;
- break;
- case aubio_pitch_fcomb:
- p->buf = new_fvec(bufsize,channels);
- p->fcomb = new_aubio_pitchfcomb(bufsize,hopsize,samplerate);
- p->callback = aubio_pitchdetection_fcomb;
- break;
- case aubio_pitch_schmitt:
- p->buf = new_fvec(bufsize,channels);
- p->schmitt = new_aubio_pitchschmitt(bufsize,samplerate);
- p->callback = aubio_pitchdetection_schmitt;
- break;
- case aubio_pitch_yinfft:
- p->buf = new_fvec(bufsize,channels);
- p->yinfft = new_aubio_pitchyinfft(bufsize);
- p->callback = aubio_pitchdetection_yinfft;
- p->yinthres = 0.85;
- break;
- default:
- break;
- }
- switch(p->mode) {
- case aubio_pitchm_freq:
- p->freqconv = freqconvpass;
- break;
- case aubio_pitchm_midi:
- p->freqconv = freqconvmidi;
- break;
- case aubio_pitchm_cent:
- /* bug: not implemented */
- p->freqconv = freqconvmidi;
- break;
- case aubio_pitchm_bin:
- p->freqconv = freqconvbin;
- break;
- default:
- break;
- }
- return p;
-}
-
-void del_aubio_pitchdetection(aubio_pitchdetection_t * p) {
- switch(p->type) {
- case aubio_pitch_yin:
- del_fvec(p->yin);
- del_fvec(p->buf);
- break;
- case aubio_pitch_mcomb:
- del_aubio_pvoc(p->pv);
- del_cvec(p->fftgrain);
- del_aubio_filter(p->filter);
- del_aubio_pitchmcomb(p->mcomb);
- break;
- case aubio_pitch_schmitt:
- del_fvec(p->buf);
- del_aubio_pitchschmitt(p->schmitt);
- break;
- case aubio_pitch_fcomb:
- del_fvec(p->buf);
- del_aubio_pitchfcomb(p->fcomb);
- break;
- case aubio_pitch_yinfft:
- del_fvec(p->buf);
- del_aubio_pitchyinfft(p->yinfft);
- break;
- default:
- break;
- }
- AUBIO_FREE(p);
-}
-
-void aubio_pitchdetection_slideblock(aubio_pitchdetection_t *p, fvec_t *ibuf){
- uint_t i,j = 0, overlap_size = 0;
- overlap_size = p->buf->length-ibuf->length;
- for (i=0;i<p->buf->channels;i++){
- for (j=0;j<overlap_size;j++){
- p->buf->data[i][j] = p->buf->data[i][j+ibuf->length];
- }
- }
- for (i=0;i<ibuf->channels;i++){
- for (j=0;j<ibuf->length;j++){
- p->buf->data[i][j+overlap_size] = ibuf->data[i][j];
- }
- }
-}
-
-void aubio_pitchdetection_set_yinthresh(aubio_pitchdetection_t *p, smpl_t thres) {
- p->yinthres = thres;
-}
-
-smpl_t aubio_pitchdetection(aubio_pitchdetection_t *p, fvec_t * ibuf) {
- return p->freqconv(p->callback(p,ibuf),p->srate,p->bufsize);
-}
-
-smpl_t aubio_pitchdetection_mcomb(aubio_pitchdetection_t *p, fvec_t *ibuf) {
- smpl_t pitch = 0.;
- aubio_filter_do(p->filter,ibuf);
- aubio_pvoc_do(p->pv,ibuf,p->fftgrain);
- pitch = aubio_pitchmcomb_detect(p->mcomb,p->fftgrain);
- /** \bug should move the >0 check within aubio_bintofreq */
- if (pitch>0.) {
- pitch = aubio_bintofreq(pitch,p->srate,p->bufsize);
- } else {
- pitch = 0.;
- }
- return pitch;
-}
-
-smpl_t aubio_pitchdetection_yin(aubio_pitchdetection_t *p, fvec_t *ibuf) {
- smpl_t pitch = 0.;
- aubio_pitchdetection_slideblock(p,ibuf);
- pitch = aubio_pitchyin_getpitchfast(p->buf,p->yin, p->yinthres);
- if (pitch>0) {
- pitch = p->srate/(pitch+0.);
- } else {
- pitch = 0.;
- }
- return pitch;
-}
-
-
-smpl_t aubio_pitchdetection_yinfft(aubio_pitchdetection_t *p, fvec_t *ibuf){
- smpl_t pitch = 0.;
- aubio_pitchdetection_slideblock(p,ibuf);
- pitch = aubio_pitchyinfft_detect(p->yinfft,p->buf,p->yinthres);
- if (pitch>0) {
- pitch = p->srate/(pitch+0.);
- } else {
- pitch = 0.;
- }
- return pitch;
-}
-
-smpl_t aubio_pitchdetection_fcomb(aubio_pitchdetection_t *p, fvec_t *ibuf){
- aubio_pitchdetection_slideblock(p,ibuf);
- return aubio_pitchfcomb_detect(p->fcomb,p->buf);
-}
-
-smpl_t aubio_pitchdetection_schmitt(aubio_pitchdetection_t *p, fvec_t *ibuf){
- aubio_pitchdetection_slideblock(p,ibuf);
- return aubio_pitchschmitt_detect(p->schmitt,p->buf);
-}
--- a/src/pitchdetection.h
+++ /dev/null
@@ -1,98 +1,0 @@
-/*
- Copyright (C) 2003 Paul Brossier
-
- 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 2 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, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifndef PITCHAUTOTCORR_H
-#define PITCHAUTOTCORR_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/** \file
-
- Generic method for pitch detection
-
- This file creates the objects required for the computation of the selected
- pitch detection algorithm and output the results, in midi note or Hz.
-
-*/
-
-/** pitch detection algorithm */
-typedef enum {
- aubio_pitch_yin, /**< YIN algorithm */
- aubio_pitch_mcomb, /**< Multi-comb filter */
- aubio_pitch_schmitt, /**< Schmitt trigger */
- aubio_pitch_fcomb, /**< Fast comb filter */
- aubio_pitch_yinfft /**< Spectral YIN */
-} aubio_pitchdetection_type;
-
-/** pitch detection output mode */
-typedef enum {
- aubio_pitchm_freq, /**< Frequency (Hz) */
- aubio_pitchm_midi, /**< MIDI note (0.,127) */
- aubio_pitchm_cent, /**< Cent */
- aubio_pitchm_bin /**< Frequency bin (0,bufsize) */
-} aubio_pitchdetection_mode;
-
-/** pitch detection object */
-typedef struct _aubio_pitchdetection_t aubio_pitchdetection_t;
-
-/** execute pitch detection on an input signal frame
-
- \param p pitch detection object as returned by new_aubio_pitchdetection
- \param ibuf input signal of length hopsize
-
-*/
-smpl_t aubio_pitchdetection(aubio_pitchdetection_t * p, fvec_t * ibuf);
-
-/** change yin or yinfft tolerance threshold
-
- default is 0.15 for yin and 0.85 for yinfft
-
-*/
-void aubio_pitchdetection_set_yinthresh(aubio_pitchdetection_t *p, smpl_t thres);
-
-/** deletion of the pitch detection object
-
- \param p pitch detection object as returned by new_aubio_pitchdetection
-
-*/
-void del_aubio_pitchdetection(aubio_pitchdetection_t * p);
-
-/** creation of the pitch detection object
-
- \param bufsize size of the input buffer to analyse
- \param hopsize step size between two consecutive analysis instant
- \param channels number of channels to analyse
- \param samplerate sampling rate of the signal
- \param type set pitch detection algorithm
- \param mode set pitch units for output
-
-*/
-aubio_pitchdetection_t * new_aubio_pitchdetection(uint_t bufsize,
- uint_t hopsize,
- uint_t channels,
- uint_t samplerate,
- aubio_pitchdetection_type type,
- aubio_pitchdetection_mode mode);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /*PITCHDETECTION_H*/
--- a/src/tempo.c
+++ /dev/null
@@ -1,146 +1,0 @@
-/*
- Copyright (C) 2006 Paul Brossier
-
- 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 2 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, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-*/
-
-#include "aubio_priv.h"
-#include "sample.h"
-#include "onset/detection.h"
-#include "beattracking.h"
-#include "phasevoc.h"
-#include "peakpick.h"
-#include "mathutils.h"
-#include "tempo.h"
-
-/* structure to store object state */
-struct _aubio_tempo_t {
- aubio_onsetdetection_t * od; /** onset detection */
- aubio_pvoc_t * pv; /** phase vocoder */
- aubio_pickpeak_t * pp; /** peak picker */
- aubio_beattracking_t * bt; /** beat tracking */
- cvec_t * fftgrain; /** spectral frame */
- fvec_t * of; /** onset detection function value */
- fvec_t * dfframe; /** peak picked detection function buffer */
- fvec_t * out; /** beat tactus candidates */
- smpl_t silence; /** silence parameter */
- smpl_t threshold; /** peak picking threshold */
- sint_t blockpos; /** current position in dfframe */
- uint_t winlen; /** dfframe bufsize */
- uint_t step; /** dfframe hopsize */
-};
-
-/* execute tempo detection function on iput buffer */
-void aubio_tempo(aubio_tempo_t *o, fvec_t * input, fvec_t * tempo)
-{
- uint_t i;
- uint_t winlen = o->winlen;
- uint_t step = o->step;
- aubio_pvoc_do (o->pv, input, o->fftgrain);
- aubio_onsetdetection(o->od, o->fftgrain, o->of);
- /*if (usedoubled) {
- aubio_onsetdetection(o2,fftgrain, onset2);
- onset->data[0][0] *= onset2->data[0][0];
- }*/
- /* execute every overlap_size*step */
- if (o->blockpos == (signed)step -1 ) {
- /* check dfframe */
- aubio_beattracking_do(o->bt,o->dfframe,o->out);
- /* rotate dfframe */
- for (i = 0 ; i < winlen - step; i++ )
- o->dfframe->data[0][i] = o->dfframe->data[0][i+step];
- for (i = winlen - step ; i < winlen; i++ )
- o->dfframe->data[0][i] = 0.;
- o->blockpos = -1;
- }
- o->blockpos++;
- tempo->data[0][1] = aubio_peakpick_pimrt_wt(o->of,o->pp,
- &(o->dfframe->data[0][winlen - step + o->blockpos]));
- /* end of second level loop */
- tempo->data[0][0] = 0; /* reset tactus */
- i=0;
- for (i = 1; i < o->out->data[0][0]; i++ ) {
- /* if current frame is a predicted tactus */
- if (o->blockpos == o->out->data[0][i]) {
- /* test for silence */
- if (aubio_silence_detection(input, o->silence)==1) {
- tempo->data[0][1] = 0; /* unset onset */
- tempo->data[0][0] = 0; /* unset tactus */
- } else {
- tempo->data[0][0] = 1; /* set tactus */
- }
- }
- }
-}
-
-void aubio_tempo_set_silence(aubio_tempo_t * o, smpl_t silence) {
- o->silence = silence;
- return;
-}
-
-void aubio_tempo_set_threshold(aubio_tempo_t * o, smpl_t threshold) {
- o->threshold = threshold;
- aubio_peakpicker_set_threshold(o->pp, o->threshold);
- return;
-}
-
-/* Allocate memory for an tempo detection */
-aubio_tempo_t * new_aubio_tempo (aubio_onsetdetection_type type_onset,
- uint_t buf_size, uint_t hop_size, uint_t channels)
-{
- aubio_tempo_t * o = AUBIO_NEW(aubio_tempo_t);
- o->winlen = SQR(512)/hop_size;
- o->step = o->winlen/4;
- o->blockpos = 0;
- o->threshold = 0.3;
- o->silence = -90;
- o->blockpos = 0;
- o->dfframe = new_fvec(o->winlen,channels);
- o->fftgrain = new_cvec(buf_size, channels);
- o->out = new_fvec(o->step,channels);
- o->pv = new_aubio_pvoc(buf_size, hop_size, channels);
- o->pp = new_aubio_peakpicker(o->threshold);
- o->od = new_aubio_onsetdetection(type_onset,buf_size,channels);
- o->of = new_fvec(1, channels);
- o->bt = new_aubio_beattracking(o->winlen,channels);
- /*if (usedoubled) {
- o2 = new_aubio_onsetdetection(type_onset2,buffer_size,channels);
- onset2 = new_fvec(1 , channels);
- }*/
- return o;
-}
-
-smpl_t aubio_tempo_get_bpm(aubio_tempo_t *o) {
- return aubio_beattracking_get_bpm(o->bt);
-}
-
-smpl_t aubio_tempo_get_confidence(aubio_tempo_t *o) {
- return aubio_beattracking_get_confidence(o->bt);
-}
-
-void del_aubio_tempo (aubio_tempo_t *o)
-{
- del_aubio_onsetdetection(o->od);
- del_aubio_beattracking(o->bt);
- del_aubio_peakpicker(o->pp);
- del_aubio_pvoc(o->pv);
- del_fvec(o->out);
- del_fvec(o->of);
- del_cvec(o->fftgrain);
- del_fvec(o->dfframe);
- AUBIO_FREE(o);
- return;
-}
--- a/src/tempo.h
+++ /dev/null
@@ -1,78 +1,0 @@
-/*
- Copyright (C) 2006 Paul Brossier
-
- 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 2 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, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-*/
-
-/** \file
-
- Tempo detection driver
-
- This object stores all the memory required for tempo detection algorithm
- and returns the estimated beat locations.
-
-*/
-
-#ifndef TEMPO_H
-#define TEMPO_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/** tempo detection structure */
-typedef struct _aubio_tempo_t aubio_tempo_t;
-
-/** create tempo detection object */
-aubio_tempo_t * new_aubio_tempo (aubio_onsetdetection_type type_onset,
- uint_t buf_size, uint_t hop_size, uint_t channels);
-
-/** execute tempo detection */
-void aubio_tempo(aubio_tempo_t *o, fvec_t * input, fvec_t * tempo);
-
-/** set tempo detection silence threshold */
-void aubio_tempo_set_silence(aubio_tempo_t * o, smpl_t silence);
-
-/** set tempo detection peak picking threshold */
-void aubio_tempo_set_threshold(aubio_tempo_t * o, smpl_t threshold);
-
-/** get current tempo
-
- \param bt beat tracking object
-
- Returns the currently observed tempo, or 0 if no consistent value is found
-
-*/
-smpl_t aubio_tempo_get_bpm(aubio_tempo_t * bt);
-
-/** get current tempo confidence
-
- \param bt beat tracking object
-
- Returns the confidence with which the tempo has been observed, 0 if no
- consistent value is found.
-
-*/
-smpl_t aubio_tempo_get_confidence(aubio_tempo_t * bt);
-
-/** delete tempo detection object */
-void del_aubio_tempo(aubio_tempo_t * o);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* TEMPO_H */
--- /dev/null
+++ b/src/tempo/beattracking.c
@@ -1,0 +1,467 @@
+/*
+ Copyright (C) 2005 Matthew Davies and Paul Brossier
+
+ 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 2 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, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#include "aubio_priv.h"
+#include "sample.h"
+#include "mathutils.h"
+#include "beattracking.h"
+
+uint_t fvec_gettimesig(smpl_t * acf, uint_t acflen, uint_t gp);
+void aubio_beattracking_checkstate(aubio_beattracking_t * bt);
+smpl_t fvec_getperiod(aubio_beattracking_t * bt);
+
+struct _aubio_beattracking_t {
+ fvec_t * rwv; /** rayleigh weight vector - rayleigh distribution function */
+ fvec_t * gwv; /** rayleigh weight vector - rayleigh distribution function */
+ fvec_t * dfwv; /** detection function weighting - exponential curve */
+ fvec_t * dfrev; /** reversed onset detection function */
+ fvec_t * acf; /** vector for autocorrelation function (of current detection function frame) */
+ fvec_t * acfout; /** store result of passing acf through s.i.c.f.b. */
+ fvec_t * phwv; /** beat expectation alignment weighting */
+ fvec_t * phout;
+ uint_t timesig; /** time signature of input, set to zero until context dependent model activated */
+ uint_t step;
+ fvec_t * locacf; /** vector to store harmonics of filterbank of acf */
+ fvec_t * inds; /** vector for max index outputs for each harmonic */
+ uint_t rayparam; /** Rayleigh parameter */
+ uint_t lastbeat;
+ sint_t counter;
+ uint_t flagstep;
+ smpl_t g_var;
+ uint_t gp;
+ uint_t bp;
+ uint_t rp;
+ uint_t rp1;
+ uint_t rp2;
+};
+
+aubio_beattracking_t * new_aubio_beattracking(uint_t winlen,
+ uint_t channels) {
+
+ aubio_beattracking_t * p = AUBIO_NEW(aubio_beattracking_t);
+ uint_t i = 0;
+ /* parameter for rayleigh weight vector - sets preferred tempo to
+ * 120bpm [43] */
+ smpl_t rayparam = 48./512. * winlen;
+ smpl_t dfwvnorm = EXP((LOG(2.0)/rayparam)*(winlen+2));
+ /** length over which beat period is found [128] */
+ uint_t laglen = winlen/4;
+ /** step increment - both in detection function samples -i.e. 11.6ms or
+ * 1 onset frame [128] */
+ uint_t step = winlen/4; /* 1.5 seconds */
+
+ uint_t maxnumelem = 4; /* max number of index output */
+ p->lastbeat = 0;
+ p->counter = 0;
+ p->flagstep = 0;
+ p->g_var = 3.901; // constthresh empirically derived!
+ p->rp = 1;
+ p->gp = 0;
+
+ p->rayparam = rayparam;
+ p->step = step;
+ p->rwv = new_fvec(laglen,channels);
+ p->gwv = new_fvec(laglen,channels);
+ p->dfwv = new_fvec(winlen,channels);
+ p->dfrev = new_fvec(winlen,channels);
+ p->acf = new_fvec(winlen,channels);
+ p->acfout = new_fvec(laglen,channels);
+ p->phwv = new_fvec(2*laglen,channels);
+ p->phout = new_fvec(winlen,channels);
+
+ p->timesig = 0;
+
+ p->inds = new_fvec(maxnumelem,channels);
+ p->locacf = new_fvec(winlen,channels);
+
+ /* exponential weighting, dfwv = 0.5 when i = 43 */
+ for (i=0;i<winlen;i++) {
+ p->dfwv->data[0][i] = (EXP((LOG(2.0)/rayparam)*(i+1)))
+ / dfwvnorm;
+ }
+
+ for (i=0;i<(laglen);i++){
+ p->rwv->data[0][i] = ((smpl_t)(i+1.) / SQR((smpl_t)rayparam)) *
+ EXP((-SQR((smpl_t)(i+1.)) / (2.*SQR((smpl_t)rayparam))));
+ }
+
+ return p;
+
+}
+
+void del_aubio_beattracking(aubio_beattracking_t * p) {
+ del_fvec(p->rwv);
+ del_fvec(p->gwv);
+ del_fvec(p->dfwv);
+ del_fvec(p->dfrev);
+ del_fvec(p->acf);
+ del_fvec(p->acfout);
+ del_fvec(p->phwv);
+ del_fvec(p->phout);
+ del_fvec(p->locacf);
+ del_fvec(p->inds);
+ AUBIO_FREE(p);
+}
+
+
+void aubio_beattracking_do(aubio_beattracking_t * bt, fvec_t * dfframe, fvec_t * output) {
+
+ uint_t i,k;
+ /* current beat period value found using gaussian weighting (from context dependent model) */
+ uint_t step = bt->step;
+ uint_t laglen = bt->rwv->length;
+ uint_t winlen = bt->dfwv->length;
+ smpl_t * phout = bt->phout->data[0];
+ smpl_t * phwv = bt->phwv->data[0];
+ smpl_t * dfrev = bt->dfrev->data[0];
+ smpl_t * dfwv = bt->dfwv->data[0];
+ smpl_t * rwv = bt->rwv->data[0];
+ smpl_t * acfout = bt->acfout->data[0];
+ smpl_t * acf = bt->acf->data[0];
+ uint_t maxindex = 0;
+ //number of harmonics in shift invariant comb filterbank
+ uint_t numelem = 4;
+
+ //smpl_t myperiod = 0.;
+ //smpl_t * out = output->data[0];
+
+ //parameters for making s.i.c.f.b.
+ uint_t a,b;
+ //beat alignment
+ uint_t phase;
+ uint_t kmax;
+ sint_t beat;
+ uint_t bp;
+
+ for (i = 0; i < winlen; i++){
+ dfrev[winlen-1-i] = 0.;
+ dfrev[winlen-1-i] = dfframe->data[0][i]*dfwv[i];
+ }
+
+ /* find autocorrelation function */
+ aubio_autocorr(dfframe,bt->acf);
+ /*
+ for (i = 0; i < winlen; i++){
+ AUBIO_DBG("%f,",acf[i]);
+ }
+ AUBIO_DBG("\n");
+ */
+
+ /* get acfout - assume Rayleigh weightvector only */
+ /* if timesig is unknown, use metrically unbiased version of filterbank */
+ if(!bt->timesig)
+ numelem = 4;
+ // AUBIO_DBG("using unbiased filterbank, timesig: %d\n", timesig);
+ else
+ numelem = bt->timesig;
+ // AUBIO_DBG("using biased filterbank, timesig: %d\n", timesig);
+
+ /* first and last output values are left intentionally as zero */
+ for (i=0; i < bt->acfout->length; i++)
+ acfout[i] = 0.;
+
+ for(i=1;i<laglen-1;i++){
+ for (a=1; a<=numelem; a++){
+ for(b=(1-a); b<a; b++){
+ acfout[i] += acf[a*(i+1)+b-1]
+ * 1./(2.*a-1.)*rwv[i];
+ }
+ }
+ }
+
+ /* find non-zero Rayleigh period */
+ maxindex = vec_max_elem(bt->acfout);
+ bt->rp = maxindex ? maxindex : 1;
+ //rp = (maxindex==127) ? 43 : maxindex; //rayparam
+ bt->rp = (maxindex==bt->acfout->length-1) ? bt->rayparam : maxindex; //rayparam
+
+ // get float period
+ //myperiod = fvec_getperiod(bt);
+ //AUBIO_DBG("\nrp = %d myperiod = %f\n",bt->rp,myperiod);
+ //AUBIO_DBG("accurate tempo is %f bpm\n",5168./myperiod);
+
+ /* activate biased filterbank */
+ aubio_beattracking_checkstate(bt);
+ bp = bt->bp;
+ /* end of biased filterbank */
+
+ /* initialize output */
+ for(i=0;i<bt->phout->length;i++) {phout[i] = 0.;}
+
+ /* deliberate integer operation, could be set to 3 max eventually */
+ kmax = winlen/bp;
+
+ for(i=0;i<bp;i++){
+ phout[i] = 0.;
+ for(k=0;k<kmax;k++){
+ phout[i] += dfrev[i+bp*k] * phwv[i];
+ }
+ }
+
+ /* find Rayleigh period */
+ maxindex = vec_max_elem(bt->phout);
+ if (maxindex == winlen-1) maxindex = 0;
+ phase = 1 + maxindex;
+
+ /* debug */
+ //AUBIO_DBG("beat period = %d, rp1 = %d, rp2 = %d\n", bp, rp1, rp2);
+ //AUBIO_DBG("rp = %d, gp = %d, phase = %d\n", bt->rp, bt->gp, phase);
+
+ /* reset output */
+ for (i = 0; i < laglen; i++)
+ output->data[0][i] = 0.;
+
+ i = 1;
+ beat = bp - phase;
+ /* start counting the beats */
+ if(beat >= 0)
+ {
+ output->data[0][i] = (smpl_t)beat;
+ i++;
+ }
+
+ while( beat+bp < step )
+ {
+ beat += bp;
+ output->data[0][i] = (smpl_t)beat;
+ i++;
+ }
+
+ bt->lastbeat = beat;
+ /* store the number of beat found in this frame as the first element */
+ output->data[0][0] = i;
+}
+
+uint_t fvec_gettimesig(smpl_t * acf, uint_t acflen, uint_t gp){
+ sint_t k = 0;
+ smpl_t three_energy = 0., four_energy = 0.;
+ if( acflen > 6 * gp + 2 ){
+ for(k=-2;k<2;k++){
+ three_energy += acf[3*gp+k];
+ four_energy += acf[4*gp+k];
+ }
+ }
+ else{ /*Expanded to be more accurate in time sig estimation*/
+ for(k=-2;k<2;k++){
+ three_energy += acf[3*gp+k]+acf[6*gp+k];
+ four_energy += acf[4*gp+k]+acf[2*gp+k];
+ }
+ }
+ return (three_energy > four_energy) ? 3 : 4;
+}
+
+smpl_t fvec_getperiod(aubio_beattracking_t * bt){
+ /*function to make a more accurate beat period measurement.*/
+
+ smpl_t period = 0.;
+ smpl_t maxval = 0.;
+ uint_t numelem = 4;
+
+ sint_t a,b;
+ uint_t i,j;
+ uint_t acfmi = bt->rp; //acfout max index
+ uint_t maxind = 0;
+
+ if(!bt->timesig)
+ numelem = 4;
+ else
+ numelem = bt->timesig;
+
+ for (i=0;i<numelem;i++) // initialize
+ bt->inds->data[0][i] = 0.;
+
+ for (i=0;i<bt->locacf->length;i++) // initialize
+ bt->locacf->data[0][i] = 0.;
+
+ // get appropriate acf elements from acf and store in locacf
+ for (a=1;a<=4;a++){
+ for(b=(1-a);b<a;b++){
+ bt->locacf->data[0][a*(acfmi)+b-1] =
+ bt->acf->data[0][a*(acfmi)+b-1];
+ }
+ }
+
+ for(i=0;i<numelem;i++){
+
+ maxind = 0;
+ maxval = 0.0;
+
+ for (j=0;j<(acfmi*(i+1)+(i)); j++){
+ if(bt->locacf->data[0][j]>maxval){
+ maxval = bt->locacf->data[0][j];
+ maxind = j;
+ }
+ //bt->locacf->data[0][maxind] = 0.;
+ bt->locacf->data[0][j] = 0.;
+ }
+ //AUBIO_DBG("\n maxind is %d\n",maxind);
+ bt->inds->data[0][i] = maxind;
+
+ }
+
+ for (i=0;i<numelem;i++){
+ period += bt->inds->data[0][i]/(i+1.);}
+
+ period = period/numelem;
+
+ return (period);
+}
+
+
+void aubio_beattracking_checkstate(aubio_beattracking_t * bt) {
+ uint_t i,j,a,b;
+ uint_t flagconst = 0;
+ sint_t counter = bt->counter;
+ uint_t flagstep = bt->flagstep;
+ uint_t gp = bt->gp;
+ uint_t bp = bt->bp;
+ uint_t rp = bt->rp;
+ uint_t rp1 = bt->rp1;
+ uint_t rp2 = bt->rp2;
+ uint_t laglen = bt->rwv->length;
+ uint_t acflen = bt->acf->length;
+ uint_t step = bt->step;
+ smpl_t * acf = bt->acf->data[0];
+ smpl_t * acfout = bt->acfout->data[0];
+ smpl_t * gwv = bt->gwv->data[0];
+ smpl_t * phwv = bt->phwv->data[0];
+
+ if (gp) {
+ // doshiftfbank again only if context dependent model is in operation
+ //acfout = doshiftfbank(acf,gwv,timesig,laglen,acfout);
+ //don't need acfout now, so can reuse vector
+ // gwv is, in first loop, definitely all zeros, but will have
+ // proper values when context dependent model is activated
+ for (i=0; i < bt->acfout->length; i++)
+ acfout[i] = 0.;
+ for(i=1;i<laglen-1;i++){
+ for (a=1;a<=bt->timesig;a++){
+ for(b=(1-a);b<a;b++){
+ acfout[i] += acf[a*(i+1)+b-1]
+ * 1. * gwv[i];
+ }
+ }
+ }
+ gp = vec_max_elem(bt->acfout);
+ /*
+ while(gp<32) gp =gp*2;
+ while(gp>64) gp = gp/2;
+ */
+ } else {
+ //still only using general model
+ gp = 0;
+ }
+
+ //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) {
+ flagstep = 1; // have observed step change.
+ counter = 3; // setup 3 frame counter
+ } else {
+ flagstep = 0;
+ }
+ }
+
+ //i.e. 3rd frame after flagstep initially set
+ if (counter==1 && flagstep==1) {
+ //check for consistency between previous beatperiod values
+ if(ABS(2.*rp - rp1 -rp2) < bt->g_var) {
+ //if true, can activate context dependent model
+ flagconst = 1;
+ counter = 0; // reset counter and flagstep
+ } else {
+ //if not consistent, then don't flag consistency!
+ flagconst = 0;
+ counter = 2; // let it look next time
+ }
+ } else if (counter > 0) {
+ //if counter doesn't = 1,
+ counter = counter-1;
+ }
+
+ rp2 = rp1; rp1 = rp;
+
+ if (flagconst) {
+ /* first run of new hypothesis */
+ gp = rp;
+ bt->timesig = fvec_gettimesig(acf,acflen, gp);
+ for(j=0;j<laglen;j++)
+ gwv[j] = EXP(-.5*SQR((smpl_t)(j+1.-gp))/SQR(bt->g_var));
+ flagconst = 0;
+ bp = gp;
+ /* flat phase weighting */
+ for(j=0;j<2*laglen;j++) {phwv[j] = 1.;}
+ } else if (bt->timesig) {
+ /* context dependant model */
+ bp = gp;
+ /* gaussian phase weighting */
+ if (step > bt->lastbeat) {
+ for(j=0;j<2*laglen;j++) {
+ phwv[j] = EXP(-.5*SQR((smpl_t)(1.+j-step+bt->lastbeat))/(bp/8.));
+ }
+ } else {
+ //AUBIO_DBG("NOT using phase weighting as step is %d and lastbeat %d \n",
+ // step,bt->lastbeat);
+ for(j=0;j<2*laglen;j++) {phwv[j] = 1.;}
+ }
+ } else {
+ /* initial state */
+ bp = rp;
+ /* flat phase weighting */
+ for(j=0;j<2*laglen;j++) {phwv[j] = 1.;}
+ }
+
+ /* do some further checks on the final bp value */
+
+ /* if tempo is > 206 bpm, half it */
+ while (bp < 25) {
+ //AUBIO_DBG("warning, doubling the beat period from %d\n", bp);
+ //AUBIO_DBG("warning, halving the tempo from %f\n", 60.*samplerate/hopsize/bp);
+ bp = bp*2;
+ }
+
+ //AUBIO_DBG("tempo:\t%3.5f bpm | ", 5168./bp);
+
+ /* smoothing */
+ //bp = (uint_t) (0.8 * (smpl_t)bp + 0.2 * (smpl_t)bp2);
+ //AUBIO_DBG("tempo:\t%3.5f bpm smoothed | bp2 %d | bp %d | ", 5168./bp, bp2, bp);
+ //bp2 = bp;
+ //AUBIO_DBG("time signature: %d \n", bt->timesig);
+ bt->counter = counter;
+ bt->flagstep = flagstep;
+ bt->gp = gp;
+ bt->bp = bp;
+ bt->rp1 = rp1;
+ bt->rp2 = rp2;
+
+}
+
+smpl_t aubio_beattracking_get_bpm(aubio_beattracking_t * bt) {
+ if (bt->timesig != 0 && bt->counter == 0 && bt->flagstep == 0) {
+ return 5168. / (smpl_t)bt->gp;
+ } else {
+ return 0.;
+ }
+}
+
+smpl_t aubio_beattracking_get_confidence(aubio_beattracking_t * bt) {
+ if (bt->gp) return vec_max(bt->acfout);
+ else return 0.;
+}
--- /dev/null
+++ b/src/tempo/beattracking.h
@@ -1,0 +1,91 @@
+/*
+ Copyright (C) 2003 Matthew Davies and Paul Brossier
+
+ 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 2 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, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+/** \file
+
+ Beat tracking using a context dependant model
+
+ This file implement the causal beat tracking algorithm designed by Matthew
+ Davies and described in the following articles:
+
+ Matthew E. P. Davies and Mark D. Plumbley. Causal tempo tracking of audio.
+ In Proceedings of the International Symposium on Music Information Retrieval
+ (ISMIR), pages 164169, Barcelona, Spain, 2004.
+
+ Matthew E. P. Davies, Paul Brossier, and Mark D. Plumbley. Beat tracking
+ towards automatic musical accompaniment. In Proceedings of the Audio
+ Engeeniring Society 118th Convention, Barcelona, Spain, May 2005.
+
+*/
+#ifndef BEATTRACKING_H
+#define BEATTRACKING_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** beat tracking object */
+typedef struct _aubio_beattracking_t aubio_beattracking_t;
+
+/** create beat tracking object
+
+ \param winlen: frame size [512]
+ \param channels number (not functionnal) [1]
+
+*/
+aubio_beattracking_t * new_aubio_beattracking(uint_t winlen, uint_t channels);
+/** 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
+
+*/
+void aubio_beattracking_do(aubio_beattracking_t * bt, fvec_t * dfframes, fvec_t * out);
+/** get current tempo in bpm
+
+ \param bt beat tracking object
+
+ Returns the currently observed tempo, in beats per minutes, or 0 if no
+ consistent value is found.
+
+*/
+smpl_t aubio_beattracking_get_bpm(aubio_beattracking_t * bt);
+/** get current tempo confidence
+
+ \param bt beat tracking object
+
+ Returns the confidence with which the tempo has been observed, 0 if no
+ consistent value is found.
+
+*/
+smpl_t aubio_beattracking_get_confidence(aubio_beattracking_t * bt);
+/** delete beat tracking object
+
+ \param p beat tracking object
+
+*/
+void del_aubio_beattracking(aubio_beattracking_t * p);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* BEATTRACKING_H */
--- /dev/null
+++ b/src/tempo/tempo.c
@@ -1,0 +1,146 @@
+/*
+ Copyright (C) 2006 Paul Brossier
+
+ 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 2 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, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#include "aubio_priv.h"
+#include "sample.h"
+#include "onset/onsetdetection.h"
+#include "tempo/beattracking.h"
+#include "phasevoc.h"
+#include "onset/peakpick.h"
+#include "mathutils.h"
+#include "tempo.h"
+
+/* structure to store object state */
+struct _aubio_tempo_t {
+ aubio_onsetdetection_t * od; /** onset detection */
+ aubio_pvoc_t * pv; /** phase vocoder */
+ aubio_pickpeak_t * pp; /** peak picker */
+ aubio_beattracking_t * bt; /** beat tracking */
+ cvec_t * fftgrain; /** spectral frame */
+ fvec_t * of; /** onset detection function value */
+ fvec_t * dfframe; /** peak picked detection function buffer */
+ fvec_t * out; /** beat tactus candidates */
+ smpl_t silence; /** silence parameter */
+ smpl_t threshold; /** peak picking threshold */
+ sint_t blockpos; /** current position in dfframe */
+ uint_t winlen; /** dfframe bufsize */
+ uint_t step; /** dfframe hopsize */
+};
+
+/* execute tempo detection function on iput buffer */
+void aubio_tempo(aubio_tempo_t *o, fvec_t * input, fvec_t * tempo)
+{
+ uint_t i;
+ uint_t winlen = o->winlen;
+ uint_t step = o->step;
+ aubio_pvoc_do (o->pv, input, o->fftgrain);
+ aubio_onsetdetection(o->od, o->fftgrain, o->of);
+ /*if (usedoubled) {
+ aubio_onsetdetection(o2,fftgrain, onset2);
+ onset->data[0][0] *= onset2->data[0][0];
+ }*/
+ /* execute every overlap_size*step */
+ if (o->blockpos == (signed)step -1 ) {
+ /* check dfframe */
+ aubio_beattracking_do(o->bt,o->dfframe,o->out);
+ /* rotate dfframe */
+ for (i = 0 ; i < winlen - step; i++ )
+ o->dfframe->data[0][i] = o->dfframe->data[0][i+step];
+ for (i = winlen - step ; i < winlen; i++ )
+ o->dfframe->data[0][i] = 0.;
+ o->blockpos = -1;
+ }
+ o->blockpos++;
+ tempo->data[0][1] = aubio_peakpick_pimrt_wt(o->of,o->pp,
+ &(o->dfframe->data[0][winlen - step + o->blockpos]));
+ /* end of second level loop */
+ tempo->data[0][0] = 0; /* reset tactus */
+ i=0;
+ for (i = 1; i < o->out->data[0][0]; i++ ) {
+ /* if current frame is a predicted tactus */
+ if (o->blockpos == o->out->data[0][i]) {
+ /* test for silence */
+ if (aubio_silence_detection(input, o->silence)==1) {
+ tempo->data[0][1] = 0; /* unset onset */
+ tempo->data[0][0] = 0; /* unset tactus */
+ } else {
+ tempo->data[0][0] = 1; /* set tactus */
+ }
+ }
+ }
+}
+
+void aubio_tempo_set_silence(aubio_tempo_t * o, smpl_t silence) {
+ o->silence = silence;
+ return;
+}
+
+void aubio_tempo_set_threshold(aubio_tempo_t * o, smpl_t threshold) {
+ o->threshold = threshold;
+ aubio_peakpicker_set_threshold(o->pp, o->threshold);
+ return;
+}
+
+/* Allocate memory for an tempo detection */
+aubio_tempo_t * new_aubio_tempo (aubio_onsetdetection_type type_onset,
+ uint_t buf_size, uint_t hop_size, uint_t channels)
+{
+ aubio_tempo_t * o = AUBIO_NEW(aubio_tempo_t);
+ o->winlen = SQR(512)/hop_size;
+ o->step = o->winlen/4;
+ o->blockpos = 0;
+ o->threshold = 0.3;
+ o->silence = -90;
+ o->blockpos = 0;
+ o->dfframe = new_fvec(o->winlen,channels);
+ o->fftgrain = new_cvec(buf_size, channels);
+ o->out = new_fvec(o->step,channels);
+ o->pv = new_aubio_pvoc(buf_size, hop_size, channels);
+ o->pp = new_aubio_peakpicker(o->threshold);
+ o->od = new_aubio_onsetdetection(type_onset,buf_size,channels);
+ o->of = new_fvec(1, channels);
+ o->bt = new_aubio_beattracking(o->winlen,channels);
+ /*if (usedoubled) {
+ o2 = new_aubio_onsetdetection(type_onset2,buffer_size,channels);
+ onset2 = new_fvec(1 , channels);
+ }*/
+ return o;
+}
+
+smpl_t aubio_tempo_get_bpm(aubio_tempo_t *o) {
+ return aubio_beattracking_get_bpm(o->bt);
+}
+
+smpl_t aubio_tempo_get_confidence(aubio_tempo_t *o) {
+ return aubio_beattracking_get_confidence(o->bt);
+}
+
+void del_aubio_tempo (aubio_tempo_t *o)
+{
+ del_aubio_onsetdetection(o->od);
+ del_aubio_beattracking(o->bt);
+ del_aubio_peakpicker(o->pp);
+ del_aubio_pvoc(o->pv);
+ del_fvec(o->out);
+ del_fvec(o->of);
+ del_cvec(o->fftgrain);
+ del_fvec(o->dfframe);
+ AUBIO_FREE(o);
+ return;
+}
--- /dev/null
+++ b/src/tempo/tempo.h
@@ -1,0 +1,78 @@
+/*
+ Copyright (C) 2006 Paul Brossier
+
+ 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 2 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, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+/** \file
+
+ Tempo detection driver
+
+ This object stores all the memory required for tempo detection algorithm
+ and returns the estimated beat locations.
+
+*/
+
+#ifndef TEMPO_H
+#define TEMPO_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** tempo detection structure */
+typedef struct _aubio_tempo_t aubio_tempo_t;
+
+/** create tempo detection object */
+aubio_tempo_t * new_aubio_tempo (aubio_onsetdetection_type type_onset,
+ uint_t buf_size, uint_t hop_size, uint_t channels);
+
+/** execute tempo detection */
+void aubio_tempo(aubio_tempo_t *o, fvec_t * input, fvec_t * tempo);
+
+/** set tempo detection silence threshold */
+void aubio_tempo_set_silence(aubio_tempo_t * o, smpl_t silence);
+
+/** set tempo detection peak picking threshold */
+void aubio_tempo_set_threshold(aubio_tempo_t * o, smpl_t threshold);
+
+/** get current tempo
+
+ \param bt beat tracking object
+
+ Returns the currently observed tempo, or 0 if no consistent value is found
+
+*/
+smpl_t aubio_tempo_get_bpm(aubio_tempo_t * bt);
+
+/** get current tempo confidence
+
+ \param bt beat tracking object
+
+ Returns the confidence with which the tempo has been observed, 0 if no
+ consistent value is found.
+
+*/
+smpl_t aubio_tempo_get_confidence(aubio_tempo_t * bt);
+
+/** delete tempo detection object */
+void del_aubio_tempo(aubio_tempo_t * o);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* TEMPO_H */