shithub: sox

Download patch

ref: e6e323a4f546a8039c2ac5ccc54b722464628c13
parent: 6033bc8ce50cfc29ec186fb6fa0e3c3c96f21329
author: rrt <rrt>
date: Thu May 31 15:58:15 EDT 2007

Update ladspa effect to work as source or sink.

Move some effects code into effects.c and the handlers table. Try to
make libsfx and libsox independent.

Bug-fix to wav-reading on big-endian machines, I hope.

--- a/soxeffect.7
+++ b/soxeffect.7
@@ -419,8 +419,9 @@
 Music Toolkit) and Steve Harris's plugin collection [7]. The first
 argument is the plugin module, the second the name of the plugin (a
 module can contain more than one plugin) and any other arguments are
-for the control ports of the plugin. Only plugins with precisely one
-input and one output port can be used at present.
+for the control ports of the plugin. Missing arguments are supplied by
+default values if possible. Only plugins with at most one audio input
+and one audio output port can be used.
 .TP
 \fBlowpass\fR [\fB-1\fR|\fB-2\fR] \fIfrequency\fR [\fRwidth\fR[\fBq\fR\^|\^\fBo\fR\^|\^\fBh\fR]]
 Apply a low-pass filter.
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -172,21 +172,20 @@
 
 libsfx_la_SOURCES = band.h biquad.c biquad.h biquads.c chorus.c compand.c	\
 	  compandt.c compandt.h dcshift.c dither.c earwax.c echo.c echos.c	\
-	  fade.c FFT.c FFT.h filter.c flanger.c ladspa.c mcompand.c	\
-	  mixer.c noiseprof.c noisered.c noisered.h pad.c pan.c		\
-	  phaser.c pitch.c polyphas.c rabbit.c rate.c repeat.c		\
+	  effects.c fade.c FFT.c FFT.h filter.c flanger.c ladspa.c	\
+	  mcompand.c mixer.c noiseprof.c noisered.c noisered.h pad.c	\
+	  pan.c phaser.c pitch.c polyphas.c rabbit.c rate.c repeat.c	\
 	  resample.c reverb.c reverse.c silence.c skeleff.c speed.c	\
-	  stat.c stretch.c swap.c synth.c tremolo.c trim.c	\
-	  vibro.c vol.c
+	  stat.c stretch.c swap.c synth.c tremolo.c trim.c vibro.c	\
+	  vol.c
 libsfx_la_CFLAGS = @SAMPLERATE_CFLAGS@
 libsfx_la_LIBADD = @SAMPLERATE_LIBS@
 
 libsox_la_SOURCES = adpcms.c adpcms.h aiff.c aiff.h cvsd.c cvsd.h cvsdfilt.h \
 	  g711.c g711.h g721.c g723_24.c g723_40.c g72x.c g72x.h vox.c vox.h	\
-	  raw.c raw.h handlers.c misc.c sox_i.h skelform.c soxio.c	\
+	  raw.c raw.h formats.c misc.c sox_i.h skelform.c soxio.c	\
 	  util.c xmalloc.c xmalloc.h getopt.c getopt1.c getopt.h	\
-	  soxconfig.h effects.c
-libsox_la_LIBADD = libsfx.la
+	  soxconfig.h
 
 sox_SOURCES = sox.c
 sox_LDADD = libsox.la
--- a/src/effects.c
+++ b/src/effects.c
@@ -1,4 +1,7 @@
 /*
+ * SoX Effects chain
+ * (c) 2007 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 of the License, or (at
@@ -14,14 +17,132 @@
  * Fifth Floor, 51 Franklin Street, Boston, MA 02111-1301, USA.
  */
 
-/* SoX Effects chain   (c) 2007 robs@users.sourceforge.net */
-
 #include "sox_i.h"
+#include <assert.h>
+#include <string.h>
+#include <strings.h>
 
