shithub: sox

Download patch

ref: e80265f904b1e0e1b7f1abf37fa811aecf3aba36
parent: a47f11eb6a3bcc2a2beafefaeb83f78b021793cb
author: rrt <rrt>
date: Thu Apr 5 10:02:11 EDT 2007

Generate all read/write functions from macros, allowing the compiler
to get performance back up to 12.17.9 levels without resorting to
inlining.

In the process, make one or two other small changes for consistency of
naming and/or function (e.g. sox_swapb -> sox_swap; sox_swapf takes
parameter by value, not reference).

--- a/src/misc.c
+++ b/src/misc.c
@@ -228,87 +228,6 @@
         return(SOX_SUCCESS);
 }
 
-/* Read double word. */
-int sox_readdw(ft_t ft, uint32_t *udw)
-{
-        if (sox_readbuf(ft, udw, 4, 1) != 1)
-        {
-            sox_fail_errno(ft,errno,sox_readerr);
-            return (SOX_EOF);
-        }
-        if (ft->signal.reverse_bytes)
-                *udw = sox_swapdw(*udw);
-        return SOX_SUCCESS;
-}
-
-/* Write double word. */
-int sox_writedw(ft_t ft, uint32_t udw)
-{
-        if (ft->signal.reverse_bytes)
-                udw = sox_swapdw(udw);
-        if (sox_writebuf(ft, &udw, 4, 1) != 1)
-        {
-                sox_fail_errno(ft,errno,sox_writerr);
-                return (SOX_EOF);
-        }
-        return(SOX_SUCCESS);
-}
-
-/* Read float. */
-int sox_readf(ft_t ft, float *f)
-{
-        if (sox_readbuf(ft, f, sizeof(float), 1) != 1)
-        {
-            sox_fail_errno(ft,errno,sox_readerr);
-            return(SOX_EOF);
-        }
-        if (ft->signal.reverse_bytes)
-                *f = sox_swapf(f);
-        return SOX_SUCCESS;
-}
-
-/* Write float. */
-int sox_writef(ft_t ft, float f)
-{
-        float t = f;
-
-        if (ft->signal.reverse_bytes)
-                t = sox_swapf(&t);
-        if (sox_writebuf(ft, &t, sizeof(float), 1) != 1)
-        {
-                sox_fail_errno(ft,errno,sox_writerr);
-                return (SOX_EOF);
-        }
-        return (SOX_SUCCESS);
-}
-
-/* Read double. */
-int sox_readdf(ft_t ft, double *d)
-{
-        if (sox_readbuf(ft, d, sizeof(double), 1) != 1)
-        {
-            sox_fail_errno(ft,errno,sox_readerr);
-            return(SOX_EOF);
-        }
-        if (ft->signal.reverse_bytes)
-                *d = sox_swapd(*d);
-        return SOX_SUCCESS;
-}
-
-/* Write double. */
-int sox_writedf(ft_t ft, double d)
-{
-        if (ft->signal.reverse_bytes)
-                d = sox_swapd(d);
-        if (sox_writebuf(ft, &d, sizeof(double), 1) != 1)
-        {
-                sox_fail_errno(ft,errno,sox_writerr);
-                return (SOX_EOF);
-        }
-        return (SOX_SUCCESS);
-}
-
-
 uint32_t get32_le(unsigned char **p)
 {
         uint32_t val = (((*p)[3]) << 24) | (((*p)[2]) << 16) | 
@@ -353,7 +272,7 @@
 }
 
 /* generic swap routine. Swap l and place in to f (datatype length = n) */
-static void sox_swapb(char *l, char *f, int n)
+static void sox_swap(char *l, char *f, int n)
 {
     register int i;
 
@@ -362,7 +281,7 @@
 }
 
 /* return swapped 32-bit float */
-float sox_swapf(float const * f)
+float sox_swapf(float f)
 {
     union {
         uint32_t dw;
@@ -369,20 +288,20 @@
         float f;
     } u;
 
-    u.f= *f;
+    u.f= f;
     u.dw= (u.dw>>24) | ((u.dw>>8)&0xff00) | ((u.dw<<8)&0xff0000) | (u.dw<<24);
     return u.f;
 }
 
