shithub: aubio

Download patch

ref: 22d33e22c85d5ff1699897f0ef5b6c251a6a5a13
parent: 2ba3440468478fdaaf5b4fbc11e7103d54f7500e
author: Paul Brossier <piem@piem.org>
date: Thu Oct 8 16:49:10 EDT 2009

src/pitch/pitchyinfft.{c,h}: add get/set for tolerance, clean and update prototypes, make multichannel

--- a/src/pitch/pitchyinfft.c
+++ b/src/pitch/pitchyinfft.c
@@ -33,6 +33,7 @@
   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 @@
   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 @@
   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,7 +124,7 @@
     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 */
@@ -127,17 +131,19 @@
     //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){
@@ -150,4 +156,13 @@
   del_fvec(p->winput);
   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;
 }
--- a/src/pitch/pitchyinfft.h
+++ b/src/pitch/pitchyinfft.h
@@ -45,10 +45,10 @@
  
   \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 
@@ -61,6 +61,23 @@
  
 */
 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
 }
--- a/tests/src/test-pitchyinfft.c
+++ b/tests/src/test-pitchyinfft.c
@@ -5,11 +5,13 @@
         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++;
         };