Index: src/synth/sampler.c
===================================================================
--- src/synth/sampler.c	(revision 128589e79c75db5014dbe6bb8c3471d3342e3223)
+++ src/synth/sampler.c	(revision f253b03af4b77fcc44f93f3ebee6c895eb1d1011)
@@ -65,4 +65,5 @@
   aubio_ringbuffer_t *ring;
   uint_t perfectloop;
+  uint_t eof_remaining;
   fvec_t *samples;
   fmat_t *msamples;
@@ -151,7 +152,8 @@
   //s->source_blocksize = 8192;
 
+  if (s->threaded_read || s->perfectloop)
+    s->source_output = new_fvec(s->source_blocksize);
   if (s->perfectloop || s->source_blocksize != s->blocksize) {
-    s->source_output = new_fvec(s->source_blocksize);
-    s->ring = new_aubio_ringbuffer(s->source_blocksize, s->blocksize);
+    s->ring = new_aubio_ringbuffer(s->source_blocksize * 2, s->blocksize);
   }
   //s->channels = 1;
@@ -236,4 +238,5 @@
     o->finished = 0;
     o->eof = 0;
+    o->eof_remaining = 0;
     o->opened = 1;
     ret = AUBIO_OK;
@@ -250,9 +253,10 @@
     o->finished = 1;
     o->eof = 0;
+    o->eof_remaining = 0;
     o->opened = 0;
     AUBIO_WRN("sampler: failed loading %s\n", uri);
   }
   if (o->ring) {
-    AUBIO_WRN("sampler: resetting ringbuffer\n");
+    //AUBIO_WRN("sampler: resetting ringbuffer\n");
     aubio_ringbuffer_reset(o->ring);
   }
@@ -369,37 +373,4 @@
   pthread_exit(NULL);
 }
-
-void *aubio_sampler_readfn_ring(void *z) {
-  aubio_sampler_t *p = z;
-  while(1) {
-    pthread_mutex_lock(&p->read_mutex);
-    if (p->open_thread_running) {
-      //AUBIO_WRN("sampler: readfn(): file is being opened\n");
-      pthread_cond_signal(&p->read_avail);
-      //pthread_cond_wait(&p->read_request, &p->read_mutex);
-    } else if (p->opened && !p->started && !p->finished) {
-      //AUBIO_WRN("sampler: readfn(): file started\n");
-      p->available = aubio_sampler_pull_from_source(p);
-      if (p->available < (sint_t)p->source_blocksize)
-        aubio_sampler_do_eof(p);
-      pthread_cond_signal(&p->read_avail);
-      if (!p->finished) {
-        pthread_cond_wait(&p->read_request, &p->read_mutex);
-      }
-    } else {
-      //AUBIO_WRN("sampler: readfn(): idle?\n");
-      //pthread_cond_signal(&p->read_avail);
-      pthread_cond_wait(&p->read_request, &p->read_mutex);
-      if (p->read_thread_finish) {
-        goto done;
-      }
-    }
-    pthread_mutex_unlock(&p->read_mutex);
-  }
-done:
-  //AUBIO_WRN("sampler: exiting reading thread\n");
-  pthread_mutex_unlock(&p->read_mutex);
-  pthread_exit(NULL);
-}
 #endif
 
@@ -412,6 +383,4 @@
   }
 }
-
-static void aubio_sampler_do_perfectloop(aubio_sampler_t *s);
 
 static void
