Index: plugins/alsavs/pcm_roar.c
===================================================================
--- plugins/alsavs/pcm_roar.c	(revision 5168)
+++ plugins/alsavs/pcm_roar.c	(revision 5174)
@@ -46,4 +46,6 @@
  struct roar_alsa_pcm * self = io->private_data;
  int fh;
+ int val;
+ int err;
 
  ROAR_DBG("roar_pcm_start(*) = ?");
@@ -53,18 +55,45 @@
   return 0;
 
- if ( roar_vio_simple_new_stream_obj(&(self->stream_vio), &(self->roar.con), &(self->stream),
-    self->info.rate, self->info.channels, self->info.bits, self->info.codec,
-    io->stream == SND_PCM_STREAM_PLAYBACK ? ROAR_DIR_PLAY : ROAR_DIR_MONITOR
-    ) == -1 ) {
-  return -EINVAL;
+ if ( (self->vss = roar_vs_new_from_con(&(self->roar.con), &err)) == NULL ) {
+  roar_err_set(err);
+  roar_err_update();
+  return -errno;
+ }
+
+ if ( roar_vs_stream(self->vss, &(self->info),
+                     io->stream == SND_PCM_STREAM_PLAYBACK ? ROAR_DIR_PLAY : ROAR_DIR_MONITOR,
+                     &err) == -1 ) {
+  roar_vs_close(self->vss, ROAR_VS_TRUE, NULL);
+  self->vss = NULL;
+  roar_err_set(err);
+  roar_err_update();
+  return -errno;
+ }
+
+ if ( roar_vs_buffer(self->vss, self->bufsize, &err) == -1 ) {
+  roar_vs_close(self->vss, ROAR_VS_TRUE, NULL);
+  self->vss = NULL;
+  roar_err_set(err);
+  roar_err_update();
+  return -errno;
+ }
+
+ val = ROAR_VS_ASYNCLEVEL_AUTO;
+ if ( roar_vs_ctl(self->vss, ROAR_VS_CMD_SET_ASYNC, &val, &err) == -1 ) {
+  roar_vs_close(self->vss, ROAR_VS_TRUE, NULL);
+  self->vss = NULL;
+  roar_err_set(err);
+  roar_err_update();
+  return -errno;
  }
 
  if ( self->stream_role != ROAR_ROLE_UNKNOWN ) {
-  if ( roar_stream_set_role(&(self->roar.con), &(self->stream), self->stream_role) == -1 ) {
-   ROAR_WARN("roar_pcm_start(*): Can not set stream role: %i: %s", self->stream_role, roar_error2str(roar_error));
+  if ( roar_vs_role(self->vss, self->stream_role, &err) == -1 ) {
+   ROAR_WARN("roar_pcm_start(*): Can not set stream role: %s(%i): %s",
+             roar_role2str(self->stream_role), self->stream_role, roar_error2str(roar_error));
   }
  }
 
- if ( roar_vio_ctl(&(self->stream_vio), 
+ if ( roar_vio_ctl(roar_vs_vio_obj(self->vss, NULL), 
     io->stream == SND_PCM_STREAM_PLAYBACK ? ROAR_VIO_CTL_GET_SELECT_WRITE_FH :
     ROAR_VIO_CTL_GET_SELECT_READ_FH, &fh) != 1 ) {
@@ -81,11 +110,16 @@
  self->stream_opened = 1;
 
- self->bufptr = 0;
+//RM: self->bufptr = 0;
+ ROAR_DBG("roar_pcm_start(*): Starting background thread");
  self->thread_active = 1; // We have to activate the thread before starting it, because the thread lives on that thread_active is 1.
  if ( pthread_create(&(self->thread), NULL, roar_plugin_thread, self) < 0 ) {
   self->thread_active = 0;
+  ROAR_DBG("roar_pcm_start(*) = -1");
   return -1;
  }
-
+ pthread_mutex_lock(&(self->lock)); // wait for the background thread to wake up.
+ ROAR_DBG("roar_pcm_start(*): background thread was successfully started");
+
+ ROAR_DBG("roar_pcm_start(*) = 0");
  return 0;
 }
@@ -95,11 +129,12 @@
   return;
 
- roar_vio_close(&(self->stream_vio));
+ roar_vs_close(self->vss, ROAR_VS_TRUE, NULL);
+ self->vss = NULL;
  self->stream_opened = 0;
  self->thread_active = 0;
- self->bufptr = 0;
- self->last_ptr = 0;
- self->total_written = 0;
- self->has_written = 0;
+//RM: self->bufptr = 0;
+//RM: self->last_ptr = 0;
+//RM: self->total_written = 0;
+//RM: self->has_written = 0;
 }
 
@@ -198,6 +233,8 @@
  struct roar_alsa_pcm * self = io->private_data;
  int ptr;
+ ssize_t avail;
 
  ROAR_DBG("roar_pcm_pointer(*) = ?");
+
  // Did ALSA just call snd_pcm_reset() or something like that without calling the plugin? 
  // We should restart our stream as well.
@@ -207,4 +244,5 @@
  }
 
+#if 0
  // ALSA has a weird way of calculating how much data can be written to the audio buffer.
  // It uses the formula:
@@ -218,4 +256,13 @@
  ptr = snd_pcm_bytes_to_frames(io->pcm, self->bufptr);
  pthread_mutex_unlock(&(self->lock));
+#else
+ pthread_mutex_lock(&(self->lock));
+ avail = roar_vs_get_avail_write(self->vss, NULL);
+ pthread_mutex_unlock(&(self->lock));
+
+ ROAR_DBG("roar_pcm_pointer(*): avail=%lli", (long long int)avail);
+
+ ptr = snd_pcm_bytes_to_frames(io->pcm, self->bufsize - avail);
+#endif
 
  ptr = io->appl_ptr - ptr;
@@ -261,4 +308,5 @@
 static int roar_pcm_delay(snd_pcm_ioplug_t *io, snd_pcm_sframes_t *delayp) {
  struct roar_alsa_pcm * self = io->private_data;
+ roar_mus_t lat;
 
  ROAR_DBG("roar_pcm_delay(*) = ?");
@@ -266,6 +314,9 @@
  // TODO: We need to set *delayp the latency in frames.
  pthread_mutex_lock(&(self->lock));
- roar_plugin_drain(self);
- *delayp = snd_pcm_bytes_to_frames(io->pcm, self->bytes_in_buffer);
+ roar_plugin_drain(self); // why do we call this?
+
+ lat = roar_vs_latency2(self->vss, ROAR_VS_BACKEND_DEFAULT, ROAR_VS_NOWAIT, NULL);
+ *delayp = lat * self->info.rate;
+
  pthread_mutex_unlock(&(self->lock));
 
@@ -373,8 +424,8 @@
  //self->bufsize = snd_pcm_frames_to_bytes(io->pcm, buffersize);
  self->bufsize = self->info.bits * self->info.channels * buffersize / 8;
- self->buffer = malloc(self->bufsize);
- if (self->buffer == NULL)
-  return -1;
- self->bufptr = 0;
+//RM: self->buffer = malloc(self->bufsize);
+//RM: if (self->buffer == NULL)
+//RM:  return -1;
+//RM: self->bufptr = 0;
 
  ROAR_DBG("roar_pcm_hw_params(*) Setting buffersize (bytes): %i", (int)self->bufsize);
@@ -398,5 +449,5 @@
  pthread_cond_destroy(&(self->cond));
 
- free(self->buffer);
+//RM: free(self->buffer);
  free(self);
 
Index: plugins/alsavs/roar.h
===================================================================
--- plugins/alsavs/roar.h	(revision 5168)
+++ plugins/alsavs/roar.h	(revision 5174)
@@ -57,13 +57,12 @@
  struct roar_alsa       roar;
  struct roar_audio_info info;
- struct roar_stream     stream;
- struct roar_vio_calls  stream_vio;
+ roar_vs_t            * vss;
  int                    stream_role;
  int                    stream_opened;
- size_t                 writec;
+ size_t                 _writec;
  size_t                 last_ptr;
- char*                  buffer;
+ char*                  _buffer;
  size_t                 bufsize;
- volatile size_t        bufptr;
+ volatile size_t        _bufptr;
  pthread_t              thread;
  pthread_mutex_t        lock;
@@ -71,8 +70,8 @@
  pthread_cond_t         cond;
  volatile int           thread_active;
- int                    bytes_in_buffer;
- volatile int64_t       total_written;
- int                    has_written;
- struct timespec        start_tv;
+ int                    _bytes_in_buffer;
+ volatile int64_t       _total_written;
+ int                    _has_written;
+ struct timespec        _start_tv;
 };
 
Index: plugins/alsavs/thread.c
===================================================================
--- plugins/alsavs/thread.c	(revision 5157)
+++ plugins/alsavs/thread.c	(revision 5174)
@@ -42,6 +42,18 @@
 
 
+
+/*
+ * The following function should be re-written:
+ * write in a loop untill all date is written,
+ * if vs write returns less than requested call the thread and ask it to iterate.
+ */
+
 // Writes to the FIFO buffer. Waits until there is room to write.
 size_t roar_plugin_write(struct roar_alsa_pcm *self, const char *buf, size_t size) {
+ ssize_t ret;
+
+ ROAR_DBG("roar_plugin_write(self=%p, buf=%p, size=%llu) = ?", self, buf, (long long unsigned int)size);
+
+#if 0
  /* Wait until we have a ready buffer */
  while (1) {
@@ -52,5 +64,5 @@
   //fprintf(stderr, "%d + %d : %d\n", (int)self->bufptr, (int)size, (int)self->bufsize);
   pthread_mutex_lock(&(self->lock));
-  if (self->bufptr + size <= self->bufsize) {
+  if (roar_vs_get_avail_write(self->vss, NULL) >= (ssize_t)size) {
    pthread_mutex_unlock(&(self->lock));
    break;
@@ -58,18 +70,32 @@
   pthread_mutex_unlock(&(self->lock));
 
+  ROAR_DBG("roar_plugin_write(self=%p, buf=%p, size=%llu): Send signal", self, buf, (long long unsigned int)size);
   pthread_cond_signal(&(self->cond));
   /* Sleeps until we can write to the FIFO. */
+  ROAR_DBG("roar_plugin_write(self=%p, buf=%p, size=%llu): Waiting for answer", self, buf, (long long unsigned int)size);
   pthread_mutex_lock(&(self->cond_lock));
   pthread_cond_wait(&(self->cond), &(self->cond_lock));
   pthread_mutex_unlock(&(self->cond_lock));
  }
-
- pthread_mutex_lock(&(self->lock));
- memcpy(self->buffer + self->bufptr, buf, size);
- self->bufptr += (int)size;
- pthread_mutex_unlock(&(self->lock));
-
- /* Send signal to thread that buffer has been updated */
- pthread_cond_signal(&(self->cond));
+#endif
+
+
+ while (size) {
+  pthread_mutex_lock(&(self->lock));
+  ret = roar_vs_write(self->vss, buf, size, NULL);
+  pthread_mutex_unlock(&(self->lock));
+
+  if ( ret == -1 ) {
+   ROAR_WARN("roar_plugin_write(self=%p, buf=?, size=?): Can not write data: %s", self, roar_error2str(roar_error));
+   return -1;
+  }
+
+  size -= ret;
+  buf  += ret;
+
+  /* Send signal to thread that buffer has been updated */
+  ROAR_DBG("roar_plugin_write(self=%p, buf=%p, size=%llu): Send signal", self, buf, (long long unsigned int)size);
+  pthread_cond_signal(&(self->cond));
+ }
 
  return size;
@@ -83,12 +109,17 @@
 // Attemps to drain the buffer at all times and write to libroar.
 // If there is no data, it will wait for roar_plugin_write() to fill up more data.
-void* roar_plugin_thread (void * thread_data) {
+void * roar_plugin_thread (void * thread_data) {
  /* We share data between thread and callable functions */
  struct roar_alsa_pcm *self = thread_data;
  int rc;
+ int err;
+
+ ROAR_DBG("roar_plugin_thread(thread_data=%p) = ?", thread_data);
+ pthread_mutex_unlock(&(self->lock)); // we are now up.
 
  /* Plays back data as long as there is data in the buffer. Else, sleep until it can. */
  /* Two loops! :3 Beware! */
  while(1) {
+  ROAR_DBG("roar_plugin_thread(thread_data=%p): got woken up.", thread_data);
   while(1) {
    _TEST_CANCEL();
@@ -96,4 +127,28 @@
    // We only bother to check after 1 sec of audio has been played, as it might be quite inaccurate in the start of the stream.
 
+   // do wee need to lock before this?
+   pthread_mutex_lock(&(self->lock));
+   ROAR_DBG("roar_plugin_thread(thread_data=%p): Start iterate", thread_data);
+   rc = roar_vs_iterate(self->vss, ROAR_VS_WAIT, &err);
+   ROAR_DBG("roar_plugin_thread(thread_data=%p): Ended iterate", thread_data);
+   pthread_mutex_unlock(&(self->lock));
+
+   if ( rc == 0 ) {
+    break;
+   } else if ( rc < 0 ) {
+    _TEST_CANCEL();
+    roar_plugin_reset(self);
+
+    /* Wakes up a potentially sleeping fill_buffer() */
+    pthread_cond_signal(&(self->cond));
+
+    /* This thread will not be joined, so detach. */
+    pthread_detach(pthread_self());
+    pthread_exit(NULL);
+   }
+
+   pthread_cond_signal(&(self->cond));
+
+#if 0
    /* If the buffer is empty or we've stopped the stream. Jump out of this for loop */
    pthread_mutex_lock(&(self->lock));
@@ -139,11 +194,15 @@
    /* Buffer has decreased, signal fill_buffer() */
    pthread_cond_signal(&(self->cond));
-
-  }
+#endif
+
+  }
+  ROAR_DBG("roar_plugin_thread(thread_data=%p): going to sleep again.", thread_data);
 
   /* If we're still good to go, sleep. We are waiting for fill_buffer() to fill up some data. */
 test_quit:
   if ( self->thread_active ) {
-   pthread_cond_signal(&(self->cond));
+   //struct timespec abstime = {0, 1000*1000*100};
+   pthread_cond_signal(&(self->cond));
+   ROAR_DBG("roar_plugin_thread(thread_data=%p): Wating for wakeup", thread_data);
    pthread_mutex_lock(&(self->cond_lock));
    pthread_cond_wait(&(self->cond), &(self->cond_lock));
@@ -159,4 +218,5 @@
 
 void roar_plugin_drain(struct roar_alsa_pcm *self) {
+#if 0
  struct timespec now_tv;
  int64_t temp, temp2;
@@ -183,4 +243,6 @@
   self->bytes_in_buffer = self->bufptr;
  }
+#endif
+ ROAR_DBG("roar_plugin_drain(self=%p) = (void)", self);
 }
 
