From: Paul Brossier Date: Sat, 22 Jul 2006 09:41:27 +0000 (+0000) Subject: add tempo and onset functions X-Git-Tag: bzr2git~603 X-Git-Url: http://git.tremily.us/?a=commitdiff_plain;h=7524d0b06149c3071be3ac55edf6cd25108e3528;p=aubio.git add tempo and onset functions add tempo and onset functions --- diff --git a/src/Makefile.am b/src/Makefile.am index 1b68cbf9..8de3f56c 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -19,6 +19,8 @@ pkginclude_HEADERS = aubio.h \ pitchfcomb.h \ pitchyinfft.h \ beattracking.h \ + onset.h \ + tempo.h \ filter.h nodist_pkginclude_HEADERS = config.h @@ -61,6 +63,10 @@ libaubio_la_SOURCES = aubio.h \ pitchyinfft.h \ beattracking.c \ beattracking.h \ + onset.c \ + onset.h \ + tempo.c \ + tempo.h \ filter.c \ filter.h diff --git a/src/aubio.h b/src/aubio.h index b326bfc7..f5235823 100644 --- a/src/aubio.h +++ b/src/aubio.h @@ -77,6 +77,8 @@ extern "C" { #include "pitchschmitt.h" #include "pitchfcomb.h" #include "beattracking.h" +#include "onset.h" +#include "tempo.h" #ifdef __cplusplus } /* extern "C" */ diff --git a/src/onset.c b/src/onset.c new file mode 100644 index 00000000..c15f00b9 --- /dev/null +++ b/src/onset.c @@ -0,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 "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); +} diff --git a/src/onset.h b/src/onset.h new file mode 100644 index 00000000..470e7929 --- /dev/null +++ b/src/onset.h @@ -0,0 +1,52 @@ +/* + 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. + +*/ + +#ifndef ONSET_H +#define ONSET_H + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct _aubio_onset_t aubio_onset_t; + +/** create onset detection object */ +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 */ +void aubio_onset(aubio_onset_t *o, fvec_t * input, fvec_t * onset); + +/** set onset detection silence threshold */ +void aubio_onset_set_silence(aubio_onset_t * o, smpl_t silence); + +/** set onset detection peak picking threshold */ +void aubio_onset_set_threshold(aubio_onset_t * o, smpl_t threshold); + +/** set onset detection peak picking threshold */ +void aubio_onset_set_minioi(aubio_onset_t * o, uint_t minioi); + +/** delete onset detection object */ +void del_aubio_onset(aubio_onset_t * o); + +#ifdef __cplusplus +} +#endif + +#endif /* ONSET_H */ diff --git a/src/tempo.c b/src/tempo.c new file mode 100644 index 00000000..e077898b --- /dev/null +++ b/src/tempo.c @@ -0,0 +1,138 @@ +/* + 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 "onsetdetection.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; +} + +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; +} diff --git a/src/tempo.h b/src/tempo.h new file mode 100644 index 00000000..b1eeccea --- /dev/null +++ b/src/tempo.h @@ -0,0 +1,49 @@ +/* + 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. + +*/ + +#ifndef TEMPO_H +#define TEMPO_H + +#ifdef __cplusplus +extern "C" { +#endif + +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); + +/** delete tempo detection object */ +void del_aubio_tempo(aubio_tempo_t * o); + +#ifdef __cplusplus +} +#endif + +#endif /* TEMPO_H */