shithub: aubio

Download patch

ref: 8a5148ed159bbb2d5c0dbbcb5a579393c3eb1e56
parent: 4c0a1db6fb446db277ca3a1e735d509ade4f7d3f
author: Paul Brossier <[email protected]>
date: Sat Feb 22 11:00:02 EST 2014

src/spectral/phasevoc.c: improve, accept that hop_s == buf_s

--- a/src/spectral/phasevoc.c
+++ b/src/spectral/phasevoc.c
@@ -30,10 +30,10 @@
   uint_t win_s;       /** grain length */
   uint_t hop_s;       /** overlap step */
   aubio_fft_t * fft;  /** fft object */
-  fvec_t * synth;     /** cur output grain [win_s] */
-  fvec_t * synthold;  /** last input frame [win_s-hop_s] */
-  fvec_t * data;      /** current input grain [win_s] */
-  fvec_t * dataold;   /** last input frame [win_s-hop_s] */
+  fvec_t * data;      /** current input grain, [win_s] frames */
+  fvec_t * dataold;   /** memory of past grain, [win_s-hop_s] frames */
+  fvec_t * synth;     /** current output grain, [win_s] frames */
+  fvec_t * synthold;  /** memory of past grain, [win_s-hop_s] frames */
   fvec_t * w;         /** grain window [win_s] */
 };
 
@@ -80,8 +80,8 @@
   } else if (win_s < 1) {
     AUBIO_ERR("got buffer_size %d, but can not be < 2\n", win_s);
     goto beach;
-  } else if (win_s < hop_s + 1) {
-    AUBIO_ERR("hop size (%d) is larger than or equal to win size (%d)\n", win_s, hop_s);
+  } else if (win_s < hop_s) {
+    AUBIO_ERR("hop size (%d) is larger than win size (%d)\n", win_s, hop_s);
     goto beach;
   }
 
@@ -92,8 +92,13 @@
   pv->synth    = new_fvec (win_s);
 
   /* new input output */
-  pv->dataold  = new_fvec  (win_s-hop_s);
-  pv->synthold = new_fvec (win_s-hop_s);
+  if (win_s > hop_s) {
+    pv->dataold  = new_fvec  (win_s-hop_s);
+    pv->synthold = new_fvec (win_s-hop_s);
+  } else {
+    pv->dataold  = new_fvec  (1);
+    pv->synthold = new_fvec (1);
+  }
   pv->w        = new_aubio_window ("hanningz", win_s);
 
   pv->hop_s    = hop_s;
@@ -140,17 +145,31 @@
 static void aubio_pvoc_addsynth(const smpl_t * synth, smpl_t * synthold, 
                 smpl_t * synthnew, uint_t win_s, uint_t hop_s)
 {
-  uint_t i;
-  smpl_t scale = 2 * hop_s / (win_s + .0);
-  /* add new synth to old one and put result in synthnew */
+  uint_t i, start;
+  smpl_t scale = hop_s * 2. / win_s;
+
+  /* put new result in synthnew */
   for (i = 0; i < hop_s; i++)
-    synthnew[i] = synthold[i] + synth[i] * scale;
+    synthnew[i] = synth[i] * scale;
+  /* no overlap, nothing else to do */
+  if (win_s <= hop_s) return;
+
+  /* add new synth to old one and */
+  for (i = 0; i < hop_s; i++)
+    synthnew[i] += synthold[i];
+
   /* shift synthold */
-  for (i = 0; i < win_s - 2 * hop_s; i++)
-    synthold[i] = synthold[i + hop_s];
+  for (i = hop_s; i < win_s - hop_s; i++)
+    synthold[i - hop_s] = synthold[i];
+
+  /* more than 50% overlap, overlap anyway */
+  if (win_s < 2 * hop_s) start = 0;
+  /* less than 50% overlap, reset latest grain trail */
+  else start = win_s - hop_s - hop_s;
   /* erase last frame in synthold */
-  for (i = win_s - hop_s; i < win_s; i++)
-    synthold[i - hop_s] = 0.;
+  for (i = start; i < win_s - hop_s; i++)
+    synthold[i] = 0.;
+
   /* additive synth */
   for (i = 0; i < win_s - hop_s; i++)
     synthold[i] += synth[i + hop_s] * scale;