shithub: aubio

Download patch

ref: bdb249b81da3c1f73413348d727d25f5c88cbe8a
parent: 885679133f98b041dd358a7eb92550acaef5f325
author: Paul Brossier <piem@piem.org>
date: Fri Sep 30 07:33:16 EDT 2016

src/effects/timestretch_rubberband.c: do not reopen thread in _seek, add flags to mark warmed-up and finished states

--- a/src/effects/timestretch_rubberband.c
+++ b/src/effects/timestretch_rubberband.c
@@ -64,6 +64,8 @@
   pthread_cond_t read_avail;
   pthread_cond_t read_request;
   sint_t available;
+  uint_t started;
+  uint_t finish;
 #endif
 };
 
@@ -112,9 +114,12 @@
   //rubberband_set_debug_level(p->rb, 10);
 
 #ifdef HAVE_THREADS
+  p->started = 0;
+  p->finish = 0;
   pthread_mutex_init(&p->read_mutex, 0);
   pthread_cond_init (&p->read_avail, 0);
   pthread_cond_init (&p->read_request, 0);
+  //AUBIO_WRN("timestretch: creating thread\n");
   pthread_create(&p->read_thread, 0, aubio_timestretch_readfn, p);
   //AUBIO_DBG("timestretch: new_ waiting for warmup, got %d available\n", p->available);
   pthread_mutex_lock(&p->read_mutex);
@@ -137,41 +142,35 @@
 aubio_timestretch_readfn(void *z)
 {
   aubio_timestretch_t *p = z;
-  // signal main-thread when we are done
-  //AUBIO_WRN("timestretch: read_thread locking, got %d available\n", p->available);
-  pthread_mutex_lock(&p->read_mutex);
-  aubio_timestretch_warmup(p);
-  //AUBIO_WRN("timestretch: signaling warmup\n");
-  pthread_cond_signal(&p->read_avail);
-  //AUBIO_WRN("timestretch: unlocking in readfn\n");
-  pthread_mutex_unlock(&p->read_mutex);
-  AUBIO_WRN("timestretch: entering readfn loop\n");
   while(1) { //p->available < (int)p->hopsize && p->eof != 1) {
     //AUBIO_WRN("timestretch: locking in readfn\n");
     pthread_mutex_lock(&p->read_mutex);
-    p->available = aubio_timestretch_fetch(p, p->hopsize);
-    //AUBIO_WRN("timestretch: read_thread read %d\n", p->available);
-    // signal main-thread when we are done
-    //AUBIO_WRN("timestretch: signaling new read\n");
-    pthread_cond_signal(&p->read_avail);
-    if (p->eof != 1) {
+    if (!p->started && !p->eof) {
+      // fetch the first few samples and mark as started
+      //AUBIO_WRN("timestretch: fetching first samples\n");
+      aubio_timestretch_warmup(p);
+      p->started = 1;
+    } else if (!p->eof) {
+      // fetch at least p->hopsize stretched samples
+      p->available = aubio_timestretch_fetch(p, p->hopsize);
+      // signal available frames
+      pthread_cond_signal(&p->read_avail);
+      if (p->eof != 1) {
+        // the end of file was not reached yet, wait for the next read_request
+        pthread_cond_wait(&p->read_request, &p->read_mutex);
+      } else {
+        // eof was reached, do not wait for a read request and mark as stopped
+        p->started = 0;
+      }
+    } else {
+      //pthread_cond_signal(&p->read_avail);
       pthread_cond_wait(&p->read_request, &p->read_mutex);
+      //AUBIO_WRN("timestretch: finished idle in readfn\n");
+      if (p->finish) pthread_exit(NULL);
     }
-    if (p->eof == 1) {
-      AUBIO_WRN("timestretch: read_thread eof reached %d, %d/%d\n", p->available,
-        p->hopsize, p->source_hopsize);
-      pthread_mutex_unlock(&p->read_mutex);
-      break;
-    }
     //AUBIO_WRN("timestretch: unlocking in readfn\n");
     pthread_mutex_unlock(&p->read_mutex);
   }
-#if 1
-  pthread_mutex_lock(&p->read_mutex);
-  //AUBIO_WRN("timestretch: signaling end\n");
-  pthread_cond_signal(&p->read_avail);
-  pthread_mutex_unlock(&p->read_mutex);
-#endif
   //AUBIO_WRN("timestretch: exiting readfn\n");
   pthread_exit(NULL);
 }
@@ -193,12 +192,13 @@
 del_aubio_timestretch (aubio_timestretch_t * p)
 {
 #ifdef HAVE_THREADS
+  void *threadfn;
+  //AUBIO_WRN("timestretch: entering delete\n");
   pthread_mutex_lock(&p->read_mutex);
+  p->finish = 1;
   pthread_cond_signal(&p->read_request);
   //pthread_cond_wait(&p->read_avail, &p->read_mutex);
   pthread_mutex_unlock(&p->read_mutex);
-#if 1
-  void *threadfn;
   if ((p->eof == 0) && (pthread_cancel(p->read_thread))) {
       AUBIO_WRN("timestretch: cancelling thread failed\n");
   }
@@ -205,7 +205,6 @@
   if (pthread_join(p->read_thread, &threadfn)) {
       AUBIO_WRN("timestretch: joining thread failed\n");
   }
-#endif
   pthread_mutex_destroy(&p->read_mutex);
   pthread_cond_destroy(&p->read_avail);
   pthread_cond_destroy(&p->read_request);
@@ -339,7 +338,6 @@
 {
   uint_t err = AUBIO_OK;
 #if HAVE_THREADS
-  AUBIO_WRN("timestretch: seek_ waiting for warmup, got %d available\n", p->available);
   pthread_mutex_lock(&p->read_mutex);
 #endif
   p->eof = 0;
@@ -347,17 +345,8 @@
   err = aubio_source_seek(p->source, pos);
 #if HAVE_THREADS
   p->available = 0;
-  void *threadfn;
-  if ((p->eof == 0) && (pthread_cancel(p->read_thread) == 0)) {
-      AUBIO_WRN("timestretch: cancelling thread failed\n");
-  }
-  if (pthread_join(p->read_thread, &threadfn)) {
-      AUBIO_WRN("timestretch: joining thread failed\n");
-  }
-  pthread_create(&p->read_thread, 0, aubio_timestretch_readfn, p);
-  pthread_cond_wait(&p->read_avail, &p->read_mutex);
+  p->started = 1;
   pthread_mutex_unlock(&p->read_mutex);
-  //AUBIO_WRN("timestretch: seek_ warm up success, got %d available\n", p->available);
 #endif
   return err;
 }