Hello!

On Sat, 8 Dec 2001, twoity wrote:
> snd_pcm_writei is returning -32 repeatedly.  The logic controlling the 
> else if looks wrong: (written_frames > 0) will always be false.
> 
> Changed to
> else if (written_frames == -EAGAIN || (-written_frames < length / 
> alsa_frame_size))

Thanks for the pointers. I looked at it. Well snd_pcm_writei only returns
negative if there was an error and the negative is just the error code, so
you can't do any math with the error codes.

What is missing is some sort of writei failure handling. I copied most
from test/pcm.c from alsa-lib source. But I changed a continue; when
writei returns -EAGAIN to snd_pcm_wait(alsa_pcm, 10) otherwise the load
is at 100% and higher.

Please try this patch and report any problems.

        Miha...

 - Miha Tomšič --- C. na postajo 55 -- SI-1351 Brezovica pri Lj. --- SLOVENIA -
--- audio.c     Tue Oct 16 23:01:06 2001
+++ audio.c.new Mon Dec 10 11:15:42 2001
@@ -237,6 +237,8 @@
 
 void alsa_write(gpointer data, gint length)
 {
+  int err;
+       
   if(paused) return;
   if(surround)
     {
@@ -259,10 +261,25 @@
          length -= written;
          data += written;
        }
-      else if (written_frames == -EAGAIN || (written_frames > 0 && written_frames < 
(length / alsa_frame_size)))
-       {
-         snd_pcm_wait(alsa_pcm, 1000);
-       }  
+      else if (written_frames == -EAGAIN) 
+       snd_pcm_wait(alsa_pcm, 10);
+      else if (written_frames == -EPIPE) 
+        {
+          err = snd_pcm_prepare(alsa_pcm); 
+         if (err < 0)
+            printf("Can't recovery from underrun, prepare failed: %s\n", 
+                  snd_strerror(err));
+       }
+      else if (written_frames == -ESTRPIPE)
+        {
+          while ((err = snd_pcm_resume(alsa_pcm)) == -EAGAIN)
+            sleep(1);            /* wait until suspend flag is released */
+          if (err < 0)
+            err = snd_pcm_prepare(alsa_pcm); 
+          if (err < 0)
+            printf("Can't recovery from suspend, prepare failed: %s\n", 
+                   snd_strerror(err));
+        }     
     }
 }
 

Reply via email to