-uint32_t sox_swap24(uint24_t udw)
+uint32_t sox_swap3(uint24_t udw)
 {
     return ((udw >> 16) & 0xff) | (udw & 0xff00) | ((udw << 16) & 0xff0000);
 }
 
-double sox_swapd(double df)
+double sox_swapdf(double df)
 {
     double sdf;
-    sox_swapb((char *)&df, (char *)&sdf, sizeof(double));
+    sox_swap((char *)&df, (char *)&sdf, sizeof(double));
     return (sdf);
 }
 
--- a/src/raw.c
+++ b/src/raw.c
@@ -93,60 +93,162 @@
   return SOX_SUCCESS;
 }
 
-#define READ_FUNC(size, sign, ctype, uctype, cast) \
-  static sox_size_t sox_ ## sign ## size ## _read_buf( \
-      ft_t ft, sox_sample_t *buf, sox_size_t len) \
+/* Dummy macros */
+#define sox_swapb(d) (d)
+#define idcast(x, y) (x)
+
+#define TWIDDLE_BYTE_READ(ub, type) \
+  if (ft->signal.reverse_bits) \
+    ub = cswap[ub]; \
+  if (ft->signal.reverse_nibbles) \
+    ub = ((ub & 15) << 4) | (ub >> 4);
+
+#define TWIDDLE_BYTE_WRITE(ub, type) \
+  if (ft->signal.reverse_nibbles) \
+    ub = ((ub & 15) << 4) | (ub >> 4); \
+  if (ft->signal.reverse_bits) \
+    ub = cswap[ub];
+
+#define TWIDDLE_WORD(uw, type) \
+  if (ft->signal.reverse_bytes ^ SOX_IS_BIGENDIAN) \
+    uw = sox_swap ## type(uw);
+
+/* N.B. This macro doesn't work for types, like 3-byte types, which
+   don't fill the type used to represent them. */
+#define READ_FUNC(type, size, sign, ctype, uctype, outtype, cast, suffix, twiddle) \
+  sox_size_t sox_read_ ## sign ## type ## suffix( \
+      ft_t ft, outtype *buf, sox_size_t len) \
   { \
+    sox_size_t n = 0, nread; \
+    ctype *data = xmalloc(sizeof(ctype) * len); \
+    if ((nread = sox_readbuf(ft, (uctype *)data, size, len)) != len) \
+      sox_fail_errno(ft, errno, sox_readerr); \
+    for (; n < nread; n++) { \
+      twiddle(((uctype *)data)[n], type); \
+      *buf++ = cast(data[n], ft->clips); \
+    } \
+    free(data); \
+    return nread; \
+  }
+
+/* This (slower) macro works for 3-byte types. */
+#define READ_FUNC2(type, size, sign, ctype, uctype, outtype, cast, suffix, twiddle) \
+  sox_size_t sox_read_ ## sign ## type ## suffix( \
+      ft_t ft, outtype *buf, sox_size_t len) \
+  { \
     sox_size_t n; \
     for (n = 0; n < len; n++) { \
-      ctype datum; \
-      int ret = sox_read ## size(ft, (uctype *)&datum); \
-      if (ret != SOX_SUCCESS) \
+      ctype datum = 0; \
+      if (sox_readbuf(ft, (uctype *)&datum, size, 1) != 1) { \
+        sox_fail_errno(ft, errno, sox_readerr); \
         break; \
-      *buf++ = SOX_ ## cast ## _TO_SAMPLE(datum, ft->clips); \
+      } \
+      twiddle(datum, type); \
+      *buf++ = cast(datum, ft->clips); \
     } \
     return n; \
   }
 
