Index: src/synth/sampler.c
===================================================================
--- src/synth/sampler.c	(revision 88a774c764e5291f1744a32b16b398a6a7959a59)
+++ src/synth/sampler.c	(revision 128589e79c75db5014dbe6bb8c3471d3342e3223)
@@ -133,19 +133,21 @@
   s->available = 0;
 
+  s->threaded_read = 0;
+  s->perfectloop = 0;
 #if 0 // naive mode
   s->source_blocksize = s->blocksize;
-  s->perfectloop = 0;
-#elif 0 // threaded mode
+#elif 0 // threaded mode, no ringbuffer
   s->source_blocksize = s->blocksize;
-  // FIXME: perfectloop fails if source_blocksize > 2048 ?!
-  //s->source_blocksize = 4096; //32 * s->blocksize;
-  s->perfectloop = 0;
-  s->threaded_read = 0;
-#elif 1 // unthreaded ringbuffer mode
+  s->threaded_read = 1;
+#elif 0 // unthreaded, with ringbuffer
   s->source_blocksize = 2048; //32 * s->blocksize;
-  // FIXME: perfectloop fails if source_blocksize > 2048 ?!
-  //s->source_blocksize = 4096; //32 * s->blocksize;
   s->perfectloop = 1;
-#endif
+#elif 1 // threaded with ringhbuffer
+  s->source_blocksize = 2048; //32 * s->blocksize;
+  s->perfectloop = 1;
+  s->threaded_read = 1;
+#endif
+  // FIXME: perfectloop fails if source_blocksize > 2048 with source_avcodec
+  //s->source_blocksize = 8192;
 
   if (s->perfectloop || s->source_blocksize != s->blocksize) {
@@ -153,4 +155,6 @@
     s->ring = new_aubio_ringbuffer(s->source_blocksize, s->blocksize);
   }
+  //s->channels = 1;
+  //s->source_moutput = new_fmat(s->source_blocksize, s->channels);
 
 #ifdef HAVE_THREADS
@@ -158,15 +162,6 @@
 
   if (s->threaded_read) {
-    s->source_blocksize = s->blocksize;
-    //s->source_output = new_fvec(s->source_blocksize);
-    s->channels = 1;
-    s->source_moutput = new_fmat(s->source_blocksize, s->channels);
+    //AUBIO_WRN("sampler: starting reading thread\n");
     aubio_sampler_open_reading_thread(s);
-  } else if (0) {
-    s->source_blocksize = s->blocksize;
-  } else {
-    //s->source_blocksize = 16*s->blocksize;
-    //s->source_blocksize = 8192; //s->blocksize;
-    //s->ring = new_aubio_ringbuffer(s->source_blocksize, s->source_blocksize);
   }
 #endif
@@ -337,4 +332,5 @@
 
 uint_t aubio_sampler_reading_from_source_ring_fetch(aubio_sampler_t*s);
+
 void *aubio_sampler_readfn(void *z) {
   aubio_sampler_t *p = z;
@@ -348,5 +344,5 @@
       //AUBIO_WRN("sampler: readfn(): file started\n");
       if (p->ring) {
-        aubio_sampler_reading_from_source_ring_fetch(p);
+        p->available = aubio_sampler_reading_from_source_ring_fetch(p);
       } else {
         p->available = aubio_sampler_pull_from_source(p);
@@ -485,10 +481,14 @@
     *read = 0;
     if (ring_avail > 0) {
+      // pull remaining frames in ring buffer
       aubio_ringbuffer_pull(s->ring, output, ring_avail);
       check_wrote += ring_avail;
       *read += ring_avail;
     }
+    // signal eof, seek to 0 if looping
     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);
   }
@@ -529,13 +529,17 @@
   //AUBIO_WRN("sampler: got %d available in _read_from_source\n", available);
   // read -> number of samples read
-  if (available >= (sint_t)s->blocksize) {
-    fvec_copy(s->source_output, output);
-    *read = s->blocksize;
-  } else if (available > 0) {
-    fvec_copy(s->source_output, output);
-    *read = available;
+  if (!s->perfectloop && s->source_blocksize == s->blocksize) {
+    if (available >= (sint_t)s->blocksize) {
+      fvec_copy(s->source_output, output);
+      *read = s->blocksize;
+    } else if (available > 0) {
+      fvec_copy(s->source_output, output);
+      *read = available;
+    } else {
+      fvec_zeros(output);
+      *read = 0;
+    }
   } else {
-    fvec_zeros(output);
-    *read = 0;
+    aubio_sampler_reading_from_source_ring_pull(s, output, read);
   }
   //*read = s->available;
@@ -547,9 +551,5 @@
 #ifdef HAVE_THREADS
   if (s->threaded_read) { // if threaded
-    if (s->source_blocksize == s->blocksize) {
-      aubio_sampler_read_from_source_threaded(s, output, read);
-    } else {
-      //abort();
-    }
+    aubio_sampler_read_from_source_threaded(s, output, read);
   } else
 #endif
@@ -578,11 +578,4 @@
     tmpout.length = s->blocksize - wrote;
     aubio_ringbuffer_pull(s->ring, &tmpout, tmpout.length);
-    //*read += tmpout.length;
-#if 0
-    int ring_avail = aubio_ringbuffer_get_available(s->ring);
-    AUBIO_WRN("sampler: perfectloop, "
-        "%d left in ring, looping pulled %d more, wrote %d + %d\n",
-        ring_avail, s->available, wrote, tmpout.length);
-#endif
     check_wrote += tmpout.length;
     return tmpout.length;
@@ -597,7 +590,6 @@
     s->available = aubio_sampler_pull_from_source(s);
     if (s->available <= 0) {
-      AUBIO_ERR("sampler: looping but s->available = 0 !\n");
+      AUBIO_ERR("sampler: perfectloop but s->available = 0 !\n");
     } else {
-      //AUBIO_ERR("sampler: perfectloop fetch and push more\n");
       aubio_ringbuffer_push(s->ring, s->source_output, s->available);
     }
@@ -621,19 +613,5 @@
     return -1;
   }
-  // do actual reading
   aubio_source_do(s->source, s->source_output, &source_read);
-#if 0
-  if (source_read < s->source_blocksize) {
-    //AUBIO_ERR("sampler: _pull_from_source: short read %d < %d\n", source_read,
-    //    s->source_blocksize);
-    //aubio_sampler_do_eof(s);
-    if (s->loop) {
-      AUBIO_ERR("sampler: _pull_from_source: loop, should seeking to 0? %d / %d\n",
-          source_read, s->source_blocksize);
-      //aubio_sampler_seek(s, 0);
-    }
-  }
-  //AUBIO_ERR("sampler: _pull_from_source: read %d / %d\n", source_read, length);
-#endif
   return source_read;
 }
