src/pitch/pitchyinfft.c: optimize by avoiding polar coordinates, closes #7
authorPaul Brossier <piem@piem.org>
Sat, 16 Mar 2013 21:44:19 +0000 (16:44 -0500)
committerPaul Brossier <piem@piem.org>
Sat, 16 Mar 2013 21:44:19 +0000 (16:44 -0500)
src/pitch/pitchyinfft.c

index d4e9905db1bef888ecf183850348d64a11a74de9..de47fdf1fa41bcc82aa2795b898ec73c5b175dab 100644 (file)
@@ -30,10 +30,10 @@ struct _aubio_pitchyinfft_t
 {
   fvec_t *win;        /**< temporal weighting window */
   fvec_t *winput;     /**< windowed spectrum */
-  cvec_t *res;        /**< complex vector to compute square difference function */
   fvec_t *sqrmag;     /**< square difference function */
   fvec_t *weight;     /**< spectral weighting window (psychoacoustic model) */
-  cvec_t *fftout;     /**< Fourier transform output */
+  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 */
@@ -58,9 +58,9 @@ new_aubio_pitchyinfft (uint_t bufsize)
   aubio_pitchyinfft_t *p = AUBIO_NEW (aubio_pitchyinfft_t);
   p->winput = new_fvec (bufsize);
   p->fft = new_aubio_fft (bufsize);
-  p->fftout = new_cvec (bufsize);
+  p->fftout = new_fvec (bufsize);
+  p->res = new_fvec (bufsize);
   p->sqrmag = new_fvec (bufsize);
-  p->res = new_cvec (bufsize);
   p->yinfft = new_fvec (bufsize / 2 + 1);
   p->tol = 0.85;
   p->win = new_aubio_window ("hanningz", bufsize);
@@ -100,7 +100,7 @@ aubio_pitchyinfft_do (aubio_pitchyinfft_t * p, fvec_t * input, fvec_t * output)
   uint_t tau, l;
   uint_t halfperiod;
   smpl_t tmp, sum;
-  cvec_t *res = (cvec_t *) p->res;
+  fvec_t *res = (fvec_t *) p->res;
   fvec_t *yin = (fvec_t *) p->yinfft;
   l = 0;
   tmp = 0.;
@@ -108,22 +108,25 @@ aubio_pitchyinfft_do (aubio_pitchyinfft_t * p, fvec_t * input, fvec_t * output)
   for (l = 0; l < input->length; l++) {
     p->winput->data[l] = p->win->data[l] * input->data[l];
   }
-  aubio_fft_do (p->fft, p->winput, p->fftout);
-  p->sqrmag->data[0] = SQR (p->fftout->norm[0]);
+  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]);
   p->sqrmag->data[0] *= p->weight->data[0];
-  for (l = 1; l < p->fftout->length; l++) {
-    p->sqrmag->data[l] = SQR (p->fftout->norm[l]);
+  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] *= p->weight->data[l];
     p->sqrmag->data[p->sqrmag->length - l] = p->sqrmag->data[l];
   }
-  for (l = 0; l < p->fftout->length; l++) {
+  p->sqrmag->data[length / 2] = SQR(p->fftout->data[length / 2]);
+  p->sqrmag->data[length / 2] *= p->weight->data[length / 2];
+  for (l = 0; l < length / 2 + 1; l++) {
     sum += p->sqrmag->data[l];
   }
   sum *= 2.;
-  aubio_fft_do (p->fft, p->sqrmag, res);
+  aubio_fft_do_complex (p->fft, p->sqrmag, res);
   yin->data[0] = 1.;
   for (tau = 1; tau < yin->length; tau++) {
-    yin->data[tau] = sum - res->norm[tau] * COS (res->phas[tau]);
+    yin->data[tau] = sum - res->data[tau];
     tmp += yin->data[tau];
     yin->data[tau] *= tau / tmp;
   }
@@ -156,8 +159,8 @@ del_aubio_pitchyinfft (aubio_pitchyinfft_t * p)
   del_aubio_fft (p->fft);
   del_fvec (p->yinfft);
   del_fvec (p->sqrmag);
-  del_cvec (p->res);
-  del_cvec (p->fftout);
+  del_fvec (p->fftout);
+  del_fvec (p->res);
   del_fvec (p->winput);
   del_fvec (p->weight);
   AUBIO_FREE (p);