-READ_FUNC(b, u, uint8_t, uint8_t, UNSIGNED_BYTE)
-READ_FUNC(b, s, int8_t, uint8_t, SIGNED_BYTE)
-READ_FUNC(b, ulaw, uint8_t, uint8_t, ULAW_BYTE)
-READ_FUNC(b, alaw, uint8_t, uint8_t, ALAW_BYTE)
-READ_FUNC(w, u, uint16_t, uint16_t, UNSIGNED_WORD)
-READ_FUNC(w, s, int16_t, uint16_t, SIGNED_WORD)
-READ_FUNC(3, u, uint24_t, uint24_t, UNSIGNED_24BIT)
-READ_FUNC(3, s, int24_t, uint24_t, SIGNED_24BIT)
-READ_FUNC(dw, u, uint32_t, uint32_t, UNSIGNED_DWORD)
-READ_FUNC(dw, s, int32_t, uint32_t, SIGNED_DWORD)
-READ_FUNC(f, su, float, float, FLOAT_DWORD)
-READ_FUNC(df, su, double, double, FLOAT_DDWORD)
+READ_FUNC(b, 1, u, uint8_t, uint8_t, uint8_t, idcast, _buf, TWIDDLE_BYTE_READ)
+READ_FUNC(b, 1, s, int8_t, uint8_t, int8_t, idcast, _buf, TWIDDLE_BYTE_READ)
+READ_FUNC(b, 1, ulaw, uint8_t, uint8_t, uint8_t, idcast, _buf, TWIDDLE_BYTE_READ)
+READ_FUNC(b, 1, alaw, uint8_t, uint8_t, uint8_t, idcast, _buf, TWIDDLE_BYTE_READ)
+READ_FUNC(w, 2, u, uint16_t, uint16_t, uint16_t, idcast, _buf, TWIDDLE_WORD)
+READ_FUNC(w, 2, s, int16_t, uint16_t, int16_t, idcast, _buf, TWIDDLE_WORD)
+READ_FUNC2(3, 3, u, uint24_t, uint24_t, uint24_t, idcast, _buf, TWIDDLE_WORD)
+READ_FUNC2(3, 3, s, int24_t, uint24_t, int24_t, idcast, _buf, TWIDDLE_WORD)
+READ_FUNC(dw, 4, u, uint32_t, uint32_t, uint32_t, idcast, _buf, TWIDDLE_WORD)
+READ_FUNC(dw, 4, s, int32_t, uint32_t, int32_t, idcast, _buf, TWIDDLE_WORD)
+READ_FUNC(f, sizeof(float), su, float, float, float, idcast, _buf, TWIDDLE_WORD)
+READ_FUNC(df, sizeof(double), su, double, double, double, idcast, _buf, TWIDDLE_WORD)
 
