Index: src/effects/timestretch_rubberband.c
===================================================================
--- src/effects/timestretch_rubberband.c	(revision 0202028b01b6a06f6570c93058095d4957a146b9)
+++ src/effects/timestretch_rubberband.c	(revision b21c75104d33e00822ac53a520a9a67f63629c3d)
@@ -65,4 +65,6 @@
   pthread_cond_t read_request;
   sint_t available;
+  uint_t started;
+  uint_t finish;
 #endif
 };
@@ -113,7 +115,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);
@@ -138,39 +143,33 @@
 {
   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);
-    }
-    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: finished idle in readfn\n");
+      if (p->finish) pthread_exit(NULL);
     }
     //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);
@@ -194,10 +193,11 @@
 {
 #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");
@@ -206,5 +206,4 @@
       AUBIO_WRN("timestretch: joining thread failed\n");
   }
-#endif
   pthread_mutex_destroy(&p->read_mutex);
   pthread_cond_destroy(&p->read_avail);
@@ -340,5 +339,4 @@
   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
@@ -348,15 +346,6 @@
 #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;
