yin pitch confidence tweaks
authorEduard Müller <mueller.eduard@googlemail.com>
Sun, 30 Jul 2017 20:53:43 +0000 (22:53 +0200)
committerEduard Müller <mueller.eduard@googlemail.com>
Sun, 30 Jul 2017 20:53:43 +0000 (22:53 +0200)
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
src/pitch/pitchyinfast.c
src/pitch/pitchyinfft.c

index 2a7f43d..32934f6 100644 (file)
@@ -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
index 45d312f..d0b6364 100644 (file)
@@ -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
index 9243e24..f213ef2 100644 (file)
@@ -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