shithub: sox

Download patch

ref: d84bb80c9a33ca9e5f8ea1441111c509b55cc46a
parent: 301fd25e93c7bfce542242a434dd35fd32a35346
author: cbagwell <cbagwell>
date: Sat Jan 19 18:34:15 EST 2008

Switch to 16-bit format for libao to work with 100% of its plugins.

--- a/ChangeLog
+++ b/ChangeLog
@@ -25,6 +25,8 @@
   o Fix [1748909] sox does not report remaining playtime of mp3s.  (robs)
   o Fix failure to read AIFF files with empty MARK chunk.  (robs)
   o Fix spurious 'Premature EOF' message in some circumstances.  (robs)
+  o Switched to 16-bit for libao driver since not all its plugins
+    support it (such as oss, nas, and pulse audio).
 
   Internal improvements:
 
@@ -34,6 +36,8 @@
   o Remove unused libltdl that could cause header mismatch with
     installed libltdl.
   o Fix AMR detection with --disable-shared.  (robs)
+  o Updated configure to support linking to static libraries
+    on mingw for flac, ogg, and libsamplerate libraries.
 
 
 sox-14.0.0
--- a/src/ao.c
+++ b/src/ao.c
@@ -29,6 +29,8 @@
   int driver_id;
   ao_device *device;
   ao_sample_format format;
+  char *buf;
+  sox_size_t buf_size;
 } *ao_priv_t;
 
 static int startread(UNUSED sox_format_t * ft)
@@ -41,6 +43,25 @@
 {
   ao_priv_t ao = (ao_priv_t)ft->priv;
 
+  if (ft->signal.size != SOX_SIZE_16BIT || 
+      ft->signal.encoding != SOX_ENCODING_SIGN2)
+  {
+      sox_report("Forcing to signed 16 bit samples for ao driver");
+      ft->signal.size = SOX_SIZE_16BIT;
+      ft->signal.encoding = SOX_ENCODING_SIGN2;
+  }
+
+  ao->buf_size = sox_globals.bufsiz - (sox_globals.bufsiz % ft->signal.size);
+  ao->buf_size *= ft->signal.size;
+  ao->buf = xmalloc(ao->buf_size);
+
+  if (!ao->buf)
+  {
+      sox_fail_errno(ft, SOX_ENOMEM, "Can not allocate memory for ao driver");
+      return SOX_EOF;
+  }
+
+
   ao_initialize();
   if (strcmp(ft->filename,"default") == 0)
   {
@@ -57,7 +78,7 @@
       }
   }
 
-  ao->format.bits = SOX_SAMPLE_BITS;
+  ao->format.bits = ft->signal.size * 8;
   ao->format.rate = ft->signal.rate;
   ao->format.channels = ft->signal.channels;
   ao->format.byte_format = AO_FMT_NATIVE;
@@ -69,11 +90,31 @@
   return SOX_SUCCESS;
 }
 
-static sox_size_t write(sox_format_t * ft, const sox_sample_t *buf, sox_size_t len)
+static void sox_sw_write_buf(char *buf1, sox_sample_t const * buf2, sox_size_t len, sox_bool swap, sox_size_t * clips)
 {
+    while (len--)
+    {
+        uint16_t datum = SOX_SAMPLE_TO_SIGNED_16BIT(*buf2++, *clips);
+        if (swap)
+            datum = sox_swapw(datum);
+        *(uint16_t *)buf1 = datum;
+        buf1++; buf1++;
+    }
+}
+
+static sox_size_t write(sox_format_t *ft, const sox_sample_t *buf, sox_size_t len)
+{
   ao_priv_t ao = (ao_priv_t)ft->priv;
+  sox_size_t aobuf_size;
 
-  if (ao_play(ao->device, (void *)buf, len * sizeof(sox_sample_t)) == 0)
+  if (len > ao->buf_size / ft->signal.size)
+      len = ao->buf_size / ft->signal.size;
+
+  aobuf_size = ft->signal.size * len;
+
+  sox_sw_write_buf((char *)ao->buf, buf, len, ft->signal.reverse_bytes,
+                   &(ft->clips));
+  if (ao_play(ao->device, (void *)ao->buf, aobuf_size) == 0)
     return 0;
 
   return len;
@@ -82,6 +123,8 @@
 static int stopwrite(sox_format_t * ft)
 {
   ao_priv_t ao = (ao_priv_t)ft->priv;
+
+  free(ao->buf);
 
   if (ao_close(ao->device) == 0) {
     sox_fail("Error closing libao output");