From 2ba3440468478fdaaf5b4fbc11e7103d54f7500e Mon Sep 17 00:00:00 2001 From: Paul Brossier Date: Thu, 8 Oct 2009 20:24:43 +0200 Subject: [PATCH] src/pitch/pitchyin.{c,h}: add proper aubio_pitchyin_t object, clean and update prototypes, make multichannel --- src/pitch/pitchyin.c | 88 +++++++++++++++++++++++++++++++-------- src/pitch/pitchyin.h | 46 ++++++++++++-------- tests/src/test-pitchyin.c | 6 +-- 3 files changed, 102 insertions(+), 38 deletions(-) diff --git a/src/pitch/pitchyin.c b/src/pitch/pitchyin.c index 30309e00..90891c6a 100644 --- a/src/pitch/pitchyin.c +++ b/src/pitch/pitchyin.c @@ -30,6 +30,45 @@ #include "mathutils.h" #include "pitch/pitchyin.h" +struct _aubio_pitchyin_t { + fvec_t * yin; + smpl_t tol; +}; + +/** compute difference function + + \param input input signal + \param yinbuf output buffer to store difference function (half shorter than input) + +*/ +void aubio_pitchyin_diff(fvec_t * input, fvec_t * yinbuf); + +/** in place computation of the YIN cumulative normalised function + + \param yinbuf input signal (a square difference function), also used to store function + +*/ +void aubio_pitchyin_getcum(fvec_t * yinbuf); + +/** detect pitch in a YIN function + + \param yinbuf input buffer as computed by aubio_pitchyin_getcum + +*/ +uint_t aubio_pitchyin_getpitch(fvec_t *yinbuf); + +aubio_pitchyin_t * new_aubio_pitchyin (uint_t bufsize) { + aubio_pitchyin_t * o = AUBIO_NEW(aubio_pitchyin_t); + o->yin = new_fvec (bufsize/2, 1); + o->tol = 0.15; + return o; +} + +void del_aubio_pitchyin (aubio_pitchyin_t *o) { + del_fvec(o->yin); + AUBIO_FREE(o); +} + /* outputs the difference function */ void aubio_pitchyin_diff(fvec_t * input, fvec_t * yin){ uint_t c,j,tau; @@ -88,28 +127,43 @@ uint_t aubio_pitchyin_getpitch(fvec_t * yin) { /* all the above in one */ -smpl_t aubio_pitchyin_getpitchfast(fvec_t * input, fvec_t * yin, smpl_t tol){ - uint_t c=0,j,tau = 0; +void aubio_pitchyin_do(aubio_pitchyin_t *o, fvec_t * input, fvec_t * out){ + smpl_t tol = o->tol; + fvec_t * yin = o->yin; + uint_t c , j,tau = 0; sint_t period; smpl_t tmp = 0., tmp2 = 0.; - yin->data[c][0] = 1.; - for (tau=1;taulength;tau++) - { - yin->data[c][tau] = 0.; - for (j=0;jlength;j++) + for (c = 0; c < input->channels; c++) { + yin->data[c][0] = 1.; + for (tau=1;taulength;tau++) { - tmp = input->data[c][j] - input->data[c][j+tau]; - yin->data[c][tau] += SQR(tmp); - } - tmp2 += yin->data[c][tau]; - yin->data[c][tau] *= tau/tmp2; - period = tau-3; - if(tau > 4 && (yin->data[c][period] < tol) && - (yin->data[c][period] < yin->data[c][period+1])) { - return fvec_quadint(yin,period,1); + yin->data[c][tau] = 0.; + for (j=0;jlength;j++) + { + tmp = input->data[c][j] - input->data[c][j+tau]; + yin->data[c][tau] += SQR(tmp); + } + tmp2 += yin->data[c][tau]; + yin->data[c][tau] *= tau/tmp2; + period = tau-3; + if(tau > 4 && (yin->data[c][period] < tol) && + (yin->data[c][period] < yin->data[c][period+1])) { + out->data[c][0] = fvec_quadint(yin,period,1); + goto beach; + } } + out->data[c][0] = fvec_quadint(yin,fvec_min_elem(yin),1); +beach: + continue; } - return fvec_quadint(yin,fvec_min_elem(yin),1); //return 0; } +uint_t aubio_pitchyin_set_tolerance (aubio_pitchyin_t *o, smpl_t tol) { + o->tol = tol; + return 0; +} + +smpl_t aubio_pitchyin_get_tolerance (aubio_pitchyin_t *o) { + return o->tol; +} diff --git a/src/pitch/pitchyin.h b/src/pitch/pitchyin.h index 3123b6f3..797a733b 100644 --- a/src/pitch/pitchyin.h +++ b/src/pitch/pitchyin.h @@ -37,36 +37,48 @@ extern "C" { #endif -/** compute difference function - - \param input input signal - \param yinbuf output buffer to store difference function (half shorter than input) +/** pitch detection object */ +typedef struct _aubio_pitchyin_t aubio_pitchyin_t; +/** creation of the pitch detection object + + \param bufsize size of the input buffer to analyse + */ -void aubio_pitchyin_diff(fvec_t * input, fvec_t * yinbuf); +aubio_pitchyin_t * new_aubio_pitchyin (uint_t bufsize); -/** in place computation of the YIN cumulative normalised function - - \param yinbuf input signal (a square difference function), also used to store function +/** deletion of the pitch detection object + + \param p pitch detection object as returned by new_aubio_pitchyin() + +*/ +void del_aubio_pitchyin (aubio_pitchyin_t * o); +/** execute pitch detection on an input buffer + + \param p pitch detection object as returned by new_aubio_pitchyin() + \param input input signal window (length as specified at creation time) + \param tol tolerance parameter for minima selection [default 0.85] + */ -void aubio_pitchyin_getcum(fvec_t * yinbuf); +void aubio_pitchyin_do (aubio_pitchyin_t * o, fvec_t *in, fvec_t *out); -/** detect pitch in a YIN function + +/** set tolerance parameter for YIN algorithm - \param yinbuf input buffer as computed by aubio_pitchyin_getcum + \param o YIN pitch detection object + \param tol tolerance parameter for minima selection [default 0.15] */ -uint_t aubio_pitchyin_getpitch(fvec_t *yinbuf); +uint_t aubio_pitchyin_set_tolerance (aubio_pitchyin_t *o, smpl_t tol); -/** fast implementation of the YIN algorithm +/** get tolerance parameter for YIN algorithm - \param input input signal - \param yinbuf input buffer used to compute the YIN function - \param tol tolerance parameter for minima selection [default 0.15] + \param o YIN pitch detection object + \return tolerance parameter for minima selection [default 0.15] */ -smpl_t aubio_pitchyin_getpitchfast(fvec_t * input, fvec_t *yinbuf, smpl_t tol); +smpl_t aubio_pitchyin_get_tolerance (aubio_pitchyin_t *o); #ifdef __cplusplus } diff --git a/tests/src/test-pitchyin.c b/tests/src/test-pitchyin.c index 5766a71e..795be34e 100644 --- a/tests/src/test-pitchyin.c +++ b/tests/src/test-pitchyin.c @@ -6,13 +6,11 @@ int main(){ uint_t channels = 1; /* number of channel */ fvec_t * in = new_fvec (win_s, channels); /* input buffer */ fvec_t * out = new_fvec (win_s/2, channels); /* input buffer */ + aubio_pitchyin_t *p = new_aubio_pitchyin (win_s); uint_t i = 0; while (i < 10) { - aubio_pitchyin_diff (in,out); - aubio_pitchyin_getcum (out); - aubio_pitchyin_getpitch (out); - aubio_pitchyin_getpitchfast (in,out,0.2); + aubio_pitchyin_do (p, in,out); i++; }; -- 2.26.2