+/* dummy effect routine for do-nothing functions */
+static int effect_nothing(sox_effect_t * effp UNUSED)
+{
+  return SOX_SUCCESS;
+}
+
+static int effect_nothing_flow(sox_effect_t * effp UNUSED, const sox_ssample_t *ibuf UNUSED, sox_ssample_t *obuf UNUSED, sox_size_t *isamp, sox_size_t *osamp)
+{
+  /* Pass through samples verbatim */
+  *isamp = *osamp = min(*isamp, *osamp);
+  memcpy(obuf, ibuf, *isamp * sizeof(sox_ssample_t));
+  return SOX_SUCCESS;
+}
+
+static int effect_nothing_drain(sox_effect_t * effp UNUSED, sox_ssample_t *obuf UNUSED, sox_size_t *osamp)
+{
+  /* Inform no more samples to drain */
+  *osamp = 0;
+  return SOX_EOF;
+}
+
+static int effect_nothing_getopts(sox_effect_t * effp, int n, char **argv UNUSED)
+{
+#undef sox_fail
+#define sox_fail sox_message_filename=effp->handler.name,sox_fail
+  if (n) {
+    sox_fail(effp->handler.usage);
+    return (SOX_EOF);
+  }
+  return (SOX_SUCCESS);
+#undef sox_fail
+}
+
+
+/* Effect chain routines */
+
+sox_effect_handler_t const * sox_find_effect(char const * name)
+{
+  int i;
+
+  for (i = 0; sox_effect_fns[i]; ++i) {
+    const sox_effect_handler_t *e = sox_effect_fns[i] ();
+    if (e && e->name && strcasecmp(e->name, name) == 0)
+      return e;                 /* Found it. */
+  }
+  return NULL;
+}
+
+void sox_create_effect(sox_effect_t * effp, sox_effect_handler_t const * e)
+{
+  assert(e);
+  memset(effp, 0, sizeof(*effp));
+  effp->global_info = &effects_global_info;
+  effp->handler = *e;
+  if (!effp->handler.getopts) effp->handler.getopts = effect_nothing_getopts;
+  if (!effp->handler.start) effp->handler.start = effect_nothing;
+  if (!effp->handler.flow) effp->handler.flow = effect_nothing_flow;
+  if (!effp->handler.drain) effp->handler.drain = effect_nothing_drain;
+  if (!effp->handler.stop) effp->handler.stop = effect_nothing;
+  if (!effp->handler.kill) effp->handler.kill = effect_nothing;
+}
+
+/*
+ * Copy input and output signal info into effect structures.
+ * Must pass in a bitmask containing info on whether SOX_EFF_CHAN
+ * or SOX_EFF_RATE has been used previously on this effect stream.
+ * If not running multiple effects then just pass in a value of 0.
+ *
+ * Return value is the same mask plus addition of SOX_EFF_CHAN or
+ * SOX_EFF_RATE if it was used in this effect.  That make this
+ * return value can be passed back into this function in future
+ * calls.
+ */
+
+int sox_update_effect(sox_effect_t * effp, const sox_signalinfo_t *in, const sox_signalinfo_t *out, 
+                    int effect_mask)
+{
+    effp->ininfo = *in;
+    effp->outinfo = *out;
+
+    if (in->channels != out->channels) {
+      /* Only effects with SOX_EFF_CHAN flag can actually handle
+       * outputing a different number of channels then the input.
+       */
+      if (!(effp->handler.flags & SOX_EFF_CHAN)) {
+        /* If this effect is being run before a SOX_EFF_CHAN effect
+         * then its output is the same as the input file; otherwise,
+         * its input contains the same number of channels as the
+         * output file. */
+        if (effect_mask & SOX_EFF_CHAN)
+          effp->ininfo.channels = out->channels;
+        else
+          effp->outinfo.channels = in->channels;
+      }
+    }
+
+    if (in->rate != out->rate)
+    {
+        /* Only SOX_EFF_RATE effects can handle an input that
+         * has a different sample rate from the output. */
+        if (!(effp->handler.flags & SOX_EFF_RATE))
+        {
+            if (effect_mask & SOX_EFF_RATE)
+                effp->ininfo.rate = out->rate;
+            else
+                effp->outinfo.rate = in->rate;
+        }
+    }
+
+    if (effp->handler.flags & SOX_EFF_CHAN)
+        effect_mask |= SOX_EFF_CHAN;
+    if (effp->handler.flags & SOX_EFF_RATE)
+        effect_mask |= SOX_EFF_RATE;
+
+    return effect_mask;
+}
+
+
 sox_effect_t * sox_effects[SOX_MAX_EFFECTS];
 unsigned sox_neffects;
 
