shithub: sox

Download patch

ref: ee4a8b7f2a9fad2e0782b427d068117371c4f7cf
parent: 91304fd460cbd67d8dbbe48ace22bc4a345c6992
author: robs <robs>
date: Sat Jun 23 03:19:31 EDT 2007

Fix alsa rec multi-channel bug

--- a/src/alsa.c
+++ b/src/alsa.c
@@ -466,70 +466,53 @@
 
 static sox_size_t sox_alsaread(sox_format_t * ft, sox_ssample_t *buf, sox_size_t nsamp)
 {
-    sox_size_t len;
-    int err;
     alsa_priv_t alsa = (alsa_priv_t)ft->priv;
     void (*read_buf)(sox_ssample_t *, char const *, sox_size_t, sox_bool, sox_size_t *) = 0;
+    sox_size_t len;
 
     switch(ft->signal.size) {
-        case SOX_SIZE_BYTE:
-            switch(ft->signal.encoding)
-            {
-                case SOX_ENCODING_SIGN2:
-                    read_buf = sb_read_buf;
-                    break;
-                case SOX_ENCODING_UNSIGNED:
-                    read_buf = ub_read_buf;
-                    break;
-                default:
-                    sox_fail_errno(ft,SOX_EFMT,"Do not support this encoding for this data size");
-                    return 0;
-            }
-            break;
-        case SOX_SIZE_16BIT:
-            switch(ft->signal.encoding)
-            {
-                case SOX_ENCODING_SIGN2:
-                    read_buf = sw_read_buf;
-                    break;
-                case SOX_ENCODING_UNSIGNED:
-                    read_buf = uw_read_buf;
-                    break;
-                default:
-                    sox_fail_errno(ft,SOX_EFMT,"Do not support this encoding for this data size");
-                    return 0;
-            }
-            break;
-        default:
-            sox_fail_errno(ft,SOX_EFMT,"Do not support this data size for this handler");
+      case SOX_SIZE_BYTE:
+        switch(ft->signal.encoding) {
+          case SOX_ENCODING_SIGN2:    read_buf = sb_read_buf; break;
+          case SOX_ENCODING_UNSIGNED: read_buf = ub_read_buf; break;
+          default:
+            sox_fail_errno(ft,SOX_EFMT,"Do not support this encoding for this data size");
             return 0;
+        }
+        break;
+      case SOX_SIZE_16BIT:
+        switch(ft->signal.encoding) {
+          case SOX_ENCODING_SIGN2:    read_buf = sw_read_buf; break;
+          case SOX_ENCODING_UNSIGNED: read_buf = uw_read_buf; break;
+          default:
+            sox_fail_errno(ft,SOX_EFMT,"Do not support this encoding for this data size");
+            return 0;
+        }
+        break;
+      default:
+        sox_fail_errno(ft,SOX_EFMT,"Do not support this data size for this handler");
+        return 0;
     }
 
     /* Prevent overflow */
     if (nsamp > alsa->buf_size/ft->signal.size)
-        nsamp = (alsa->buf_size/ft->signal.size);
-    len = 0;
+      nsamp = (alsa->buf_size/ft->signal.size);
 
-    while (len < nsamp)
-    {
-        /* ALSA library takes "frame" counts. */
-        err = snd_pcm_readi(alsa->pcm_handle, alsa->buf, 
-                            (nsamp - len)/ft->signal.channels);
-        if (err < 0)
-        {
-            if (xrun_recovery(alsa->pcm_handle, err) < 0)
-            {
-                sox_fail_errno(ft, SOX_EPERM, "ALSA write error");
-                return 0;
-            }
+    len = 0;
+    while (len < nsamp) {
+      sox_size_t n = snd_pcm_readi(alsa->pcm_handle, alsa->buf, 
+          (nsamp - len)/ft->signal.channels); /* ALSA takes "frame" counts. */
+      if ((int)n < 0) {
+        if (xrun_recovery(alsa->pcm_handle, (int)n) < 0) {
+          sox_fail_errno(ft, SOX_EPERM, "ALSA read error");
+          return 0;
         }
-        else
-        {
-            read_buf(buf+(len*sizeof(sox_ssample_t)), alsa->buf, (unsigned)err, ft->signal.reverse_bytes, &ft->clips);
-            len += err * ft->signal.channels;
-        }
+      } else {
+        n *= ft->signal.channels;
+        read_buf(buf + len, alsa->buf, n, ft->signal.reverse_bytes, &ft->clips);
+        len += n;
+      }
     }
-
     return len;
 }