shithub: sox

Download patch

ref: b427d364b9bcbe7c8707e8a9e4428c00a826fbef
parent: 19144759ff0bc03f470689c61a15fac88caacd7d
author: rrt <rrt>
date: Mon Dec 11 16:48:39 EST 2006

Remove output buffering.

--- a/src/alsa.c
+++ b/src/alsa.c
@@ -1,11 +1,3 @@
-/*
- * Copyright 1997-2005 Jimen Ching And Sundry Contributors
- * This source code is freely redistributable and may be used for
- * any purpose.  This copyright notice must be maintained.
- * Jimen Ching And Sundry Contributors are not
- * responsible for the consequences of using this software.
- */
-
 /* ALSA sound driver
  *
  * converted to alsalib cbagwell 20050914
@@ -12,6 +4,12 @@
  * added by Jimen Ching (jching@flex.com) 19990207
  * based on info grabed from aplay.c in alsa-utils package.
  * Updated for ALSA 0.9.X API 20020824.
+ *
+ * Copyright 1997-2005 Jimen Ching And Sundry Contributors
+ * This source code is freely redistributable and may be used for
+ * any purpose.  This copyright notice must be maintained.
+ * Jimen Ching And Sundry Contributors are not
+ * responsible for the consequences of using this software.
  */
 
 #include "st_i.h"
--- a/src/flac.c
+++ b/src/flac.c
@@ -434,7 +434,7 @@
       case  8: encoder->decoded_samples[i] = ST_SAMPLE_TO_SIGNED_BYTE(sampleBuffer[i], format->clippedCount); break;
       case 16: encoder->decoded_samples[i] = ST_SAMPLE_TO_SIGNED_WORD(sampleBuffer[i], format->clippedCount); break;
       case 24: encoder->decoded_samples[i] = ST_SAMPLE_TO_SIGNED_24BIT(sampleBuffer[i],format->clippedCount); break;
-      case 32: encoder->decoded_samples[i] = ST_SAMPLE_TO_SIGNED_DWORD(sampleBuffer[i]); break;
+      case 32: encoder->decoded_samples[i] = ST_SAMPLE_TO_SIGNED_DWORD(sampleBuffer[i],); break;
     }
   }
   FLAC__stream_encoder_process_interleaved(encoder->flac, encoder->decoded_samples, len / format->info.channels);
--- a/src/raw.c
+++ b/src/raw.c
@@ -124,7 +124,7 @@
 }
 
 #define READ_FUNC(size, sign, ctype, uctype, cast) \
-  static st_size_t st_ ## sign ## size ## _read_buf(st_sample_t *buf1, ft_t ft, st_size_t len, st_size_t *clippedCount UNUSED) \
+  static st_size_t st_ ## sign ## size ## _read_buf(st_sample_t *buf, ft_t ft, st_size_t len, st_size_t *clippedCount UNUSED) \
   { \
     st_size_t n; \
     for (n = 0; n < len; n++) { \
@@ -132,7 +132,7 @@
       int ret = st_read ## size(ft, (uctype *)&datum); \
       if (ret != ST_SUCCESS) \
         break; \
-      *buf1++ = ST_ ## cast ## _TO_SAMPLE(datum, *clippedCount); \
+      *buf++ = ST_ ## cast ## _TO_SAMPLE(datum, *clippedCount); \
     } \
     return n; \
   }
@@ -152,33 +152,52 @@
 READ_FUNC(f, , float, float, FLOAT_DWORD)
 READ_FUNC(df, , double, double, FLOAT_DDWORD)
 