-
 int sox_add_effect(sox_effect_t * e, sox_signalinfo_t * in, sox_signalinfo_t * out, int * effects_mask)
 {
   unsigned f, flows;
@@ -276,3 +397,66 @@
   while (sox_neffects)
     free(sox_effects[--sox_neffects]);
 }
+
+
+/* Effects handlers. */
+
+/* FIXME: Generate this list automatically */
+sox_effect_fn_t sox_effect_fns[] = {
+  sox_allpass_effect_fn,
+  sox_avg_effect_fn,
+  sox_band_effect_fn,
+  sox_bandpass_effect_fn,
+  sox_bandreject_effect_fn,
+  sox_bass_effect_fn,
+  sox_chorus_effect_fn,
+  sox_compand_effect_fn,
+  sox_dcshift_effect_fn,
+  sox_deemph_effect_fn,
+  sox_dither_effect_fn,
+  sox_earwax_effect_fn,
+  sox_echo_effect_fn,
+  sox_echos_effect_fn,
+  sox_equalizer_effect_fn,
+  sox_fade_effect_fn,
+  sox_filter_effect_fn,
+  sox_flanger_effect_fn,
+  sox_highpass_effect_fn,
+  sox_highp_effect_fn,
+#ifdef HAVE_LADSPA_H
+  sox_ladspa_effect_fn,
+#endif
+  sox_lowpass_effect_fn,
+  sox_lowp_effect_fn,
+  sox_mask_effect_fn,
+  sox_mcompand_effect_fn,
+  sox_mixer_effect_fn,
+  sox_noiseprof_effect_fn,
+  sox_noisered_effect_fn,
+  sox_pad_effect_fn,
+  sox_pan_effect_fn,
+  sox_phaser_effect_fn,
+  sox_pick_effect_fn,
+  sox_pitch_effect_fn,
+  sox_polyphase_effect_fn,
+#ifdef HAVE_SAMPLERATE_H
+  sox_rabbit_effect_fn,
+#endif
+  sox_rate_effect_fn,
+  sox_repeat_effect_fn,
+  sox_resample_effect_fn,
+  sox_reverb_effect_fn,
+  sox_reverse_effect_fn,
+  sox_silence_effect_fn,
+  sox_speed_effect_fn,
+  sox_stat_effect_fn,
+  sox_stretch_effect_fn,
+  sox_swap_effect_fn,
+  sox_synth_effect_fn,
+  sox_treble_effect_fn,
+  sox_tremolo_effect_fn,
+  sox_trim_effect_fn,
+  sox_vibro_effect_fn,
+  sox_vol_effect_fn,
+  NULL
+};
--- /dev/null
+++ b/src/formats.c
@@ -1,0 +1,29 @@
+/*
+ * Originally created: July 5, 1991
+ * Copyright 1991 Lance Norskog And Sundry Contributors
+ * This source code is freely redistributable and may be used for
+ * any purpose.  This copyright notice must be maintained.
+ * Lance Norskog And Sundry Contributors are not responsible for
+ * the consequences of using this software.
+ */
+
+#include "sox_i.h"
+
+/* File format handlers. */
+
+#ifdef HAVE_LTDL_H
+/* FIXME: Use a vector, not a fixed-size array */
+  #define MAX_FORMATS 256
+  unsigned sox_formats = 0;
+  sox_format_tab_t sox_format_fns[MAX_FORMATS];
+#else
+  #define FORMAT(f) extern sox_format_t const * sox_##f##_format_fn(void);
+  #include "formats.h"
+  #undef FORMAT
+  sox_format_tab_t sox_format_fns[] = {
+  #define FORMAT(f) {0, sox_##f##_format_fn},
+  #include "formats.h"
+  #undef FORMAT
+  };
+  unsigned sox_formats = array_length(sox_format_fns);
+#endif 
--- a/src/ladspa.c
+++ b/src/ladspa.c
@@ -24,6 +24,7 @@
 #include <assert.h>
 #include <limits.h>
 #include <string.h>
+#include <math.h>
 #include <ltdl.h>
 #include <ladspa.h>
 
@@ -39,6 +40,46 @@
   unsigned long input_port, output_port;
 } *ladspa_t;
 
