Index: ChangeLog
===================================================================
--- ChangeLog	(revision 5182)
+++ ChangeLog	(revision 5196)
@@ -12,4 +12,5 @@
 	* Updated manpages (pr1)
 	* Updated filters to support 8 and 32 bit mode as well (pr1)
+	* Re-wrote ALSA plugin (pr1)
 
 v. 0.4rc0 - Mon Sep 05 2011 15:25 CEST
Index: plugins/alsavs/.release-helper
===================================================================
--- plugins/alsavs/.release-helper	(revision 5196)
+++ plugins/alsavs/.release-helper	(revision 5196)
@@ -0,0 +1,3 @@
+#!RELEASE-HELPER:0.0beta0
+@RM thread.c
+#!END
Index: plugins/alsavs/Makefile
===================================================================
--- plugins/alsavs/Makefile	(revision 5165)
+++ plugins/alsavs/Makefile	(revision 5196)
@@ -3,5 +3,5 @@
 TARGET=$(SLIB)
 INSTALL_DIR=$(PREFIX_LIB)/alsa-lib/
-OBJS=pcm_roar.o roar.o thread.o
+OBJS=pcm_roar.o roar.o
 
 include ../../Makefile.conf
Index: plugins/alsavs/pcm_roar.c
===================================================================
--- plugins/alsavs/pcm_roar.c	(revision 5174)
+++ plugins/alsavs/pcm_roar.c	(revision 5196)
@@ -3,5 +3,5 @@
 /*
  *      Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2010-2011
- *      Copyright (C) Hans-Kristian 'maister' Arntzen - 2010
+ *      Copyright (C) Hans-Kristian 'maister' Arntzen - 2010-2011
  *
  *  This file is part of libroar a part of RoarAudio,
@@ -71,5 +71,6 @@
  }
 
- if ( roar_vs_buffer(self->vss, self->bufsize, &err) == -1 ) {
+ // ALSA really expects there to be self->bufsize writable bytes.
+ if ( roar_vs_buffer(self->vss, self->bufsize + 1, &err) == -1 ) {
   roar_vs_close(self->vss, ROAR_VS_TRUE, NULL);
   self->vss = NULL;
@@ -110,15 +111,4 @@
  self->stream_opened = 1;
 
-//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;
@@ -132,9 +122,5 @@
  self->vss = NULL;
  self->stream_opened = 0;
- self->thread_active = 0;
-//RM: self->bufptr = 0;
-//RM: self->last_ptr = 0;
-//RM: self->total_written = 0;
-//RM: self->has_written = 0;
+ self->last_ptr = 0;
 }
 
@@ -153,11 +139,4 @@
 
  ROAR_DBG("roar_pcm_stop(*) = 0");
-
-
- if ( self->thread_active ) {
-  self->thread_active = 0;
-  pthread_cond_signal(&(self->cond));
-  pthread_join(self->thread, NULL);
- }
 
  roar_plugin_reset(self);
@@ -233,4 +212,5 @@
  struct roar_alsa_pcm * self = io->private_data;
  int ptr;
+ int buffered;
  ssize_t avail;
 
@@ -244,30 +224,18 @@
  }
 
-#if 0
- // ALSA has a weird way of calculating how much data can be written to the audio buffer.
- // It uses the formula:
- // avail = bufsize + ptr - io->appl_ptr; (??!?)
- // We really want this:
- // avail = bufsize - ptr;
- // This is the obvious way, so we have to manipulate ptr like this:
- // ptr = io->appl_ptr - ptr;
-
- pthread_mutex_lock(&(self->lock));
- ptr = snd_pcm_bytes_to_frames(io->pcm, self->bufptr);
- pthread_mutex_unlock(&(self->lock));
-#else
- pthread_mutex_lock(&(self->lock));
+ // ALSA expects return value to be equal to the amount of data written on the hardware side.
+ // It uses this to calculate writable amount. (Because hey, just calling a get_avail() is too hard.)
+ // Return value is thus io->appl_ptr - buffered_amount;
+
+ while ( roar_vs_iterate(self->vss, ROAR_VS_NOWAIT, NULL) == 2 );
+
  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;
+ buffered = snd_pcm_bytes_to_frames(io->pcm, self->bufsize - avail);
+
+ ptr = io->appl_ptr - buffered;
  self->last_ptr = io->appl_ptr;
 
- ROAR_DBG("roar_pcm_pointer(*) appl_ptr: %i, ptr: %i, calculated avail frames: %i", (int)io->appl_ptr, (int)ptr, (int)(io->appl_ptr - ptr));
+ ROAR_DBG("roar_pcm_pointer(*) appl_ptr (frames): %i, buffered (frames): %i", (int)io->appl_ptr, (int)buffered);
  ROAR_DBG("roar_pcm_pointer(*) = %i", ptr);
  return ptr;
@@ -293,8 +261,20 @@
  buf = (char *)areas->addr + (areas->first + areas->step * offset) / 8;
 
- ret = roar_plugin_write(self, buf, len);
-
- if ( ret == -1 )
-  return -EIO;
+ while (len) {
+  ret = roar_vs_write(self->vss, buf, len, NULL);
+/*
+ * <ph3-der-loewe> is it supposed to be EIO?
+ * <ph3-der-loewe> or can we return the true error code from roar_vs_write()?
+ * <maister> ALSA tends to give -EIO errors
+ * <maister> It shouldn't cause problems to pass roar_vs errnos.
+ * <maister> But the error strings might be a bit confusing perhaps
+ */
+  if ( ret == -1 )
+   return -EIO;
+  len -= ret;
+  buf += ret;
+ }
+
+ while ( roar_vs_iterate(self->vss, ROAR_VS_NOWAIT, NULL) == 2 );
 
  ROAR_DBG("roar_pcm_transfer(*) = %lli", (long long int)size);