-/* Read a stream of some type into SoX's internal buffer format. */
-st_size_t st_rawread(ft_t ft, st_sample_t *buf, st_size_t nsamp)
-{
-    st_size_t done = 0;
-    st_size_t (*read_buf)(st_sample_t *, ft_t ft, st_size_t, st_size_t *) = NULL;
+#define WRITE_FUNC(size, sign, cast) \
+  static st_size_t st_ ## sign ## size ## _write_buf(st_sample_t *buf, ft_t ft, st_size_t len, st_size_t *clippedCount UNUSED) \
+  { \
+    st_size_t n; \
+    for (n = 0; n < len; n++) { \
+      int ret = st_write ## size(ft, ST_SAMPLE_TO_ ## cast(*buf++, *clippedCount)); \
+      if (ret != ST_SUCCESS) \
+        break; \
+    } \
+    return n; \
+  }
 
+WRITE_FUNC(b, u, UNSIGNED_BYTE)
+WRITE_FUNC(b, s, SIGNED_BYTE)
+WRITE_FUNC(b, ulaw, ULAW_BYTE)
+WRITE_FUNC(b, alaw, ALAW_BYTE)
+WRITE_FUNC(b, inv_ulaw, INVERT_ULAW_BYTE)
+WRITE_FUNC(b, inv_alaw, INVERT_ALAW_BYTE)
+WRITE_FUNC(w, u, UNSIGNED_WORD)
+WRITE_FUNC(w, s, SIGNED_WORD)
+WRITE_FUNC(3, u, UNSIGNED_24BIT)
+WRITE_FUNC(3, s, SIGNED_24BIT)
+WRITE_FUNC(dw, u, UNSIGNED_DWORD)
+WRITE_FUNC(dw, , SIGNED_DWORD)
+WRITE_FUNC(f, , FLOAT_DWORD)
+WRITE_FUNC(df, , FLOAT_DDWORD)
+
+typedef st_size_t (ft_io_fun)(st_sample_t *buf, ft_t ft, st_size_t len, st_size_t *clippedCount);
+
+static ft_io_fun *check_format(ft_t ft, bool write)
+{
     switch (ft->info.size) {
     case ST_SIZE_BYTE:
-      switch(ft->info.encoding) {
+      switch (ft->info.encoding) {
       case ST_ENCODING_SIGN2:
-        read_buf = st_sb_read_buf;
-        break;
+        return write ? st_sb_write_buf : st_sb_read_buf;
       case ST_ENCODING_UNSIGNED:
-        read_buf = st_ub_read_buf;
-        break;
+        return write ? st_ub_write_buf : st_ub_read_buf;
       case ST_ENCODING_ULAW:
-        read_buf = st_ulawb_read_buf;
-        break;
+        return write ? st_ulawb_write_buf : st_ulawb_read_buf;
       case ST_ENCODING_ALAW:
-        read_buf = st_alawb_read_buf;
-        break;
+        return write ? st_alawb_write_buf : st_alawb_read_buf;
       case ST_ENCODING_INV_ULAW:
-        read_buf = st_inv_ulawb_read_buf;
-        break;
+        return write ? st_inv_ulawb_write_buf : st_inv_ulawb_read_buf;
       case ST_ENCODING_INV_ALAW:
-        read_buf = st_inv_alawb_read_buf;
-        break;
+        return write ? st_inv_alawb_write_buf : st_inv_alawb_read_buf;
       default:
         break;
       }
@@ -185,13 +204,11 @@
       break;
       
     case ST_SIZE_WORD: 
-      switch(ft->info.encoding) {
+      switch (ft->info.encoding) {
       case ST_ENCODING_SIGN2:
-        read_buf = st_sw_read_buf;
-        break;
+        return write ? st_sw_write_buf : st_sw_read_buf;
       case ST_ENCODING_UNSIGNED:
-        read_buf = st_uw_read_buf;
-        break;
+        return write ? st_uw_write_buf : st_uw_read_buf;
       default:
         break;
       }
@@ -198,13 +215,11 @@
       break;
 
     case ST_SIZE_24BIT:
-      switch(ft->info.encoding) {
+      switch (ft->info.encoding) {
       case ST_ENCODING_SIGN2:
-        read_buf = st_s3_read_buf;
-        break;
+        return write ? st_s3_write_buf : st_s3_read_buf;
       case ST_ENCODING_UNSIGNED:
-        read_buf = st_u3_read_buf;
-        break;
+        return write ? st_u3_write_buf: st_u3_read_buf;
       default:
         break;
       }
@@ -211,16 +226,13 @@
       break;
       
     case ST_SIZE_DWORD:
-      switch(ft->info.encoding) {
+      switch (ft->info.encoding) {
       case ST_ENCODING_SIGN2:
-        read_buf = st_dw_read_buf;
-        break;
+        return write ? st_dw_write_buf : st_dw_read_buf;
       case ST_ENCODING_UNSIGNED:
-        read_buf = st_udw_read_buf;
-        break;
+        return write ? st_udw_write_buf : st_udw_read_buf;
       case ST_ENCODING_FLOAT:
-        read_buf = st_f_read_buf;
-        break;
+        return write ? st_f_write_buf : st_f_read_buf;
       default:
         break;
       }
@@ -227,10 +239,9 @@
       break;
       
     case ST_SIZE_DDWORD:
-      switch(ft->info.encoding) {
+      switch (ft->info.encoding) {
       case ST_ENCODING_FLOAT:
-        read_buf = st_df_read_buf;
-        break;
+        return write ? st_df_write_buf : st_df_read_buf;
       default:
         break;
       }
@@ -238,336 +249,48 @@
 
     default:
       st_fail_errno(ft,ST_EFMT,"this handler does not support this data size");
-      return ST_EOF;
+      return NULL;
     }
 
-    if (read_buf == NULL) {
-        st_fail_errno(ft,ST_EFMT,"this encoding is not supported for this data size");
-        return ST_EOF;
-    }
-    
-    if (nsamp)
-        done += read_buf(buf + done, ft, nsamp, &ft->clippedCount);
-
-    return done;
+    st_fail_errno(ft,ST_EFMT,"this encoding is not supported for this data size");
+    return NULL;
 }
 
-int st_rawstopread(ft_t ft)
+/* Read a stream of some type into SoX's internal buffer format. */
+st_size_t st_rawread(ft_t ft, st_sample_t *buf, st_size_t nsamp)
 {
-        free(ft->file.buf);
+    st_size_t (*read_buf)(st_sample_t *, ft_t, st_size_t, st_size_t *) = check_format(ft, false);
 
-        return ST_SUCCESS;
-}
+    if (read_buf && nsamp)
+      return read_buf(buf, ft, nsamp, &ft->clippedCount);
 
-static void st_ub_write_buf(char* buf1, st_sample_t const * buf2, st_size_t len, st_size_t * clippedCount)
-{
-    while (len)
-    {
-        *(uint8_t *)buf1++ = ST_SAMPLE_TO_UNSIGNED_BYTE(*buf2++, *clippedCount);
-        len--;
-    }
+    return 0;
 }
 
-static void st_sb_write_buf(char *buf1, st_sample_t const * buf2, st_size_t len, st_size_t * clippedCount)
+int st_rawstopread(ft_t ft)
 {
-    while (len)
-    {
-        *(int8_t *)buf1++ = ST_SAMPLE_TO_SIGNED_BYTE(*buf2++, *clippedCount);
-        len--;
-    }
-}
+        free(ft->file.buf);
 
-static void st_ulaw_write_buf(char *buf1, st_sample_t const * buf2, st_size_t len, st_size_t * clippedCount)
-{
-    while (len)
-    {
-        *(uint8_t *)buf1++ = ST_SAMPLE_TO_ULAW_BYTE(*buf2++, *clippedCount);
-        len--;
-    }
+        return ST_SUCCESS;
 }
 
-static void st_alaw_write_buf(char *buf1, st_sample_t const * buf2, st_size_t len, st_size_t * clippedCount)
-{
-    while (len)
-    {
-        *(uint8_t *)buf1++ = ST_SAMPLE_TO_ALAW_BYTE(*buf2++, *clippedCount);
-        len--;
-    }
-}
-
-static void st_inv_ulaw_write_buf(char *buf1, st_sample_t const * buf2, st_size_t len, st_size_t * clippedCount)
-{
-    while (len)
-    {
-        *(uint8_t *)buf1++ = ST_SAMPLE_TO_INVERT_ULAW_BYTE(*buf2++, *clippedCount);
-        len--;
-    }
-}
-
-static void st_inv_alaw_write_buf(char *buf1, st_sample_t const * buf2, st_size_t len, st_size_t * clippedCount)
-{
-    while (len)
-    {
-        *(uint8_t *)buf1++ = ST_SAMPLE_TO_INVERT_ALAW_BYTE(*buf2++, *clippedCount);
-        len--;
-    }
-}
-
-static void st_uw_write_buf(char *buf1, st_sample_t const * buf2, st_size_t len, st_size_t * clippedCount)
-{
-    while (len)
-    {
-        uint16_t datum;
-
-        datum = ST_SAMPLE_TO_UNSIGNED_WORD(*buf2++, *clippedCount);
-        *(uint16_t *)buf1 = datum;
-        buf1++; buf1++;
-
-        len--;
-    }
-}
-
-static void st_sw_write_buf(char *buf1, st_sample_t const * buf2, st_size_t len, st_size_t * clippedCount)
-{
-    while (len)
-    {
-        int16_t datum;
-
-        datum = ST_SAMPLE_TO_SIGNED_WORD(*buf2++, *clippedCount);
-        *(int16_t *)buf1 = datum;
-        buf1++; buf1++;
-
-        len--;
-    }
-}
-
-
-
-static void st_24_write_one(char * * const buf1, int24_t datum)
-{
-  if (ST_IS_BIGENDIAN)
-    datum <<= 8;
-
-  /* N.B. overwrites an extra byte; however SoX buffers are 2^n bytes long and
-   * since 2^n != 0 (mod 3), there will always be an extra byte to write to. */
-  *(int24_t *)*buf1 = datum;
-
-  *buf1 += 3;
-}
-
-
-
-static void st_u24_write_buf(char * buf1, st_sample_t const * buf2, st_size_t len, st_size_t * clippedCount)
-{
-  while (len--)
-  {
-    int24_t datum = ST_SAMPLE_TO_UNSIGNED_24BIT(*buf2++, *clippedCount);
-    st_24_write_one(&buf1, datum);
-  }
-}
-
-
-
-static void st_s24_write_buf(char * buf1, st_sample_t const * buf2, st_size_t len, st_size_t * clippedCount)
-{
-  while (len--)
-  {
-    int24_t datum = ST_SAMPLE_TO_SIGNED_24BIT(*buf2++, *clippedCount);
-    st_24_write_one(&buf1, datum);
-  }
-}
-
-
-
-static void st_udw_write_buf(char *buf1, st_sample_t const * buf2, st_size_t len, st_size_t * clippedCount UNUSED)
-{
-    while (len)
-    {
-        uint32_t datum;
-
-        datum = ST_SAMPLE_TO_UNSIGNED_DWORD(*buf2++);
-        *(uint32_t *)buf1 = datum;
-        buf1++; buf1++; buf1++; buf1++;
-
-        len--;
-    }
-}
-
-static void st_dw_write_buf(char *buf1, st_sample_t const * buf2, st_size_t len, st_size_t * clippedCount UNUSED)
-{
-    while (len)
-    {
-        int32_t datum;
-
-        datum = ST_SAMPLE_TO_SIGNED_DWORD(*buf2++);
-        *(int32_t *)buf1 = datum;
-        buf1++; buf1++; buf1++; buf1++;
-
-        len--;
-    }
-}
-
-static void st_f32_write_buf(char *buf1, st_sample_t const * buf2, st_size_t len, st_size_t * clippedCount)
-{
-    while (len)
-    {
-        float datum;
-
-        datum = ST_SAMPLE_TO_FLOAT_DWORD(*buf2++, *clippedCount);
-        *(float *)buf1 = datum;
-        buf1++; buf1++; buf1++; buf1++;
-
-        len--;
-    }
-}
-
-static void st_f64_write_buf(char *buf1, st_sample_t const * buf2, st_size_t len, st_size_t * clippedCount)
-{
-    while (len)
-    {
-        double datum;
-
-        datum = ST_SAMPLE_TO_FLOAT_DDWORD(*buf2++, *clippedCount);
-        *(double *)buf1 = datum;
-        buf1++; buf1++; buf1++; buf1++;
-        buf1++; buf1++; buf1++; buf1++;
-
-        len--;
-    }
-}
-
-
 static void writeflush(ft_t ft)
 {
         if (st_writebuf(ft, ft->file.buf, 1, ft->file.pos) != ft->file.pos)
-        {
             ft->file.eof = ST_EOF;
-        }
         ft->file.pos = 0;
 }
 
 
-/* Writes SoX's internal buffer format to buffer of various data types.
- */
-/* FIXME:  This function adds buffering on top of stdio's buffering.
- * Mixing st_rawwrites's and fwrites or even SoX's other util
- * functions will cause a loss of data!  Need to have sox implement
- * a consistent buffering protocol.
- */
+/* Writes SoX's internal buffer format to buffer of various data types. */
 st_size_t st_rawwrite(ft_t ft, const st_sample_t *buf, st_size_t nsamp)
 {
-    st_size_t len, done = 0;
-    void (*write_buf)(char *, st_sample_t const *, st_size_t, st_size_t *) = 0;
+    ft_io_fun *write_buf = check_format(ft, true);
 
-    switch(ft->info.size) {
-        case ST_SIZE_BYTE:
-            switch(ft->info.encoding)
-            {
-                case ST_ENCODING_SIGN2:
-                    write_buf = st_sb_write_buf;
-                    break;
-                case ST_ENCODING_UNSIGNED:
-                    write_buf = st_ub_write_buf;
-                    break;
-                case ST_ENCODING_ULAW:
-                    write_buf = st_ulaw_write_buf;
-                    break;
-                case ST_ENCODING_ALAW:
-                    write_buf = st_alaw_write_buf;
-                    break;
-                case ST_ENCODING_INV_ULAW:
-                    write_buf = st_inv_ulaw_write_buf;
-                    break;
-                case ST_ENCODING_INV_ALAW:
-                    write_buf = st_inv_alaw_write_buf;
-                    break;
-                default:
-                    st_fail_errno(ft,ST_EFMT,"Do not support this encoding for this data size");
-                    return ST_EOF;
-            }
-            break;
+    if (write_buf && nsamp)
+      return write_buf((st_sample_t *)buf, ft, nsamp, &ft->clippedCount);
 
-        case ST_SIZE_WORD:
-            switch(ft->info.encoding)
-            {
-                case ST_ENCODING_SIGN2:
-                    write_buf = st_sw_write_buf;
-                    break;
-                case ST_ENCODING_UNSIGNED:
-                    write_buf = st_uw_write_buf;
-                    break;
-                default:
-                    st_fail_errno(ft,ST_EFMT,"Do not support this encoding for this data size");
-                    return ST_EOF;
-            }
-            break;
-
-        case ST_SIZE_24BIT:
-            switch(ft->info.encoding)
-            {
-                case ST_ENCODING_SIGN2:
-                    write_buf = st_s24_write_buf;
-                    break;
-                case ST_ENCODING_UNSIGNED:
-                    write_buf = st_u24_write_buf;
-                    break;
-                default:
-                    st_fail_errno(ft,ST_EFMT,"Do not support this encoding for this data size");
-                    return ST_EOF;
-            }
-            break;
-
-        case ST_SIZE_DWORD:
-            switch(ft->info.encoding)
-            {
-                case ST_ENCODING_SIGN2:
-                    write_buf = st_dw_write_buf;
-                    break;
-                case ST_ENCODING_UNSIGNED:
-                    write_buf = st_udw_write_buf;
-                    break;
-                case ST_ENCODING_FLOAT:
-                    write_buf = st_f32_write_buf;
-                    break;
-                default:
-                    st_fail_errno(ft,ST_EFMT,"Do not support this encoding for this data size");
-                    return ST_EOF;
-            }
-            break;
-
-        case ST_SIZE_DDWORD:
-            switch(ft->info.encoding)
-            {
-                case ST_ENCODING_FLOAT:
-                    write_buf = st_f64_write_buf;
-                    break;
-                default:
-                    st_fail_errno(ft,ST_EFMT,"Do not support this encoding for this data size");
-                    return ST_EOF;
-            }
-            break;
-
-        default:
-            st_fail_errno(ft,ST_EFMT,"Do not support this data size for this handler");
-            return ST_EOF;
-    }
-
-    while (done < nsamp && !ft->file.eof)
-    {
-        if (ft->file.pos > (ft->file.size-ft->info.size))
-        {
-            writeflush(ft);
-        }
-
-        len = min(nsamp-done,(ft->file.size-ft->file.pos)/ft->info.size);
-        if (len)
-        {
-            write_buf(ft->file.buf + ft->file.pos, buf+done, len, &ft->clippedCount);
-            ft->file.pos += (len*ft->info.size);
-            done += len;
-        }
-    }
-    return done;
+    return 0;
 }
 
 int st_rawstopwrite(ft_t ft)
--- a/src/silence.c
+++ b/src/silence.c
@@ -344,7 +344,7 @@
             ratio = (double)abs(value) / (double)ST_INT24_MAX;
             break;
         case ST_SIZE_DWORD:
-            value = ST_SAMPLE_TO_SIGNED_DWORD(value);
+            value = ST_SAMPLE_TO_SIGNED_DWORD(value,);
             ratio = (double)labs(value) / (double)ST_INT32_MAX;
             break;
         default:
--- a/src/st.h
+++ b/src/st.h
@@ -119,9 +119,9 @@
 #define ST_SAMPLE_TO_SIGNED_WORD(d,clips) ST_SAMPLE_TO_SIGNED(16,d,clips)
 #define ST_SAMPLE_TO_UNSIGNED_24BIT(d,clips) ST_SAMPLE_TO_UNSIGNED(24,d,clips)
 #define ST_SAMPLE_TO_SIGNED_24BIT(d,clips) ST_SAMPLE_TO_SIGNED(24,d,clips)
-#define ST_SAMPLE_TO_UNSIGNED_DWORD(d) (uint32_t)((d)^ST_SAMPLE_NEG)
-#define ST_SAMPLE_TO_SIGNED_DWORD(d) (int32_t)(d)
-#define ST_SAMPLE_TO_FLOAT_DWORD (float)ST_SAMPLE_TO_FLOAT_DDWORD
+#define ST_SAMPLE_TO_UNSIGNED_DWORD(d,clips) (uint32_t)((d)^ST_SAMPLE_NEG)
+#define ST_SAMPLE_TO_SIGNED_DWORD(d,clips) (int32_t)(d)
+#define ST_SAMPLE_TO_FLOAT_DWORD ST_SAMPLE_TO_FLOAT_DDWORD
 #define ST_SAMPLE_TO_FLOAT_DDWORD(d,clips) (st_macro_temp_sample=d,st_macro_temp_sample==ST_SAMPLE_MIN?++(clips),-1.0:((double)(st_macro_temp_sample)*(1.0/ST_SAMPLE_MAX)))