chiark / gitweb /
The command backend now sends 0s rather than suspending output when a
authorRichard Kettlewell <rjk@greenend.org.uk>
Fri, 13 Mar 2009 21:42:33 +0000 (21:42 +0000)
committerRichard Kettlewell <rjk@greenend.org.uk>
Fri, 13 Mar 2009 21:42:33 +0000 (21:42 +0000)
pause occurs.  This saves the receiver from having to infer pauses
from flow control.  It could usefuly be made into an option.

lib/uaudio-alsa.c
lib/uaudio-command.c
lib/uaudio-oss.c
lib/uaudio-rtp.c
lib/uaudio-thread.c
lib/uaudio.h

index 48ae1be..721639c 100644 (file)
@@ -136,7 +136,8 @@ static void alsa_start(uaudio_callback *callback,
   alsa_open();
   uaudio_thread_start(callback, userdata, alsa_play,
                       32 / uaudio_sample_size,
-                      4096 / uaudio_sample_size);
+                      4096 / uaudio_sample_size,
+                      0);
 }
 
 static void alsa_stop(void) {
index 5e4531e..096888d 100644 (file)
@@ -121,7 +121,8 @@ static void command_start(uaudio_callback *callback,
                       userdata,
                       command_play,
                       uaudio_channels,
-                     4096 / uaudio_sample_size);
+                     4096 / uaudio_sample_size,
+                      UAUDIO_THREAD_FAKE_PAUSE);
 }
 
 static void command_stop(void) {
index 35e14c0..6d902cb 100644 (file)
@@ -128,13 +128,15 @@ static void oss_start(uaudio_callback *callback,
   /* Very specific buffer size requirements here apparently */
   uaudio_thread_start(callback, userdata, oss_play, 
                       4608 / uaudio_sample_size,
-                      4608 / uaudio_sample_size);
+                      4608 / uaudio_sample_size,
+                      0);
 #else
   /* We could SNDCTL_DSP_GETBLKSIZE but only when the device is already open,
    * which is kind of inconvenient.  We go with 1-4Kbyte for now. */
   uaudio_thread_start(callback, userdata, oss_play, 
                       32 / uaudio_sample_size,
-                      4096 / uaudio_sample_size);
+                      4096 / uaudio_sample_size,
+                      0);
 #endif
 }
 
index 702747a..31e8f57 100644 (file)
@@ -281,7 +281,8 @@ static void rtp_start(uaudio_callback *callback,
                       rtp_play,
                       256 / uaudio_sample_size,
                       (NETWORK_BYTES - sizeof(struct rtp_header))
-                      / uaudio_sample_size);
+                      / uaudio_sample_size,
+                      0);
 }
 
 static void rtp_stop(void) {
index cd0d727..6bed4a8 100644 (file)
@@ -68,6 +68,9 @@ static pthread_t uaudio_collect_thread;
 /** @brief Playing thread ID */
 static pthread_t uaudio_play_thread;
 
+/** @brief Flags */
+static unsigned uaudio_thread_flags;
+
 static uaudio_callback *uaudio_thread_collect_callback;
 static uaudio_playcallback *uaudio_thread_play_callback;
 static void *uaudio_thread_userdata;
@@ -104,7 +107,8 @@ static void *uaudio_collect_thread_fn(void attribute((unused)) *arg) {
     /* We are definitely active now */
     uaudio_thread_collecting = 1;
     pthread_cond_broadcast(&uaudio_thread_cond);
-    while(uaudio_thread_activated) {
+    while(uaudio_thread_activated
+          || (uaudio_thread_flags & UAUDIO_THREAD_FAKE_PAUSE)) {
       if(uaudio_buffers_used() < UAUDIO_THREAD_BUFFERS - 1) {
         /* At least one buffer is available.  We release the lock while
          * collecting data so that other already-filled buffers can be played
@@ -115,12 +119,17 @@ static void *uaudio_collect_thread_fn(void attribute((unused)) *arg) {
         
         /* Keep on trying until we get the minimum required amount of data */
         b->nsamples = 0;
-        while(b->nsamples < uaudio_thread_min) {
-          b->nsamples += uaudio_thread_collect_callback
-            ((char *)b->samples
-             + b->nsamples * uaudio_sample_size,
-             uaudio_thread_max - b->nsamples,
-             uaudio_thread_userdata);
+        if(uaudio_thread_activated) {
+          while(b->nsamples < uaudio_thread_min) {
+            b->nsamples += uaudio_thread_collect_callback
+              ((char *)b->samples
+               + b->nsamples * uaudio_sample_size,
+               uaudio_thread_max - b->nsamples,
+               uaudio_thread_userdata);
+          }
+        } else if(uaudio_thread_flags & UAUDIO_THREAD_FAKE_PAUSE) {
+          memset(b->samples, 0, uaudio_thread_min * uaudio_sample_size);
+          b->nsamples += uaudio_thread_min;
         }
         pthread_mutex_lock(&uaudio_thread_lock);
         /* Advance to next buffer */
@@ -199,13 +208,15 @@ void uaudio_thread_start(uaudio_callback *callback,
                         void *userdata,
                         uaudio_playcallback *playcallback,
                         size_t min,
-                         size_t max) {
+                         size_t max,
+                         unsigned flags) {
   int e;
   uaudio_thread_collect_callback = callback;
   uaudio_thread_userdata = userdata;
   uaudio_thread_play_callback = playcallback;
   uaudio_thread_min = min;
   uaudio_thread_max = max;
+  uaudio_thread_flags = flags;
   uaudio_thread_started = 1;
   for(int n = 0; n < UAUDIO_THREAD_BUFFERS; ++n)
     uaudio_buffers[n].samples = xcalloc_noptr(uaudio_thread_max,
@@ -253,9 +264,10 @@ void uaudio_thread_deactivate(void) {
   pthread_mutex_lock(&uaudio_thread_lock);
   uaudio_thread_activated = 0;
   pthread_cond_broadcast(&uaudio_thread_cond);
-
-  while(uaudio_thread_collecting || uaudio_buffers_used())
-    pthread_cond_wait(&uaudio_thread_cond, &uaudio_thread_lock);
+  if(!(uaudio_thread_flags & UAUDIO_THREAD_FAKE_PAUSE)) {
+    while(uaudio_thread_collecting || uaudio_buffers_used())
+      pthread_cond_wait(&uaudio_thread_cond, &uaudio_thread_lock);
+  }
   pthread_mutex_unlock(&uaudio_thread_lock);
 }
 
index e796393..d6376c8 100644 (file)
@@ -136,7 +136,17 @@ void uaudio_thread_start(uaudio_callback *callback,
                         void *userdata,
                         uaudio_playcallback *playcallback,
                         size_t min,
-                         size_t max);
+                         size_t max,
+                         unsigned flags);
+
+/** @brief Fake pauses
+ *
+ * This flag is used for audio backends that cannot sensibly be paused.
+ * The thread support code will supply silence while deactivated in this
+ * case.
+ */
+#define UAUDIO_THREAD_FAKE_PAUSE 0x00000001
+
 void uaudio_thread_stop(void);
 void uaudio_thread_activate(void);
 void uaudio_thread_deactivate(void);