@@ -312,12 +292,6 @@
  ROAR_DBG("roar_pcm_delay(*) = ?");
 
- // TODO: We need to set *delayp the latency in frames.
- pthread_mutex_lock(&(self->lock));
- 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));
+ *delayp = (lat * self->info.rate) / 1000000;
 
  return 0;
@@ -420,12 +394,7 @@
   return err;
 
- ROAR_DBG("roar_pcm_hw_params(*) buffersize (bytes): %i", (int)buffersize);
-
- //self->bufsize = snd_pcm_frames_to_bytes(io->pcm, buffersize);
+ ROAR_DBG("roar_pcm_hw_params(*) buffersize (frames): %i", (int)buffersize);
+
  self->bufsize = self->info.bits * self->info.channels * buffersize / 8;
-//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);
@@ -445,9 +414,4 @@
  roar_disconnect(&(self->roar.con));
 
- pthread_mutex_destroy(&(self->lock));
- pthread_mutex_destroy(&(self->cond_lock));
- pthread_cond_destroy(&(self->cond));
-
-//RM: free(self->buffer);
  free(self);
 
@@ -533,9 +497,4 @@
  }
 
- pthread_mutex_init(&(self->lock), NULL);
- pthread_mutex_init(&(self->cond_lock), NULL);
- pthread_cond_init(&(self->cond), NULL);
-
-
  if ( (ret = roar_hw_constraint(self)) < 0 ) {
   snd_pcm_ioplug_delete(&(self->io));
Index: plugins/alsavs/roar.h
===================================================================
--- plugins/alsavs/roar.h	(revision 5174)
+++ plugins/alsavs/roar.h	(revision 5196)
@@ -3,5 +3,5 @@
 /*
  *      Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2010-2011
- *      Copyright (C) Hans-Kristian 'maister' Arntzen - 2010
+ *      Copyright (C) Hans-Kristian 'maister' Arntzen - 2010-2011
  *
  *  This file is part of libroar a part of RoarAudio,
@@ -60,18 +60,6 @@
  int                    stream_role;
  int                    stream_opened;
- size_t                 _writec;
+ size_t                 bufsize;
  size_t                 last_ptr;
- char*                  _buffer;
- size_t                 bufsize;
- volatile size_t        _bufptr;
- pthread_t              thread;
- pthread_mutex_t        lock;
- pthread_mutex_t        cond_lock;
- pthread_cond_t         cond;
- volatile int           thread_active;
- int                    _bytes_in_buffer;
- volatile int64_t       _total_written;
- int                    _has_written;
- struct timespec        _start_tv;
 };
 
