From 22d33e22c85d5ff1699897f0ef5b6c251a6a5a13 Mon Sep 17 00:00:00 2001 From: Paul Brossier Date: Thu, 8 Oct 2009 20:49:10 +0200 Subject: [PATCH] src/pitch/pitchyinfft.{c,h}: add get/set for tolerance, clean and update prototypes, make multichannel --- src/pitch/pitchyinfft.c | 37 +++++++++++++++++++++++++----------- src/pitch/pitchyinfft.h | 21 ++++++++++++++++++-- tests/src/test-pitchyinfft.c | 4 +++- 3 files changed, 48 insertions(+), 14 deletions(-) diff --git a/src/pitch/pitchyinfft.c b/src/pitch/pitchyinfft.c index c53e283a..04209871 100644 --- a/src/pitch/pitchyinfft.c +++ b/src/pitch/pitchyinfft.c @@ -33,6 +33,7 @@ struct _aubio_pitchyinfft_t { cvec_t * fftout; /**< Fourier transform output */ aubio_fft_t * fft; /**< fft object to compute square difference function */ fvec_t * yinfft; /**< Yin function */ + smpl_t tol; /**< Yin tolerance */ }; static const smpl_t freqs[] = {0., 20., 25., 31.5, 40., 50., 63., 80., 100., @@ -54,6 +55,7 @@ aubio_pitchyinfft_t * new_aubio_pitchyinfft (uint_t bufsize) p->sqrmag = new_fvec(bufsize,1); p->res = new_cvec(bufsize,1); p->yinfft = new_fvec(bufsize/2+1,1); + p->tol = 0.85; p->win = new_aubio_window(bufsize, aubio_win_hanningz); p->weight = new_fvec(bufsize/2+1,1); { @@ -87,14 +89,16 @@ aubio_pitchyinfft_t * new_aubio_pitchyinfft (uint_t bufsize) return p; } -smpl_t aubio_pitchyinfft_do (aubio_pitchyinfft_t * p, fvec_t * input, smpl_t tol) { - uint_t tau, l = 0; +void aubio_pitchyinfft_do (aubio_pitchyinfft_t * p, fvec_t * input, fvec_t * output) { + uint_t i, tau, l; uint_t halfperiod; - smpl_t tmp = 0, sum = 0; + smpl_t tmp, sum; cvec_t * res = (cvec_t *)p->res; fvec_t * yin = (fvec_t *)p->yinfft; + for (i=0; i < input->channels; i++){ + l = 0; tmp = 0.; sum = 0.; for (l=0; l < input->length; l++){ - p->winput->data[0][l] = p->win->data[0][l] * input->data[0][l]; + p->winput->data[0][l] = p->win->data[0][l] * input->data[i][l]; } aubio_fft_do(p->fft,p->winput,p->fftout); for (l=0; l < p->fftout->length; l++){ @@ -120,24 +124,26 @@ smpl_t aubio_pitchyinfft_do (aubio_pitchyinfft_t * p, fvec_t * input, smpl_t tol yin->data[0][tau] *= tau/tmp; } tau = fvec_min_elem(yin); - if (yin->data[0][tau] < tol) { + if (yin->data[0][tau] < p->tol) { /* no interpolation */ //return tau; /* 3 point quadratic interpolation */ //return fvec_quadint_min(yin,tau,1); /* additional check for (unlikely) octave doubling in higher frequencies */ if (tau>35) { - return fvec_quadint(yin,tau,1); + output->data[i][0] = fvec_quadint(yin,tau,1); } else { /* should compare the minimum value of each interpolated peaks */ halfperiod = FLOOR(tau/2+.5); - if (yin->data[0][halfperiod] < tol) - return fvec_quadint(yin,halfperiod,1); + if (yin->data[0][halfperiod] < p->tol) + output->data[i][0] = fvec_quadint(yin,halfperiod,1); else - return fvec_quadint(yin,tau,1); + output->data[i][0] = fvec_quadint(yin,tau,1); } - } else - return 0.; + } else { + output->data[i][0] = 0.; + } + } } void del_aubio_pitchyinfft(aubio_pitchyinfft_t *p){ @@ -151,3 +157,12 @@ void del_aubio_pitchyinfft(aubio_pitchyinfft_t *p){ del_fvec(p->weight); AUBIO_FREE(p); } + +uint_t aubio_pitchyinfft_set_tolerance (aubio_pitchyinfft_t * p, smpl_t tol) { + p->tol = tol; + return 0; +} + +smpl_t aubio_pitchyinfft_get_tolerance (aubio_pitchyinfft_t * p) { + return p->tol; +} diff --git a/src/pitch/pitchyinfft.h b/src/pitch/pitchyinfft.h index 155fcdca..44c557e4 100644 --- a/src/pitch/pitchyinfft.h +++ b/src/pitch/pitchyinfft.h @@ -45,10 +45,10 @@ typedef struct _aubio_pitchyinfft_t aubio_pitchyinfft_t; \param p pitch detection object as returned by new_aubio_pitchyinfft \param input input signal window (length as specified at creation time) - \param tol tolerance parameter for minima selection [default 0.85] + \param output pitch period candidates, in samples */ -smpl_t aubio_pitchyinfft_do (aubio_pitchyinfft_t *p, fvec_t * input, smpl_t tol); +void aubio_pitchyinfft_do (aubio_pitchyinfft_t *p, fvec_t * input, fvec_t * output); /** creation of the pitch detection object \param bufsize size of the input buffer to analyse @@ -62,6 +62,23 @@ aubio_pitchyinfft_t * new_aubio_pitchyinfft (uint_t bufsize); */ void del_aubio_pitchyinfft (aubio_pitchyinfft_t *p); +/** get tolerance parameter for YIN algorithm + + \param o YIN pitch detection object + + \return tolerance parameter for minima selection [default 0.15] + +*/ +smpl_t aubio_pitchyinfft_get_tolerance (aubio_pitchyinfft_t * p); + +/** set tolerance parameter for YIN algorithm + + \param o YIN pitch detection object + \param tol tolerance parameter for minima selection [default 0.15] + +*/ +uint_t aubio_pitchyinfft_set_tolerance (aubio_pitchyinfft_t * p, smpl_t tol); + #ifdef __cplusplus } #endif diff --git a/tests/src/test-pitchyinfft.c b/tests/src/test-pitchyinfft.c index 5e74c8b7..9b26e3de 100644 --- a/tests/src/test-pitchyinfft.c +++ b/tests/src/test-pitchyinfft.c @@ -5,11 +5,13 @@ int main(){ uint_t win_s = 1024; /* window size */ uint_t channels = 1; /* number of channel */ fvec_t * in = new_fvec (win_s, channels); /* input buffer */ + fvec_t * out = new_fvec (1, channels); /* output pitch periods */ aubio_pitchyinfft_t * o = new_aubio_pitchyinfft(win_s); + aubio_pitchyinfft_set_tolerance (o, 0.2); uint_t i = 0; while (i < 10) { - aubio_pitchyinfft_do (o,in,0.2); + aubio_pitchyinfft_do (o,in,out); i++; }; -- 2.26.2