[xiph-commits] r3892 - libsydneyaudio/trunk/src

doublec at svn.annodex.net doublec at svn.annodex.net
Thu Mar 26 15:03:08 PDT 2009


Author: doublec
Date: 2009-03-26 15:03:08 -0700 (Thu, 26 Mar 2009)
New Revision: 3892

Modified:
   libsydneyaudio/trunk/src/sydney_audio_alsa.c
Log:
Fix for ticket 458. Handling of write sizes incorrect in alsa backend

Modified: libsydneyaudio/trunk/src/sydney_audio_alsa.c
===================================================================
--- libsydneyaudio/trunk/src/sydney_audio_alsa.c	2009-03-20 04:12:45 UTC (rev 3891)
+++ libsydneyaudio/trunk/src/sydney_audio_alsa.c	2009-03-26 22:03:08 UTC (rev 3892)
@@ -210,6 +210,9 @@
     if(nframes < s->period_size)
       len = nframes;
     frames = snd_pcm_writei(s->output_unit, data, len);
+    if (frames == -EAGAIN || frames == -EINTR)
+      continue;
+
     if (frames < 0) {
       frames = snd_pcm_recover(s->output_unit, frames, 1);
       if (frames < 0) {
@@ -219,8 +222,9 @@
       if(frames > 0 && frames < len)
         printf("short write (expected %d, wrote %d)\n", (int)len, (int)frames);
     }
-    nframes -= s->period_size;
-    data = ((unsigned char *)data) + s->period_bytes;
+    nframes -= len;
+
+    data = ((unsigned char *)data) + (unsigned int)snd_pcm_frames_to_bytes(s->output_unit, len);
   }
 
   s->bytes_written += nbytes;
@@ -240,14 +244,20 @@
 
 int
 sa_stream_get_write_size(sa_stream_t *s, size_t *size) {
-  snd_pcm_sframes_t avail;
-
+  snd_pcm_status_t *status;
+  snd_pcm_uframes_t avail;
+  int r = 0;
   if (s == NULL || s->output_unit == NULL) {
     return SA_ERROR_NO_INIT;
   }
 
-  avail = snd_pcm_avail_update(s->output_unit);
+  snd_pcm_status_alloca(&status);
+  if ((r = snd_pcm_status(s->output_unit, status)) < 0) {
+    *size = 0;
+    return SA_ERROR_SYSTEM;
+  }
 
+  avail = snd_pcm_status_get_avail(status);
   *size = snd_pcm_frames_to_bytes(s->output_unit, avail);
 
   return SA_SUCCESS;
@@ -270,17 +280,19 @@
     delay = 0;
   }
   else if (snd_pcm_delay (s->output_unit, &delay) != 0) {
-    printf("snd_pcm_delay failed\n");
     delay = 0;
   }
   if (delay < 0) {
+    snd_pcm_forward(s->output_unit, -delay);
     delay = 0;
   }
   if (delay > s->buffer_size) {
-    printf("delay just wrong %d vs %d\n", delay, s->buffer_size);
     delay = s->buffer_size;
   }
 
+  snd_pcm_avail_update(s->output_unit);
+  // delay means audio is 'x' frames behind what we've written. We need to
+  // subtract the delay from the data written to return the actual bytes played.
   s->bytes_played = s->bytes_written - snd_pcm_frames_to_bytes(s->output_unit, delay);
 
   *pos = s->bytes_played;



More information about the commits mailing list