-#define WRITE_FUNC(size, sign, cast) \
-  static sox_size_t sox_ ## sign ## size ## _write_buf( \
-      ft_t ft, sox_sample_t *buf, sox_size_t len) \
+static READ_FUNC(b, 1, u, uint8_t, uint8_t, sox_sample_t, SOX_UNSIGNED_BYTE_TO_SAMPLE, _samples, TWIDDLE_BYTE_READ)
+static READ_FUNC(b, 1, s, int8_t, uint8_t, sox_sample_t, SOX_SIGNED_BYTE_TO_SAMPLE, _samples, TWIDDLE_BYTE_READ)
+static READ_FUNC(b, 1, ulaw, uint8_t, uint8_t, sox_sample_t, SOX_ULAW_BYTE_TO_SAMPLE, _samples, TWIDDLE_BYTE_READ)
+static READ_FUNC(b, 1, alaw, uint8_t, uint8_t, sox_sample_t, SOX_ALAW_BYTE_TO_SAMPLE, _samples, TWIDDLE_BYTE_READ)
+static READ_FUNC(w, 2, u, uint16_t, uint16_t, sox_sample_t, SOX_UNSIGNED_WORD_TO_SAMPLE, _samples, TWIDDLE_WORD)
+static READ_FUNC(w, 2, s, int16_t, uint16_t, sox_sample_t, SOX_SIGNED_WORD_TO_SAMPLE, _samples, TWIDDLE_WORD)
+static READ_FUNC2(3, 3, u, uint24_t, uint24_t, sox_sample_t, SOX_UNSIGNED_24BIT_TO_SAMPLE, _samples, TWIDDLE_WORD)
+static READ_FUNC2(3, 3, s, int24_t, uint24_t, sox_sample_t, SOX_SIGNED_24BIT_TO_SAMPLE, _samples, TWIDDLE_WORD)
+static READ_FUNC(dw, 4, u, uint32_t, uint32_t, sox_sample_t, SOX_UNSIGNED_DWORD_TO_SAMPLE, _samples, TWIDDLE_WORD)
+static READ_FUNC(dw, 4, s, int32_t, uint32_t, sox_sample_t, SOX_SIGNED_DWORD_TO_SAMPLE, _samples, TWIDDLE_WORD)
+static READ_FUNC(f, sizeof(float), su, float, float, sox_sample_t, SOX_FLOAT_DWORD_TO_SAMPLE, _samples, TWIDDLE_WORD)
+static READ_FUNC(df, sizeof(double), su, double, double, sox_sample_t, SOX_FLOAT_DDWORD_TO_SAMPLE, _samples, TWIDDLE_WORD)
+
+/* N.B. This macro doesn't work for types, like 3-byte types, which
+   don't fill the type used to represent them. */
+#define WRITE_FUNC(type, size, sign, ctype, uctype, outtype, cast, suffix, twiddle) \
+  sox_size_t sox_write_ ## sign ## type ## suffix( \
+      ft_t ft, outtype *buf, sox_size_t len) \
   { \
+    sox_size_t n = 0, nwritten; \
+    ctype *data = xmalloc(sizeof(ctype) * len); \
+    for (; n < len; n++) { \
+      data[n] = cast(*buf++, ft->clips); \
+      twiddle(((uctype *)data)[n], type); \
+    } \
+    if ((nwritten = sox_writebuf(ft, (uctype *)data, size, len)) != len) \
+      sox_fail_errno(ft, errno, sox_readerr); \
+    free(data); \
+    return nwritten; \
+  }
+
+/* This (slower) macro works for 3-byte types. */
+#define WRITE_FUNC2(type, size, sign, ctype, uctype, intype, cast, suffix, twiddle) \
+  sox_size_t sox_write_ ## sign ## type ## suffix( \
+      ft_t ft, intype *buf, sox_size_t len) \
+  { \
     sox_size_t n; \
     for (n = 0; n < len; n++) { \
-      int ret = sox_write ## size(ft, SOX_SAMPLE_TO_ ## cast(*buf++, ft->clips)); \
-      if (ret != SOX_SUCCESS) \
+      ctype datum = cast(*buf++, ft->clips); \
+      twiddle(datum, type); \
+      if (sox_writebuf(ft, (uctype *)&datum, size, 1) != 1) { \
+        sox_fail_errno(ft, errno, sox_readerr); \
         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(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, s, SIGNED_DWORD)
-WRITE_FUNC(f, su, FLOAT_DWORD)
-WRITE_FUNC(df, su, FLOAT_DDWORD)
+WRITE_FUNC(b, 1, u, uint8_t, uint8_t, uint8_t, idcast, _buf, TWIDDLE_BYTE_WRITE)
+WRITE_FUNC(b, 1, s, int8_t, uint8_t, int8_t, idcast, _buf, TWIDDLE_BYTE_WRITE)
+WRITE_FUNC(b, 1, ulaw, uint8_t, uint8_t, uint8_t, idcast, _buf, TWIDDLE_BYTE_WRITE)
+WRITE_FUNC(b, 1, alaw, uint8_t, uint8_t, uint8_t, idcast, _buf, TWIDDLE_BYTE_WRITE)
+WRITE_FUNC(w, 2, u, uint16_t, uint16_t, uint16_t, idcast, _buf, TWIDDLE_WORD)
+WRITE_FUNC(w, 2, s, int16_t, uint16_t, int16_t, idcast, _buf, TWIDDLE_WORD)
+WRITE_FUNC2(3, 3, u, uint24_t, uint24_t, uint24_t, idcast, _buf, TWIDDLE_WORD)
+WRITE_FUNC2(3, 3, s, int24_t, uint24_t, int24_t, idcast, _buf, TWIDDLE_WORD)
+WRITE_FUNC(dw, 4, u, uint32_t, uint32_t, uint32_t, idcast, _buf, TWIDDLE_WORD)
+WRITE_FUNC(dw, 4, s, int32_t, uint32_t, int32_t, idcast, _buf, TWIDDLE_WORD)
+WRITE_FUNC(f, sizeof(float), su, float, float, float, idcast, _buf, TWIDDLE_WORD)
+WRITE_FUNC(df, sizeof(double), su, double, double, double, idcast, _buf, TWIDDLE_WORD)
 
+static WRITE_FUNC(b, 1, u, uint8_t, uint8_t, sox_sample_t, SOX_SAMPLE_TO_UNSIGNED_BYTE, _samples, TWIDDLE_BYTE_WRITE)
+static WRITE_FUNC(b, 1, s, int8_t, uint8_t, sox_sample_t, SOX_SAMPLE_TO_SIGNED_BYTE, _samples, TWIDDLE_BYTE_WRITE)
+static WRITE_FUNC(b, 1, ulaw, uint8_t, uint8_t, sox_sample_t, SOX_SAMPLE_TO_ULAW_BYTE, _samples, TWIDDLE_BYTE_WRITE)
+static WRITE_FUNC(b, 1, alaw, uint8_t, uint8_t, sox_sample_t, SOX_SAMPLE_TO_ALAW_BYTE, _samples, TWIDDLE_BYTE_WRITE)
+static WRITE_FUNC(w, 2, u, uint16_t, uint16_t, sox_sample_t, SOX_SAMPLE_TO_UNSIGNED_WORD, _samples, TWIDDLE_WORD)
+static WRITE_FUNC(w, 2, s, int16_t, uint16_t, sox_sample_t, SOX_SAMPLE_TO_SIGNED_WORD, _samples, TWIDDLE_WORD)
+static WRITE_FUNC2(3, 3, u, uint24_t, uint24_t, sox_sample_t, SOX_SAMPLE_TO_UNSIGNED_24BIT, _samples, TWIDDLE_WORD)
+static WRITE_FUNC2(3, 3, s, int24_t, uint24_t, sox_sample_t, SOX_SAMPLE_TO_SIGNED_24BIT, _samples, TWIDDLE_WORD)
+static WRITE_FUNC(dw, 4, u, uint32_t, uint32_t, sox_sample_t, SOX_SAMPLE_TO_UNSIGNED_DWORD, _samples, TWIDDLE_WORD)
+static WRITE_FUNC(dw, 4, s, int32_t, uint32_t, sox_sample_t, SOX_SAMPLE_TO_SIGNED_DWORD, _samples, TWIDDLE_WORD)
+static WRITE_FUNC(f, sizeof(float), su, float, float, sox_sample_t, SOX_SAMPLE_TO_FLOAT_DWORD, _samples, TWIDDLE_WORD)
+static WRITE_FUNC(df, sizeof(double), su, double, double, sox_sample_t, SOX_SAMPLE_TO_FLOAT_DDWORD, _samples, TWIDDLE_WORD)
+
+#define WRITE1_FUNC(type, sign, ctype) \
+  int sox_write ## type(ft_t ft, ctype datum) \
+  { \
+    return sox_write_ ## sign ## type ## _buf(ft, &datum, 1) == 1 ? SOX_SUCCESS : SOX_EOF; \
+  }
+
+WRITE1_FUNC(b, u, uint8_t)
+WRITE1_FUNC(w, u, uint16_t)
+WRITE1_FUNC(3, u, uint24_t)
+WRITE1_FUNC(dw, u, uint32_t)
+WRITE1_FUNC(f, su, float)
+WRITE1_FUNC(df, su, double)
+
 typedef sox_size_t (ft_io_fun)(ft_t ft, sox_sample_t *buf, sox_size_t len);
 
 static ft_io_fun *check_format(ft_t ft, sox_bool write)
@@ -155,13 +257,13 @@
     case SOX_SIZE_BYTE:
       switch (ft->signal.encoding) {
       case SOX_ENCODING_SIGN2:
-        return write ? sox_sb_write_buf : sox_sb_read_buf;
+        return write ? sox_write_sb_samples : sox_read_sb_samples;
       case SOX_ENCODING_UNSIGNED:
-        return write ? sox_ub_write_buf : sox_ub_read_buf;
+        return write ? sox_write_ub_samples : sox_read_ub_samples;
       case SOX_ENCODING_ULAW:
-        return write ? sox_ulawb_write_buf : sox_ulawb_read_buf;
+        return write ? sox_write_ulawb_samples : sox_read_ulawb_samples;
       case SOX_ENCODING_ALAW:
-        return write ? sox_alawb_write_buf : sox_alawb_read_buf;
+        return write ? sox_write_alawb_samples : sox_read_alawb_samples;
       default:
         break;
       }
@@ -170,9 +272,9 @@
     case SOX_SIZE_16BIT: 
       switch (ft->signal.encoding) {
       case SOX_ENCODING_SIGN2:
-        return write ? sox_sw_write_buf : sox_sw_read_buf;
+        return write ? sox_write_sw_samples : sox_read_sw_samples;
       case SOX_ENCODING_UNSIGNED:
-        return write ? sox_uw_write_buf : sox_uw_read_buf;
+        return write ? sox_write_uw_samples : sox_read_uw_samples;
       default:
         break;
       }
@@ -181,9 +283,9 @@
     case SOX_SIZE_24BIT:
       switch (ft->signal.encoding) {
       case SOX_ENCODING_SIGN2:
-        return write ? sox_s3_write_buf : sox_s3_read_buf;
+        return write ? sox_write_s3_samples : sox_read_s3_samples;
       case SOX_ENCODING_UNSIGNED:
-        return write ? sox_u3_write_buf: sox_u3_read_buf;
+        return write ? sox_write_u3_samples: sox_read_u3_samples;
       default:
         break;
       }
@@ -192,11 +294,11 @@
     case SOX_SIZE_32BIT:
       switch (ft->signal.encoding) {
       case SOX_ENCODING_SIGN2:
-        return write ? sox_sdw_write_buf : sox_sdw_read_buf;
+        return write ? sox_write_sdw_samples : sox_read_sdw_samples;
       case SOX_ENCODING_UNSIGNED:
-        return write ? sox_udw_write_buf : sox_udw_read_buf;
+        return write ? sox_write_udw_samples : sox_read_udw_samples;
       case SOX_ENCODING_FLOAT:
-        return write ? sox_suf_write_buf : sox_suf_read_buf;
+        return write ? sox_write_suf_samples : sox_read_suf_samples;
       default:
         break;
       }
@@ -205,7 +307,7 @@
     case SOX_SIZE_64BIT:
       switch (ft->signal.encoding) {
       case SOX_ENCODING_FLOAT:
-        return write ? sox_sudf_write_buf : sox_sudf_read_buf;
+        return write ? sox_write_sudf_samples : sox_read_sudf_samples;
       default:
         break;
       }
--- a/src/sf.c
+++ b/src/sf.c
@@ -105,7 +105,7 @@
         }
         memcpy(&sf->info, &sfhead.sfinfo, sizeof(struct sfinfo));
         if (ft->signal.reverse_bytes) {
-                sf->info.sf_srate = sox_swapf(&sf->info.sf_srate);
+                sf->info.sf_srate = sox_swapf(sf->info.sf_srate);
                 sf->info.sf_packmode = sox_swapdw(sf->info.sf_packmode);
                 sf->info.sf_chans = sox_swapdw(sf->info.sf_chans);
         }
--- a/src/sox_i.h
+++ b/src/sox_i.h
@@ -105,11 +105,44 @@
 size_t sox_writebuf(ft_t ft, void const *buf, size_t size, sox_size_t len);
 int sox_reads(ft_t ft, char *c, sox_size_t len);
 int sox_writes(ft_t ft, char const * c);
-int sox_readdw(ft_t ft, uint32_t *udw);
+
+sox_size_t sox_read_ub_buf(ft_t ft, uint8_t *buf, sox_size_t len);
+sox_size_t sox_read_sb_buf(ft_t ft, int8_t *buf, sox_size_t len);
+sox_size_t sox_read_ulawb_buf(ft_t ft, uint8_t *buf, sox_size_t len);
+sox_size_t sox_read_alawb_buf(ft_t ft, uint8_t *buf, sox_size_t len);
+sox_size_t sox_read_uw_buf(ft_t ft, uint16_t *buf, sox_size_t len);
+sox_size_t sox_read_sw_buf(ft_t ft, int16_t *buf, sox_size_t len);
+sox_size_t sox_read_u3_buf(ft_t ft, uint24_t *buf, sox_size_t len);
+sox_size_t sox_read_s3_buf(ft_t ft, int24_t *buf, sox_size_t len);
+sox_size_t sox_read_udw_buf(ft_t ft, uint32_t *buf, sox_size_t len);
+sox_size_t sox_read_sdw_buf(ft_t ft, int32_t *buf, sox_size_t len);
+sox_size_t sox_read_suf_buf(ft_t ft, float *buf, sox_size_t len);
+sox_size_t sox_read_sudf_buf(ft_t ft, double *buf, sox_size_t len);
+
+sox_size_t sox_write_ub_buf(ft_t ft, uint8_t *buf, sox_size_t len);
+sox_size_t sox_write_sb_buf(ft_t ft, int8_t *buf, sox_size_t len);
+sox_size_t sox_write_ulawb_buf(ft_t ft, uint8_t *buf, sox_size_t len);
+sox_size_t sox_write_alawb_buf(ft_t ft, uint8_t *buf, sox_size_t len);
+sox_size_t sox_write_uw_buf(ft_t ft, uint16_t *buf, sox_size_t len);
+sox_size_t sox_write_sw_buf(ft_t ft, int16_t *buf, sox_size_t len);
+sox_size_t sox_write_u3_buf(ft_t ft, uint24_t *buf, sox_size_t len);
+sox_size_t sox_write_s3_buf(ft_t ft, int24_t *buf, sox_size_t len);
+sox_size_t sox_write_udw_buf(ft_t ft, uint32_t *buf, sox_size_t len);
+sox_size_t sox_write_sdw_buf(ft_t ft, int32_t *buf, sox_size_t len);
+sox_size_t sox_write_suf_buf(ft_t ft, float *buf, sox_size_t len);
+sox_size_t sox_write_sudf_buf(ft_t ft, double *buf, sox_size_t len);
+
+#define sox_readb(ft, ub) (sox_read_ub_buf(ft, ub, 1) == 1 ? SOX_SUCCESS : SOX_EOF)
+int sox_writeb(ft_t ft, uint8_t ub);
+#define sox_readw(ft, uw) (sox_read_uw_buf(ft, uw, 1) == 1 ? SOX_SUCCESS : SOX_EOF)
+int sox_writew(ft_t ft, uint16_t uw);
+#define sox_read3(ft, u3) (sox_read_u3_buf(ft, u3, 1) == 1 ? SOX_SUCCESS : SOX_EOF)
+int sox_write3(ft_t ft, uint24_t u3);
+#define sox_readdw(ft, udw) (sox_read_udw_buf(ft, udw, 1) == 1 ? SOX_SUCCESS : SOX_EOF)
 int sox_writedw(ft_t ft, uint32_t udw);
-int sox_readf(ft_t ft, float *f);
+#define sox_readf(ft, f) (sox_read_suf_buf(ft, f, 1) == 1 ? SOX_SUCCESS : SOX_EOF)
 int sox_writef(ft_t ft, float f);
-int sox_readdf(ft_t ft, double *d);
+#define sox_readdf(ft, d) (sox_read_sudf_buf(ft, d, 1) == 1 ? SOX_SUCCESS : SOX_EOF)
 int sox_writedf(ft_t ft, double d);
 int sox_seeki(ft_t ft, sox_size_t offset, int whence);
 sox_size_t sox_filelength(ft_t ft);
@@ -136,9 +169,9 @@
 #define sox_swapw(uw) (((uw >> 8) | (uw << 8)) & 0xffff)
 #define sox_swapdw(udw) ((udw >> 24) | ((udw >> 8) & 0xff00) | ((udw << 8) & 0xff0000) | (udw << 24))
 #endif
-float sox_swapf(float const * f);
-uint32_t sox_swap24(uint32_t udw);
-double sox_swapd(double d);
+float sox_swapf(float f);
+uint32_t sox_swap3(uint32_t udw);
+double sox_swapdf(double d);
 
 /* util.c */
 typedef void (*sox_output_message_handler_t)(int level, const char *filename, const char *fmt, va_list ap);
@@ -186,88 +219,6 @@
 extern const char sox_readerr[];
 extern const char sox_writerr[];
 extern uint8_t const cswap[256];
-
-/* Read byte. */
-UNUSED static int sox_readb(ft_t ft, uint8_t *ub)
-{
-  int ch1;
-  if ((ch1 = getc(ft->fp)) == EOF) {
-    sox_fail_errno(ft,errno,sox_readerr);
-    return SOX_EOF;
-  }
-  *ub = ft->signal.reverse_bits? cswap[ch1]: ch1;
-  if (ft->signal.reverse_nibbles)
-    *ub = ((*ub & 15) << 4) | (*ub >> 4);
-  return SOX_SUCCESS;
-}
-
-/* Write byte. */
-UNUSED static int sox_writeb(ft_t ft, int ub)
-{
-  if (ft->signal.reverse_nibbles)
-    ub = ((ub & 15) << 4) | (ub >> 4);
-  if (ft->signal.reverse_bits)
-    ub = cswap[ub];
-  if (putc(ub, ft->fp) == EOF) {
-    sox_fail_errno(ft,errno,sox_writerr);
-    return SOX_EOF;
-  }
-  return SOX_SUCCESS;
-}
-
-/* Read word. */
-UNUSED static int sox_readw(ft_t ft, uint16_t *uw)
-{
-  char * c = (char *)uw;
-  int ch1, ch2;
-  if ((ch1 = getc(ft->fp)) == EOF || (ch2 = getc(ft->fp)) == EOF) {
-    sox_fail_errno(ft,errno,sox_readerr);
-    return SOX_EOF;
-  }
-  c[SOX_IS_BIGENDIAN    ^ ft->signal.reverse_bytes] = ch1;
-  c[SOX_IS_LITTLEENDIAN ^ ft->signal.reverse_bytes] = ch2;
-  return SOX_SUCCESS;
-}
-
-/* Write word. */
-UNUSED static int sox_writew(ft_t ft, int uw)
-{
-  char * c = (char *)&uw;
-  if (putc(c[SOX_IS_BIGENDIAN    ^ ft->signal.reverse_bytes], ft->fp) == EOF ||
-      putc(c[SOX_IS_LITTLEENDIAN ^ ft->signal.reverse_bytes], ft->fp) == EOF) {
-    sox_fail_errno(ft,errno,sox_writerr);
-    return SOX_EOF;
-  }
-  return SOX_SUCCESS;
-}
-
-/* Read three bytes. */
-UNUSED static int sox_read3(ft_t ft, uint24_t *u3)
-{
-  char * c = (char *)u3;
-  int ch1, ch2, ch3;
-  if ((ch1 = getc(ft->fp)) == EOF || (ch2 = getc(ft->fp)) == EOF || (ch3 = getc(ft->fp)) == EOF) {
-    sox_fail_errno(ft,errno,sox_readerr);
-    return SOX_EOF;
-  }
-  c[(SOX_IS_BIGENDIAN    ^ ft->signal.reverse_bytes)<<1] = ch1;
-  c[1] = ch2;
-  c[(SOX_IS_LITTLEENDIAN ^ ft->signal.reverse_bytes)<<1] = ch3;
-  return SOX_SUCCESS;
-}
-
-/* Write three bytes. */
-UNUSED static int sox_write3(ft_t ft, uint24_t u3)
-{
-  char * c = (char *)&u3;
-  if (putc(c[(SOX_IS_BIGENDIAN    ^ ft->signal.reverse_bytes)<<1], ft->fp) == EOF ||
-      putc(c[1], ft->fp) == EOF ||
-      putc(c[(SOX_IS_LITTLEENDIAN ^ ft->signal.reverse_bytes)<<1], ft->fp) == EOF) {
-    sox_fail_errno(ft,errno,sox_writerr);
-    return SOX_EOF;
-  }
-  return SOX_SUCCESS;
-}
 
 /*=============================================================================
  * File Handlers