+static LADSPA_Data ladspa_default(const LADSPA_PortRangeHint *p)
+{
+  LADSPA_Data d;
+  
+  if (LADSPA_IS_HINT_DEFAULT_0(p->HintDescriptor))
+    d = 0.0;
+  else if (LADSPA_IS_HINT_DEFAULT_1(p->HintDescriptor))
+    d = 1.0;
+  else if (LADSPA_IS_HINT_DEFAULT_100(p->HintDescriptor))
+    d = 100.0;
+  else if (LADSPA_IS_HINT_DEFAULT_440(p->HintDescriptor))
+    d = 440.0;
+  else if (LADSPA_IS_HINT_DEFAULT_MINIMUM(p->HintDescriptor))
+    d = p->LowerBound;
+  else if (LADSPA_IS_HINT_DEFAULT_MAXIMUM(p->HintDescriptor))
+    d = p->UpperBound;
+  else if (LADSPA_IS_HINT_DEFAULT_LOW(p->HintDescriptor)) {
+    if (LADSPA_IS_HINT_LOGARITHMIC(p->HintDescriptor))
+      d = exp(log(p->LowerBound) * 0.75 + log(p->UpperBound) * 0.25);
+    else
+      d = p->LowerBound * 0.75 + p->UpperBound * 0.25;
+  } else if (LADSPA_IS_HINT_DEFAULT_MIDDLE(p->HintDescriptor)) {
+    if (LADSPA_IS_HINT_LOGARITHMIC(p->HintDescriptor))
+      d = exp(log(p->LowerBound) * 0.5 + log(p->UpperBound) * 0.5);
+    else
+      d = p->LowerBound * 0.5 + p->UpperBound * 0.5;
+  } else if (LADSPA_IS_HINT_DEFAULT_HIGH(p->HintDescriptor)) {
+    if (LADSPA_IS_HINT_LOGARITHMIC(p->HintDescriptor))
+      d = exp(log(p->LowerBound) * 0.25 + log(p->UpperBound) * 0.75);
+    else
+      d = p->LowerBound * 0.25 + p->UpperBound * 0.75;
+  } else { /* shouldn't happen */
+    /* FIXME: Deal with this at a higher level */
+    sox_fail("non-existent default value; using 0.1");
+    d = 0.1; /* Should at least avoid divide by 0 */
+  }
+
+  return d;
+}
+
 /*
  * Process options
  */
@@ -48,7 +89,6 @@
   char *path;
   LADSPA_Descriptor_Function l_fn;
   unsigned long index = 0, i;
-  unsigned long audio_ports = 0;
   double arg;
 
   l_st->input_port = ULONG_MAX;
@@ -88,7 +128,7 @@
 
   /* If more than one plugin, or first argument is not a number, try
      to use first argument as plugin label. */