@@ -438,31 +407,30 @@
   if (ring_avail < (sint_t)s->blocksize) {
     available = aubio_sampler_pull_from_source(s);
-#if 0
-    //AUBIO_MSG("sampler: got %d / %d fetching from source\n", s->available,
-    //    s->source_blocksize);
-    if (s->available == 0) {
-      //aubio_sampler_do_eof(s);
-      //aubio_sampler_do_perfectloop(s, output);
-    }
-    if (s->available < s->source_blocksize) {
-      AUBIO_ERR("sampler: short read from source"
-          " s->available %d, ring_avail %d \n", s->available, ring_avail);
-      //s->eof = 0;
-      //abort();
-    }
-#endif
     if (available > 0) {
       aubio_ringbuffer_push(s->ring, s->source_output, available);
-    } else {
-      //if (s->playing && !s->finished)
-      //AUBIO_WRN("sampler: not reading anymore should do eof now %d\n", check_wrote);
-      // TODO: move eof fetch now
+    }
+    if (available < s->source_blocksize) {
+      if (ring_avail + available <= s->blocksize) {
+        s->eof_remaining = available + ring_avail;
+        if (s->eof_remaining == 0) s->eof_remaining = s->blocksize;
+        //AUBIO_ERR("sampler: marking special eof got: %d, in ring: %d, %d, eof remaining %d\n",
+        //    available, ring_avail, s->blocksize, s->eof_remaining);
+        if (s->loop) {
+          aubio_sampler_seek(s,0);
+          // read some frames from beginning of source for perfect looping
+          if (s->perfectloop) {
+            available = aubio_sampler_pull_from_source(s);
+            if (available <= 0) {
+              AUBIO_ERR("sampler: perfectloop but s->available = 0 !\n");
+            } else {
+              aubio_ringbuffer_push(s->ring, s->source_output, available);
+            }
+          }
+        }
+      }
     }
   }
   return available;
 }
-
-uint_t
-aubio_sampler_write_remaining_ring(aubio_sampler_t *s, fvec_t *output, uint_t wrote);
 
 static void
@@ -477,6 +445,14 @@
     check_wrote += s->blocksize;
     *read = s->blocksize;
+    if (s->eof_remaining > 0) {
+      if (s->eof_remaining <= s->blocksize) {
+        s->eof = 1;
+        s->eof_remaining = 0;
+      } else if (s->eof_remaining <= s->source_blocksize) {
+        s->eof_remaining -= s->blocksize;
+      }
+    }
   } else {
-    //AUBIO_MSG("sampler: last frame, pulling remaining %d left\n", ring_avail);
+    AUBIO_MSG("sampler: last frame, pulling remaining %d left\n", ring_avail);
     *read = 0;
     if (ring_avail > 0) {
@@ -486,10 +462,9 @@
       *read += ring_avail;
     }
-    // signal eof, seek to 0 if looping
+    // signal eof
     aubio_sampler_do_eof(s);
-    // read new frames from source early if needed
-    aubio_sampler_do_perfectloop(s);
-    // write the remaining frames
-    *read += aubio_sampler_write_remaining_ring(s, output, ring_avail);
+    // finished playing, reset ringbuffer for next read
+    if (!s->playing)
+      aubio_ringbuffer_reset(s->ring);
   }
 }
@@ -571,30 +546,4 @@
 }
 
-uint_t
-aubio_sampler_write_remaining_ring(aubio_sampler_t *s, fvec_t *output, uint_t wrote){
-  if (s->perfectloop && s->loop) {
-    fvec_t tmpout;
-    tmpout.data = output->data + wrote;
-    tmpout.length = s->blocksize - wrote;
-    aubio_ringbuffer_pull(s->ring, &tmpout, tmpout.length);
-    check_wrote += tmpout.length;
-    return tmpout.length;
-  }
-  return 0;
-}
-
-void
-aubio_sampler_do_perfectloop(aubio_sampler_t *s) {
-  // perfectloop fetched new samples from start of source to ringbuffer
-  if (s->perfectloop && s->loop) {
-    s->available = aubio_sampler_pull_from_source(s);
-    if (s->available <= 0) {
-      AUBIO_ERR("sampler: perfectloop but s->available = 0 !\n");
-    } else {
-      aubio_ringbuffer_push(s->ring, s->source_output, s->available);
-    }
-  }
-}
-
 void
 aubio_sampler_read_from_table(aubio_sampler_t *o, fvec_t *output, uint_t *read) {
@@ -778,5 +727,5 @@
 #endif
   //if (o->source_output) {
-  if (o->perfectloop || o->ring) {
+  if (o->source_output && (o->threaded_read || o->perfectloop)) {
     del_fvec(o->source_output);
   }
