From 3e48568b094d6dbc6310a445ec4afd79f7f53da3 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Eduard=20M=C3=BCller?= Date: Sun, 30 Jul 2017 22:53:43 +0200 Subject: [PATCH] yin pitch confidence tweaks return pitch candidate search's confidence in yin algorithms and not the global minimum, so that the confidence reflects the returned pitch value --- src/pitch/pitchyin.c | 16 ++++++++-------- src/pitch/pitchyinfast.c | 30 +++++++++++++++--------------- src/pitch/pitchyinfft.c | 12 +++++++----- 3 files changed, 30 insertions(+), 28 deletions(-) diff --git a/src/pitch/pitchyin.c b/src/pitch/pitchyin.c index 2a7f43db..32934f61 100644 --- a/src/pitch/pitchyin.c +++ b/src/pitch/pitchyin.c @@ -36,7 +36,7 @@ struct _aubio_pitchyin_t { fvec_t *yin; smpl_t tol; - smpl_t confidence; + uint_t peak_pos; }; /** compute difference function @@ -67,6 +67,7 @@ new_aubio_pitchyin (uint_t bufsize) aubio_pitchyin_t *o = AUBIO_NEW (aubio_pitchyin_t); o->yin = new_fvec (bufsize / 2); o->tol = 0.15; + o->peak_pos = 0; return o; } @@ -156,19 +157,18 @@ aubio_pitchyin_do (aubio_pitchyin_t * o, const fvec_t * input, fvec_t * out) period = tau - 3; if (tau > 4 && (yin_data[period] < tol) && (yin_data[period] < yin_data[period + 1])) { - out->data[0] = fvec_quadratic_peak_pos (yin, period); - goto beach; + o->peak_pos = (uint_t)period; + out->data[0] = fvec_quadratic_peak_pos (yin, o->peak_pos); + return; } } - out->data[0] = fvec_quadratic_peak_pos (yin, fvec_min_elem (yin)); -beach: - return; + o->peak_pos = (uint_t)fvec_min_elem (yin); + out->data[0] = fvec_quadratic_peak_pos (yin, o->peak_pos); } smpl_t aubio_pitchyin_get_confidence (aubio_pitchyin_t * o) { - o->confidence = 1. - fvec_min (o->yin); - return o->confidence; + return 1. - o->yin->data[o->peak_pos]; } uint_t diff --git a/src/pitch/pitchyinfast.c b/src/pitch/pitchyinfast.c index 45d312fa..d0b63642 100644 --- a/src/pitch/pitchyinfast.c +++ b/src/pitch/pitchyinfast.c @@ -38,7 +38,7 @@ struct _aubio_pitchyinfast_t { fvec_t *yin; smpl_t tol; - smpl_t confidence; + uint_t peak_pos; fvec_t *tmpdata; fvec_t *sqdiff; fvec_t *kernel; @@ -59,6 +59,7 @@ new_aubio_pitchyinfast (uint_t bufsize) o->kernel_fft = new_fvec (bufsize); o->fft = new_aubio_fft (bufsize); o->tol = 0.15; + o->peak_pos = 0; return o; } @@ -85,7 +86,6 @@ aubio_pitchyinfast_do (aubio_pitchyinfast_t * o, const fvec_t * input, fvec_t * uint_t B = o->tmpdata->length; uint_t W = o->yin->length; // B / 2 fvec_t tmp_slice, kernel_ptr; - smpl_t *yin_data = yin->data; uint_t tau; sint_t period; smpl_t tmp2 = 0.; @@ -142,36 +142,36 @@ aubio_pitchyinfast_do (aubio_pitchyinfast_t * o, const fvec_t * input, fvec_t * aubio_fft_rdo_complex(o->fft, compmul, rt_of_tau); // compute square difference r_t(tau) = sqdiff - 2 * r_t_tau[W-1:-1] for (tau = 0; tau < W; tau++) { - yin_data[tau] = o->sqdiff->data[tau] - 2. * rt_of_tau->data[tau+W]; + yin->data[tau] = o->sqdiff->data[tau] - 2. * rt_of_tau->data[tau+W]; } } // now build yin and look for first minimum - fvec_set_all(out, 0.); - yin_data[0] = 1.; + fvec_zeros(out); + yin->data[0] = 1.; for (tau = 1; tau < length; tau++) { - tmp2 += yin_data[tau]; + tmp2 += yin->data[tau]; if (tmp2 != 0) { yin->data[tau] *= tau / tmp2; } else { yin->data[tau] = 1.; } period = tau - 3; - if (tau > 4 && (yin_data[period] < tol) && - (yin_data[period] < yin_data[period + 1])) { - out->data[0] = fvec_quadratic_peak_pos (yin, period); - goto beach; + if (tau > 4 && (yin->data[period] < tol) && + (yin->data[period] < yin->data[period + 1])) { + o->peak_pos = (uint_t)period; + out->data[0] = fvec_quadratic_peak_pos (yin, o->peak_pos); + return; } } - out->data[0] = fvec_quadratic_peak_pos (yin, fvec_min_elem (yin) ); -beach: - return; + // use global minimum + o->peak_pos = (uint_t)fvec_min_elem (yin); + out->data[0] = fvec_quadratic_peak_pos (yin, o->peak_pos); } smpl_t aubio_pitchyinfast_get_confidence (aubio_pitchyinfast_t * o) { - o->confidence = 1. - fvec_min (o->yin); - return o->confidence; + return 1. - o->yin->data[o->peak_pos]; } uint_t diff --git a/src/pitch/pitchyinfft.c b/src/pitch/pitchyinfft.c index 9243e24f..f213ef24 100644 --- a/src/pitch/pitchyinfft.c +++ b/src/pitch/pitchyinfft.c @@ -36,7 +36,7 @@ struct _aubio_pitchyinfft_t aubio_fft_t *fft; /**< fft object to compute square difference function */ fvec_t *yinfft; /**< Yin function */ smpl_t tol; /**< Yin tolerance */ - smpl_t confidence; /**< confidence */ + uint_t peak_pos; /**< currently selected peak pos*/ uint_t short_period; /** shortest period under which to check for octave error */ }; @@ -67,6 +67,7 @@ new_aubio_pitchyinfft (uint_t samplerate, uint_t bufsize) p->sqrmag = new_fvec (bufsize); p->yinfft = new_fvec (bufsize / 2 + 1); p->tol = 0.85; + p->peak_pos = 0; p->win = new_aubio_window ("hanningz", bufsize); p->weight = new_fvec (bufsize / 2 + 1); for (i = 0; i < p->weight->length; i++) { @@ -161,11 +162,13 @@ aubio_pitchyinfft_do (aubio_pitchyinfft_t * p, const fvec_t * input, fvec_t * ou /* should compare the minimum value of each interpolated peaks */ halfperiod = FLOOR (tau / 2 + .5); if (yin->data[halfperiod] < p->tol) - output->data[0] = fvec_quadratic_peak_pos (yin, halfperiod); + p->peak_pos = halfperiod; else - output->data[0] = fvec_quadratic_peak_pos (yin, tau); + p->peak_pos = tau; + output->data[0] = fvec_quadratic_peak_pos (yin, p->peak_pos); } } else { + p->peak_pos = 0; output->data[0] = 0.; } } @@ -185,8 +188,7 @@ del_aubio_pitchyinfft (aubio_pitchyinfft_t * p) smpl_t aubio_pitchyinfft_get_confidence (aubio_pitchyinfft_t * o) { - o->confidence = 1. - fvec_min (o->yinfft); - return o->confidence; + return 1. - o->yinfft->data[o->peak_pos]; } uint_t -- 2.11.0