-  if (l_fn(1) != NULL || !sscanf(argv[0], "%lf", &arg)) {
+  if (n > 0 && (l_fn(1) != NULL || !sscanf(argv[0], "%lf", &arg))) {
     while (l_st->desc && strcmp(l_st->desc->Label, argv[0]) != 0)
       l_st->desc = l_fn(++index);
     if (l_st->desc == NULL) {
@@ -98,14 +138,6 @@
       n--; argv++;
   }
 
-
-  /* Instantiate the plugin */
-  l_st->handle = l_st->desc->instantiate(l_st->desc, effp->ininfo.rate);
-  if (l_st->handle == NULL) {
-    sox_fail("could not instantiate plugin");
-    return SOX_EOF;
-  }
-
   /* Scan the ports to check there's one input and one output */
   l_st->control = xcalloc(l_st->desc->PortCount, sizeof(LADSPA_Data));
   for (i = 0; i < l_st->desc->PortCount; i++) {
@@ -122,44 +154,39 @@
     }
                
     if (LADSPA_IS_PORT_AUDIO(port)) {
-      audio_ports++;
-      if (audio_ports > 2) {
-        sox_fail("can't use a plugin with more than two audio ports");
-        return SOX_EOF;
-      }
-
-      /* Don't bother counting input and output ports, as if we have
-         too many or not enough we'll find out anyway */
-      if (LADSPA_IS_PORT_INPUT(port))
+      if (LADSPA_IS_PORT_INPUT(port)) {
+        if (l_st->input_port != ULONG_MAX) {
+          sox_fail("can't use a plugin with more than one audio input port");
+          return SOX_EOF;
+        }
         l_st->input_port = i;
-      else if (LADSPA_IS_PORT_OUTPUT(port))
+      } else if (LADSPA_IS_PORT_OUTPUT(port)) {
+        if (l_st->output_port != ULONG_MAX) {
+          sox_fail("can't use a plugin with more than one audio output port");
+          return SOX_EOF;
+        }
         l_st->output_port = i;
+      }
     } else {                    /* Control port */
       if (n == 0) {
-        sox_fail("not enough arguments for control ports");
-        return SOX_EOF;
+        if (!LADSPA_IS_HINT_HAS_DEFAULT(l_st->desc->PortRangeHints[i].HintDescriptor)) {
+          sox_fail("not enough arguments for control ports");
+          return SOX_EOF;
+        }
+        l_st->control[i] = ladspa_default(&(l_st->desc->PortRangeHints[i]));
+        sox_debug("default argument for port %d is %f", i, l_st->control[i]);
+      } else {
+        if (!sscanf(argv[0], "%lf", &arg)) {
+          sox_fail(effp->handler.usage);
+          return SOX_EOF;
+        }
+        l_st->control[i] = (LADSPA_Data)arg;
+        sox_debug("argument for port %d is %f", i, l_st->control[i]);
+        n--; argv++;
       }
-      if (!sscanf(argv[0], "%lf", &arg)) {
-        sox_fail(effp->handler.usage);
-        return SOX_EOF;
-      }
-      l_st->control[i] = (LADSPA_Data)arg;
-      sox_debug("argument for port %d is %f", i, l_st->control[i]);
-      n--; argv++;
-      l_st->desc->connect_port(l_st->handle, i, &(l_st->control[i]));
     }
   }
 
-  /* FIXME: allow use of source and sink plugins; needs a design
-     change to allow an effect to be a source or sink */
-  if (l_st->input_port == ULONG_MAX) {
-    sox_fail("no input port");
-    return SOX_EOF;
-  } else if (l_st->output_port == ULONG_MAX) {
-    sox_fail("no output port");
-    return SOX_EOF;
-  }
-  
   /* Stop if we have any unused arguments */
   if (n > 0) {
     sox_fail(sox_ladspa_effect.usage);
@@ -175,7 +202,23 @@
 static int sox_ladspa_start(sox_effect_t * effp)
 {
   ladspa_t l_st = (ladspa_t)effp->priv;
+  unsigned long i;
 
+  /* Instantiate the plugin */
+  sox_debug("rate for plugin is %d", effp->ininfo.rate);
+  l_st->handle = l_st->desc->instantiate(l_st->desc, effp->ininfo.rate);
+  if (l_st->handle == NULL) {
+    sox_fail("could not instantiate plugin");
+    return SOX_EOF;
+  }
+
+  for (i = 0; i < l_st->desc->PortCount; i++) {
+    const LADSPA_PortDescriptor port = l_st->desc->PortDescriptors[i];
+
+    if (LADSPA_IS_PORT_CONTROL(port))
+      l_st->desc->connect_port(l_st->handle, i, &(l_st->control[i]));
+  }
+
   /* If needed, activate the plugin */
   if (l_st->desc->activate)
     l_st->desc->activate(l_st->handle);
@@ -190,29 +233,41 @@
                            sox_size_t *isamp, sox_size_t *osamp)
 {
   ladspa_t l_st = (ladspa_t)effp->priv;
-  LADSPA_Data *buf = xmalloc(sizeof(LADSPA_Data) * *isamp);
   sox_sample_t i;
   sox_size_t len = min(*isamp, *osamp);
 
   *osamp = *isamp = len;
 
-  /* Copy the input; FIXME: Assume LADSPA_Data == float! */
-  for (i = 0; i < *isamp; i++)
-    buf[i] = SOX_SAMPLE_TO_FLOAT_32BIT(ibuf[i], effp->clips);
+  if (len) {
+    LADSPA_Data *buf = xmalloc(sizeof(LADSPA_Data) * len);
+    
+    /* Insert input if effect takes it */
+    if (l_st->input_port != ULONG_MAX) {
+      /* Copy the input; FIXME: Assume LADSPA_Data == float! */
+      for (i = 0; i < len; i++)
+        buf[i] = SOX_SAMPLE_TO_FLOAT_32BIT(ibuf[i], effp->clips);
+      
+      /* Connect the input port */
+      l_st->desc->connect_port(l_st->handle, l_st->input_port, buf);
+    }
+    
+    /* Connect the output port if used */
+    if (l_st->output_port != ULONG_MAX)
+      l_st->desc->connect_port(l_st->handle, l_st->output_port, buf);
+    
+    /* Run the plugin */
+    l_st->desc->run(l_st->handle, len);
+    
+    /* Grab output if effect produces it */
+    if (l_st->output_port != ULONG_MAX)
+      /* FIXME: Assume LADSPA_Data == float! */
+      for (i = 0; i < len; i++) {
+        obuf[i] = SOX_FLOAT_32BIT_TO_SAMPLE(buf[i], effp->clips);
+      }
+    
+    free(buf);
+  }
 
-  /* Connect the I/O ports */
-  l_st->desc->connect_port(l_st->handle, l_st->input_port, buf);
-  l_st->desc->connect_port(l_st->handle, l_st->output_port, buf);
-
-  /* Run the plugin */
-  l_st->desc->run(l_st->handle, *isamp);
-
-  /* Copy the output; FIXME: Assume LADSPA_Data == float! */
-  for (i = 0; i < *osamp; i++)
-    obuf[i] = SOX_FLOAT_32BIT_TO_SAMPLE(buf[i], effp->clips);
-
-  free(buf);
-
   return SOX_SUCCESS;
 }
 
@@ -244,7 +299,7 @@
 static sox_effect_handler_t sox_ladspa_effect = {
   "ladspa",
   "Usage: ladspa MODULE [PLUGIN] [ARGUMENT...]",
-  SOX_EFF_RATE | SOX_EFF_MCHAN,
+  0,
   sox_ladspa_getopts,
   sox_ladspa_start,
   sox_ladspa_flow,
--- a/src/noiseprof.c
+++ b/src/noiseprof.c
@@ -118,7 +118,7 @@
     int ncopy = 0;
     sox_size_t i;
 
-    /* FIXME: Make this non-fatal */
+    /* FIXME: Make this automatic for all effects */
     assert(effp->ininfo.channels == effp->outinfo.channels);
 
     /* How many samples per track to analyze? */
--- a/src/noisered.c
+++ b/src/noisered.c
@@ -269,7 +269,7 @@
     int oldbuf = data->bufdata;
     sox_size_t i;
 
-    /* FIXME: make this non-fatal */
+    /* FIXME: Make this automatic for all effects */
     assert(effp->ininfo.channels == effp->outinfo.channels);
 
     if (whole_window)
--- a/src/silence.c
+++ b/src/silence.c
@@ -263,7 +263,7 @@
 
         clear_rms(effp);
 
-        /* Now that we now sample rate, reparse duration. */
+        /* Now that we know sample rate, reparse duration. */
         if (silence->start)
         {
             if (sox_parsesamples(effp->ininfo.rate, silence->start_duration_str,
--- a/src/util.c
+++ b/src/util.c
@@ -14,6 +14,7 @@
 #include <assert.h>
 #include <stddef.h>
 #include <string.h>
+#include <strings.h>
 #include <ctype.h>
 #include <stdarg.h>
 
@@ -145,119 +146,6 @@
     sox_fail_errno(formp, SOX_EFMT, "File type `%s' is not known",
                   formp->filetype);
     return SOX_EFMT;
-}
-
-sox_effect_handler_t const * sox_find_effect(char const * name)
-{
-  int i;
-
-  for (i = 0; sox_effect_fns[i]; ++i) {
-    const sox_effect_handler_t *e = sox_effect_fns[i] ();
-    if (e && e->name && strcasecmp(e->name, name) == 0)
-      return e;                 /* Found it. */
-  }
-  return NULL;
-}
-
-/* dummy effect routine for do-nothing functions */
-static int effect_nothing(sox_effect_t * effp UNUSED)
-{
-  return SOX_SUCCESS;
-}
-
-static int effect_nothing_flow(sox_effect_t * effp UNUSED, const sox_ssample_t *ibuf UNUSED, sox_ssample_t *obuf UNUSED, sox_size_t *isamp, sox_size_t *osamp)
-{
-  /* Pass through samples verbatim */
-  *isamp = *osamp = min(*isamp, *osamp);
-  memcpy(obuf, ibuf, *isamp * sizeof(sox_ssample_t));
-  return SOX_SUCCESS;
-}
-
-static int effect_nothing_drain(sox_effect_t * effp UNUSED, sox_ssample_t *obuf UNUSED, sox_size_t *osamp)
-{
-  /* Inform no more samples to drain */
-  *osamp = 0;
-  return SOX_EOF;
-}
-
-static int effect_nothing_getopts(sox_effect_t * effp, int n, char **argv UNUSED)
-{
-#undef sox_fail
-#define sox_fail sox_message_filename=effp->handler.name,sox_fail
-  if (n) {
-    sox_fail(effp->handler.usage);
-    return (SOX_EOF);
-  }
-  return (SOX_SUCCESS);
-}
-
-void sox_create_effect(sox_effect_t * effp, sox_effect_handler_t const * e)
-{
-  assert(e);
-  memset(effp, 0, sizeof(*effp));
-  effp->global_info = &effects_global_info;
-  effp->handler = *e;
-  if (!effp->handler.getopts) effp->handler.getopts = effect_nothing_getopts;
-  if (!effp->handler.start) effp->handler.start = effect_nothing;
-  if (!effp->handler.flow) effp->handler.flow = effect_nothing_flow;
-  if (!effp->handler.drain) effp->handler.drain = effect_nothing_drain;
-  if (!effp->handler.stop) effp->handler.stop = effect_nothing;
-  if (!effp->handler.kill) effp->handler.kill = effect_nothing;
-}
-
-/*
- * Copy input and output signal info into effect structures.
- * Must pass in a bitmask containing info on whether SOX_EFF_CHAN
- * or SOX_EFF_RATE has been used previously on this effect stream.
- * If not running multiple effects then just pass in a value of 0.
- *
- * Return value is the same mask plus addition of SOX_EFF_CHAN or
- * SOX_EFF_RATE if it was used in this effect.  That make this
- * return value can be passed back into this function in future
- * calls.
- */
-
-int sox_update_effect(sox_effect_t * effp, const sox_signalinfo_t *in, const sox_signalinfo_t *out, 
-                    int effect_mask)
-{
-    effp->ininfo = *in;
-    effp->outinfo = *out;
-
-    if (in->channels != out->channels) {
-      /* Only effects with SOX_EFF_CHAN flag can actually handle
-       * outputing a different number of channels then the input.
-       */
-      if (!(effp->handler.flags & SOX_EFF_CHAN)) {
-        /* If this effect is being run before a SOX_EFF_CHAN effect
-         * then its output is the same as the input file; otherwise,
-         * its input contains the same number of channels as the
-         * output file. */
-        if (effect_mask & SOX_EFF_CHAN)
-          effp->ininfo.channels = out->channels;
-        else
-          effp->outinfo.channels = in->channels;
-      }
-    }
-
-    if (in->rate != out->rate)
-    {
-        /* Only SOX_EFF_RATE effects can handle an input that
-         * has a different sample rate from the output. */
-        if (!(effp->handler.flags & SOX_EFF_RATE))
-        {
-            if (effect_mask & SOX_EFF_RATE)
-                effp->ininfo.rate = out->rate;
-            else
-                effp->outinfo.rate = in->rate;
-        }
-    }
-
-    if (effp->handler.flags & SOX_EFF_CHAN)
-        effect_mask |= SOX_EFF_CHAN;
-    if (effp->handler.flags & SOX_EFF_RATE)
-        effect_mask |= SOX_EFF_RATE;
-
-    return effect_mask;
 }
 
 /*
--- a/src/wav.c
+++ b/src/wav.c
@@ -419,9 +419,8 @@
     if (strncmp("RIFX", magic, 4) == 0) 
     {
         sox_debug("Found RIFX header, swapping bytes");
-        ft->signal.reverse_bytes ^= SOX_IS_LITTLEENDIAN;
+        ft->signal.reverse_bytes = !ft->signal.reverse_bytes;
     }
-    else ft->signal.reverse_bytes ^= SOX_IS_BIGENDIAN;
 
     sox_readdw(ft, &dwRiffLength);