From: Paul Brossier Date: Wed, 12 Aug 2015 16:28:17 +0000 (+0200) Subject: src/spectral/awhitening.c: add adaptive whitening X-Git-Tag: 0.4.5~20^2~49 X-Git-Url: https://git.aubio.org/?a=commitdiff_plain;h=9f060d11650a940dba7dfacc9b933b92802cdb04;p=aubio.git src/spectral/awhitening.c: add adaptive whitening --- diff --git a/src/aubio.h b/src/aubio.h index c615dd93..ce9a957f 100644 --- a/src/aubio.h +++ b/src/aubio.h @@ -178,6 +178,7 @@ extern "C" #include "spectral/filterbank_mel.h" #include "spectral/mfcc.h" #include "spectral/specdesc.h" +#include "spectral/awhitening.h" #include "spectral/tss.h" #include "pitch/pitch.h" #include "onset/onset.h" diff --git a/src/onset/onset.c b/src/onset/onset.c index 98660aad..a3f1e663 100644 --- a/src/onset/onset.c +++ b/src/onset/onset.c @@ -23,6 +23,7 @@ #include "cvec.h" #include "spectral/specdesc.h" #include "spectral/phasevoc.h" +#include "spectral/awhitening.h" #include "onset/peakpicker.h" #include "mathutils.h" #include "onset/onset.h" @@ -42,6 +43,9 @@ struct _aubio_onset_t { uint_t total_frames; /**< total number of frames processed since the beginning */ uint_t last_onset; /**< last detected onset location, in frames */ + + uint_t apply_adaptive_whitening; + aubio_spectral_whitening_t *spectral_whitening; }; /* execute onset detection function on iput buffer */ @@ -49,6 +53,15 @@ void aubio_onset_do (aubio_onset_t *o, fvec_t * input, fvec_t * onset) { smpl_t isonset = 0; aubio_pvoc_do (o->pv,input, o->fftgrain); + /* + if (apply_filtering) { + } + if (apply_compression) { + } + */ + if (o->apply_adaptive_whitening) { + aubio_spectral_whitening_do(o->spectral_whitening, o->fftgrain); + } aubio_specdesc_do (o->od, o->fftgrain, o->desc); aubio_peakpicker_do(o->pp, o->desc, onset); isonset = onset->data[0]; @@ -209,6 +222,9 @@ aubio_onset_t * new_aubio_onset (char_t * onset_mode, aubio_onset_set_minioi_ms(o, 20.); aubio_onset_set_silence(o, -70.); + o->spectral_whitening = new_aubio_spectral_whitening(buf_size, hop_size, samplerate); + o->apply_adaptive_whitening = 1; + /* initialize internal variables */ o->last_onset = 0; o->total_frames = 0; @@ -221,6 +237,7 @@ beach: void del_aubio_onset (aubio_onset_t *o) { + del_aubio_spectral_whitening(o->spectral_whitening); del_aubio_specdesc(o->od); del_aubio_peakpicker(o->pp); del_aubio_pvoc(o->pv); diff --git a/src/spectral/awhitening.c b/src/spectral/awhitening.c new file mode 100644 index 00000000..6061c188 --- /dev/null +++ b/src/spectral/awhitening.c @@ -0,0 +1,106 @@ +/* + * Copyright (C) 2003-2015 Paul Brossier + * + * This file is part of aubio. + * + * aubio is free software: you can redistribute it and/or modify it under the + * terms of the GNU General Public License as published by the Free Software + * Foundation, either version 3 of the License, or (at your option) any later + * version. + * + * aubio 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 + * aubio. If not, see . + * + */ + +#include "aubio_priv.h" +#include "fvec.h" +#include "cvec.h" +#include "mathutils.h" +#include "spectral/awhitening.h" + +#define aubio_spectral_whitening_default_relax_time 30 // in seconds +#define aubio_spectral_whitening_default_decay 0.001 // -60dB attenuation + +/** structure to store object state */ +struct _aubio_spectral_whitening_t { + uint_t buf_size; + uint_t hop_size; + uint_t samplerate; + smpl_t relax_time; + smpl_t r_decay; + smpl_t floor; + fvec_t *peak_values; +}; + +void +aubio_spectral_whitening_do (aubio_spectral_whitening_t * o, cvec_t * fftgrain) +{ + uint_t i = 0; + for (i = 0; i < o->peak_values->length; i++) { + o->peak_values->data[i] = + MAX(fftgrain->norm[i], o->r_decay * o->peak_values->data[i]); + fftgrain->norm[i] /= o->peak_values->data[i]; + } +} + +aubio_spectral_whitening_t * +new_aubio_spectral_whitening (uint_t buf_size, uint_t hop_size, uint_t samplerate) +{ + aubio_spectral_whitening_t *o = AUBIO_NEW (aubio_spectral_whitening_t); + if ((sint_t)buf_size < 1) { + AUBIO_ERR("spectral_whitening: got buffer_size %d, but can not be < 1\n", buf_size); + goto beach; + } else if ((sint_t)hop_size < 1) { + AUBIO_ERR("spectral_whitening: got hop_size %d, but can not be < 1\n", hop_size); + goto beach; + } else if ((sint_t)samplerate < 1) { + AUBIO_ERR("spectral_whitening: got samplerate %d, but can not be < 1\n", samplerate); + goto beach; + } + o->peak_values = new_fvec (buf_size / 2 + 1); + o->buf_size = buf_size; + o->hop_size = hop_size; + o->samplerate = samplerate; + o->floor = 1.e-6; // from 1.e-6 to 0.2 + aubio_spectral_whitening_set_relax_time (o, aubio_spectral_whitening_default_relax_time); + aubio_spectral_whitening_reset (o); + return o; + +beach: + AUBIO_FREE(o); + return NULL; +} + +void +aubio_spectral_whitening_set_relax_time (aubio_spectral_whitening_t * o, smpl_t relax_time) +{ + o->relax_time = relax_time; + o->r_decay = POW (aubio_spectral_whitening_default_decay, + (o->hop_size / (float) o->samplerate) / o->relax_time); +} + +smpl_t +aubio_spectral_whitening_get_relax_time (aubio_spectral_whitening_t * o) +{ + return o->relax_time; +} + +void +aubio_spectral_whitening_reset (aubio_spectral_whitening_t * o) +{ + /* cover the case n == 0. */ + fvec_set_all (o->peak_values, o->floor); +} + +void +del_aubio_spectral_whitening (aubio_spectral_whitening_t * o) +{ + del_fvec (o->peak_values); + AUBIO_FREE (o); +} diff --git a/src/spectral/awhitening.h b/src/spectral/awhitening.h new file mode 100644 index 00000000..f319796d --- /dev/null +++ b/src/spectral/awhitening.h @@ -0,0 +1,106 @@ +/* + Copyright (C) 2003-2015 Paul Brossier + + This file is part of aubio. + + aubio is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + aubio 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 aubio. If not, see . + +*/ + +/** \file + + Spectral adaptive whitening + + References: + + D. Stowell and M. D. Plumbley. Adaptive whitening for improved real-time + audio onset detection. In Proceedings of the International Computer Music + Conference (ICMC), 2007, Copenhagen, Denmark. + + http://www.eecs.qmul.ac.uk/~markp/2007/StowellPlumbley07-icmc.pdf + + S. Böck,, F. Krebs, and M. Schedl. Evaluating the Online Capabilities of + Onset Detection Methods. In Proceedings of the 13th International Society for + Music Information Retrieval Conference (ISMIR), 2012, Porto, Portugal. + + http://ismir2012.ismir.net/event/papers/049_ISMIR_2012.pdf + http://www.cp.jku.at/research/papers/Boeck_etal_ISMIR_2012.pdf + +*/ + + +#ifndef _AUBIO_SPECTRAL_WHITENING_H +#define _AUBIO_SPECTRAL_WHITENING_H + +#ifdef __cplusplus +extern "C" { +#endif + +/** spectral whitening structure */ +typedef struct _aubio_spectral_whitening_t aubio_spectral_whitening_t; + +/** execute spectral adaptive whitening, in-place + + \param o spectral whitening object as returned by new_aubio_spectral_whitening() + \param fftgrain input signal spectrum as computed by aubio_pvoc_do() or aubio_fft_do() + +*/ +void aubio_spectral_whitening_do (aubio_spectral_whitening_t * o, + cvec_t * fftgrain); + +/** creation of a spectral whitening object + + \param win_size length of the input spectrum frame + +*/ +aubio_spectral_whitening_t *new_aubio_spectral_whitening (uint_t buf_size, + uint_t hop_size, + uint_t samplerate); + +/** reset spectral whitening object + + \param o spectral whitening object as returned by new_aubio_spectral_whitening() + + */ +void aubio_spectral_whitening_reset (aubio_spectral_whitening_t * o); + +/** set relaxation time for spectral whitening + + \param o spectral whitening object as returned by new_aubio_spectral_whitening() + \param relax_time relaxation time in seconds + + */ +void aubio_spectral_whitening_set_relax_time (aubio_spectral_whitening_t * o, + smpl_t relax_time); + +/** get relaxation time of spectral whitening + + \param o spectral whitening object as returned by new_aubio_spectral_whitening() + \return relaxation time in seconds + +*/ +smpl_t aubio_spectral_whitening_get_relax_time (aubio_spectral_whitening_t * o); + +/** deletion of a spectral whitening + + \param o spectral whitening object as returned by new_aubio_spectral_whitening() + +*/ +void del_aubio_spectral_whitening (aubio_spectral_whitening_t * o); + +#ifdef __cplusplus +} +#endif + +#endif /* _AUBIO_SPECTRAL_WHITENING_H */