shithub: sox

Download patch

ref: 8446fc532f2c32005d7fab57a93f5c0b13e7ad12
parent: 82528814c05f863eb65157fa9238a94f5d3847b5
author: robs <robs>
date: Sat Oct 25 07:50:47 EDT 2008

further support for multiple input pipes

--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -28,30 +28,30 @@
 
 # Format with: !xargs echo|tr ' ' '\n'|sort|column|expand|sed 's/^/  /'
 set(effects_srcs
-  bend            earwax          mcompand        polyphas        splice
-  biquad          echo            mixer           rate            stat
-  biquads         echos           noiseprof       remix           swap
-  chorus          fade            noisered        repeat          synth
-  compand         fft4g           normalise       resample        tempo
-  compandt                        output          reverb          tremolo
-  contrast        filter          pad             reverse         trim
-  dcshift         flanger         pan             silence         vol
-  delay           input           phaser          skeleff stretch
-  dither          loudness        pitch           speed
+  bend            earwax          mixer           rate            stat
+  biquad          echo            noiseprof       remix           stretch
+  biquads         echos           noisered        repeat          swap
+  chorus          fade            normalise       resample        synth
+  compand         fft4g           output          reverb          tempo
+  compandt        filter          pad             reverse         tremolo
+  contrast        flanger         pan             silence         trim
+  dcshift         input           phaser          skeleff         vol
+  delay           loudness        pitch           speed
+  dither          mcompand        polyphas        splice
 )
 set(formats_srcs
-  8svx            dat             ima-fmt         s3-fmt          u4-fmt
-  adpcm           dvms-fmt        ima_rw          s4-fmt          ul-fmt
-  adpcms          f4-fmt          la-fmt          sf              voc
-  aifc-fmt        f8-fmt          lpc10.c         skelform        vox
-  aiff            g711            lu-fmt          smp             vox-fmt
-  aiff-fmt        g721            maud            sounder         wav
-  al-fmt          g723_24         nulfile         soundtool       wve
-  au              g723_40         prc             sphere          xa
-  avr             g72x            raw             tx16w
-  cdr             gsm.c           raw-fmt         u1-fmt
-  cvsd            hcom            s1-fmt          u2-fmt
-  cvsd-fmt        htk             s2-fmt          u3-fmt
+  8svx            dat             ima-fmt         s3-fmt          u3-fmt
+  adpcm           dvms-fmt        ima_rw          s4-fmt          u4-fmt
+  adpcms          f4-fmt          la-fmt          sf              ul-fmt
+  aifc-fmt        f8-fmt          lpc10.c         skelform        voc
+  aiff            g711            lu-fmt          smp             vox
+  aiff-fmt        g721            maud            sounder         vox-fmt
+  al-fmt          g723_24         nulfile         soundtool       wav
+  au              g723_40         prc             sox-fmt         wve
+  avr             g72x            raw             sphere          xa
+  cdr             gsm.c           raw-fmt         tx16w
+  cvsd            hcom            s1-fmt          u1-fmt
+  cvsd-fmt        htk             s2-fmt          u2-fmt
 )
 add_library(lib${PROJECT_NAME}
   effects                 ${formats_srcs}         ${optional_srcs}
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -258,7 +258,7 @@
 	  g711.c g711.h g721.c g723_24.c g723_40.c g72x.c g72x.h vox.c vox.h \
 	  raw.c raw.h formats.c formats.h formats_i.c sox_i.h skelform.c \
 	  xmalloc.c xmalloc.h getopt.c getopt1.c getopt.h \
-	  util.c util.h libsox.c libsox_i.c
+	  util.c util.h libsox.c libsox_i.c sox-fmt.c
 
 # Effects source
 libsox_la_SOURCES += \
--- a/src/formats.c
+++ b/src/formats.c
@@ -445,7 +445,11 @@
       }
     }
     else {
-      if (!(filetype = lsx_find_file_extension(path))) {
+      if (ft->io_type == lsx_io_pipe) {
+        filetype = "sox";
+        lsx_report("assuming input pipe `%s' has file-type `sox'", path);
+      }
+      else if (!(filetype = lsx_find_file_extension(path))) {
         lsx_fail("can't determine type of `%s'", path);
         goto error;
       }
@@ -781,7 +785,7 @@
     ft->signal.length = ft->signal.length * ft->signal.rate / signal->rate *
       ft->signal.channels / signal->channels + .5;
 
-  if ((ft->handler.flags & SOX_FILE_REWIND) && !ft->signal.length && !ft->seekable)
+  if ((ft->handler.flags & SOX_FILE_REWIND) && strcmp(ft->filetype, "sox") && !ft->signal.length && !ft->seekable)
     lsx_warn("can't seek in output file `%s'; length in file header will be unspecified", ft->filename);
 
   ft->priv = lsx_calloc(1, ft->handler.priv_size);
@@ -992,7 +996,10 @@
 
 int sox_format_init(void) /* Find & load format handlers.  */
 {
+  sox_format_handler_t const * sox_sox_format_fn(void);
   int ret;
+
+  sox_format_fns[nformats++].fn = sox_sox_format_fn;
 
   if ((ret = lt_dlinit()) != 0) {
     lsx_fail("lt_dlinit failed with %d error(s): %s", ret, lt_dlerror());
--- a/src/formats.h
+++ b/src/formats.h
@@ -48,6 +48,7 @@
   FORMAT(smp)
   FORMAT(sounder)
   FORMAT(soundtool)
+  FORMAT(sox)
   FORMAT(sphere)
   FORMAT(svx)
   FORMAT(txw)
--- a/src/formats_i.c
+++ b/src/formats_i.c
@@ -272,22 +272,30 @@
     *f = u.f;
 }
 
-/* generic swap routine. Swap l and place in to f (datatype length = n) */
-static void swap(char const * l, char * f, size_t n)
+static void swap(void * data, size_t len)
 {
-    size_t i;
+  uint8_t * bytes = (uint8_t *)data;
+  size_t i;
 
-    for (i= 0; i< n; i++)
-        f[i]= l[n-i-1];
+  for (i = 0; i < len / 2; ++i) {
+    char tmp = bytes[i];
+    bytes[i] = bytes[len - 1 - i];
+    bytes[len - 1 - i] = tmp;
+  }
 }
 
-static double lsx_swapdf(double df)
+static double lsx_swapdf(double data)
 {
-    double sdf;
-    swap((char *)&df, (char *)&sdf, (size_t) sizeof(double));
-    return (sdf);
+  swap(&data, sizeof(data));
+  return data;
 }
 
+static uint64_t lsx_swapqw(uint64_t data)
+{
+  swap(&data, sizeof(data));
+  return data;
+}
+
 /* Lookup table to reverse the bit order of a byte. ie MSB become LSB */
 static uint8_t const cswap[256] = {
   0x00, 0x80, 0x40, 0xC0, 0x20, 0xA0, 0x60, 0xE0, 0x10, 0x90, 0x50, 0xD0,
@@ -368,6 +376,7 @@
 READ_FUNC(w, 2, uint16_t, TWIDDLE_WORD)
 READ_FUNC_UNPACK(3, 3, uint24_t, TWIDDLE_WORD)
 READ_FUNC(dw, 4, uint32_t, TWIDDLE_WORD)
+READ_FUNC(qw, 8, uint64_t, TWIDDLE_WORD)
 READ_FUNC(f, sizeof(float), float, TWIDDLE_FLOAT)
 READ_FUNC(df, sizeof(double), double, TWIDDLE_WORD)
 
@@ -386,6 +395,7 @@
 READ1_FUNC(w,  uint16_t)
 READ1_FUNC(3,  uint24_t)
 READ1_FUNC(dw, uint32_t)
+READ1_FUNC(qw, uint64_t)
 READ1_FUNC(f,  float)
 READ1_FUNC(df, double)
 
@@ -437,6 +447,7 @@
 WRITE_FUNC(w, 2, uint16_t, TWIDDLE_WORD)
 WRITE_FUNC_PACK(3, 3, uint24_t, TWIDDLE_WORD)
 WRITE_FUNC(dw, 4, uint32_t, TWIDDLE_WORD)
+WRITE_FUNC(qw, 8, uint64_t, TWIDDLE_WORD)
 WRITE_FUNC(f, sizeof(float), float, TWIDDLE_FLOAT)
 WRITE_FUNC(df, sizeof(double), double, TWIDDLE_WORD)
 
@@ -462,6 +473,7 @@
 WRITE1U_FUNC(w, uint16_t)
 WRITE1U_FUNC(3, uint24_t)
 WRITE1U_FUNC(dw, uint32_t)
+WRITE1_FUNC(qw, uint64_t)
 WRITE1S_FUNC(b, uint8_t)
 WRITE1S_FUNC(w, uint16_t)
 WRITE1_FUNC(df, double)
--- /dev/null
+++ b/src/sox-fmt.c
@@ -1,0 +1,91 @@
+/* libSoX file format: SoX temporary   (c) 2008 robs@users.sourceforge.net
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or (at
+ * your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#include "sox_i.h"
+#include <string.h>
+
+static char const magic[4] = ".SoX";
+#define FIXED_HDR     (4 + 4 + 8 + 8 + 4)
+
+static int startread(sox_format_t * ft)
+{
+  char     magic_[sizeof(magic)];
+  uint32_t hdr_size;
+  uint64_t data_size;
+  double   rate;
+  uint32_t channels;
+
+  if (lsx_readchars(ft, magic_, sizeof(magic)))
+    return SOX_EOF;
+
+  if (memcmp(magic, magic_, sizeof(magic))) {
+    lsx_fail_errno(ft, SOX_EHDR, "can't find sox file format identifier");
+    return SOX_EOF;
+  }
+  if (lsx_readdw(ft, &hdr_size) ||
+      lsx_readqw(ft, &data_size) ||
+      lsx_readdf(ft, &rate) ||
+      lsx_readdw(ft, &channels))
+    return SOX_EOF;
+
+  if (hdr_size < FIXED_HDR) {
+    lsx_fail_errno(ft, SOX_EHDR, "header size %u is too small", hdr_size);
+    return SOX_EOF;
+  }
+
+  if (hdr_size > FIXED_HDR) {
+    size_t info_size = hdr_size - FIXED_HDR;
+    char * buf = lsx_calloc(1, info_size + 1); /* +1 ensures null-terminated */
+    if (lsx_readchars(ft, buf, info_size) != SOX_SUCCESS) {
+      free(buf);
+      return SOX_EOF;
+    }
+    sox_append_comments(&ft->oob.comments, buf);
+    free(buf);
+  }
+  return lsx_check_read_params(
+      ft, channels, rate, SOX_ENCODING_SIGN2, 32, (off_t)data_size);
+}
+
+static int write_header(sox_format_t * ft)
+{
+  char * comment  = lsx_cat_comments(ft->oob.comments);
+  size_t len      = strlen(comment) + 1;     /* Write out null-terminated */
+  size_t info_len = max(4, (len + 3) & ~3u); /* Minimum & multiple of 4 bytes */
+  uint64_t size   = ft->olength? ft->olength : ft->signal.length;
+  sox_bool error  = sox_false
+  ||lsx_writechars(ft, magic, sizeof(magic))
+  ||lsx_writedw(ft, FIXED_HDR + (unsigned)info_len)
+  ||lsx_writeqw(ft, size)
+  ||lsx_writedf(ft, ft->signal.rate)
+  ||lsx_writedw(ft, ft->signal.channels)
+  ||lsx_writechars(ft, comment, len)
+  ||lsx_padbytes(ft, info_len - len);
+  free(comment);
+  return error? SOX_EOF: SOX_SUCCESS;
+}
+
+SOX_FORMAT_HANDLER(sox)
+{
+  static char const * const names[] = {"sox", NULL};
+  static unsigned const write_encodings[] = {SOX_ENCODING_SIGN2, 32, 0, 0};
+  static sox_format_handler_t const handler = {SOX_LIB_VERSION_CODE,
+    "SoX temporary", names, SOX_FILE_REWIND, startread, lsx_rawread, NULL,
+    write_header, lsx_rawwrite, NULL, lsx_rawseek, write_encodings, NULL, 0
+  };
+  return &handler;
+}
--- a/src/sox.c
+++ b/src/sox.c
@@ -1588,8 +1588,9 @@
   static char const * lines[] = {
 "SPECIAL FILENAMES (infile, outfile):",
 "-                        Pipe/redirect input/output (stdin/stdout); use with -t",
-"-d                       Use the default audio device (where available)",
-"-n                       Use the `null' file handler; e.g. with synth effect",
+"-d, --default-device     Use the default audio device (where available)",
+"-n, --null               Use the `null' file handler; e.g. with synth effect",
+"-p, --pipe               Alias for `-t sox -'",
 "http://server/file       Use the given URL as input file (where supported)",
 "",
 "GLOBAL OPTIONS (gopts) (can be specified at any point before the first effect):",
@@ -1785,7 +1786,7 @@
   free(text);
 }
 
-static char *getoptstr = "+ab:c:de:fghimnoqr:st:uv:xABC:LMNRSTUV::X12348";
+static char *getoptstr = "+ab:c:de:fghimnopqr:st:uv:xABC:LMNRSTUV::X12348";
 
 static struct option long_options[] =
   {
@@ -1808,9 +1809,12 @@
     {"bits"            , required_argument, NULL, 'b'},
     {"channels"        , required_argument, NULL, 'c'},
     {"compression"     , required_argument, NULL, 'C'},
+    {"default-device"  ,       no_argument, NULL, 'd'},
     {"encoding"        , required_argument, NULL, 'e'},
     {"help"            ,       no_argument, NULL, 'h'},
+    {"null"            ,       no_argument, NULL, 'n'},
     {"no-show-progress",       no_argument, NULL, 'q'},
+    {"pipe"            ,       no_argument, NULL, 'p'},
     {"rate"            , required_argument, NULL, 'r'},
     {"reverse-bits"    ,       no_argument, NULL, 'X'},
     {"reverse-nibbles" ,       no_argument, NULL, 'N'},
@@ -1989,7 +1993,7 @@
       sox_globals.repeatable = sox_true;
       break;
 
-    case 'd': case 'n':
+    case 'd': case 'n': case 'p':
       return c;
       break;
 
@@ -2195,6 +2199,12 @@
     }
     else if (c == 'd') /* is default device? */
       add_file(&opts, set_default_device(&opts));
+    else if (c == 'p') { /* is sox pipe? */
+      if (opts.filetype != NULL && strcmp(opts.filetype, "sox") != 0)
+        lsx_warn("ignoring `-t %s'.", opts.filetype);
+      opts.filetype = "sox";
+      add_file(&opts, "-");
+    }
     else if (optind >= argc || sox_find_effect(argv[optind]))
       break;
     else if (!sox_is_playlist(argv[optind]))
--- a/src/sox_i.h
+++ b/src/sox_i.h
@@ -124,6 +124,7 @@
 size_t lsx_read_b_buf(sox_format_t * ft, uint8_t *buf, size_t len);
 size_t lsx_read_df_buf(sox_format_t * ft, double *buf, size_t len);
 size_t lsx_read_dw_buf(sox_format_t * ft, uint32_t *buf, size_t len);
+size_t lsx_read_qw_buf(sox_format_t * ft, uint64_t *buf, size_t len);
 size_t lsx_read_f_buf(sox_format_t * ft, float *buf, size_t len);
 size_t lsx_read_w_buf(sox_format_t * ft, uint16_t *buf, size_t len);
 
@@ -131,6 +132,7 @@
 size_t lsx_write_b_buf(sox_format_t * ft, uint8_t *buf, size_t len);
 size_t lsx_write_df_buf(sox_format_t * ft, double *buf, size_t len);
 size_t lsx_write_dw_buf(sox_format_t * ft, uint32_t *buf, size_t len);
+size_t lsx_write_qw_buf(sox_format_t * ft, uint64_t *buf, size_t len);
 size_t lsx_write_f_buf(sox_format_t * ft, float *buf, size_t len);
 size_t lsx_write_w_buf(sox_format_t * ft, uint16_t *buf, size_t len);
 
@@ -139,6 +141,7 @@
 int lsx_readchars(sox_format_t * ft, char * chars, size_t len);
 int lsx_readdf(sox_format_t * ft, double * d);
 int lsx_readdw(sox_format_t * ft, uint32_t * udw);
+int lsx_readqw(sox_format_t * ft, uint64_t * udw);
 int lsx_readf(sox_format_t * ft, float * f);
 int lsx_readw(sox_format_t * ft, uint16_t * uw);
 
@@ -151,6 +154,7 @@
 int lsx_writeb(sox_format_t * ft, unsigned ub);
 int lsx_writedf(sox_format_t * ft, double d);
 int lsx_writedw(sox_format_t * ft, unsigned udw);
+int lsx_writeqw(sox_format_t * ft, uint64_t uqw);
 int lsx_writef(sox_format_t * ft, double f);
 int lsx_writew(sox_format_t * ft, unsigned uw);