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);