From b31f26206b5f006b15b51aaddf5209db60560269 Mon Sep 17 00:00:00 2001 From: Paul Brossier Date: Mon, 13 Jun 2005 23:07:08 +0000 Subject: [PATCH] add Kullback Liebler onset detection function and its modified version --- python/aubio/aubioclass.py | 8 +++---- python/aubio/gnuplot.py | 2 ++ src/onsetdetection.c | 45 ++++++++++++++++++++++++++++++++++++-- src/onsetdetection.h | 8 ++++++- 4 files changed, 56 insertions(+), 7 deletions(-) diff --git a/python/aubio/aubioclass.py b/python/aubio/aubioclass.py index 8b192f74..b3e723c7 100644 --- a/python/aubio/aubioclass.py +++ b/python/aubio/aubioclass.py @@ -76,14 +76,14 @@ class onsetpick: def __init__(self,bufsize,hopsize,channels,myvec,threshold,mode='dual',derivate=False): self.myfft = cvec(bufsize,channels) self.pv = pvoc(bufsize,hopsize,channels) - if mode in [complexdomain,hfc,phase,energy,specdiff] : - self.myod = onsetdetection(mode,bufsize,channels) - self.myonset = fvec(1,channels) - else: + if mode in ['dual'] : self.myod = onsetdetection(hfc,bufsize,channels) self.myod2 = onsetdetection(complexdomain,bufsize,channels) self.myonset = fvec(1,channels) self.myonset2 = fvec(1,channels) + else: + self.myod = onsetdetection(mode,bufsize,channels) + self.myonset = fvec(1,channels) self.mode = mode self.pp = peakpick(float(threshold)) self.derivate = derivate diff --git a/python/aubio/gnuplot.py b/python/aubio/gnuplot.py index 0e12ca13..e3bfebc7 100644 --- a/python/aubio/gnuplot.py +++ b/python/aubio/gnuplot.py @@ -150,6 +150,8 @@ def plot_onsets(filename, onsets, ofunc, samplerate=44100., hopsize=512, outplot import numarray from aubio.onsetcompare import onset_roc + if len(onsets) == 0: onsets = [0.]; + # onset detection function downtime = (hopsize/samplerate)*numarray.arange(len(ofunc)) d = Gnuplot.Data(downtime,ofunc,with='lines') diff --git a/src/onsetdetection.c b/src/onsetdetection.c index c881e5c0..8810e8b3 100644 --- a/src/onsetdetection.c +++ b/src/onsetdetection.c @@ -67,7 +67,6 @@ void aubio_onsetdetection_hfc(aubio_onsetdetection_t *o, cvec_t * fftgrain, fvec /* Complex Domain Method onset detection function */ -/* moved to /2 032402 */ void aubio_onsetdetection_complex (aubio_onsetdetection_t *o, cvec_t * fftgrain, fvec_t * onset) { uint_t i, j; uint_t nbins = fftgrain->length; @@ -127,7 +126,6 @@ void aubio_onsetdetection_phase(aubio_onsetdetection_t *o, } /* Spectral difference method onset detection function */ -/* moved to /2 032402 */ void aubio_onsetdetection_specdiff(aubio_onsetdetection_t *o, cvec_t * fftgrain, fvec_t * onset){ uint_t i, j; @@ -156,6 +154,37 @@ void aubio_onsetdetection_specdiff(aubio_onsetdetection_t *o, } } +/* Kullback Liebler onset detection function + * note we use ln(1+Xn/(Xn-1+0.0001)) to avoid + * negative (1.+) and infinite values (+1.e-10) */ +void aubio_onsetdetection_kl(aubio_onsetdetection_t *o, cvec_t * fftgrain, fvec_t * onset){ + uint_t i,j; + for (i=0;ichannels;i++) { + onset->data[i][0] = 0.; + for (j=0;jlength;j++) { + onset->data[i][0] += fftgrain->norm[i][j] + *LOG(1.+fftgrain->norm[i][j]/(o->oldmag->data[i][j]+1.e-10)); + o->oldmag->data[i][j] = fftgrain->norm[i][j]; + } + if (isnan(onset->data[i][0])) onset->data[i][0] = 0.; + } +} + +/* Modified Kullback Liebler onset detection function + * note we use ln(1+Xn/(Xn-1+0.0001)) to avoid + * negative (1.+) and infinite values (+1.e-10) */ +void aubio_onsetdetection_mkl(aubio_onsetdetection_t *o, cvec_t * fftgrain, fvec_t * onset){ + uint_t i,j; + for (i=0;ichannels;i++) { + onset->data[i][0] = 0.; + for (j=0;jlength;j++) { + onset->data[i][0] += LOG(1.+fftgrain->norm[i][j]/(o->oldmag->data[i][j]+1.e-10)); + o->oldmag->data[i][j] = fftgrain->norm[i][j]; + } + if (isnan(onset->data[i][0])) onset->data[i][0] = 0.; + } +} + /* Generic function pointing to the choosen one */ void aubio_onsetdetection(aubio_onsetdetection_t *o, cvec_t * fftgrain, @@ -204,6 +233,12 @@ aubio_onsetdetection_alloc (aubio_onsetdetection_type type, o->histog = new_aubio_hist(0.0f, PI, 10, channels); o->threshold = 0.1; break; + case kl: + o->oldmag = new_fvec(rsize,channels); + break; + case mkl: + o->oldmag = new_fvec(rsize,channels); + break; default: break; } @@ -228,6 +263,12 @@ aubio_onsetdetection_alloc (aubio_onsetdetection_type type, case specdiff: o->funcpointer = aubio_onsetdetection_specdiff; break; + case kl: + o->funcpointer = aubio_onsetdetection_kl; + break; + case mkl: + o->funcpointer = aubio_onsetdetection_mkl; + break; default: break; } diff --git a/src/onsetdetection.h b/src/onsetdetection.h index dbc2417a..a27cb7e4 100644 --- a/src/onsetdetection.h +++ b/src/onsetdetection.h @@ -53,7 +53,9 @@ typedef enum { specdiff, /**< spectral diff */ hfc, /**< high frequency content */ complexdomain, /**< complex domain */ - phase /**< phase fast */ + phase, /**< phase fast */ + kl, /**< Kullback Liebler (Hainsworth et al., Onset detection in musical audio signals) */ + mkl /**< modified Kullback Liebler (Hainsworth et al., Onset detection in musical audio signals) */ } aubio_onsetdetection_type; /** onsetdetection structure */ @@ -98,6 +100,10 @@ void aubio_onsetdetection_phase(aubio_onsetdetection_t *o, cvec_t * fftgrain, fv * - interpfact 2 */ void aubio_onsetdetection_specdiff(aubio_onsetdetection_t *o, cvec_t * fftgrain, fvec_t * onset); +/** Kullback-Liebler onset detection function */ +void aubio_onsetdetection_kl(aubio_onsetdetection_t *o, cvec_t * fftgrain, fvec_t * onset); +/** Modified Kullback-Liebler onset detection function */ +void aubio_onsetdetection_mkl(aubio_onsetdetection_t *o, cvec_t * fftgrain, fvec_t * onset); /** Generic function pointing to the choosen one */ void aubio_onsetdetection(aubio_onsetdetection_t *o, cvec_t * fftgrain, fvec_t * onset); /** Allocate memory for an onset detection */ -- 2.26.2