ref: 4f128442d49e9f07699a06238230c1727b126d8c
parent: ef75a218af2fb6da7935ba65a892f28ad59a0e29
parent: 9cff6d9490758dade5bff6c645d4478b14ab3da6
author: Rob Sykes <robs@users.sourceforge.net>
date: Tue Mar 13 09:39:53 EDT 2012
Merge branch 'master' of ssh://sox.git.sourceforge.net/gitroot/sox/sox
--- a/ChangeLog
+++ b/ChangeLog
@@ -4,7 +4,7 @@
This file contains a list of all changes starting after the release of
sox-11gamma, followed by a list of prior authors and features.
-sox-14.4.1 20xx-xx-xx
+sox-14.4.2 20xx-xx-xx
----------
Previously deprecated features that have been removed in this release:
@@ -23,6 +23,15 @@
ated in [F(ormat)] [E(ffect)] Replacement due after
------- ---------------------- ---------------------- -------
14.4.0 E mixer remix 2013-03-04
+
+Internal improvements:
+
+ o Speed optimization for effects that operate on channels
+ independently. (Ulrich Klauer)
+
+
+sox-14.4.1 20xx-xx-xx
+----------
sox-14.4.0 2012-03-04
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,8 +1,28 @@
-sox (14.4.1-0+git20120306-1) UNRELEASED; urgency=low
+sox (14.4.1-0+git20120311-1) UNRELEASED; urgency=low
* Git Version.
+ * [debian/control]:
+ - Bumped libsox2 to libsox3, interface changes.
- -- Pascal Giard <evilynux@gmail.com> Sat, 06 Mar 2012 23:00:01 -0500
+ -- Pascal Giard <evilynux@gmail.com> Mon, 12 Mar 2012 00:22:05 -0500
+
+sox (14.4.0-2) unstable; urgency=low
+
+ * [debian/sox.install, debian/libsox-dev.install]:
+ - Removed brace expensions fixing lintian warning
+ "brace-expansion-in-debhelper-config-file".
+ * [debian/control]:
+ - Added versioned dependency to format libraries, fixes upgrades in some
+ use cases.
+ - Added MP2 to short description of libsox-fmt-mp3.
+ * [debian/copyright]:
+ - Long due update, thanks to Ulrich Klauer <ulrich@chirlu.de> for pointing
+ this out.
+ - libst is now libsox.
+ - FFT code is no longer Audacity's GPL code.
+ - Updated link to LGPL license to 2.1.
+
+ -- Pascal Giard <pascal@debian.org> Sun, 11 Mar 2012 23:59:36 -0400
sox (14.4.0-1) unstable; urgency=low
--- a/debian/control
+++ b/debian/control
@@ -30,8 +30,9 @@
Package: sox
Architecture: any
-Depends: libsox-fmt-alsa [linux-any] | libsox-fmt-ao | libsox-fmt-oss | libsox-fmt-pulse,
- libsox-fmt-base,
+Depends: libsox-fmt-alsa (= ${binary:Version}) [linux-any] | libsox-fmt-ao (= ${binary:Version}) | libsox-fmt-oss (= ${binary:Version}) | libsox-fmt-pulse (= ${binary:Version}),
+ libsox-fmt-base (= ${binary:Version}),
+ libsox3 (= ${binary:Version}),
${misc:Depends},
${shlibs:Depends}
Suggests: libsox-fmt-all
@@ -50,13 +51,13 @@
(respectively provided by libsox-fmt-alsa, libsox-fmt-ao, libsox-fmt-oss and
libsox-fmt-pulse). It also supports LADSPA plugins.
-Package: libsox2
+Package: libsox3
Architecture: any
Depends: ${misc:Depends}, ${shlibs:Depends}
Recommends: libsox-fmt-alsa [linux-any] | libsox-fmt-ao | libsox-fmt-oss | libsox-fmt-pulse,
libsox-fmt-base
-Conflicts: libsox0, libsox0a, libsox1, libsox1a
-Replaces: libsox1b
+Conflicts: libsox0, libsox0a, libsox1, libsox1a, libsox1b
+Replaces: libsox2
Suggests: libsox-fmt-all
Description: SoX library of audio effects and processing
SoX is the swiss army knife of sound processing.
@@ -117,7 +118,7 @@
Package: libsox-fmt-mp3
Architecture: any
Depends: ${misc:Depends}, ${shlibs:Depends}
-Description: SoX MP3 format library
+Description: SoX MP2 and MP3 format library
SoX is the swiss army knife of sound processing.
.
This package contains the SoX MP2 and MP3 format library.
@@ -150,13 +151,13 @@
Package: libsox-fmt-all
Architecture: any
-Depends: libsox-fmt-alsa [linux-any],
- libsox-fmt-ao,
- libsox-fmt-base,
- libsox-fmt-ffmpeg,
- libsox-fmt-mp3,
- libsox-fmt-oss,
- libsox-fmt-pulse,
+Depends: libsox-fmt-alsa (= ${binary:Version}) [linux-any],
+ libsox-fmt-ao (= ${binary:Version}),
+ libsox-fmt-base (= ${binary:Version}),
+ libsox-fmt-ffmpeg (= ${binary:Version}),
+ libsox-fmt-mp3 (= ${binary:Version}),
+ libsox-fmt-oss (= ${binary:Version}),
+ libsox-fmt-pulse (= ${binary:Version}),
${misc:Depends}
Description: All SoX format libraries
SoX is the swiss army knife of sound processing.
@@ -167,7 +168,7 @@
Architecture: any
Section: libdevel
Depends: libsox-fmt-all (= ${binary:Version}),
- libsox2 (= ${binary:Version}),
+ libsox3 (= ${binary:Version}),
${misc:Depends}
Description: Development files for the SoX library
SoX is the swiss army knife of sound processing.
--- a/debian/copyright
+++ b/debian/copyright
@@ -17,19 +17,13 @@
sox.c, and thus SoX-the user application, is distributed under the GPL.
-The remaining files that make up libst are licensed under the less
+The remaining files that make up libsox are licensed under the less
restrictive license LGPL.
-There is currently only one exception to this. The files FFT.c and
-FFT.h are original from the Audacity program and fall under its
-license of GPL. The noise profiling and noise reduction effects
-both make use of this FFT code and would need to be removed from
-any program that requires LGPL only software.
-
On Debian systems, the complete text of the GNU General Public License
can be found in the '/usr/share/common-licenses/GPL-2' file.
The complete text of the GNU Lesser General Public License can be found in the
-'/usr/share/common-licenses/LGPL-2' file.
+'/usr/share/common-licenses/LGPL-2.1' file.
The original copyright owner was Lance Norskog.
Current upstream development is being made by Chris Bagwell and others.
--- a/debian/libsox-dev.install
+++ b/debian/libsox-dev.install
@@ -1,5 +1,6 @@
debian/tmp/usr/include/* usr/include/
-debian/tmp/usr/lib/lib*.{a,so} usr/lib/
+debian/tmp/usr/lib/lib*.a usr/lib/
+debian/tmp/usr/lib/lib*.so usr/lib/
debian/tmp/usr/lib/pkgconfig/sox.pc usr/lib/pkgconfig/
debian/tmp/usr/lib/sox/lib*.a usr/lib/sox/
debian/tmp/usr/share/man/man3 usr/share/man/
--- a/debian/libsox2.dirs
+++ /dev/null
@@ -1,1 +1,0 @@
-usr/lib
--- a/debian/libsox2.install
+++ /dev/null
@@ -1,1 +1,0 @@
-debian/tmp/usr/lib/*.so.* usr/lib/
--- a/debian/libsox2.shlibs
+++ /dev/null
@@ -1,1 +1,0 @@
-libsox 2 libsox2 (>= 14.4.0)
--- /dev/null
+++ b/debian/libsox3.dirs
@@ -1,0 +1,1 @@
+usr/lib
--- /dev/null
+++ b/debian/libsox3.install
@@ -1,0 +1,1 @@
+debian/tmp/usr/lib/*.so.* usr/lib/
--- /dev/null
+++ b/debian/libsox3.shlibs
@@ -1,0 +1,1 @@
+libsox 3 libsox3 (>= 14.4.1)
--- a/debian/rules
+++ b/debian/rules
@@ -1,7 +1,7 @@
#!/usr/bin/make -f
# -*- mode: makefile; coding: utf-8 -*-
-DEB_TAR_SRCDIR := sox-14.4.1
+DEB_TAR_SRCDIR := sox-14.4.1git
include /usr/share/cdbs/1/rules/tarball.mk
include /usr/share/cdbs/1/rules/debhelper.mk
--- a/debian/sox.install
+++ b/debian/sox.install
@@ -1,2 +1,6 @@
-debian/tmp/usr/bin/{play,rec,sox,soxi} usr/bin/
-debian/tmp/usr/share/man/man{1,7} usr/share/man/
+debian/tmp/usr/bin/play usr/bin/
+debian/tmp/usr/bin/rec usr/bin/
+debian/tmp/usr/bin/sox usr/bin/
+debian/tmp/usr/bin/soxi usr/bin/
+debian/tmp/usr/share/man/man1 usr/share/man/
+debian/tmp/usr/share/man/man7 usr/share/man/
--- a/src/effects.c
+++ b/src/effects.c
@@ -209,15 +209,43 @@
return SOX_SUCCESS;
}
+/* An effect's output buffer (effp->obuf) generally has this layout:
+ * |. . . A1A2A3B1B2B3C1C2C3. . . . . . . . . . . . . . . . . . |
+ * ^0 ^obeg ^oend ^bufsiz
+ * (where A1 is the first sample of channel 1, A2 the first sample of
+ * channel 2, etc.), i.e. the channels are interleaved.
+ * However, while sox_flow_effects() is running, output buffers are
+ * adapted to how the following effect expects its input, to avoid
+ * back-and-forth conversions. If the following effect operates on
+ * each of several channels separately (flows > 1), the layout is
+ * changed to this uninterleaved form:
+ * |. A1B1C1. . . . . . . A2B2C2. . . . . . . A3B3C3. . . . . . |
+ * ^0 ^obeg ^oend ^bufsiz
+ * <--- channel 1 ----><--- channel 2 ----><--- channel 3 ---->
+ * The buffer is logically subdivided into channel buffers of size
+ * bufsiz/flows each, starting at offsets 0, bufsiz/flows,
+ * 2*(bufsiz/flows) etc. Within the channel buffers, the data starts
+ * at position obeg/flows and ends before oend/flows. In case bufsiz
+ * is not evenly divisible by flows, there will be an unused area at
+ * the very end of the output buffer.
+ * The interleave() and deinterleave() functions convert between these
+ * two representations.
+ */
+static void interleave(size_t flows, size_t length, sox_sample_t *from,
+ size_t bufsiz, size_t offset, sox_sample_t *to);
+static void deinterleave(size_t flows, size_t length, sox_sample_t *from,
+ sox_sample_t *to, size_t bufsiz, size_t offset);
+
static int flow_effect(sox_effects_chain_t * chain, size_t n)
{
- sox_effect_t * effp1 = &chain->effects[n - 1][0];
- sox_effect_t * effp = &chain->effects[n][0];
+ sox_effect_t *effp1 = chain->effects[n - 1];
+ sox_effect_t *effp = chain->effects[n];
int effstatus = SOX_SUCCESS;
- size_t i, f = 0;
- const sox_sample_t *ibuf;
+ size_t f = 0;
size_t idone = effp1->oend - effp1->obeg;
size_t obeg = sox_globals.bufsiz - effp->oend;
+ sox_bool il_change = (effp->flows == 1) !=
+ (chain->length == n + 1 || chain->effects[n+1]->flows == 1);
#if DEBUG_EFFECTS_CHAIN
size_t pre_idone = idone;
size_t pre_odone = obeg;
@@ -225,21 +253,21 @@
if (effp->flows == 1) { /* Run effect on all channels at once */
idone -= idone % effp->in_signal.channels;
- effstatus = effp->handler.flow(effp, &effp1->obuf[effp1->obeg],
- &effp->obuf[effp->oend], &idone, &obeg);
+ effstatus = effp->handler.flow(effp, effp1->obuf + effp1->obeg,
+ il_change ? chain->il_buf : effp->obuf + effp->oend,
+ &idone, &obeg);
if (obeg % effp->out_signal.channels != 0) {
lsx_fail("multi-channel effect flowed asymmetrically!");
effstatus = SOX_EOF;
}
+ if (il_change)
+ deinterleave(chain->effects[n+1]->flows, obeg, chain->il_buf,
+ effp->obuf, sox_globals.bufsiz, effp->oend);
} else { /* Run effect on each channel individually */
- sox_sample_t *obuf = &effp->obuf[effp->oend];
+ sox_sample_t *obuf = il_change ? chain->il_buf : effp->obuf;
+ size_t flow_offs = sox_globals.bufsiz/effp->flows;
size_t idone_last = 0, odone_last = 0; /* Initialised to prevent warning */
- ibuf = &effp1->obuf[effp1->obeg];
- for (i = 0; i < idone; i += effp->flows)
- for (f = 0; f < effp->flows; ++f)
- chain->ibufc[f][i / effp->flows] = *ibuf++;
-
#ifdef HAVE_OPENMP
if (sox_globals.use_threads && effp->flows > 1)
{
@@ -248,7 +276,9 @@
size_t idonec = idone / effp->flows;
size_t odonec = obeg / effp->flows;
int eff_status_c = effp->handler.flow(&chain->effects[n][f],
- chain->ibufc[f], chain->obufc[f], &idonec, &odonec);
+ effp1->obuf + f*flow_offs + effp1->obeg/effp->flows,
+ obuf + f*flow_offs + effp->oend/effp->flows,
+ &idonec, &odonec);
if (!f) {
idone_last = idonec;
odone_last = odonec;
@@ -265,7 +295,9 @@
size_t idonec = idone / effp->flows;
size_t odonec = obeg / effp->flows;
int eff_status_c = effp->handler.flow(&chain->effects[n][f],
- chain->ibufc[f], chain->obufc[f], &idonec, &odonec);
+ effp1->obuf + f*flow_offs + effp1->obeg/effp->flows,
+ obuf + f*flow_offs + effp->oend/effp->flows,
+ &idonec, &odonec);
if (f && (idonec != idone_last || odonec != odone_last)) {
lsx_fail("flowed asymmetrically!");
effstatus = SOX_EOF;
@@ -278,18 +310,22 @@
}
}
- for (i = 0; i < odone_last; ++i)
- for (f = 0; f < effp->flows; ++f)
- *obuf++ = chain->obufc[f][i];
-
idone = effp->flows * idone_last;
obeg = effp->flows * odone_last;
+
+ if (il_change)
+ interleave(effp->flows, obeg, chain->il_buf, sox_globals.bufsiz,
+ effp->oend, effp->obuf + effp->oend);
}
effp1->obeg += idone;
if (effp1->obeg == effp1->oend)
effp1->obeg = effp1->oend = 0;
- else if (effp1->oend - effp1->obeg < effp->imin ) { /* Need to refill? */
- memmove(effp1->obuf, &effp1->obuf[effp1->obeg], (effp1->oend - effp1->obeg) * sizeof(*effp1->obuf));
+ else if (effp1->oend - effp1->obeg < effp->imin) { /* Need to refill? */
+ size_t flow_offs = sox_globals.bufsiz/effp->flows;
+ for (f = 0; f < effp->flows; ++f)
+ memcpy(effp1->obuf + f * flow_offs,
+ effp1->obuf + f * flow_offs + effp1->obeg/effp->flows,
+ (effp1->oend - effp1->obeg)/effp->flows * sizeof(*effp1->obuf));
effp1->oend -= effp1->obeg;
effp1->obeg = 0;
}
@@ -310,27 +346,37 @@
/* The same as flow_effect but with no input */
static int drain_effect(sox_effects_chain_t * chain, size_t n)
{
- sox_effect_t * effp = &chain->effects[n][0];
+ sox_effect_t *effp = chain->effects[n];
int effstatus = SOX_SUCCESS;
- size_t i, f;
+ size_t f = 0;
size_t obeg = sox_globals.bufsiz - effp->oend;
+ sox_bool il_change = (effp->flows == 1) !=
+ (chain->length == n + 1 || chain->effects[n+1]->flows == 1);
#if DEBUG_EFFECTS_CHAIN
size_t pre_odone = obeg;
#endif
if (effp->flows == 1) { /* Run effect on all channels at once */
- effstatus = effp->handler.drain(effp, &effp->obuf[effp->oend], &obeg);
+ effstatus = effp->handler.drain(effp,
+ il_change ? chain->il_buf : effp->obuf + effp->oend,
+ &obeg);
if (obeg % effp->out_signal.channels != 0) {
lsx_fail("multi-channel effect drained asymmetrically!");
effstatus = SOX_EOF;
}
+ if (il_change)
+ deinterleave(chain->effects[n+1]->flows, obeg, chain->il_buf,
+ effp->obuf, sox_globals.bufsiz, effp->oend);
} else { /* Run effect on each channel individually */
- sox_sample_t *obuf = &effp->obuf[effp->oend];
+ sox_sample_t *obuf = il_change ? chain->il_buf : effp->obuf;
+ size_t flow_offs = sox_globals.bufsiz/effp->flows;
size_t odone_last = 0; /* Initialised to prevent warning */
for (f = 0; f < effp->flows; ++f) {
size_t odonec = obeg / effp->flows;
- int eff_status_c = effp->handler.drain(&chain->effects[n][f], chain->obufc[f], &odonec);
+ int eff_status_c = effp->handler.drain(&chain->effects[n][f],
+ obuf + f*flow_offs + effp->oend/effp->flows,
+ &odonec);
if (f && (odonec != odone_last)) {
lsx_fail("drained asymmetrically!");
effstatus = SOX_EOF;
@@ -341,10 +387,11 @@
effstatus = SOX_EOF;
}
- for (i = 0; i < odone_last; ++i)
- for (f = 0; f < effp->flows; ++f)
- *obuf++ = chain->obufc[f][i];
- obeg = f * odone_last;
+ obeg = effp->flows * odone_last;
+
+ if (il_change)
+ interleave(effp->flows, obeg, chain->il_buf, sox_globals.bufsiz,
+ effp->oend, effp->obuf + effp->oend);
}
if (!obeg) /* This is the only thing that drain has and flow hasn't */
effstatus = SOX_EOF;
@@ -365,30 +412,43 @@
{
int flow_status = SOX_SUCCESS;
size_t e, source_e = 0; /* effect indices */
- size_t f, max_flows = 0;
+ size_t max_flows = 0;
sox_bool draining = sox_true;
for (e = 0; e < chain->length; ++e) {
- chain->effects[e][0].obuf = lsx_realloc(chain->effects[e][0].obuf,
- sox_globals.bufsiz * sizeof(chain->effects[e][0].obuf[0]));
- /* Possibly there is already a buffer, if this is a used effect;
- it may still contain samples in that case. */
+ sox_effect_t *effp = chain->effects[e];
+ effp->obuf =
+ lsx_realloc(effp->obuf, sox_globals.bufsiz * sizeof(*effp->obuf));
/* Memory will be freed by sox_delete_effect() later. */
- max_flows = max(max_flows, chain->effects[e][0].flows);
+ /* Possibly there was already a buffer, if this is a used effect;
+ it may still contain samples in that case. */
+ if (effp->oend > sox_globals.bufsiz) {
+ lsx_warn("buffer size insufficient; buffered samples were dropped");
+ /* can only happen if bufsize has been reduced since the last run */
+ effp->obeg = effp->oend = 0;
+ }
+ max_flows = max(max_flows, effp->flows);
}
- if (max_flows == 1) /* don't need interleave buffers */
- max_flows = 0;
- chain->ibufc = lsx_calloc(max_flows, sizeof(*chain->ibufc));
- chain->obufc = lsx_calloc(max_flows, sizeof(*chain->obufc));
- for (f = 0; f < max_flows; ++f) {
- chain->ibufc[f] = lsx_calloc(sox_globals.bufsiz / 2, sizeof(chain->ibufc[f][0]));
- chain->obufc[f] = lsx_calloc(sox_globals.bufsiz / 2, sizeof(chain->obufc[f][0]));
+ if (max_flows > 1) /* might need interleave buffer */
+ chain->il_buf = lsx_malloc(sox_globals.bufsiz * sizeof(sox_sample_t));
+ else
+ chain->il_buf = NULL;
+
+ /* Go through the effects, and if there are samples in one of the
+ buffers, deinterleave it (if necessary). */
+ for (e = 0; e + 1 < chain->length; e++) {
+ sox_effect_t *effp = chain->effects[e];
+ if (effp->oend > effp->obeg && chain->effects[e+1]->flows > 1) {
+ sox_sample_t *sw = chain->il_buf; chain->il_buf = effp->obuf; effp->obuf = sw;
+ deinterleave(chain->effects[e+1]->flows, effp->oend - effp->obeg,
+ chain->il_buf, effp->obuf, sox_globals.bufsiz, effp->obeg);
+ }
}
e = chain->length - 1;
while (source_e < chain->length) {
-#define have_imin (e > 0 && e < chain->length && chain->effects[e - 1][0].oend - chain->effects[e - 1][0].obeg >= chain->effects[e][0].imin)
- size_t osize = chain->effects[e][0].oend - chain->effects[e][0].obeg;
+#define have_imin (e > 0 && e < chain->length && chain->effects[e - 1]->oend - chain->effects[e - 1]->obeg >= chain->effects[e]->imin)
+ size_t osize = chain->effects[e]->oend - chain->effects[e]->obeg;
if (e == source_e && (draining || !have_imin)) {
if (drain_effect(chain, e) == SOX_EOF) {
++source_e;
@@ -401,7 +461,7 @@
source_e = e;
draining = sox_true;
}
- if (e < chain->length && chain->effects[e][0].oend - chain->effects[e][0].obeg > osize) /* False for output */
+ if (e < chain->length && chain->effects[e]->oend - chain->effects[e]->obeg > osize) /* False for output */
++e;
else if (e == source_e)
draining = sox_true;
@@ -416,13 +476,19 @@
}
}
- for (f = 0; f < max_flows; ++f) {
- free(chain->ibufc[f]);
- free(chain->obufc[f]);
+ /* If an effect's output buffer still has samples, and if it is
+ uninterleaved, then re-interleave it. Necessary since it might
+ be reused, and at that time possibly followed by an MCHAN effect. */
+ for (e = 0; e + 1 < chain->length; e++) {
+ sox_effect_t *effp = chain->effects[e];
+ if (effp->oend > effp->obeg && chain->effects[e+1]->flows > 1) {
+ sox_sample_t *sw = chain->il_buf; chain->il_buf = effp->obuf; effp->obuf = sw;
+ interleave(chain->effects[e+1]->flows, effp->oend - effp->obeg,
+ chain->il_buf, sox_globals.bufsiz, effp->obeg, effp->obuf);
+ }
}
- free(chain->obufc);
- free(chain->ibufc);
+ free(chain->il_buf);
return flow_status;
}
@@ -549,4 +615,51 @@
return eh; /* Found it. */
}
return NULL;
+}
+
+
+/*----------------------------- Helper functions -----------------------------*/
+
+/* interleave() parameters:
+ * flows: number of samples per wide sample
+ * length: number of samples to copy
+ * [pertaining to the (non-interleaved) source buffer:]
+ * from: start address
+ * bufsiz: total size
+ * offset: position at which to start reading
+ * [pertaining to the (interleaved) destination buffer:]
+ * to: start address
+ */
+static void interleave(size_t flows, size_t length, sox_sample_t *from,
+ size_t bufsiz, size_t offset, sox_sample_t *to)
+{
+ size_t i, f;
+ size_t wide_samples = length/flows;
+ size_t flow_offs = bufsiz/flows;
+ from += offset/flows;
+ for (i = 0; i < wide_samples; i++)
+ for (f = 0; f < flows; f++)
+ *to++ = from[f*flow_offs + i];
+}
+
+/* deinterleave() parameters:
+ * flows: number of samples per wide sample
+ * length: number of samples to copy
+ * [pertaining to the (interleaved) source buffer:]
+ * from: start address
+ * [pertaining to the (non-interleaved) destination buffer:]
+ * to: start address
+ * bufsiz: total size
+ * offset: position at which to start writing
+ */
+static void deinterleave(size_t flows, size_t length, sox_sample_t *from,
+ sox_sample_t *to, size_t bufsiz, size_t offset)
+{
+ size_t i, f;
+ size_t wide_samples = length/flows;
+ size_t flow_offs = bufsiz/flows;
+ to += offset/flows;
+ for (i = 0; i < wide_samples; i++)
+ for (f = 0; f < flows; f++)
+ to[f*flow_offs + i] = *from++;
}
--- a/src/sox.h
+++ b/src/sox.h
@@ -1627,8 +1627,7 @@
sox_encodinginfo_t const * out_enc; /**< Output encoding */
/* The following items are private to the libSoX effects chain functions. */
size_t table_size; /**< Size of effects table (including unused entries) */
- sox_sample_t **ibufc; /**< Channel interleave buffer */
- sox_sample_t **obufc; /**< Channel interleave buffer */
+ sox_sample_t *il_buf; /**< Channel interleave buffer */
} sox_effects_chain_t;
/*****************************************************************************