src/pitch/pitchyinfft.c: simplify, add some comment, update copyright
authorPaul Brossier <piem@piem.org>
Mon, 18 Mar 2013 08:18:30 +0000 (03:18 -0500)
committerPaul Brossier <piem@piem.org>
Mon, 18 Mar 2013 08:18:30 +0000 (03:18 -0500)
src/pitch/pitchyinfft.c

index de47fdf1fa41bcc82aa2795b898ec73c5b175dab..6e42cf0445921fd28f088feeb9ac6ea1a195bc70 100644 (file)
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2003-2009 Paul Brossier <piem@aubio.org>
+  Copyright (C) 2003-2013 Paul Brossier <piem@aubio.org>
 
   This file is part of aubio.
 
@@ -33,7 +33,6 @@ struct _aubio_pitchyinfft_t
   fvec_t *sqrmag;     /**< square difference function */
   fvec_t *weight;     /**< spectral weighting window (psychoacoustic model) */
   fvec_t *fftout;     /**< Fourier transform output */
-  fvec_t *res;        /**< complex vector to compute square difference function */
   aubio_fft_t *fft;   /**< fft object to compute square difference function */
   fvec_t *yinfft;     /**< Yin function */
   smpl_t tol;         /**< Yin tolerance */
@@ -59,7 +58,6 @@ new_aubio_pitchyinfft (uint_t bufsize)
   p->winput = new_fvec (bufsize);
   p->fft = new_aubio_fft (bufsize);
   p->fftout = new_fvec (bufsize);
-  p->res = new_fvec (bufsize);
   p->sqrmag = new_fvec (bufsize);
   p->yinfft = new_fvec (bufsize / 2 + 1);
   p->tol = 0.85;
@@ -98,43 +96,50 @@ void
 aubio_pitchyinfft_do (aubio_pitchyinfft_t * p, fvec_t * input, fvec_t * output)
 {
   uint_t tau, l;
+  uint_t length = p->fftout->length;
   uint_t halfperiod;
-  smpl_t tmp, sum;
-  fvec_t *res = (fvec_t *) p->res;
-  fvec_t *yin = (fvec_t *) p->yinfft;
-  l = 0;
-  tmp = 0.;
-  sum = 0.;
+  fvec_t *fftout = p->fftout;
+  fvec_t *yin = p->yinfft;
+  smpl_t tmp = 0., sum = 0.;
+  // window the input
   for (l = 0; l < input->length; l++) {
     p->winput->data[l] = p->win->data[l] * input->data[l];
   }
-  aubio_fft_do_complex (p->fft, p->winput, p->fftout);
-  uint_t length = p->fftout->length;
-  p->sqrmag->data[0] = SQR(p->fftout->data[0]);
+  // get the real / imag parts of its fft
+  aubio_fft_do_complex (p->fft, p->winput, fftout);
+  // get the squared magnitude spectrum, applying some weight
+  p->sqrmag->data[0] = SQR(fftout->data[0]);
   p->sqrmag->data[0] *= p->weight->data[0];
   for (l = 1; l < length / 2; l++) {
-    p->sqrmag->data[l] = SQR(p->fftout->data[l]) + SQR(p->fftout->data[length - l]);
+    p->sqrmag->data[l] = SQR(fftout->data[l]) + SQR(fftout->data[length - l]);
     p->sqrmag->data[l] *= p->weight->data[l];
-    p->sqrmag->data[p->sqrmag->length - l] = p->sqrmag->data[l];
+    p->sqrmag->data[length - l] = p->sqrmag->data[l];
   }
-  p->sqrmag->data[length / 2] = SQR(p->fftout->data[length / 2]);
+  p->sqrmag->data[length / 2] = SQR(fftout->data[length / 2]);
   p->sqrmag->data[length / 2] *= p->weight->data[length / 2];
+  // get sum of weighted squared mags
   for (l = 0; l < length / 2 + 1; l++) {
     sum += p->sqrmag->data[l];
   }
   sum *= 2.;
-  aubio_fft_do_complex (p->fft, p->sqrmag, res);
+  // get the real / imag parts of the fft of the squared magnitude
+  aubio_fft_do_complex (p->fft, p->sqrmag, fftout);
   yin->data[0] = 1.;
   for (tau = 1; tau < yin->length; tau++) {
-    yin->data[tau] = sum - res->data[tau];
+    // compute the square differences
+    yin->data[tau] = sum - fftout->data[tau];
+    // and the cumulative mean normalized difference function
     tmp += yin->data[tau];
     yin->data[tau] *= tau / tmp;
   }
+  // find best candidates
   tau = fvec_min_elem (yin);
   if (yin->data[tau] < p->tol) {
-    /* no interpolation */
-    //return tau;
-    /* 3 point quadratic interpolation */
+    // no interpolation, directly return the period as an integer
+    //output->data[0] = tau;
+    //return;
+
+    // 3 point quadratic interpolation
     //return fvec_quadint_min(yin,tau,1);
     /* additional check for (unlikely) octave doubling in higher frequencies */
     if (tau > 35) {
@@ -160,7 +165,6 @@ del_aubio_pitchyinfft (aubio_pitchyinfft_t * p)
   del_fvec (p->yinfft);
   del_fvec (p->sqrmag);
   del_fvec (p->fftout);
-  del_fvec (p->res);
   del_fvec (p->winput);
   del_fvec (p->weight);
   AUBIO_FREE (p);