Index: libroar/buffer.c
===================================================================
--- libroar/buffer.c	(revision 4522)
+++ libroar/buffer.c	(revision 4615)
@@ -481,4 +481,9 @@
 
 int roar_buffer_ring_read  (struct roar_buffer *  buf, void * data, size_t * len) {
+ struct roar_buffer_ring * ring;
+ size_t havelen;
+ size_t done;
+ size_t tmp;
+
  if ( buf == NULL || len == NULL )
   return -1;
@@ -497,20 +502,72 @@
   return -1;
 
- if ( buf->meta.ring.read_pos >= buf->user_len )
-  buf->meta.ring.read_pos -= buf->user_len;
-
- if ( (*len + buf->meta.ring.read_pos) > buf->user_len ) {
-  // wraped mode:
-  memcpy(data, buf->user_data+buf->meta.ring.read_pos, buf->user_len - buf->meta.ring.read_pos);
-  memcpy(data, buf->user_data, *len + buf->meta.ring.read_pos - buf->user_len);
-
-  buf->meta.ring.read_pos += *len;
-  buf->meta.ring.read_pos -= buf->user_len;
-  return 0;
+ if ( (buf->flags & ROAR_BUFFER_FLAG_FREE_RUNNING) ) {
+  if ( buf->meta.ring.read_pos >= buf->user_len )
+   buf->meta.ring.read_pos -= buf->user_len;
+
+  if ( (*len + buf->meta.ring.read_pos) > buf->user_len ) {
+   // wraped mode:
+   memcpy(data, buf->user_data+buf->meta.ring.read_pos, buf->user_len - buf->meta.ring.read_pos);
+   memcpy(data, buf->user_data, *len + buf->meta.ring.read_pos - buf->user_len);
+ 
+   buf->meta.ring.read_pos += *len;
+   buf->meta.ring.read_pos -= buf->user_len;
+   return 0;
+  } else {
+   // unwarped mode:
+   memcpy(data, buf->user_data+buf->meta.ring.read_pos, *len);
+   buf->meta.ring.read_pos += *len;
+   return 0;
+  }
  } else {
-  // unwarped mode:
-  memcpy(data, buf->user_data+buf->meta.ring.read_pos, *len);
-  buf->meta.ring.read_pos += *len;
-  return 0;
+  ring = &(buf->meta.ring);
+
+  if ( ring->read_pos == ring->write_pos ) {
+   *len = 0;
+   return 0;
+  } else if ( ring->read_pos < ring->write_pos ) {
+   havelen = ring->write_pos - ring->read_pos;
+
+   if ( havelen > *len )
+    havelen = *len;
+
+   memcpy(data, buf->user_data+ring->read_pos, havelen);
+   ring->read_pos += havelen;
+
+   *len = havelen;
+   return 0;
+  } else { // write_pos < read_pos
+   done = 0;
+
+   // first pass: use data up to end of buffer
+
+   havelen = buf->user_len - ring->read_pos;
+
+   if ( havelen > *len )
+    havelen = *len;
+
+   memcpy(data, buf->user_data+ring->read_pos, havelen);
+   ring->read_pos += havelen;
+
+   done += havelen;
+
+   if ( ring->read_pos == buf->user_len ) {
+    ring->read_pos = 0;
+   }
+
+   // second pass: use data from strat of buffer to write pointer
+
+   if ( *len > done ) {
+    tmp = *len - done;
+    if ( roar_buffer_ring_read(buf, data+done, &tmp) == 0 ) {
+     done += tmp;
+    }
+   }
+
+   *len = done;
+   return 0;
+  }
+
+  return -1;
  }
 
@@ -535,20 +592,24 @@
   return -1;
 
- if ( buf->meta.ring.write_pos >= buf->user_len )
-  buf->meta.ring.write_pos -= buf->user_len;
-
- if ( (*len + buf->meta.ring.write_pos) > buf->user_len ) {
-  // wraped mode:
-  memcpy(buf->user_data+buf->meta.ring.write_pos, data, buf->user_len - buf->meta.ring.write_pos);
-  memcpy(buf->user_data, data, *len + buf->meta.ring.write_pos - buf->user_len);
-
-  buf->meta.ring.write_pos += *len;
-  buf->meta.ring.write_pos -= buf->user_len;
-  return 0;
+ if ( (buf->flags & ROAR_BUFFER_FLAG_FREE_RUNNING) ) {
+  if ( buf->meta.ring.write_pos >= buf->user_len )
+   buf->meta.ring.write_pos -= buf->user_len;
+
+  if ( (*len + buf->meta.ring.write_pos) > buf->user_len ) {
+   // wraped mode:
+   memcpy(buf->user_data+buf->meta.ring.write_pos, data, buf->user_len - buf->meta.ring.write_pos);
+   memcpy(buf->user_data, data, *len + buf->meta.ring.write_pos - buf->user_len);
+
+   buf->meta.ring.write_pos += *len;
+   buf->meta.ring.write_pos -= buf->user_len;
+   return 0;
+  } else {
+   // unwarped mode:
+   memcpy(buf->user_data+buf->meta.ring.write_pos, data, *len);
+   buf->meta.ring.write_pos += *len;
+   return 0;
+  }
  } else {
-  // unwarped mode:
-  memcpy(buf->user_data+buf->meta.ring.write_pos, data, *len);
-  buf->meta.ring.write_pos += *len;
-  return 0;
+  return -1;
  }
 
