minimal set of sox 14.4.1 source files we need; unit test builds and runs OK
authordrowe67 <drowe67@01035d8c-6547-0410-b346-abe4f91aad63>
Sat, 28 Jan 2017 07:47:19 +0000 (07:47 +0000)
committerdrowe67 <drowe67@01035d8c-6547-0410-b346-abe4f91aad63>
Sat, 28 Jan 2017 07:47:19 +0000 (07:47 +0000)
git-svn-id: https://svn.code.sf.net/p/freetel/code@3001 01035d8c-6547-0410-b346-abe4f91aad63

18 files changed:
freedv-dev/src/fdmdv2_main.cpp
freedv-dev/src/sox/band.h [new file with mode: 0644]
freedv-dev/src/sox/biquad.c [new file with mode: 0644]
freedv-dev/src/sox/biquad.h [new file with mode: 0644]
freedv-dev/src/sox/biquads.c [new file with mode: 0644]
freedv-dev/src/sox/effects.c [new file with mode: 0644]
freedv-dev/src/sox/effects.h [new file with mode: 0644]
freedv-dev/src/sox/effects_i.c [new file with mode: 0644]
freedv-dev/src/sox/formats_i.c [new file with mode: 0644]
freedv-dev/src/sox/libsox.c [new file with mode: 0644]
freedv-dev/src/sox/sox.h [new file with mode: 0644]
freedv-dev/src/sox/sox_i.h [new file with mode: 0644]
freedv-dev/src/sox/soxconfig.h [new file with mode: 0644]
freedv-dev/src/sox/soxomp.h [new file with mode: 0644]
freedv-dev/src/sox/util.h [new file with mode: 0644]
freedv-dev/src/sox/xmalloc.c [new file with mode: 0644]
freedv-dev/src/sox/xmalloc.h [new file with mode: 0644]
freedv-dev/src/sox_biquad.c

index 337db40af87f05ad11e4028a011758ddf5eceb02..49fddfe26751ee6f0dcae94d7fe090843e0dfde7 100644 (file)
@@ -3183,6 +3183,7 @@ void *MainFrame::designAnEQFilter(const char filterType[], float freqHz, float g
     assert(argc <= SBQ_MAX_ARGS);
 
     sbq = sox_biquad_create(argc-1, (const char **)arg);
+    assert(sbq != NULL);
 
     return sbq;
 }
diff --git a/freedv-dev/src/sox/band.h b/freedv-dev/src/sox/band.h
new file mode 100644 (file)
index 0000000..5398ff4
--- /dev/null
@@ -0,0 +1,47 @@
+/* libSoX Bandpass effect file.     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.
+ *
+ * Algorithm:  2nd order recursive filter.
+ * Formula stolen from MUSIC56K, a toolkit of 56000 assembler stuff.
+ * Quote:
+ *   This is a 2nd order recursive band pass filter of the form.
+ *   y(n)= a * x(n) - b * y(n-1) - c * y(n-2)
+ *   where :
+ *        x(n) = "IN"
+ *        "OUT" = y(n)
+ *        c = EXP(-2*pi*cBW/S_RATE)
+ *        b = -4*c/(1+c)*COS(2*pi*cCF/S_RATE)
+ *   if cSCL=2 (i.e. noise input)
+ *        a = SQT(((1+c)*(1+c)-b*b)*(1-c)/(1+c))
+ *   else
+ *        a = SQT(1-b*b/(4*c))*(1-c)
+ *   endif
+ *   note :     cCF is the center frequency in Hertz
+ *        cBW is the band width in Hertz
+ *        cSCL is a scale factor, use 1 for pitched sounds
+ *   use 2 for noise.
+ *
+ *
+ * July 1, 1999 - Jan Paul Schmidt <jps@fundament.org>
+ *
+ *   This looks like the resonator band pass in SPKit. It's a
+ *   second order all-pole (IIR) band-pass filter described
+ *   at the pages 186 - 189 in
+ *     Dodge, Charles & Jerse, Thomas A. 1985:
+ *       Computer Music -- Synthesis, Composition and Performance.
+ *       New York: Schirmer Books.
+ *   Reference from the SPKit manual.
+ */
+
+  p->a2 = exp(-2 * M_PI * bw_Hz / effp->in_signal.rate);
+  p->a1 = -4 * p->a2 / (1 + p->a2) * cos(2 * M_PI * p->fc / effp->in_signal.rate);
+  p->b0 = sqrt(1 - p->a1 * p->a1 / (4 * p->a2)) * (1 - p->a2);
+  if (p->filter_type == filter_BPF_SPK_N) {
+    mult = sqrt(((1+p->a2) * (1+p->a2) - p->a1*p->a1) * (1-p->a2) / (1+p->a2)) / p->b0;
+    p->b0 *= mult;
+  }
diff --git a/freedv-dev/src/sox/biquad.c b/freedv-dev/src/sox/biquad.c
new file mode 100644 (file)
index 0000000..c57f190
--- /dev/null
@@ -0,0 +1,178 @@
+/* libSoX Biquad filter common functions   (c) 2006-7 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 "biquad.h"
+#include <string.h>
+
+typedef biquad_t priv_t;
+
+static char const * const width_str[] = {
+  "band-width(Hz)",
+  "band-width(kHz)",
+  "band-width(Hz, no warp)", /* deprecated */
+  "band-width(octaves)",
+  "Q",
+  "slope",
+};
+static char const all_width_types[] = "hkboqs";
+
+
+int lsx_biquad_getopts(sox_effect_t * effp, int argc, char **argv,
+    int min_args, int max_args, int fc_pos, int width_pos, int gain_pos,
+    char const * allowed_width_types, filter_t filter_type)
+{
+  priv_t * p = (priv_t *)effp->priv;
+  char width_type = *allowed_width_types;
+  char dummy, * dummy_p;     /* To check for extraneous chars. */
+  --argc, ++argv;
+
+  p->filter_type = filter_type;
+  if (argc < min_args || argc > max_args ||
+      (argc > fc_pos    && ((p->fc = lsx_parse_frequency(argv[fc_pos], &dummy_p)) <= 0 || *dummy_p)) ||
+      (argc > width_pos && ((unsigned)(sscanf(argv[width_pos], "%lf%c %c", &p->width, &width_type, &dummy)-1) > 1 || p->width <= 0)) ||
+      (argc > gain_pos  && sscanf(argv[gain_pos], "%lf %c", &p->gain, &dummy) != 1) ||
+      !strchr(allowed_width_types, width_type) || (width_type == 's' && p->width > 1))
+    return lsx_usage(effp);
+  p->width_type = strchr(all_width_types, width_type) - all_width_types;
+  if ((size_t)p->width_type >= strlen(all_width_types))
+    p->width_type = 0;
+  if (p->width_type == width_bw_kHz) {
+    p->width *= 1000;
+    p->width_type = width_bw_Hz;
+  }
+  return SOX_SUCCESS;
+}
+
+
+static int start(sox_effect_t * effp)
+{
+  priv_t * p = (priv_t *)effp->priv;
+  /* Simplify: */
+  p->b2 /= p->a0;
+  p->b1 /= p->a0;
+  p->b0 /= p->a0;
+  p->a2 /= p->a0;
+  p->a1 /= p->a0;
+
+  p->o2 = p->o1 = p->i2 = p->i1 = 0;
+  return SOX_SUCCESS;
+}
+
+
+int lsx_biquad_start(sox_effect_t * effp)
+{
+  priv_t * p = (priv_t *)effp->priv;
+
+  start(effp);
+
+  if (effp->global_info->plot == sox_plot_octave) {
+    printf(
+      "%% GNU Octave file (may also work with MATLAB(R) )\n"
+      "Fs=%g;minF=10;maxF=Fs/2;\n"
+      "sweepF=logspace(log10(minF),log10(maxF),200);\n"
+      "[h,w]=freqz([%.15e %.15e %.15e],[1 %.15e %.15e],sweepF,Fs);\n"
+      "semilogx(w,20*log10(h))\n"
+      "title('SoX effect: %s gain=%g frequency=%g %s=%g (rate=%g)')\n"
+      "xlabel('Frequency (Hz)')\n"
+      "ylabel('Amplitude Response (dB)')\n"
+      "axis([minF maxF -35 25])\n"
+      "grid on\n"
+      "disp('Hit return to continue')\n"
+      "pause\n"
+      , effp->in_signal.rate, p->b0, p->b1, p->b2, p->a1, p->a2
+      , effp->handler.name, p->gain, p->fc, width_str[p->width_type], p->width
+      , effp->in_signal.rate);
+    return SOX_EOF;
+  }
+  if (effp->global_info->plot == sox_plot_gnuplot) {
+    printf(
+      "# gnuplot file\n"
+      "set title 'SoX effect: %s gain=%g frequency=%g %s=%g (rate=%g)'\n"
+      "set xlabel 'Frequency (Hz)'\n"
+      "set ylabel 'Amplitude Response (dB)'\n"
+      "Fs=%g\n"
+      "b0=%.15e; b1=%.15e; b2=%.15e; a1=%.15e; a2=%.15e\n"
+      "o=2*pi/Fs\n"
+      "H(f)=sqrt((b0*b0+b1*b1+b2*b2+2.*(b0*b1+b1*b2)*cos(f*o)+2.*(b0*b2)*cos(2.*f*o))/(1.+a1*a1+a2*a2+2.*(a1+a1*a2)*cos(f*o)+2.*a2*cos(2.*f*o)))\n"
+      "set logscale x\n"
+      "set samples 250\n"
+      "set grid xtics ytics\n"
+      "set key off\n"
+      "plot [f=10:Fs/2] [-35:25] 20*log10(H(f))\n"
+      "pause -1 'Hit return to continue'\n"
+      , effp->handler.name, p->gain, p->fc, width_str[p->width_type], p->width
+      , effp->in_signal.rate, effp->in_signal.rate
+      , p->b0, p->b1, p->b2, p->a1, p->a2);
+    return SOX_EOF;
+  }
+  if (effp->global_info->plot == sox_plot_data) {
+    printf("# SoX effect: %s gain=%g frequency=%g %s=%g (rate=%g)\n"
+      "# IIR filter\n"
+      "# rate: %g\n"
+      "# name: b\n"
+      "# type: matrix\n"
+      "# rows: 3\n"
+      "# columns: 1\n"
+      "%24.16e\n%24.16e\n%24.16e\n"
+      "# name: a\n"
+      "# type: matrix\n"
+      "# rows: 3\n"
+      "# columns: 1\n"
+      "%24.16e\n%24.16e\n%24.16e\n"
+      , effp->handler.name, p->gain, p->fc, width_str[p->width_type], p->width
+      , effp->in_signal.rate, effp->in_signal.rate
+      , p->b0, p->b1, p->b2, 1. /* a0 */, p->a1, p->a2);
+    return SOX_EOF;
+  }
+  return SOX_SUCCESS;
+}
+
+
+int lsx_biquad_flow(sox_effect_t * effp, const sox_sample_t *ibuf,
+    sox_sample_t *obuf, size_t *isamp, size_t *osamp)
+{
+  priv_t * p = (priv_t *)effp->priv;
+  size_t len = *isamp = *osamp = min(*isamp, *osamp);
+  while (len--) {
+    double o0 = *ibuf*p->b0 + p->i1*p->b1 + p->i2*p->b2 - p->o1*p->a1 - p->o2*p->a2;
+    p->i2 = p->i1, p->i1 = *ibuf++;
+    p->o2 = p->o1, p->o1 = o0;
+    *obuf++ = SOX_ROUND_CLIP_COUNT(o0, effp->clips);
+  }
+  return SOX_SUCCESS;
+}
+
+static int create(sox_effect_t * effp, int argc, char * * argv)
+{
+  priv_t             * p = (priv_t *)effp->priv;
+  double             * d = &p->b0;
+  char               c;
+
+  --argc, ++argv;
+  if (argc == 6)
+    for (; argc && sscanf(*argv, "%lf%c", d, &c) == 1; --argc, ++argv, ++d);
+  return argc? lsx_usage(effp) : SOX_SUCCESS;
+}
+
+sox_effect_handler_t const * lsx_biquad_effect_fn(void)
+{
+  static sox_effect_handler_t handler = {
+    "biquad", "b0 b1 b2 a0 a1 a2", 0,
+    create, lsx_biquad_start, lsx_biquad_flow, NULL, NULL, NULL, sizeof(priv_t)
+  };
+  return &handler;
+}
diff --git a/freedv-dev/src/sox/biquad.h b/freedv-dev/src/sox/biquad.h
new file mode 100644 (file)
index 0000000..8786ac8
--- /dev/null
@@ -0,0 +1,78 @@
+/* libSoX Biquad filter common definitions (c) 2006-7 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
+ */
+
+#ifndef biquad_included
+#define biquad_included
+
+#define LSX_EFF_ALIAS
+#include "sox_i.h"
+
+typedef enum {
+  filter_LPF,
+  filter_HPF,
+  filter_BPF_CSG,
+  filter_BPF,
+  filter_notch,
+  filter_APF,
+  filter_peakingEQ,
+  filter_lowShelf,
+  filter_highShelf,
+  filter_LPF_1,
+  filter_HPF_1,
+  filter_BPF_SPK,
+  filter_BPF_SPK_N,
+  filter_AP1,
+  filter_AP2,
+  filter_deemph,
+  filter_riaa
+} filter_t;
+
+typedef enum {
+  width_bw_Hz,
+  width_bw_kHz,
+  /* The old, non-RBJ, non-freq-warped band-pass/reject response;
+   * leaving here for now just in case anybody misses it: */
+  width_bw_old,
+  width_bw_oct,
+  width_Q,
+  width_slope
+} width_t;
+
+/* Private data for the biquad filter effects */
+typedef struct {
+  double gain;             /* For EQ filters */
+  double fc;               /* Centre/corner/cutoff frequency */
+  double width;            /* Filter width; interpreted as per width_type */
+  width_t width_type;
+
+  filter_t filter_type;
+
+  double b0, b1, b2;       /* Filter coefficients */
+  double a0, a1, a2;       /* Filter coefficients */
+
+  sox_sample_t i1, i2;     /* Filter memory */
+  double      o1, o2;      /* Filter memory */
+} biquad_t;
+
+int lsx_biquad_getopts(sox_effect_t * effp, int n, char **argv,
+    int min_args, int max_args, int fc_pos, int width_pos, int gain_pos,
+    char const * allowed_width_types, filter_t filter_type);
+int lsx_biquad_start(sox_effect_t * effp);
+int lsx_biquad_flow(sox_effect_t * effp, const sox_sample_t *ibuf, sox_sample_t *obuf,
+                        size_t *isamp, size_t *osamp);
+
+#endif
diff --git a/freedv-dev/src/sox/biquads.c b/freedv-dev/src/sox/biquads.c
new file mode 100644 (file)
index 0000000..19793a6
--- /dev/null
@@ -0,0 +1,400 @@
+/* libSoX Biquad filter effects   (c) 2006-8 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
+ *
+ *
+ * 2-pole filters designed by Robert Bristow-Johnson <rbj@audioimagination.com>
+ *   see http://www.musicdsp.org/files/Audio-EQ-Cookbook.txt
+ *
+ * 1-pole filters based on code (c) 2000 Chris Bagwell <cbagwell@sprynet.com>
+ *   Algorithms: Recursive single pole low/high pass filter
+ *   Reference: The Scientist and Engineer's Guide to Digital Signal Processing
+ *
+ *   low-pass: output[N] = input[N] * A + output[N-1] * B
+ *     X = exp(-2.0 * pi * Fc)
+ *     A = 1 - X
+ *     B = X
+ *     Fc = cutoff freq / sample rate
+ *
+ *     Mimics an RC low-pass filter:
+ *
+ *     ---/\/\/\/\----------->
+ *                   |
+ *                  --- C
+ *                  ---
+ *                   |
+ *                   |
+ *                   V
+ *
+ *   high-pass: output[N] = A0 * input[N] + A1 * input[N-1] + B1 * output[N-1]
+ *     X  = exp(-2.0 * pi * Fc)
+ *     A0 = (1 + X) / 2
+ *     A1 = -(1 + X) / 2
+ *     B1 = X
+ *     Fc = cutoff freq / sample rate
+ *
+ *     Mimics an RC high-pass filter:
+ *
+ *         || C
+ *     ----||--------->
+ *         ||    |
+ *               <
+ *               > R
+ *               <
+ *               |
+ *               V
+ */
+
+
+#include "biquad.h"
+#include <assert.h>
+#include <string.h>
+
+typedef biquad_t priv_t;
+
+
+static int hilo1_getopts(sox_effect_t * effp, int argc, char **argv) {
+  return lsx_biquad_getopts(effp, argc, argv, 1, 1, 0, 1, 2, "",
+      *effp->handler.name == 'l'? filter_LPF_1 : filter_HPF_1);
+}
+
+
+static int hilo2_getopts(sox_effect_t * effp, int argc, char **argv) {
+  priv_t * p = (priv_t *)effp->priv;
+  if (argc > 1 && strcmp(argv[1], "-1") == 0)
+    return hilo1_getopts(effp, argc - 1, argv + 1);
+  if (argc > 1 && strcmp(argv[1], "-2") == 0)
+    ++argv, --argc;
+  p->width = sqrt(0.5); /* Default to Butterworth */
+  return lsx_biquad_getopts(effp, argc, argv, 1, 2, 0, 1, 2, "qohk",
+      *effp->handler.name == 'l'? filter_LPF : filter_HPF);
+}
+
+
+static int bandpass_getopts(sox_effect_t * effp, int argc, char **argv) {
+  filter_t type = filter_BPF;
+  if (argc > 1 && strcmp(argv[1], "-c") == 0)
+    ++argv, --argc, type = filter_BPF_CSG;
+  return lsx_biquad_getopts(effp, argc, argv, 2, 2, 0, 1, 2, "hkqob", type);
+}
+
+
+static int bandrej_getopts(sox_effect_t * effp, int argc, char **argv) {
+  return lsx_biquad_getopts(effp, argc, argv, 2, 2, 0, 1, 2, "hkqob", filter_notch);
+}
+
+
+static int allpass_getopts(sox_effect_t * effp, int argc, char **argv) {
+  filter_t type = filter_APF;
+  int m;
+  if (argc > 1 && strcmp(argv[1], "-1") == 0)
+    ++argv, --argc, type = filter_AP1;
+  else if (argc > 1 && strcmp(argv[1], "-2") == 0)
+    ++argv, --argc, type = filter_AP2;
+  m = 1 + (type == filter_APF);
+  return lsx_biquad_getopts(effp, argc, argv, m, m, 0, 1, 2, "hkqo", type);
+}
+
+
+static int tone_getopts(sox_effect_t * effp, int argc, char **argv) {
+  priv_t * p = (priv_t *)effp->priv;
+  p->width = 0.5;
+  p->fc = *effp->handler.name == 'b'? 100 : 3000;
+  return lsx_biquad_getopts(effp, argc, argv, 1, 3, 1, 2, 0, "shkqo",
+      *effp->handler.name == 'b'?  filter_lowShelf: filter_highShelf);
+}
+
+
+static int equalizer_getopts(sox_effect_t * effp, int argc, char **argv) {
+  return lsx_biquad_getopts(effp, argc, argv, 3, 3, 0, 1, 2, "qohk", filter_peakingEQ);
+}
+
+
+static int band_getopts(sox_effect_t * effp, int argc, char **argv) {
+  filter_t type = filter_BPF_SPK;
+  if (argc > 1 && strcmp(argv[1], "-n") == 0)
+    ++argv, --argc, type = filter_BPF_SPK_N;
+  return lsx_biquad_getopts(effp, argc, argv, 1, 2, 0, 1, 2, "hkqo", type);
+}
+
+
+static int deemph_getopts(sox_effect_t * effp, int argc, char **argv) {
+  priv_t * p = (priv_t *)effp->priv;
+  p->fc    = 5283;
+  p->width = 0.4845;
+  p->gain  = -9.477;
+  return lsx_biquad_getopts(effp, argc, argv, 0, 0, 0, 1, 2, "s", filter_deemph);
+}
+
+
+static int riaa_getopts(sox_effect_t * effp, int argc, char **argv) {
+  priv_t * p = (priv_t *)effp->priv;
+  p->filter_type = filter_riaa;
+  (void)argv;
+  return --argc? lsx_usage(effp) : SOX_SUCCESS;
+}
+
+
+static void make_poly_from_roots(
+    double const * roots, size_t num_roots, double * poly)
+{
+  size_t i, j;
+  poly[0] = 1;
+  poly[1] = -roots[0];
+  memset(poly + 2, 0, (num_roots + 1 - 2) * sizeof(*poly));
+  for (i = 1; i < num_roots; ++i)
+    for (j = num_roots; j > 0; --j)
+      poly[j] -= poly[j - 1] * roots[i];
+}
+
+static int start(sox_effect_t * effp)
+{
+  priv_t * p = (priv_t *)effp->priv;
+  double w0 = 2 * M_PI * p->fc / effp->in_signal.rate;
+  double A  = exp(p->gain / 40 * log(10.));
+  double alpha = 0, mult = dB_to_linear(max(p->gain, 0));
+
+  if (w0 > M_PI) {
+    lsx_fail("frequency must be less than half the sample-rate (Nyquist rate)");
+    return SOX_EOF;
+  }
+
+  /* Set defaults: */
+  p->b0 = p->b1 = p->b2 = p->a1 = p->a2 = 0;
+  p->a0 = 1;
+
+  if (p->width) switch (p->width_type) {
+    case width_slope:
+      alpha = sin(w0)/2 * sqrt((A + 1/A)*(1/p->width - 1) + 2);
+      break;
+
+    case width_Q:
+      alpha = sin(w0)/(2*p->width);
+      break;
+
+    case width_bw_oct:
+      alpha = sin(w0)*sinh(log(2.)/2 * p->width * w0/sin(w0));
+      break;
+
+    case width_bw_Hz:
+      alpha = sin(w0)/(2*p->fc/p->width);
+      break;
+
+    case width_bw_kHz: assert(0); /* Shouldn't get here */
+
+    case width_bw_old:
+      alpha = tan(M_PI * p->width / effp->in_signal.rate);
+      break;
+  }
+  switch (p->filter_type) {
+    case filter_LPF: /* H(s) = 1 / (s^2 + s/Q + 1) */
+      p->b0 =  (1 - cos(w0))/2;
+      p->b1 =   1 - cos(w0);
+      p->b2 =  (1 - cos(w0))/2;
+      p->a0 =   1 + alpha;
+      p->a1 =  -2*cos(w0);
+      p->a2 =   1 - alpha;
+      break;
+
+    case filter_HPF: /* H(s) = s^2 / (s^2 + s/Q + 1) */
+      p->b0 =  (1 + cos(w0))/2;
+      p->b1 = -(1 + cos(w0));
+      p->b2 =  (1 + cos(w0))/2;
+      p->a0 =   1 + alpha;
+      p->a1 =  -2*cos(w0);
+      p->a2 =   1 - alpha;
+      break;
+
+    case filter_BPF_CSG: /* H(s) = s / (s^2 + s/Q + 1)  (constant skirt gain, peak gain = Q) */
+      p->b0 =   sin(w0)/2;
+      p->b1 =   0;
+      p->b2 =  -sin(w0)/2;
+      p->a0 =   1 + alpha;
+      p->a1 =  -2*cos(w0);
+      p->a2 =   1 - alpha;
+      break;
+
+    case filter_BPF: /* H(s) = (s/Q) / (s^2 + s/Q + 1)      (constant 0 dB peak gain) */
+      p->b0 =   alpha;
+      p->b1 =   0;
+      p->b2 =  -alpha;
+      p->a0 =   1 + alpha;
+      p->a1 =  -2*cos(w0);
+      p->a2 =   1 - alpha;
+      break;
+
+    case filter_notch: /* H(s) = (s^2 + 1) / (s^2 + s/Q + 1) */
+      p->b0 =   1;
+      p->b1 =  -2*cos(w0);
+      p->b2 =   1;
+      p->a0 =   1 + alpha;
+      p->a1 =  -2*cos(w0);
+      p->a2 =   1 - alpha;
+      break;
+
+    case filter_APF: /* H(s) = (s^2 - s/Q + 1) / (s^2 + s/Q + 1) */
+      p->b0 =   1 - alpha;
+      p->b1 =  -2*cos(w0);
+      p->b2 =   1 + alpha;
+      p->a0 =   1 + alpha;
+      p->a1 =  -2*cos(w0);
+      p->a2 =   1 - alpha;
+      break;
+
+    case filter_peakingEQ: /* H(s) = (s^2 + s*(A/Q) + 1) / (s^2 + s/(A*Q) + 1) */
+      if (A == 1)
+        return SOX_EFF_NULL;
+      p->b0 =   1 + alpha*A;
+      p->b1 =  -2*cos(w0);
+      p->b2 =   1 - alpha*A;
+      p->a0 =   1 + alpha/A;
+      p->a1 =  -2*cos(w0);
+      p->a2 =   1 - alpha/A;
+      break;
+
+    case filter_lowShelf: /* H(s) = A * (s^2 + (sqrt(A)/Q)*s + A)/(A*s^2 + (sqrt(A)/Q)*s + 1) */
+      if (A == 1)
+        return SOX_EFF_NULL;
+      p->b0 =    A*( (A+1) - (A-1)*cos(w0) + 2*sqrt(A)*alpha );
+      p->b1 =  2*A*( (A-1) - (A+1)*cos(w0)                   );
+      p->b2 =    A*( (A+1) - (A-1)*cos(w0) - 2*sqrt(A)*alpha );
+      p->a0 =        (A+1) + (A-1)*cos(w0) + 2*sqrt(A)*alpha;
+      p->a1 =   -2*( (A-1) + (A+1)*cos(w0)                   );
+      p->a2 =        (A+1) + (A-1)*cos(w0) - 2*sqrt(A)*alpha;
+      break;
+
+    case filter_deemph:  /* See deemph.plt for documentation */
+      if (effp->in_signal.rate != 44100) {
+        lsx_fail("Sample rate must be 44100 (audio-CD)");
+        return SOX_EOF;
+      }
+      /* Falls through... */
+
+    case filter_highShelf: /* H(s) = A * (A*s^2 + (sqrt(A)/Q)*s + 1)/(s^2 + (sqrt(A)/Q)*s + A) */
+      if (!A)
+        return SOX_EFF_NULL;
+      p->b0 =    A*( (A+1) + (A-1)*cos(w0) + 2*sqrt(A)*alpha );
+      p->b1 = -2*A*( (A-1) + (A+1)*cos(w0)                   );
+      p->b2 =    A*( (A+1) + (A-1)*cos(w0) - 2*sqrt(A)*alpha );
+      p->a0 =        (A+1) - (A-1)*cos(w0) + 2*sqrt(A)*alpha;
+      p->a1 =    2*( (A-1) - (A+1)*cos(w0)                   );
+      p->a2 =        (A+1) - (A-1)*cos(w0) - 2*sqrt(A)*alpha;
+      break;
+
+    case filter_LPF_1: /* single-pole */
+      p->a1 = -exp(-w0);
+      p->b0 = 1 + p->a1;
+      break;
+
+    case filter_HPF_1: /* single-pole */
+      p->a1 = -exp(-w0);
+      p->b0 = (1 - p->a1)/2;
+      p->b1 = -p->b0;
+      break;
+
+    case filter_BPF_SPK: case filter_BPF_SPK_N: {
+      double bw_Hz;
+      if (!p->width)
+        p->width = p->fc / 2;
+      bw_Hz = p->width_type == width_Q?  p->fc / p->width :
+        p->width_type == width_bw_Hz? p->width :
+        p->fc * (pow(2., p->width) - 1) * pow(2., -0.5 * p->width); /* bw_oct */
+      #include "band.h" /* Has different licence */
+      break;
+    }
+
+    case filter_AP1:     /* Experimental 1-pole all-pass from Tom Erbe @ UCSD */
+      p->b0 = exp(-w0);
+      p->b1 = -1;
+      p->a1 = -exp(-w0);
+      break;
+
+    case filter_AP2:     /* Experimental 2-pole all-pass from Tom Erbe @ UCSD */
+      p->b0 = 1 - sin(w0);
+      p->b1 = -2 * cos(w0);
+      p->b2 = 1 + sin(w0);
+      p->a0 = 1 + sin(w0);
+      p->a1 = -2 * cos(w0);
+      p->a2 = 1 - sin(w0);
+      break;
+
+    case filter_riaa: /* http://www.dsprelated.com/showmessage/73300/3.php */
+      if (effp->in_signal.rate == 44100) {
+        static const double zeros[] = {-0.2014898, 0.9233820};
+        static const double poles[] = {0.7083149, 0.9924091};
+        make_poly_from_roots(zeros, (size_t)2, &p->b0);
+        make_poly_from_roots(poles, (size_t)2, &p->a0);
+      }
+      else if (effp->in_signal.rate == 48000) {
+        static const double zeros[] = {-0.1766069, 0.9321590};
+        static const double poles[] = {0.7396325, 0.9931330};
+        make_poly_from_roots(zeros, (size_t)2, &p->b0);
+        make_poly_from_roots(poles, (size_t)2, &p->a0);
+      }
+      else if (effp->in_signal.rate == 88200) {
+        static const double zeros[] = {-0.1168735, 0.9648312};
+        static const double poles[] = {0.8590646, 0.9964002};
+        make_poly_from_roots(zeros, (size_t)2, &p->b0);
+        make_poly_from_roots(poles, (size_t)2, &p->a0);
+      }
+      else if (effp->in_signal.rate == 96000) {
+        static const double zeros[] = {-0.1141486, 0.9676817};
+        static const double poles[] = {0.8699137, 0.9966946};
+        make_poly_from_roots(zeros, (size_t)2, &p->b0);
+        make_poly_from_roots(poles, (size_t)2, &p->a0);
+      }
+      else {
+        lsx_fail("Sample rate must be 44.1k, 48k, 88.2k, or 96k");
+        return SOX_EOF;
+      }
+      { /* Normalise to 0dB at 1kHz (Thanks to Glenn Davis) */
+        double y = 2 * M_PI * 1000 / effp->in_signal.rate;
+        double b_re = p->b0 + p->b1 * cos(-y) + p->b2 * cos(-2 * y);
+        double a_re = p->a0 + p->a1 * cos(-y) + p->a2 * cos(-2 * y);
+        double b_im = p->b1 * sin(-y) + p->b2 * sin(-2 * y);
+        double a_im = p->a1 * sin(-y) + p->a2 * sin(-2 * y);
+        double g = 1 / sqrt((sqr(b_re) + sqr(b_im)) / (sqr(a_re) + sqr(a_im)));
+        p->b0 *= g; p->b1 *= g; p->b2 *= g;
+      }
+      mult = (p->b0 + p->b1 + p->b2) / (p->a0 + p->a1 + p->a2);
+      lsx_debug("gain=%f", linear_to_dB(mult));
+      break;
+  }
+  if (effp->in_signal.mult)
+    *effp->in_signal.mult /= mult;
+  return lsx_biquad_start(effp);
+}
+
+
+#define BIQUAD_EFFECT(name,group,usage,flags) \
+sox_effect_handler_t const * lsx_##name##_effect_fn(void) { \
+  static sox_effect_handler_t handler = { \
+    #name, usage, flags, \
+    group##_getopts, start, lsx_biquad_flow, 0, 0, 0, sizeof(biquad_t)\
+  }; \
+  return &handler; \
+}
+
+BIQUAD_EFFECT(highpass,  hilo2,    "[-1|-2] frequency [width[q|o|h|k](0.707q)]", 0)
+BIQUAD_EFFECT(lowpass,   hilo2,    "[-1|-2] frequency [width[q|o|h|k]](0.707q)", 0)
+BIQUAD_EFFECT(bandpass,  bandpass, "[-c] frequency width[h|k|q|o]", 0)
+BIQUAD_EFFECT(bandreject,bandrej,  "frequency width[h|k|q|o]", 0)
+BIQUAD_EFFECT(allpass,   allpass,  "frequency width[h|k|q|o]", 0)
+BIQUAD_EFFECT(bass,      tone,     "gain [frequency(100) [width[s|h|k|q|o]](0.5s)]", 0)
+BIQUAD_EFFECT(treble,    tone,     "gain [frequency(3000) [width[s|h|k|q|o]](0.5s)]", 0)
+BIQUAD_EFFECT(equalizer, equalizer,"frequency width[q|o|h|k] gain", 0)
+BIQUAD_EFFECT(band,      band,     "[-n] center [width[h|k|q|o]]", 0)
+BIQUAD_EFFECT(deemph,    deemph,   NULL, 0)
+BIQUAD_EFFECT(riaa,      riaa,     NULL, 0)
diff --git a/freedv-dev/src/sox/effects.c b/freedv-dev/src/sox/effects.c
new file mode 100644 (file)
index 0000000..435412f
--- /dev/null
@@ -0,0 +1,544 @@
+/* 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.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
+ */
+
+#define LSX_EFF_ALIAS
+#include "sox_i.h"
+#include <assert.h>
+#include <string.h>
+#ifdef HAVE_STRINGS_H
+  #include <strings.h>
+#endif
+
+#define DEBUG_EFFECTS_CHAIN 0
+
+/* Default effect handler functions for do-nothing situations: */
+
+static int default_function(sox_effect_t * effp UNUSED)
+{
+  return SOX_SUCCESS;
+}
+
+/* Pass through samples verbatim */
+int lsx_flow_copy(sox_effect_t * effp UNUSED, const sox_sample_t * ibuf,
+    sox_sample_t * obuf, size_t * isamp, size_t * osamp)
+{
+  *isamp = *osamp = min(*isamp, *osamp);
+  memcpy(obuf, ibuf, *isamp * sizeof(*obuf));
+  return SOX_SUCCESS;
+}
+
+/* Inform no more samples to drain */
+static int default_drain(sox_effect_t * effp UNUSED, sox_sample_t *obuf UNUSED, size_t *osamp)
+{
+  *osamp = 0;
+  return SOX_EOF;
+}
+
+/* Check that no parameters have been given */
+static int default_getopts(sox_effect_t * effp, int argc, char **argv UNUSED)
+{
+  return --argc? lsx_usage(effp) : SOX_SUCCESS;
+}
+
+/* Partially initialise the effect structure; signal info will come later */
+sox_effect_t * sox_create_effect(sox_effect_handler_t const * eh)
+{
+  sox_effect_t * effp = lsx_calloc(1, sizeof(*effp));
+  effp->obuf = NULL;
+
+  effp->global_info = sox_get_effects_globals();
+  effp->handler = *eh;
+  if (!effp->handler.getopts) effp->handler.getopts = default_getopts;
+  if (!effp->handler.start  ) effp->handler.start   = default_function;
+  if (!effp->handler.flow   ) effp->handler.flow    = lsx_flow_copy;
+  if (!effp->handler.drain  ) effp->handler.drain   = default_drain;
+  if (!effp->handler.stop   ) effp->handler.stop    = default_function;
+  if (!effp->handler.kill   ) effp->handler.kill    = default_function;
+
+  effp->priv = lsx_calloc(1, effp->handler.priv_size);
+
+  return effp;
+} /* sox_create_effect */
+
+int sox_effect_options(sox_effect_t *effp, int argc, char * const argv[])
+{
+  int result;
+
+  char * * argv2 = lsx_malloc((argc + 1) * sizeof(*argv2));
+  argv2[0] = (char *)effp->handler.name;
+  memcpy(argv2 + 1, argv, argc * sizeof(*argv2));
+  result = effp->handler.getopts(effp, argc + 1, argv2);
+  free(argv2);
+  return result;
+} /* sox_effect_options */
+
+/* Effects chain: */
+
+sox_effects_chain_t * sox_create_effects_chain(
+    sox_encodinginfo_t const * in_enc, sox_encodinginfo_t const * out_enc)
+{
+  sox_effects_chain_t * result = lsx_calloc(1, sizeof(sox_effects_chain_t));
+  result->global_info = *sox_get_effects_globals();
+  result->in_enc = in_enc;
+  result->out_enc = out_enc;
+  return result;
+} /* sox_create_effects_chain */
+
+void sox_delete_effects_chain(sox_effects_chain_t *ecp)
+{
+    if (ecp && ecp->length)
+        sox_delete_effects(ecp);
+    free(ecp->effects);
+    free(ecp);
+} /* sox_delete_effects_chain */
+
+/* Effect can call in start() or flow() to set minimum input size to flow() */
+int lsx_effect_set_imin(sox_effect_t * effp, size_t imin)
+{
+  if (imin > sox_globals.bufsiz / effp->flows) {
+    lsx_fail("sox_bufsiz not big enough");
+    return SOX_EOF;
+  }
+
+  effp->imin = imin;
+  return SOX_SUCCESS;
+}
+
+/* Effects table to be extended in steps of EFF_TABLE_STEP */
+#define EFF_TABLE_STEP 8
+
+/* Add an effect to the chain. *in is the input signal for this effect. *out is
+ * a suggestion as to what the output signal should be, but depending on its
+ * given options and *in, the effect can choose to do differently.  Whatever
+ * output rate and channels the effect does produce are written back to *in,
+ * ready for the next effect in the chain.
+ */
+int sox_add_effect(sox_effects_chain_t * chain, sox_effect_t * effp, sox_signalinfo_t * in, sox_signalinfo_t const * out)
+{
+  int ret, (*start)(sox_effect_t * effp) = effp->handler.start;
+  unsigned f;
+  sox_effect_t eff0;  /* Copy of effect for flow 0 before calling start */
+
+  effp->global_info = &chain->global_info;
+  effp->in_signal = *in;
+  effp->out_signal = *out;
+  effp->in_encoding = chain->in_enc;
+  effp->out_encoding = chain->out_enc;
+  if (!(effp->handler.flags & SOX_EFF_CHAN))
+    effp->out_signal.channels = in->channels;
+  if (!(effp->handler.flags & SOX_EFF_RATE))
+    effp->out_signal.rate = in->rate;
+  if (!(effp->handler.flags & SOX_EFF_PREC))
+    effp->out_signal.precision = (effp->handler.flags & SOX_EFF_MODIFY)?
+        in->precision : SOX_SAMPLE_PRECISION;
+  if (!(effp->handler.flags & SOX_EFF_GAIN))
+    effp->out_signal.mult = in->mult;
+
+  effp->flows =
+    (effp->handler.flags & SOX_EFF_MCHAN)? 1 : effp->in_signal.channels;
+  effp->clips = 0;
+  effp->imin = 0;
+  eff0 = *effp, eff0.priv = lsx_memdup(eff0.priv, eff0.handler.priv_size);
+  eff0.in_signal.mult = NULL; /* Only used in channel 0 */
+  ret = start(effp);
+  if (ret == SOX_EFF_NULL) {
+    lsx_report("has no effect in this configuration");
+    free(eff0.priv);
+    free(effp->priv);
+    effp->priv = NULL;
+    return SOX_SUCCESS;
+  }
+  if (ret != SOX_SUCCESS) {
+    free(eff0.priv);
+    return SOX_EOF;
+  }
+  if (in->mult)
+    lsx_debug("mult=%g", *in->mult);
+
+  if (!(effp->handler.flags & SOX_EFF_LENGTH)) {
+    effp->out_signal.length = in->length;
+    if (effp->out_signal.length != SOX_UNKNOWN_LEN) {
+      if (effp->handler.flags & SOX_EFF_CHAN)
+        effp->out_signal.length =
+          effp->out_signal.length / in->channels * effp->out_signal.channels;
+      if (effp->handler.flags & SOX_EFF_RATE)
+        effp->out_signal.length =
+          effp->out_signal.length / in->rate * effp->out_signal.rate + .5;
+    }
+  }
+
+  *in = effp->out_signal;
+
+  if (chain->length == chain->table_size) {
+    chain->table_size += EFF_TABLE_STEP;
+    lsx_debug_more("sox_add_effect: extending effects table, "
+      "new size = %lu", (unsigned long)chain->table_size);
+    lsx_revalloc(chain->effects, chain->table_size);
+  }
+
+  chain->effects[chain->length] =
+    lsx_calloc(effp->flows, sizeof(chain->effects[chain->length][0]));
+  chain->effects[chain->length][0] = *effp;
+
+  for (f = 1; f < effp->flows; ++f) {
+    chain->effects[chain->length][f] = eff0;
+    chain->effects[chain->length][f].flow = f;
+    chain->effects[chain->length][f].priv = lsx_memdup(eff0.priv, eff0.handler.priv_size);
+    if (start(&chain->effects[chain->length][f]) != SOX_SUCCESS) {
+      free(eff0.priv);
+      return SOX_EOF;
+    }
+  }
+
+  ++chain->length;
+  free(eff0.priv);
+  return SOX_SUCCESS;
+}
+
+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];
+  int effstatus = SOX_SUCCESS, f = 0;
+  size_t i;
+  const sox_sample_t *ibuf;
+  size_t idone = effp1->oend - effp1->obeg;
+  size_t obeg = sox_globals.bufsiz - effp->oend;
+#if DEBUG_EFFECTS_CHAIN
+  size_t pre_idone = idone;
+  size_t pre_odone = obeg;
+#endif
+
+  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);
+    if (obeg % effp->out_signal.channels != 0) {
+      lsx_fail("multi-channel effect flowed asymmetrically!");
+      effstatus = SOX_EOF;
+    }
+  } else {               /* Run effect on each channel individually */
+    sox_sample_t *obuf = &effp->obuf[effp->oend];
+    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 < (int)effp->flows; ++f)
+        chain->ibufc[f][i / effp->flows] = *ibuf++;
+
+#ifdef HAVE_OPENMP
+    if (sox_globals.use_threads && effp->flows > 1)
+    {
+      #pragma omp parallel for
+      for (f = 0; f < (int)effp->flows; ++f) {
+        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);
+        if (!f) {
+          idone_last = idonec;
+          odone_last = odonec;
+        }
+
+        if (eff_status_c != SOX_SUCCESS)
+          effstatus = SOX_EOF;
+      }
+    }
+    else /* sox_globals.use_threads */
+#endif
+    {
+      for (f = 0; f < (int)effp->flows; ++f) {
+        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);
+        if (f && (idonec != idone_last || odonec != odone_last)) {
+          lsx_fail("flowed asymmetrically!");
+          effstatus = SOX_EOF;
+        }
+        idone_last = idonec;
+        odone_last = odonec;
+
+        if (eff_status_c != SOX_SUCCESS)
+          effstatus = SOX_EOF;
+      }
+    }
+
+    for (i = 0; i < odone_last; ++i)
+      for (f = 0; f < (int)effp->flows; ++f)
+        *obuf++ = chain->obufc[f][i];
+
+    idone = effp->flows * idone_last;
+    obeg = effp->flows * odone_last;
+  }
+#if DEBUG_EFFECTS_CHAIN
+  lsx_report("flow:  %5" PRIuPTR " %5" PRIuPTR " %5" PRIuPTR " %5" PRIuPTR,
+      pre_idone, pre_odone, idone, obeg);
+#endif
+  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));
+    effp1->oend -= effp1->obeg;
+    effp1->obeg = 0;
+  }
+
+  effp->oend += obeg;
+
+  return effstatus == SOX_SUCCESS? SOX_SUCCESS : SOX_EOF;
+}
+
+/* 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];
+  int effstatus = SOX_SUCCESS;
+  size_t i, f;
+  size_t obeg = sox_globals.bufsiz - effp->oend;
+#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);
+    if (obeg % effp->out_signal.channels != 0) {
+      lsx_fail("multi-channel effect drained asymmetrically!");
+      effstatus = SOX_EOF;
+    }
+  } else {                       /* Run effect on each channel individually */
+    sox_sample_t *obuf = &effp->obuf[effp->oend];
+    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);
+      if (f && (odonec != odone_last)) {
+        lsx_fail("drained asymmetrically!");
+        effstatus = SOX_EOF;
+      }
+      odone_last = odonec;
+
+      if (eff_status_c != SOX_SUCCESS)
+        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;
+  }
+#if DEBUG_EFFECTS_CHAIN
+  lsx_report("drain: %5" PRIuPTR " %5" PRIuPTR " %5" PRIuPTR " %5" PRIuPTR,
+      (size_t)0, pre_odone, (size_t)0, obeg);
+#endif
+  if (!obeg)   /* This is the only thing that drain has and flow hasn't */
+    effstatus = SOX_EOF;
+
+  effp->oend += obeg;
+
+  return effstatus == SOX_SUCCESS? SOX_SUCCESS : SOX_EOF;
+}
+
+/* Flow data through the effects chain until an effect or callback gives EOF */
+int sox_flow_effects(sox_effects_chain_t * chain, int (* callback)(sox_bool all_done, void * client_data), void * client_data)
+{
+  int flow_status = SOX_SUCCESS;
+  size_t e, source_e = 0;               /* effect indices */
+  size_t f, 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. */
+      /* Memory will be freed by sox_delete_effect() later. */
+    max_flows = max(max_flows, chain->effects[e][0].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]));
+  }
+
+  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;
+    if (e == source_e && (draining || !have_imin)) {
+      if (drain_effect(chain, e) == SOX_EOF) {
+        ++source_e;
+        draining = sox_false;
+      }
+    } else if (have_imin && flow_effect(chain, e) == SOX_EOF) {
+      flow_status = SOX_EOF;
+      if (e == chain->length - 1)
+        break;
+      source_e = e;
+      draining = sox_true;
+    }
+    if (e < chain->length && chain->effects[e][0].oend - chain->effects[e][0].obeg > osize) /* False for output */
+      ++e;
+    else if (e == source_e)
+      draining = sox_true;
+    else if ((int)--e < (int)source_e)
+      e = source_e;
+
+    if (callback && callback(source_e == chain->length, client_data) != SOX_SUCCESS) {
+      flow_status = SOX_EOF; /* Client has requested to stop the flow. */
+      break;
+    }
+  }
+
+  for (f = 0; f < max_flows; ++f) {
+    free(chain->ibufc[f]);
+    free(chain->obufc[f]);
+  }
+  free(chain->obufc);
+  free(chain->ibufc);
+
+  return flow_status;
+}
+
+sox_uint64_t sox_effects_clips(sox_effects_chain_t * chain)
+{
+  unsigned i, f;
+  uint64_t clips = 0;
+  for (i = 1; i < chain->length - 1; ++i)
+    for (f = 0; f < chain->effects[i][0].flows; ++f)
+      clips += chain->effects[i][f].clips;
+  return clips;
+}
+
+sox_uint64_t sox_stop_effect(sox_effect_t *effp)
+{
+  unsigned f;
+  uint64_t clips = 0;
+
+  for (f = 0; f < effp->flows; ++f) {
+    effp[f].handler.stop(&effp[f]);
+    clips += effp[f].clips;
+  }
+  return clips;
+}
+
+void sox_push_effect_last(sox_effects_chain_t *chain, sox_effect_t *effp)
+{
+  if (chain->length == chain->table_size) {
+    chain->table_size += EFF_TABLE_STEP;
+    lsx_debug_more("sox_push_effect_last: extending effects table, "
+        "new size = %lu", (unsigned long)chain->table_size);
+    lsx_revalloc(chain->effects, chain->table_size);
+  }
+
+  chain->effects[chain->length++] = effp;
+} /* sox_push_effect_last */
+
+sox_effect_t *sox_pop_effect_last(sox_effects_chain_t *chain)
+{
+  if (chain->length > 0)
+  {
+    sox_effect_t *effp;
+    chain->length--;
+    effp = chain->effects[chain->length];
+    chain->effects[chain->length] = NULL;
+    return effp;
+  }
+  else
+    return NULL;
+} /* sox_pop_effect_last */
+
+/* Free resources related to effect.
+ * Note: This currently closes down the effect which might
+ * not be obvious from name.
+ */
+void sox_delete_effect(sox_effect_t *effp)
+{
+  uint64_t clips;
+  unsigned f;
+
+  if ((clips = sox_stop_effect(effp)) != 0)
+    lsx_warn("%s clipped %" PRIu64 " samples; decrease volume?",
+        effp->handler.name, clips);
+  if (effp->obeg != effp->oend)
+    lsx_debug("output buffer still held %" PRIuPTR " samples; dropped.",
+        (effp->oend - effp->obeg)/effp->out_signal.channels);
+      /* May or may not indicate a problem; it is normal if the user aborted
+         processing, or if an effect like "trim" stopped early. */
+  effp->handler.kill(effp); /* N.B. only one kill; not one per flow */
+  for (f = 0; f < effp->flows; ++f)
+    free(effp[f].priv);
+  free(effp->obuf);
+  free(effp);
+}
+
+void sox_delete_effect_last(sox_effects_chain_t *chain)
+{
+  if (chain->length > 0)
+  {
+    chain->length--;
+    sox_delete_effect(chain->effects[chain->length]);
+    chain->effects[chain->length] = NULL;
+  }
+} /* sox_delete_effect_last */
+
+/* Remove all effects from the chain.
+ * Note: This currently closes down the effect which might
+ * not be obvious from name.
+ */
+void sox_delete_effects(sox_effects_chain_t * chain)
+{
+  size_t e;
+
+  for (e = 0; e < chain->length; ++e) {
+    sox_delete_effect(chain->effects[e]);
+    chain->effects[e] = NULL;
+  }
+  chain->length = 0;
+}
+
+/*----------------------------- Effects library ------------------------------*/
+
+static sox_effect_fn_t s_sox_effect_fns[] = {
+#define EFFECT(f) lsx_##f##_effect_fn,
+#include "effects.h"
+#undef EFFECT
+  NULL
+};
+
+const sox_effect_fn_t*
+sox_get_effect_fns(void)
+{
+    return s_sox_effect_fns;
+}
+
+/* Find a named effect in the effects library */
+sox_effect_handler_t const * sox_find_effect(char const * name)
+{
+  int e;
+  sox_effect_fn_t const * fns = sox_get_effect_fns();
+  for (e = 0; fns[e]; ++e) {
+    const sox_effect_handler_t *eh = fns[e] ();
+    if (eh && eh->name && strcasecmp(eh->name, name) == 0)
+      return eh;                 /* Found it. */
+  }
+  return NULL;
+}
diff --git a/freedv-dev/src/sox/effects.h b/freedv-dev/src/sox/effects.h
new file mode 100644 (file)
index 0000000..8d7025c
--- /dev/null
@@ -0,0 +1,22 @@
+/* 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
+ */
+
+/* Manually edited for FreeDV to contain just the effects we need */
+
+  EFFECT(bass)
+  EFFECT(highpass)
+  EFFECT(treble)
+  EFFECT(equalizer)
+
diff --git a/freedv-dev/src/sox/effects_i.c b/freedv-dev/src/sox/effects_i.c
new file mode 100644 (file)
index 0000000..e5770a9
--- /dev/null
@@ -0,0 +1,379 @@
+/* Implements a libSoX internal interface for implementing effects.
+ * All public functions & data are prefixed with lsx_ .
+ *
+ * Copyright (c) 2005-8 Chris Bagwell and SoX contributors
+ *
+ * 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
+ */
+
+#define LSX_EFF_ALIAS
+#include "sox_i.h"
+#include <string.h>
+#include <ctype.h>
+
+int lsx_usage(sox_effect_t * effp)
+{
+  if (effp->handler.usage)
+    lsx_fail("usage: %s", effp->handler.usage);
+  else
+    lsx_fail("this effect takes no parameters");
+  return SOX_EOF;
+}
+
+char * lsx_usage_lines(char * * usage, char const * const * lines, size_t n)
+{
+  if (!*usage) {
+    size_t i, len;
+    for (len = i = 0; i < n; len += strlen(lines[i++]) + 1);
+    *usage = lsx_malloc(len); /* FIXME: this memory will never be freed */
+    strcpy(*usage, lines[0]);
+    for (i = 1; i < n; ++i) {
+      strcat(*usage, "\n");
+      strcat(*usage, lines[i]);
+    }
+  }
+  return *usage;
+}
+
+static lsx_enum_item const s_lsx_wave_enum[] = {
+  LSX_ENUM_ITEM(SOX_WAVE_,SINE)
+  LSX_ENUM_ITEM(SOX_WAVE_,TRIANGLE)
+  {0, 0}};
+
+lsx_enum_item const * lsx_get_wave_enum(void)
+{
+  return s_lsx_wave_enum;
+}
+
+void lsx_generate_wave_table(
+    lsx_wave_t wave_type,
+    sox_data_t data_type,
+    void *table,
+    size_t table_size,
+    double min,
+    double max,
+    double phase)
+{
+  uint32_t t;
+  uint32_t phase_offset = phase / M_PI / 2 * table_size + 0.5;
+
+  for (t = 0; t < table_size; t++)
+  {
+    uint32_t point = (t + phase_offset) % table_size;
+    double d;
+    switch (wave_type)
+    {
+      case SOX_WAVE_SINE:
+      d = (sin((double)point / table_size * 2 * M_PI) + 1) / 2;
+      break;
+
+      case SOX_WAVE_TRIANGLE:
+      d = (double)point * 2 / table_size;
+      switch (4 * point / table_size)
+      {
+        case 0:         d = d + 0.5; break;
+        case 1: case 2: d = 1.5 - d; break;
+        case 3:         d = d - 1.5; break;
+      }
+      break;
+
+      default: /* Oops! FIXME */
+        d = 0.0; /* Make sure we have a value */
+      break;
+    }
+    d  = d * (max - min) + min;
+    switch (data_type)
+    {
+      case SOX_FLOAT:
+        {
+          float *fp = (float *)table;
+          *fp++ = (float)d;
+          table = fp;
+          continue;
+        }
+      case SOX_DOUBLE:
+        {
+          double *dp = (double *)table;
+          *dp++ = d;
+          table = dp;
+          continue;
+        }
+      default: break;
+    }
+    d += d < 0? -0.5 : +0.5;
+    switch (data_type)
+    {
+      case SOX_SHORT:
+        {
+          short *sp = table;
+          *sp++ = (short)d;
+          table = sp;
+          continue;
+        }
+      case SOX_INT:
+        {
+          int *ip = table;
+          *ip++ = (int)d;
+          table = ip;
+          continue;
+        }
+      default: break;
+    }
+  }
+}
+
+/*
+ * lsx_parsesamples
+ *
+ * Parse a string for # of samples.  If string ends with a 's'
+ * then the string is interpreted as a user calculated # of samples.
+ * If string contains ':' or '.' or if it ends with a 't' then its
+ * treated as an amount of time.  This is converted into seconds and
+ * fraction of seconds and then use the sample rate to calculate
+ * # of samples.
+ * Returns NULL on error, pointer to next char to parse otherwise.
+ */
+char const * lsx_parsesamples(sox_rate_t rate, const char *str0, uint64_t *samples, int def)
+{
+  int i, found_samples = 0, found_time = 0;
+  char const * end;
+  char const * pos;
+  sox_bool found_colon, found_dot;
+  char * str = (char *)str0;
+
+  for (;*str == ' '; ++str);
+  for (end = str; *end && strchr("0123456789:.ets", *end); ++end);
+  if (end == str)
+    return NULL;
+
+  pos = strchr(str, ':');
+  found_colon = pos && pos < end;
+
+  pos = strchr(str, '.');
+  found_dot = pos && pos < end;
+
+  if (found_colon || found_dot || *(end-1) == 't')
+    found_time = 1;
+  else if (*(end-1) == 's')
+    found_samples = 1;
+
+  if (found_time || (def == 't' && !found_samples)) {
+    for (*samples = 0, i = 0; *str != '.' && i < 3; ++i) {
+      char * last_str = str;
+      long part = strtol(str, &str, 10);
+      if (!i && str == last_str)
+        return NULL;
+      *samples += rate * part;
+      if (i < 2) {
+        if (*str != ':')
+          break;
+        ++str;
+        *samples *= 60;
+      }
+    }
+    if (*str == '.') {
+      char * last_str = str;
+      double part = strtod(str, &str);
+      if (str == last_str)
+        return NULL;
+      *samples += rate * part + .5;
+    }
+    return *str == 't'? str + 1 : str;
+  }
+  {
+    char * last_str = str;
+    double part = strtod(str, &str);
+    if (str == last_str)
+      return NULL;
+    *samples = part + .5;
+    return *str == 's'? str + 1 : str;
+  }
+}
+
+#if 0
+
+#include <assert.h>
+
+#define TEST(st, samp, len) \
+  str = st; \
+  next = lsx_parsesamples(10000, str, &samples, 't'); \
+  assert(samples == samp && next == str + len);
+
+int main(int argc, char * * argv)
+{
+  char const * str, * next;
+  uint64_t samples;
+
+  TEST("0"  , 0, 1)
+  TEST("1" , 10000, 1)
+
+  TEST("0s" , 0, 2)
+  TEST("0s,", 0, 2)
+  TEST("0s/", 0, 2)
+  TEST("0s@", 0, 2)
+
+  TEST("0t" , 0, 2)
+  TEST("0t,", 0, 2)
+  TEST("0t/", 0, 2)
+  TEST("0t@", 0, 2)
+
+  TEST("1s" , 1, 2)
+  TEST("1s,", 1, 2)
+  TEST("1s/", 1, 2)
+  TEST("1s@", 1, 2)
+  TEST(" 01s" , 1, 4)
+  TEST("1e6s" , 1000000, 4)
+
+  TEST("1t" , 10000, 2)
+  TEST("1t,", 10000, 2)
+  TEST("1t/", 10000, 2)
+  TEST("1t@", 10000, 2)
+  TEST("1.1t" , 11000, 4)
+  TEST("1.1t,", 11000, 4)
+  TEST("1.1t/", 11000, 4)
+  TEST("1.1t@", 11000, 4)
+  TEST("1e6t" , 10000, 1)
+
+  TEST(".0", 0, 2)
+  TEST("0.0", 0, 3)
+  TEST("0:0.0", 0, 5)
+  TEST("0:0:0.0", 0, 7)
+
+  TEST(".1", 1000, 2)
+  TEST(".10", 1000, 3)
+  TEST("0.1", 1000, 3)
+  TEST("1.1", 11000, 3)
+  TEST("1:1.1", 611000, 5)
+  TEST("1:1:1.1", 36611000, 7)
+  TEST("1:1", 610000, 3)
+  TEST("1:01", 610000, 4)
+  TEST("1:1:1", 36610000, 5)
+  TEST("1:", 600000, 2)
+  TEST("1::", 36000000, 3)
+
+  TEST("0.444444", 4444, 8)
+  TEST("0.555555", 5556, 8)
+
+  assert(!lsx_parsesamples(10000, "x", &samples, 't'));
+  return 0;
+}
+#endif 
+
+/* a note is given as an int,
+ * 0   => 440 Hz = A
+ * >0  => number of half notes 'up',
+ * <0  => number of half notes down,
+ * example 12 => A of next octave, 880Hz
+ *
+ * calculated by freq = 440Hz * 2**(note/12)
+ */
+static double calc_note_freq(double note, int key)
+{
+  if (key != INT_MAX) {                         /* Just intonation. */
+    static const int n[] = {16, 9, 6, 5, 4, 7}; /* Numerator. */
+    static const int d[] = {15, 8, 5, 4, 3, 5}; /* Denominator. */
+    static double j[13];                        /* Just semitones */
+    int i, m = floor(note);
+
+    if (!j[1]) for (i = 1; i <= 12; ++i)
+      j[i] = i <= 6? log((double)n[i - 1] / d[i - 1]) / log(2.) : 1 - j[12 - i];
+    note -= m;
+    m -= key = m - ((INT_MAX / 2 - ((INT_MAX / 2) % 12) + m - key) % 12);
+    return 440 * pow(2., key / 12. + j[m] + (j[m + 1] - j[m]) * note);
+  }
+  return 440 * pow(2., note / 12);
+}
+
+int lsx_parse_note(char const * text, char * * end_ptr)
+{
+  int result = INT_MAX;
+
+  if (*text >= 'A' && *text <= 'G') {
+    result = (int)(5/3. * (*text++ - 'A') + 9.5) % 12 - 9;
+    if (*text == 'b') {--result; ++text;}
+    else if (*text == '#') {++result; ++text;}
+    if (isdigit((unsigned char)*text))
+      result += 12 * (*text++ - '4'); 
+  }
+  *end_ptr = (char *)text;
+  return result;
+}
+
+/* Read string 'text' and convert to frequency.
+ * 'text' can be a positive number which is the frequency in Hz.
+ * If 'text' starts with a '%' and a following number the corresponding
+ * note is calculated.
+ * Return -1 on error.
+ */
+double lsx_parse_frequency_k(char const * text, char * * end_ptr, int key)
+{
+  double result;
+
+  if (*text == '%') {
+    result = strtod(text + 1, end_ptr);
+    if (*end_ptr == text + 1)
+      return -1;
+    return calc_note_freq(result, key);
+  }
+  if (*text >= 'A' && *text <= 'G') {
+    int result2 = lsx_parse_note(text, end_ptr);
+    return result2 == INT_MAX? - 1 : calc_note_freq((double)result2, key);
+  }
+  result = strtod(text, end_ptr);
+  if (end_ptr) {
+    if (*end_ptr == text)
+      return -1;
+    if (**end_ptr == 'k') {
+      result *= 1000;
+      ++*end_ptr;
+    }
+  }
+  return result < 0 ? -1 : result;
+}
+
+FILE * lsx_open_input_file(sox_effect_t * effp, char const * filename)
+{
+  FILE * file;
+
+  if (!filename || !strcmp(filename, "-")) {
+    if (effp->global_info->global_info->stdin_in_use_by) {
+      lsx_fail("stdin already in use by `%s'", effp->global_info->global_info->stdin_in_use_by);
+      return NULL;
+    }
+    effp->global_info->global_info->stdin_in_use_by = effp->handler.name;
+    file = stdin;
+  }
+  else if (!(file = fopen(filename, "r"))) {
+    lsx_fail("couldn't open file %s: %s", filename, strerror(errno));
+    return NULL;
+  }
+  return file;
+}
+
+int lsx_effects_init(void)
+{
+  #ifndef __FREEDV__
+  init_fft_cache();
+  #endif
+  return SOX_SUCCESS;
+}
+
+int lsx_effects_quit(void)
+{
+  #ifndef __FREEDV__
+  clear_fft_cache();
+  #endif
+  return SOX_SUCCESS;
+}
diff --git a/freedv-dev/src/sox/formats_i.c b/freedv-dev/src/sox/formats_i.c
new file mode 100644 (file)
index 0000000..17c4061
--- /dev/null
@@ -0,0 +1,487 @@
+/* Implements a libSoX internal interface for use in implementing file formats.
+ * All public functions & data are prefixed with lsx_ .
+ *
+ * (c) 2005-8 Chris Bagwell and SoX contributors
+ *
+ * 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>
+#include <sys/stat.h>
+#include <stdarg.h>
+
+void lsx_fail_errno(sox_format_t * ft, int sox_errno, const char *fmt, ...)
+{
+  va_list args;
+
+  ft->sox_errno = sox_errno;
+
+  va_start(args, fmt);
+#ifdef HAVE_VSNPRINTF
+  vsnprintf(ft->sox_errstr, sizeof(ft->sox_errstr), fmt, args);
+#else
+  vsprintf(ft->sox_errstr, fmt, args);
+#endif
+  va_end(args);
+  ft->sox_errstr[255] = '\0';
+}
+
+void lsx_set_signal_defaults(sox_format_t * ft)
+{
+  if (!ft->signal.rate     ) ft->signal.rate      = SOX_DEFAULT_RATE;
+  if (!ft->signal.precision) ft->signal.precision = SOX_DEFAULT_PRECISION;
+  if (!ft->signal.channels ) ft->signal.channels  = SOX_DEFAULT_CHANNELS;
+
+  if (!ft->encoding.bits_per_sample)
+    ft->encoding.bits_per_sample = ft->signal.precision;
+  if (ft->encoding.encoding == SOX_ENCODING_UNKNOWN)
+    ft->encoding.encoding = SOX_ENCODING_SIGN2;
+}
+
+#ifndef __FREEDV__
+int lsx_check_read_params(sox_format_t * ft, unsigned channels,
+    sox_rate_t rate, sox_encoding_t encoding, unsigned bits_per_sample,
+    uint64_t num_samples, sox_bool check_length)
+{
+  ft->signal.length = ft->signal.length == SOX_IGNORE_LENGTH? SOX_UNSPEC : num_samples;
+
+  if (ft->seekable)
+    ft->data_start = lsx_tell(ft);
+
+  if (channels && ft->signal.channels && ft->signal.channels != channels)
+    lsx_warn("`%s': overriding number of channels", ft->filename);
+  else ft->signal.channels = channels;
+
+  if (rate && ft->signal.rate && ft->signal.rate != rate)
+    lsx_warn("`%s': overriding sample rate", ft->filename);
+  else ft->signal.rate = rate;
+
+  if (encoding && ft->encoding.encoding && ft->encoding.encoding != encoding)
+    lsx_warn("`%s': overriding encoding type", ft->filename);
+  else ft->encoding.encoding = encoding;
+
+  if (bits_per_sample && ft->encoding.bits_per_sample && ft->encoding.bits_per_sample != bits_per_sample)
+    lsx_warn("`%s': overriding encoding size", ft->filename);
+  ft->encoding.bits_per_sample = bits_per_sample;
+
+  if (check_length && ft->encoding.bits_per_sample && lsx_filelength(ft)) {
+    uint64_t calculated_length = div_bits(lsx_filelength(ft) - ft->data_start, ft->encoding.bits_per_sample);
+    if (!ft->signal.length)
+      ft->signal.length = calculated_length;
+    else if (num_samples != calculated_length)
+      lsx_warn("`%s': file header gives the total number of samples as %" PRIu64 " but file length indicates the number is in fact %" PRIu64, ft->filename, num_samples, calculated_length);
+  }
+
+  if (sox_precision(ft->encoding.encoding, ft->encoding.bits_per_sample))
+    return SOX_SUCCESS;
+  lsx_fail_errno(ft, EINVAL, "invalid format for this file type");
+  return SOX_EOF;
+}
+#endif
+
+/* Read in a buffer of data of length len bytes.
+ * Returns number of bytes read.
+ */
+size_t lsx_readbuf(sox_format_t * ft, void *buf, size_t len)
+{
+  size_t ret = fread(buf, (size_t) 1, len, (FILE*)ft->fp);
+  if (ret != len && ferror((FILE*)ft->fp))
+    lsx_fail_errno(ft, errno, "lsx_readbuf");
+  ft->tell_off += ret;
+  return ret;
+}
+
+/* Skip input without seeking. */
+int lsx_skipbytes(sox_format_t * ft, size_t n)
+{
+  unsigned char trash;
+
+  while (n--)
+    if (lsx_readb(ft, &trash) == SOX_EOF)
+      return (SOX_EOF);
+
+  return (SOX_SUCCESS);
+}
+
+/* Pad output. */
+int lsx_padbytes(sox_format_t * ft, size_t n)
+{
+  while (n--)
+    if (lsx_writeb(ft, '\0') == SOX_EOF)
+      return (SOX_EOF);
+
+  return (SOX_SUCCESS);
+}
+
+/* Write a buffer of data of length bytes.
+ * Returns number of bytes written.
+ */
+size_t lsx_writebuf(sox_format_t * ft, void const * buf, size_t len)
+{
+  size_t ret = fwrite(buf, (size_t) 1, len, (FILE*)ft->fp);
+  if (ret != len) {
+    lsx_fail_errno(ft, errno, "error writing output file");
+    clearerr((FILE*)ft->fp); /* Allows us to seek back to write header */
+  }
+  ft->tell_off += ret;
+  return ret;
+}
+
+uint64_t lsx_filelength(sox_format_t * ft)
+{
+  struct stat st;
+  int ret = fstat(fileno((FILE*)ft->fp), &st);
+
+  return (!ret && (st.st_mode & S_IFREG))? (uint64_t)st.st_size : 0;
+}
+
+int lsx_flush(sox_format_t * ft)
+{
+  return fflush((FILE*)ft->fp);
+}
+
+off_t lsx_tell(sox_format_t * ft)
+{
+  return ft->seekable? (off_t)ftello((FILE*)ft->fp) : (off_t)ft->tell_off;
+}
+
+int lsx_eof(sox_format_t * ft)
+{
+  return feof((FILE*)ft->fp);
+}
+
+int lsx_error(sox_format_t * ft)
+{
+  return ferror((FILE*)ft->fp);
+}
+
+void lsx_rewind(sox_format_t * ft)
+{
+  rewind((FILE*)ft->fp);
+  ft->tell_off = 0;
+}
+
+void lsx_clearerr(sox_format_t * ft)
+{
+  clearerr((FILE*)ft->fp);
+  ft->sox_errno = 0;
+}
+
+int lsx_unreadb(sox_format_t * ft, unsigned b)
+{
+  return ungetc((int)b, ft->fp);
+}
+
+/* Implements traditional fseek() behavior.  Meant to abstract out
+ * file operations so that they could one day also work on memory
+ * buffers.
+ *
+ * N.B. Can only seek forwards on non-seekable streams!
+ */
+int lsx_seeki(sox_format_t * ft, off_t offset, int whence)
+{
+    if (ft->seekable == 0) {
+        /* If a stream peel off chars else EPERM */
+        if (whence == SEEK_CUR) {
+            while (offset > 0 && !feof((FILE*)ft->fp)) {
+                getc((FILE*)ft->fp);
+                offset--;
+                ++ft->tell_off;
+            }
+            if (offset)
+                lsx_fail_errno(ft,SOX_EOF, "offset past EOF");
+            else
+                ft->sox_errno = SOX_SUCCESS;
+        } else
+            lsx_fail_errno(ft,SOX_EPERM, "file not seekable");
+    } else {
+        if (fseeko((FILE*)ft->fp, offset, whence) == -1)
+            lsx_fail_errno(ft,errno, "%s", strerror(errno));
+        else
+            ft->sox_errno = SOX_SUCCESS;
+    }
+    return ft->sox_errno;
+}
+
+int lsx_offset_seek(sox_format_t * ft, off_t byte_offset, off_t to_sample)
+{
+  double wide_sample = to_sample - (to_sample % ft->signal.channels);
+  double to_d = wide_sample * ft->encoding.bits_per_sample / 8;
+  off_t to = to_d;
+  return (to != to_d)? SOX_EOF : lsx_seeki(ft, (byte_offset + to), SEEK_SET);
+}
+
+/* Read and write known datatypes in "machine format".  Swap if indicated.
+ * They all return SOX_EOF on error and SOX_SUCCESS on success.
+ */
+/* Read n-char string (and possibly null-terminating).
+ * Stop reading and null-terminate string if either a 0 or \n is reached.
+ */
+int lsx_reads(sox_format_t * ft, char *c, size_t len)
+{
+    char *sc;
+    char in;
+
+    sc = c;
+    do
+    {
+        if (lsx_readbuf(ft, &in, (size_t)1) != 1)
+        {
+            *sc = 0;
+            return (SOX_EOF);
+        }
+        if (in == 0 || in == '\n')
+            break;
+
+        *sc = in;
+        sc++;
+    } while (sc - c < (ptrdiff_t)len);
+    *sc = 0;
+    return(SOX_SUCCESS);
+}
+
+/* Write null-terminated string (without \0). */
+int lsx_writes(sox_format_t * ft, char const * c)
+{
+        if (lsx_writebuf(ft, c, strlen(c)) != strlen(c))
+                return(SOX_EOF);
+        return(SOX_SUCCESS);
+}
+
+/* return swapped 32-bit float */
+static void lsx_swapf(float * f)
+{
+    union {
+        uint32_t dw;
+        float f;
+    } u;
+
+    u.f= *f;
+    u.dw= (u.dw>>24) | ((u.dw>>8)&0xff00) | ((u.dw<<8)&0xff0000) | (u.dw<<24);
+    *f = u.f;
+}
+
+static void swap(void * data, size_t len)
+{
+  uint8_t * bytes = (uint8_t *)data;
+  size_t i;
+
+  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 data)
+{
+  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,
+  0x30, 0xB0, 0x70, 0xF0, 0x08, 0x88, 0x48, 0xC8, 0x28, 0xA8, 0x68, 0xE8,
+  0x18, 0x98, 0x58, 0xD8, 0x38, 0xB8, 0x78, 0xF8, 0x04, 0x84, 0x44, 0xC4,
+  0x24, 0xA4, 0x64, 0xE4, 0x14, 0x94, 0x54, 0xD4, 0x34, 0xB4, 0x74, 0xF4,
+  0x0C, 0x8C, 0x4C, 0xCC, 0x2C, 0xAC, 0x6C, 0xEC, 0x1C, 0x9C, 0x5C, 0xDC,
+  0x3C, 0xBC, 0x7C, 0xFC, 0x02, 0x82, 0x42, 0xC2, 0x22, 0xA2, 0x62, 0xE2,
+  0x12, 0x92, 0x52, 0xD2, 0x32, 0xB2, 0x72, 0xF2, 0x0A, 0x8A, 0x4A, 0xCA,
+  0x2A, 0xAA, 0x6A, 0xEA, 0x1A, 0x9A, 0x5A, 0xDA, 0x3A, 0xBA, 0x7A, 0xFA,
+  0x06, 0x86, 0x46, 0xC6, 0x26, 0xA6, 0x66, 0xE6, 0x16, 0x96, 0x56, 0xD6,
+  0x36, 0xB6, 0x76, 0xF6, 0x0E, 0x8E, 0x4E, 0xCE, 0x2E, 0xAE, 0x6E, 0xEE,
+  0x1E, 0x9E, 0x5E, 0xDE, 0x3E, 0xBE, 0x7E, 0xFE, 0x01, 0x81, 0x41, 0xC1,
+  0x21, 0xA1, 0x61, 0xE1, 0x11, 0x91, 0x51, 0xD1, 0x31, 0xB1, 0x71, 0xF1,
+  0x09, 0x89, 0x49, 0xC9, 0x29, 0xA9, 0x69, 0xE9, 0x19, 0x99, 0x59, 0xD9,
+  0x39, 0xB9, 0x79, 0xF9, 0x05, 0x85, 0x45, 0xC5, 0x25, 0xA5, 0x65, 0xE5,
+  0x15, 0x95, 0x55, 0xD5, 0x35, 0xB5, 0x75, 0xF5, 0x0D, 0x8D, 0x4D, 0xCD,
+  0x2D, 0xAD, 0x6D, 0xED, 0x1D, 0x9D, 0x5D, 0xDD, 0x3D, 0xBD, 0x7D, 0xFD,
+  0x03, 0x83, 0x43, 0xC3, 0x23, 0xA3, 0x63, 0xE3, 0x13, 0x93, 0x53, 0xD3,
+  0x33, 0xB3, 0x73, 0xF3, 0x0B, 0x8B, 0x4B, 0xCB, 0x2B, 0xAB, 0x6B, 0xEB,
+  0x1B, 0x9B, 0x5B, 0xDB, 0x3B, 0xBB, 0x7B, 0xFB, 0x07, 0x87, 0x47, 0xC7,
+  0x27, 0xA7, 0x67, 0xE7, 0x17, 0x97, 0x57, 0xD7, 0x37, 0xB7, 0x77, 0xF7,
+  0x0F, 0x8F, 0x4F, 0xCF, 0x2F, 0xAF, 0x6F, 0xEF, 0x1F, 0x9F, 0x5F, 0xDF,
+  0x3F, 0xBF, 0x7F, 0xFF
+};
+
+/* Utilities to byte-swap values, use libc optimized macros if possible  */
+#define TWIDDLE_BYTE(ub, type) \
+  do { \
+    if (ft->encoding.reverse_bits) \
+      ub = cswap[ub]; \
+    if (ft->encoding.reverse_nibbles) \
+      ub = ((ub & 15) << 4) | (ub >> 4); \
+  } while (0);
+
+#define TWIDDLE_WORD(uw, type) \
+  if (ft->encoding.reverse_bytes) \
+    uw = lsx_swap ## type(uw);
+
+#define TWIDDLE_FLOAT(f, type) \
+  if (ft->encoding.reverse_bytes) \
+    lsx_swapf(&f);
+
+/* N.B. This macro doesn't work for unaligned types (e.g. 3-byte
+   types). */
+#define READ_FUNC(type, size, ctype, twiddle) \
+  size_t lsx_read_ ## type ## _buf( \
+      sox_format_t * ft, ctype *buf, size_t len) \
+  { \
+    size_t n, nread; \
+    nread = lsx_readbuf(ft, buf, len * size) / size; \
+    for (n = 0; n < nread; n++) \
+      twiddle(buf[n], type); \
+    return nread; \
+  }
+
+/* Unpack a 3-byte value from a uint8_t * */
+#define sox_unpack3(p) (ft->encoding.reverse_bytes == MACHINE_IS_BIGENDIAN? \
+  ((p)[0] | ((p)[1] << 8) | ((p)[2] << 16)) : \
+  ((p)[2] | ((p)[1] << 8) | ((p)[0] << 16)))
+
+/* This (slower) macro works for unaligned types (e.g. 3-byte types)
+   that need to be unpacked. */
+#define READ_FUNC_UNPACK(type, size, ctype, twiddle) \
+  size_t lsx_read_ ## type ## _buf( \
+      sox_format_t * ft, ctype *buf, size_t len) \
+  { \
+    size_t n, nread; \
+    uint8_t *data = lsx_malloc(size * len); \
+    nread = lsx_readbuf(ft, data, len * size) / size; \
+    for (n = 0; n < nread; n++) \
+      buf[n] = sox_unpack ## size(data + n * size); \
+    free(data); \
+    return n; \
+  }
+
+READ_FUNC(b, 1, uint8_t, TWIDDLE_BYTE)
+READ_FUNC(w, 2, uint16_t, TWIDDLE_WORD)
+READ_FUNC_UNPACK(3, 3, sox_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)
+
+#define READ1_FUNC(type, ctype) \
+int lsx_read ## type(sox_format_t * ft, ctype * datum) { \
+  if (lsx_read_ ## type ## _buf(ft, datum, (size_t)1) == 1) \
+    return SOX_SUCCESS; \
+  if (!lsx_error(ft)) \
+    lsx_fail_errno(ft, errno, premature_eof); \
+  return SOX_EOF; \
+}
+
+static char const premature_eof[] = "premature EOF";
+
+READ1_FUNC(b,  uint8_t)
+READ1_FUNC(w,  uint16_t)
+READ1_FUNC(3,  sox_uint24_t)
+READ1_FUNC(dw, uint32_t)
+READ1_FUNC(qw, uint64_t)
+READ1_FUNC(f,  float)
+READ1_FUNC(df, double)
+
+int lsx_readchars(sox_format_t * ft, char * chars, size_t len)
+{
+  size_t ret = lsx_readbuf(ft, chars, len);
+  if (ret == len)
+    return SOX_SUCCESS;
+  if (!lsx_error(ft))
+    lsx_fail_errno(ft, errno, premature_eof);
+  return SOX_EOF;
+}
+
+/* N.B. This macro doesn't work for unaligned types (e.g. 3-byte
+   types). */
+#define WRITE_FUNC(type, size, ctype, twiddle) \
+  size_t lsx_write_ ## type ## _buf( \
+      sox_format_t * ft, ctype *buf, size_t len) \
+  { \
+    size_t n, nwritten; \
+    for (n = 0; n < len; n++) \
+      twiddle(buf[n], type); \
+    nwritten = lsx_writebuf(ft, buf, len * size); \
+    return nwritten / size; \
+  }
+
+/* Pack a 3-byte value to a uint8_t * */
+#define sox_pack3(p, v) do {if (ft->encoding.reverse_bytes == MACHINE_IS_BIGENDIAN)\
+{(p)[0] = v & 0xff; (p)[1] = (v >> 8) & 0xff; (p)[2] = (v >> 16) & 0xff;} else \
+{(p)[2] = v & 0xff; (p)[1] = (v >> 8) & 0xff; (p)[0] = (v >> 16) & 0xff;} \
+} while (0)
+
+/* This (slower) macro works for unaligned types (e.g. 3-byte types)
+   that need to be packed. */
+#define WRITE_FUNC_PACK(type, size, ctype, twiddle) \
+  size_t lsx_write_ ## type ## _buf( \
+      sox_format_t * ft, ctype *buf, size_t len) \
+  { \
+    size_t n, nwritten; \
+    uint8_t *data = lsx_malloc(size * len); \
+    for (n = 0; n < len; n++) \
+      sox_pack ## size(data + n * size, buf[n]); \
+    nwritten = lsx_writebuf(ft, data, len * size); \
+    free(data); \
+    return nwritten / size; \
+  }
+
+WRITE_FUNC(b, 1, uint8_t, TWIDDLE_BYTE)
+WRITE_FUNC(w, 2, uint16_t, TWIDDLE_WORD)
+WRITE_FUNC_PACK(3, 3, sox_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)
+
+#define WRITE1U_FUNC(type, ctype) \
+  int lsx_write ## type(sox_format_t * ft, unsigned d) \
+  { ctype datum = (ctype)d; \
+    return lsx_write_ ## type ## _buf(ft, &datum, (size_t)1) == 1 ? SOX_SUCCESS : SOX_EOF; \
+  }
+
+#define WRITE1S_FUNC(type, ctype) \
+  int lsx_writes ## type(sox_format_t * ft, signed d) \
+  { ctype datum = (ctype)d; \
+    return lsx_write_ ## type ## _buf(ft, &datum, (size_t)1) == 1 ? SOX_SUCCESS : SOX_EOF; \
+  }
+
+#define WRITE1_FUNC(type, ctype) \
+  int lsx_write ## type(sox_format_t * ft, ctype datum) \
+  { \
+    return lsx_write_ ## type ## _buf(ft, &datum, (size_t)1) == 1 ? SOX_SUCCESS : SOX_EOF; \
+  }
+
+WRITE1U_FUNC(b, uint8_t)
+WRITE1U_FUNC(w, uint16_t)
+WRITE1U_FUNC(3, sox_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)
+
+int lsx_writef(sox_format_t * ft, double datum)
+{
+  float f = datum;
+  return lsx_write_f_buf(ft, &f, (size_t) 1) == 1 ? SOX_SUCCESS : SOX_EOF;
+}
diff --git a/freedv-dev/src/sox/libsox.c b/freedv-dev/src/sox/libsox.c
new file mode 100644 (file)
index 0000000..4362025
--- /dev/null
@@ -0,0 +1,225 @@
+/* Implements the public API for libSoX general functions
+ * All public functions & data are prefixed with sox_ .
+ *
+ * (c) 2006-8 Chris Bagwell and SoX contributors
+ *
+ * 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>
+
+const char *sox_version(void)
+{
+  static char versionstr[20];
+
+  sprintf(versionstr, "%d.%d.%d",
+          (SOX_LIB_VERSION_CODE & 0xff0000) >> 16,
+          (SOX_LIB_VERSION_CODE & 0x00ff00) >> 8,
+          (SOX_LIB_VERSION_CODE & 0x0000ff));
+  return(versionstr);
+}
+
+sox_version_info_t const * sox_version_info(void)
+{
+#define STRINGIZE1(x) #x
+#define STRINGIZE(x) STRINGIZE1(x)
+    static char arch[30];
+    static sox_version_info_t info = {
+        /* size */
+        sizeof(sox_version_info_t),
+        /* flags */
+        (sox_version_flags_t)(
+#if HAVE_POPEN
+        sox_version_have_popen +
+#endif
+#if  HAVE_MAGIC
+        sox_version_have_magic +
+#endif
+#if HAVE_OPENMP
+        sox_version_have_threads +
+#endif
+#ifdef HAVE_FMEMOPEN
+        sox_version_have_memopen +
+#endif
+        sox_version_none),
+        /* version_code */
+        SOX_LIB_VERSION_CODE,
+        /* version */
+        NULL,
+        /* sox_version_extra */
+#ifdef PACKAGE_EXTRA
+        PACKAGE_EXTRA,
+#else
+        NULL,
+#endif
+        /* sox_time */
+        __DATE__ " " __TIME__,
+        /* sox_distro */
+#ifdef DISTRO
+        DISTRO,
+#else
+        NULL,
+#endif
+        /* sox_compiler */
+#if defined __GNUC__
+        "gcc " __VERSION__,
+#elif defined _MSC_VER
+        "msvc " STRINGIZE(_MSC_FULL_VER),
+#elif defined __SUNPRO_C
+    fprintf(file, "sun c " STRINGIZE(__SUNPRO_C),
+#else
+        NULL,
+#endif
+        /* sox_arch */
+        NULL
+    };
+
+    if (!info.version)
+    {
+        info.version = sox_version();
+    }
+
+    if (!info.arch)
+    {
+        snprintf(arch, sizeof(arch),
+            "%" PRIuPTR "%" PRIuPTR "%" PRIuPTR "%" PRIuPTR
+            " %" PRIuPTR "%" PRIuPTR " %" PRIuPTR "%" PRIuPTR " %c %s",
+            sizeof(char), sizeof(short), sizeof(long), sizeof(off_t),
+            sizeof(float), sizeof(double), sizeof(int *), sizeof(int (*)(void)),
+            MACHINE_IS_BIGENDIAN ? 'B' : 'L',
+            (info.flags & sox_version_have_threads) ? "OMP" : "");
+        arch[sizeof(arch) - 1] = 0;
+        info.arch = arch;
+    }
+
+    return &info;
+}
+
+/* Default routine to output messages; can be overridden */
+static void output_message(
+    unsigned level, const char *filename, const char *fmt, va_list ap)
+{
+  if (sox_globals.verbosity >= level) {
+    char base_name[128];
+    sox_basename(base_name, sizeof(base_name), filename);
+    fprintf(stderr, "%s: ", base_name);
+    vfprintf(stderr, fmt, ap);
+    fprintf(stderr, "\n");
+  }
+}
+
+static sox_globals_t s_sox_globals = {
+  2,               /* unsigned     verbosity */
+  output_message,  /* sox_output_message_handler */
+  sox_false,       /* sox_bool     repeatable */
+  8192,            /* size_t       bufsiz */
+  0,               /* size_t       input_bufsiz */
+  0,               /* int32_t      ranqd1 */
+  NULL,            /* char const * stdin_in_use_by */
+  NULL,            /* char const * stdout_in_use_by */
+  NULL,            /* char const * subsystem */
+  NULL,            /* char       * tmp_path */
+  sox_false,       /* sox_bool     use_magic */
+  sox_false        /* sox_bool     use_threads */
+};
+
+sox_globals_t * sox_get_globals(void)
+{
+    return &s_sox_globals;
+}
+
+/* FIXME: Not thread safe using globals */
+static sox_effects_globals_t s_sox_effects_globals =
+    {sox_plot_off, &s_sox_globals};
+
+sox_effects_globals_t *
+sox_get_effects_globals(void)
+{
+    return &s_sox_effects_globals;
+}
+
+char const * sox_strerror(int sox_errno)
+{
+  static char const * const errors[] = {
+    "Invalid Audio Header",
+    "Unsupported data format",
+    "Can't allocate memory",
+    "Operation not permitted",
+    "Operation not supported",
+    "Invalid argument",
+  };
+  if (sox_errno < SOX_EHDR)
+    return strerror(sox_errno);
+  sox_errno -= SOX_EHDR;
+  if (sox_errno < 0 || (size_t)sox_errno >= array_length(errors))
+    return "Unknown error";
+  return errors[sox_errno];
+}
+
+size_t sox_basename(char * base_buffer, size_t base_buffer_len, const char * filename)
+{
+  if (!base_buffer || !base_buffer_len)
+  {
+    return 0;
+  }
+  else
+  {
+    char const * slash_pos = LAST_SLASH(filename);
+    char const * base_name = slash_pos ? slash_pos + 1 : filename;
+    char const * dot_pos   = strrchr(base_name, '.');
+    size_t i, len;
+    dot_pos = dot_pos ? dot_pos : base_name + strlen(base_name);
+    len = dot_pos - base_name;
+    len = min(len, base_buffer_len - 1);
+    for (i = 0; i < len; i++)
+    {
+      base_buffer[i] = base_name[i];
+    }
+    base_buffer[i] = 0;
+    return i;
+  }
+}
+
+#define SOX_MESSAGE_FUNCTION(name,level) \
+void name(char const * fmt, ...) { \
+  va_list ap; \
+  va_start(ap, fmt); \
+  if (sox_globals.output_message_handler) \
+    (*sox_globals.output_message_handler)(level,sox_globals.subsystem,fmt,ap); \
+  va_end(ap); \
+}
+
+SOX_MESSAGE_FUNCTION(lsx_fail_impl  , 1)
+SOX_MESSAGE_FUNCTION(lsx_warn_impl  , 2)
+SOX_MESSAGE_FUNCTION(lsx_report_impl, 3)
+SOX_MESSAGE_FUNCTION(lsx_debug_impl , 4)
+SOX_MESSAGE_FUNCTION(lsx_debug_more_impl , 5)
+SOX_MESSAGE_FUNCTION(lsx_debug_most_impl , 6)
+
+#undef SOX_MESSAGE_FUNCTION
+
+int sox_init(void)
+{
+  return lsx_effects_init();
+}
+
+int sox_quit(void)
+{
+  #ifndef __FREEDV__
+  sox_format_quit();
+  #endif
+  return lsx_effects_quit();
+}
diff --git a/freedv-dev/src/sox/sox.h b/freedv-dev/src/sox/sox.h
new file mode 100644 (file)
index 0000000..0537255
--- /dev/null
@@ -0,0 +1,2608 @@
+/* libSoX Library Public Interface
+ *
+ * Copyright 1999-2011 Chris Bagwell and SoX Contributors.
+ *
+ * This source code is freely redistributable and may be used for
+ * any purpose.  This copyright notice must be maintained.
+ * Chris Bagwell And SoX Contributors are not responsible for
+ * the consequences of using this software.
+ */
+
+/** @file
+Contains the interface exposed to clients of the libSoX library.
+Symbols starting with "sox_" or "SOX_" are part of the public interface for
+libSoX clients (applications that consume libSoX). Symbols starting with
+"lsx_" or "LSX_" are internal use by libSoX and plugins.
+LSX_ and lsx_ symbols should not be used by libSoX-based applications.
+*/
+
+#ifndef SOX_H
+#define SOX_H /**< Client API: This macro is defined if sox.h has been included. */
+
+#include <limits.h>
+#include <stdarg.h>
+#include <stddef.h>
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+/* Suppress warnings from use of type long long. */
+#if defined __GNUC__
+#pragma GCC system_header
+#endif
+
+/*****************************************************************************
+API decoration macros:
+Mostly for documentation purposes. For some compilers, decorations also affect
+code generation, influence compiler warnings or activate compiler
+optimizations.
+*****************************************************************************/
+
+/**
+Plugins API:
+Attribute required on all functions exported by libSoX and on all function
+pointer types used by the libSoX API.
+*/
+#ifdef __GNUC__
+#define LSX_API  __attribute__ ((cdecl)) /* libSoX function */
+#elif _MSC_VER
+#define LSX_API  __cdecl /* libSoX function */
+#else
+#define LSX_API /* libSoX function */
+#endif
+
+/**
+Plugins API:
+Attribute applied to a parameter or local variable to suppress warnings about
+the variable being unused (especially in macro-generated code).
+*/
+#ifdef __GNUC__
+#define LSX_UNUSED  __attribute__ ((unused)) /* Parameter or local variable is intentionally unused. */
+#else
+#define LSX_UNUSED /* Parameter or local variable is intentionally unused. */
+#endif
+
+/**
+Plugins API:
+LSX_PRINTF12: Attribute applied to a function to indicate that it requires
+a printf-style format string for arg1 and that printf parameters start at
+arg2.
+*/
+#ifdef __GNUC__
+#define LSX_PRINTF12  __attribute__ ((format (printf, 1, 2))) /* Function has printf-style arguments. */
+#else
+#define LSX_PRINTF12 /* Function has printf-style arguments. */
+#endif
+
+/**
+Plugins API:
+Attribute applied to a function to indicate that it has no side effects and
+depends only its input parameters and global memory. If called repeatedly, it
+returns the same result each time.
+*/
+#ifdef __GNUC__
+#define LSX_RETURN_PURE __attribute__ ((pure)) /* Function is pure. */
+#else
+#define LSX_RETURN_PURE /* Function is pure. */
+#endif
+
+/**
+Plugins API:
+Attribute applied to a function to indicate that the
+return value is always a pointer to a valid object (never NULL).
+*/
+#ifdef _Ret_
+#define LSX_RETURN_VALID _Ret_ /* Function always returns a valid object (never NULL). */
+#else
+#define LSX_RETURN_VALID /* Function always returns a valid object (never NULL). */
+#endif
+
+/**
+Plugins API:
+Attribute applied to a function to indicate that the return value is always a
+pointer to a valid array (never NULL).
+*/
+#ifdef _Ret_valid_
+#define LSX_RETURN_ARRAY _Ret_valid_ /* Function always returns a valid array (never NULL). */
+#else
+#define LSX_RETURN_ARRAY /* Function always returns a valid array (never NULL). */
+#endif
+
+/**
+Plugins API:
+Attribute applied to a function to indicate that the return value is always a
+pointer to a valid 0-terminated array (never NULL).
+*/
+#ifdef _Ret_z_
+#define LSX_RETURN_VALID_Z _Ret_z_ /* Function always returns a 0-terminated array (never NULL). */
+#else
+#define LSX_RETURN_VALID_Z /* Function always returns a 0-terminated array (never NULL). */
+#endif
+
+/**
+Plugins API:
+Attribute applied to a function to indicate that the returned pointer may be
+null.
+*/
+#ifdef _Ret_opt_
+#define LSX_RETURN_OPT _Ret_opt_ /* Function may return NULL. */
+#else
+#define LSX_RETURN_OPT /* Function may return NULL. */
+#endif
+
+/**
+Plugins API:
+Attribute applied to a parameter to indicate that the parameter is a valid
+pointer to one const element of the pointed-to type (never NULL).
+*/
+#ifdef _In_
+#define LSX_PARAM_IN _In_ /* Required const pointer to a valid object (never NULL). */
+#else
+#define LSX_PARAM_IN /* Required const pointer to a valid object (never NULL). */
+#endif
+
+/**
+Plugins API:
+Attribute applied to a parameter to indicate that the parameter is a valid
+pointer to a const 0-terminated string (never NULL).
+*/
+#ifdef _In_z_
+#define LSX_PARAM_IN_Z _In_z_ /* Required const pointer to 0-terminated string (never NULL). */
+#else
+#define LSX_PARAM_IN_Z /* Required const pointer to 0-terminated string (never NULL). */
+#endif
+
+/**
+Plugins API:
+Attribute applied to a parameter to indicate that the parameter is a const
+pointer to a 0-terminated printf format string.
+*/
+#ifdef _Printf_format_string_
+#define LSX_PARAM_IN_PRINTF _Printf_format_string_ /* Required const pointer to 0-terminated printf format string (never NULL). */
+#else
+#define LSX_PARAM_IN_PRINTF /* Required const pointer to 0-terminated printf format string (never NULL). */
+#endif
+
+/**
+Plugins API:
+Attribute applied to a parameter to indicate that the parameter is a valid
+pointer to (len) const initialized elements of the pointed-to type, where
+(len) is the name of another parameter.
+@param len The parameter that contains the number of elements in the array.
+*/
+#ifdef _In_count_
+#define LSX_PARAM_IN_COUNT(len) _In_count_(len) /* Required const pointer to (len) valid objects (never NULL). */
+#else
+#define LSX_PARAM_IN_COUNT(len) /* Required const pointer to (len) valid objects (never NULL). */
+#endif
+
+/**
+Plugins API:
+Attribute applied to a parameter to indicate that the parameter is a valid
+pointer to (len) const bytes of initialized data, where (len) is the name of
+another parameter.
+@param len The parameter that contains the number of bytes in the array.
+*/
+#ifdef _In_bytecount_
+#define LSX_PARAM_IN_BYTECOUNT(len) _In_bytecount_(len) /* Required const pointer to (len) bytes of data (never NULL). */
+#else
+#define LSX_PARAM_IN_BYTECOUNT(len) /* Required const pointer to (len) bytes of data (never NULL). */
+#endif
+
+/**
+Plugins API:
+Attribute applied to a parameter to indicate that the parameter is either NULL
+or a valid pointer to one const element of the pointed-to type.
+*/
+#ifdef _In_opt_
+#define LSX_PARAM_IN_OPT _In_opt_ /* Optional const pointer to a valid object (may be NULL). */
+#else
+#define LSX_PARAM_IN_OPT /* Optional const pointer to a valid object (may be NULL). */
+#endif
+
+/**
+Plugins API:
+Attribute applied to a parameter to indicate that the parameter is either NULL
+or a valid pointer to a const 0-terminated string.
+*/
+#ifdef _In_opt_z_
+#define LSX_PARAM_IN_OPT_Z _In_opt_z_ /* Optional const pointer to 0-terminated string (may be NULL). */
+#else
+#define LSX_PARAM_IN_OPT_Z /* Optional const pointer to 0-terminated string (may be NULL). */
+#endif
+
+/**
+Plugins API:
+Attribute applied to a parameter to indicate that the parameter is a valid
+pointer to one initialized element of the pointed-to type (never NULL). The
+function may modify the element.
+*/
+#ifdef _Inout_
+#define LSX_PARAM_INOUT _Inout_ /* Required pointer to a valid object (never NULL). */
+#else
+#define LSX_PARAM_INOUT /* Required pointer to a valid object (never NULL). */
+#endif
+
+/**
+Plugins API:
+Attribute applied to a parameter to indicate that the parameter is a valid
+pointer to (len) initialized elements of the pointed-to type (never NULL). The
+function may modify the elements.
+@param len The parameter that contains the number of elements in the array.
+*/
+#ifdef _Inout_count_x_
+#define LSX_PARAM_INOUT_COUNT(len) _Inout_count_x_(len) /* Required pointer to (len) valid objects (never NULL). */
+#else
+#define LSX_PARAM_INOUT_COUNT(len) /* Required pointer to (len) valid objects (never NULL). */
+#endif
+
+/**
+Plugins API:
+Attribute applied to a parameter to indicate that the parameter is a valid
+pointer to memory sufficient for one element of the pointed-to type (never
+NULL). The function will initialize the element.
+*/
+#ifdef _Out_
+#define LSX_PARAM_OUT _Out_ /* Required pointer to an object to be initialized (never NULL). */
+#else
+#define LSX_PARAM_OUT /* Required pointer to an object to be initialized (never NULL). */
+#endif
+
+/**
+Plugins API:
+Attribute applied to a parameter to indicate that the parameter is a valid
+pointer to memory sufficient for (len) bytes of data (never NULL), where (len)
+is the name of another parameter. The function may write up to len bytes of
+data to this memory.
+@param len The parameter that contains the number of bytes in the array.
+*/
+#ifdef _Out_bytecap_
+#define LSX_PARAM_OUT_BYTECAP(len) _Out_bytecap_(len) /* Required pointer to writable buffer with room for len bytes. */
+#else
+#define LSX_PARAM_OUT_BYTECAP(len) /* Required pointer to writable buffer with room for len bytes. */
+#endif
+
+/**
+Plugins API:
+Attribute applied to a parameter to indicate that the parameter is a valid
+pointer to memory sufficient for (len) elements of the pointed-to type (never
+NULL), where (len) is the name of another parameter. On return, (filled)
+elements will have been initialized, where (filled) is either the dereference
+of another pointer parameter (for example "*written") or the "return"
+parameter (indicating that the function returns the number of elements
+written).
+@param len The parameter that contains the number of elements in the array.
+@param filled The dereference of the parameter that receives the number of elements written to the array, or "return" if the value is returned.
+*/
+#ifdef _Out_cap_post_count_
+#define LSX_PARAM_OUT_CAP_POST_COUNT(len,filled) _Out_cap_post_count_(len,filled) /* Required pointer to buffer for (len) elements (never NULL); on return, (filled) elements will have been initialized. */
+#else
+#define LSX_PARAM_OUT_CAP_POST_COUNT(len,filled) /* Required pointer to buffer for (len) elements (never NULL); on return, (filled) elements will have been initialized. */
+#endif
+
+/**
+Plugins API:
+Attribute applied to a parameter to indicate that the parameter is a valid
+pointer to memory sufficient for (len) elements of the pointed-to type (never
+NULL), where (len) is the name of another parameter. On return, (filled+1)
+elements will have been initialized, with the last element having been
+initialized to 0, where (filled) is either the dereference of another pointer
+parameter (for example, "*written") or the "return" parameter (indicating that
+the function returns the number of elements written).
+@param len The parameter that contains the number of elements in the array.
+@param filled The dereference of the parameter that receives the number of elements written to the array (not counting the terminating null), or "return" if the value is returned.
+*/
+#ifdef _Out_z_cap_post_count_
+#define LSX_PARAM_OUT_Z_CAP_POST_COUNT(len,filled) _Out_z_cap_post_count_(len,filled) /* Required pointer to buffer for (len) elements (never NULL); on return, (filled+1) elements will have been initialized, and the array will be 0-terminated. */
+#else
+#define LSX_PARAM_OUT_Z_CAP_POST_COUNT(len,filled) /* Required pointer to buffer for (len) elements (never NULL); on return, (filled+1) elements will have been initialized, and the array will be 0-terminated. */
+#endif
+
+/**
+Plugins API:
+Attribute applied to a parameter to indicate that the parameter is either NULL
+or a valid pointer to memory sufficient for one element of the pointed-to
+type. The function will initialize the element.
+*/
+#ifdef _Out_opt_
+#define LSX_PARAM_OUT_OPT _Out_opt_ /* Optional pointer to an object to be initialized (may be NULL). */
+#else
+#define LSX_PARAM_OUT_OPT /* Optional pointer to an object to be initialized (may be NULL). */
+#endif
+
+/**
+Plugins API:
+Attribute applied to a parameter to indicate that the parameter is a valid
+pointer (never NULL) to another pointer which may be NULL when the function is
+invoked.
+*/
+#ifdef _Deref_pre_maybenull_
+#define LSX_PARAM_DEREF_PRE_MAYBENULL _Deref_pre_maybenull_ /* Required pointer (never NULL) to another pointer (may be NULL). */
+#else
+#define LSX_PARAM_DEREF_PRE_MAYBENULL /* Required pointer (never NULL) to another pointer (may be NULL). */
+#endif
+
+/**
+Plugins API:
+Attribute applied to a parameter to indicate that the parameter is a valid
+pointer (never NULL) to another pointer which will be NULL when the function
+returns.
+*/
+#ifdef _Deref_post_null_
+#define LSX_PARAM_DEREF_POST_NULL _Deref_post_null_ /* Required pointer (never NULL) to another pointer, which will be NULL on exit. */
+#else
+#define LSX_PARAM_DEREF_POST_NULL /* Required pointer (never NULL) to another pointer, which will be NULL on exit. */
+#endif
+
+/**
+Plugins API:
+Attribute applied to a parameter to indicate that the parameter is a valid
+pointer (never NULL) to another pointer which will be non-NULL when the
+function returns.
+*/
+#ifdef _Deref_post_notnull_
+#define LSX_PARAM_DEREF_POST_NOTNULL _Deref_post_notnull_ /* Required pointer (never NULL) to another pointer, which will be valid (not NULL) on exit. */
+#else
+#define LSX_PARAM_DEREF_POST_NOTNULL /* Required pointer (never NULL) to another pointer, which will be valid (not NULL) on exit. */
+#endif
+
+/**
+Plugins API:
+Expression that "uses" a potentially-unused variable to avoid compiler
+warnings (especially in macro-generated code).
+*/
+#ifdef _PREFAST_
+#define LSX_USE_VAR(x)  ((void)(x=0)) /* During static analysis, initialize unused variables to 0. */
+#else
+#define LSX_USE_VAR(x)  ((void)(x)) /* Parameter or variable is intentionally unused. */
+#endif
+
+/**
+Plugins API:
+Compile-time assertion. Causes a compile error if the expression is false.
+@param e  The expression to test. If expression is false, compilation will fail.
+@param f  A unique identifier for the test, for example foo_must_not_be_zero.
+*/
+#define lsx_static_assert(e,f) enum {lsx_static_assert_##f = 1/((e) ? 1 : 0)}
+
+/*****************************************************************************
+Basic typedefs:
+*****************************************************************************/
+
+/**
+Client API:
+Signed twos-complement 8-bit type. Typically defined as signed char.
+*/
+#if SCHAR_MAX==127 && SCHAR_MIN==(-128)
+typedef signed char sox_int8_t;
+#elif CHAR_MAX==127 && CHAR_MIN==(-128)
+typedef char sox_int8_t;
+#else
+#error Unable to determine an appropriate definition for sox_int8_t.
+#endif
+
+/**
+Client API:
+Unsigned 8-bit type. Typically defined as unsigned char.
+*/
+#if UCHAR_MAX==0xff
+typedef unsigned char sox_uint8_t;
+#elif CHAR_MAX==0xff && CHAR_MIN==0
+typedef char sox_uint8_t;
+#else
+#error Unable to determine an appropriate definition for sox_uint8_t.
+#endif
+
+/**
+Client API:
+Signed twos-complement 16-bit type. Typically defined as short.
+*/
+#if SHRT_MAX==32767 && SHRT_MIN==(-32768)
+typedef short sox_int16_t;
+#elif INT_MAX==32767 && INT_MIN==(-32768)
+typedef int sox_int16_t;
+#else
+#error Unable to determine an appropriate definition for sox_int16_t.
+#endif
+
+/**
+Client API:
+Unsigned 16-bit type. Typically defined as unsigned short.
+*/
+#if USHRT_MAX==0xffff
+typedef unsigned short sox_uint16_t;
+#elif UINT_MAX==0xffff
+typedef unsigned int sox_uint16_t;
+#else
+#error Unable to determine an appropriate definition for sox_uint16_t.
+#endif
+
+/**
+Client API:
+Signed twos-complement 32-bit type. Typically defined as int.
+*/
+#if INT_MAX==2147483647 && INT_MIN==(-2147483647-1)
+typedef int sox_int32_t;
+#elif LONG_MAX==2147483647 && LONG_MIN==(-2147483647-1)
+typedef long sox_int32_t;
+#else
+#error Unable to determine an appropriate definition for sox_int32_t.
+#endif
+
+/**
+Client API:
+Unsigned 32-bit type. Typically defined as unsigned int.
+*/
+#if UINT_MAX==0xffffffff
+typedef unsigned int sox_uint32_t;
+#elif ULONG_MAX==0xffffffff
+typedef unsigned long sox_uint32_t;
+#else
+#error Unable to determine an appropriate definition for sox_uint32_t.
+#endif
+
+/**
+Client API:
+Signed twos-complement 64-bit type. Typically defined as long or long long.
+*/
+#if LONG_MAX==9223372036854775807 && LONG_MIN==(-9223372036854775807-1)
+typedef long sox_int64_t;
+#elif defined(_MSC_VER)
+typedef __int64 sox_int64_t;
+#else
+typedef long long sox_int64_t;
+#endif
+
+/**
+Client API:
+Unsigned 64-bit type. Typically defined as unsigned long or unsigned long long.
+*/
+#if ULONG_MAX==0xffffffffffffffff
+typedef unsigned long sox_uint64_t;
+#elif defined(_MSC_VER)
+typedef unsigned __int64 sox_uint64_t;
+#else
+typedef unsigned long long sox_uint64_t;
+#endif
+
+#ifndef _DOXYGEN_
+lsx_static_assert(sizeof(sox_int8_t)==1,   sox_int8_size);
+lsx_static_assert(sizeof(sox_uint8_t)==1,  sox_uint8_size);
+lsx_static_assert(sizeof(sox_int16_t)==2,  sox_int16_size);
+lsx_static_assert(sizeof(sox_uint16_t)==2, sox_uint16_size);
+lsx_static_assert(sizeof(sox_int32_t)==4,  sox_int32_size);
+lsx_static_assert(sizeof(sox_uint32_t)==4, sox_uint32_size);
+lsx_static_assert(sizeof(sox_int64_t)==8,  sox_int64_size);
+lsx_static_assert(sizeof(sox_uint64_t)==8, sox_uint64_size);
+#endif
+
+/**
+Client API:
+Alias for sox_int32_t (beware of the extra byte).
+*/
+typedef sox_int32_t sox_int24_t;
+
+/**
+Client API:
+Alias for sox_uint32_t (beware of the extra byte).
+*/
+typedef sox_uint32_t sox_uint24_t;
+
+/**
+Client API:
+Native SoX audio sample type (alias for sox_int32_t).
+*/
+typedef sox_int32_t sox_sample_t;
+
+/**
+Client API:
+Samples per second is stored as a double.
+*/
+typedef double sox_rate_t;
+
+/**
+Client API:
+File's metadata, access via sox_*_comments functions.
+*/
+typedef char * * sox_comments_t;
+
+/*****************************************************************************
+Enumerations:
+*****************************************************************************/
+
+/**
+Client API:
+Boolean type, assignment (but not necessarily binary) compatible with C++ bool.
+*/
+typedef enum sox_bool {
+    sox_false, /**< False = 0. */
+    sox_true   /**< True = 1. */
+} sox_bool;
+
+/**
+Client API:
+no, yes, or default (default usually implies some kind of auto-detect logic).
+*/
+typedef enum sox_option_t {
+    sox_option_no,      /**< Option specified as no = 0. */
+    sox_option_yes,     /**< Option specified as yes = 1. */
+    sox_option_default  /**< Option unspecified = 2. */
+} sox_option_t;
+
+/**
+Client API:
+The libSoX-specific error codes.
+libSoX functions may return these codes or others that map from errno codes.
+*/
+enum sox_error_t {
+  SOX_SUCCESS = 0,     /**< Function succeeded = 0 */
+  SOX_EOF = -1,        /**< End Of File or other error = -1 */
+  SOX_EHDR = 2000,     /**< Invalid Audio Header = 2000 */
+  SOX_EFMT,            /**< Unsupported data format = 2001 */
+  SOX_ENOMEM,          /**< Can't alloc memory = 2002 */
+  SOX_EPERM,           /**< Operation not permitted = 2003 */
+  SOX_ENOTSUP,         /**< Operation not supported = 2004 */
+  SOX_EINVAL           /**< Invalid argument = 2005 */
+};
+
+/**
+Client API:
+Flags indicating whether optional features are present in this build of libSoX.
+*/
+typedef enum sox_version_flags_t {
+    sox_version_none = 0,         /**< No special features = 0. */
+    sox_version_have_popen = 1,   /**< popen = 1. */
+    sox_version_have_magic = 2,   /**< magic = 2. */
+    sox_version_have_threads = 4, /**< threads = 4. */
+    sox_version_have_memopen = 8  /**< memopen = 8. */
+} sox_version_flags_t;
+
+/**
+Client API:
+Format of sample data.
+*/
+typedef enum sox_encoding_t {
+  SOX_ENCODING_UNKNOWN   , /**< encoding has not yet been determined */
+
+  SOX_ENCODING_SIGN2     , /**< signed linear 2's comp: Mac */
+  SOX_ENCODING_UNSIGNED  , /**< unsigned linear: Sound Blaster */
+  SOX_ENCODING_FLOAT     , /**< floating point (binary format) */
+  SOX_ENCODING_FLOAT_TEXT, /**< floating point (text format) */
+  SOX_ENCODING_FLAC      , /**< FLAC compression */
+  SOX_ENCODING_HCOM      , /**< Mac FSSD files with Huffman compression */
+  SOX_ENCODING_WAVPACK   , /**< WavPack with integer samples */
+  SOX_ENCODING_WAVPACKF  , /**< WavPack with float samples */
+  SOX_ENCODING_ULAW      , /**< u-law signed logs: US telephony, SPARC */
+  SOX_ENCODING_ALAW      , /**< A-law signed logs: non-US telephony, Psion */
+  SOX_ENCODING_G721      , /**< G.721 4-bit ADPCM */
+  SOX_ENCODING_G723      , /**< G.723 3 or 5 bit ADPCM */
+  SOX_ENCODING_CL_ADPCM  , /**< Creative Labs 8 --> 2,3,4 bit Compressed PCM */
+  SOX_ENCODING_CL_ADPCM16, /**< Creative Labs 16 --> 4 bit Compressed PCM */
+  SOX_ENCODING_MS_ADPCM  , /**< Microsoft Compressed PCM */
+  SOX_ENCODING_IMA_ADPCM , /**< IMA Compressed PCM */
+  SOX_ENCODING_OKI_ADPCM , /**< Dialogic/OKI Compressed PCM */
+  SOX_ENCODING_DPCM      , /**< Differential PCM: Fasttracker 2 (xi) */
+  SOX_ENCODING_DWVW      , /**< Delta Width Variable Word */
+  SOX_ENCODING_DWVWN     , /**< Delta Width Variable Word N-bit */
+  SOX_ENCODING_GSM       , /**< GSM 6.10 33byte frame lossy compression */
+  SOX_ENCODING_MP3       , /**< MP3 compression */
+  SOX_ENCODING_VORBIS    , /**< Vorbis compression */
+  SOX_ENCODING_AMR_WB    , /**< AMR-WB compression */
+  SOX_ENCODING_AMR_NB    , /**< AMR-NB compression */
+  SOX_ENCODING_CVSD      , /**< Continuously Variable Slope Delta modulation */
+  SOX_ENCODING_LPC10     , /**< Linear Predictive Coding */
+
+  SOX_ENCODINGS            /**< End of list marker */
+} sox_encoding_t;
+
+/**
+Client API:
+Flags for sox_encodings_info_t: lossless/lossy1/lossy2.
+*/
+typedef enum sox_encodings_flags_t {
+  sox_encodings_none   = 0, /**< no flags specified (implies lossless encoding) = 0. */
+  sox_encodings_lossy1 = 1, /**< encode, decode: lossy once = 1. */
+  sox_encodings_lossy2 = 2  /**< encode, decode, encode, decode: lossy twice = 2. */
+} sox_encodings_flags_t;
+
+/**
+Client API:
+Type of plot.
+*/
+typedef enum sox_plot_t {
+    sox_plot_off,     /**< No plot = 0. */
+    sox_plot_octave,  /**< Octave plot = 1. */
+    sox_plot_gnuplot, /**< Gnuplot plot = 2. */
+    sox_plot_data     /**< Plot data = 3. */
+} sox_plot_t;
+
+/**
+Client API:
+Loop modes: upper 4 bits mask the loop blass, lower 4 bits describe
+the loop behaviour, for example single shot, bidirectional etc.
+*/
+enum sox_loop_flags_t {
+  sox_loop_none = 0,          /**< single-shot = 0 */
+  sox_loop_forward = 1,       /**< forward loop = 1 */
+  sox_loop_forward_back = 2,  /**< forward/back loop = 2 */
+  sox_loop_8 = 32,            /**< 8 loops (??) = 32 */
+  sox_loop_sustain_decay = 64 /**< AIFF style, one sustain & one decay loop = 64 */
+};
+
+/**
+Plugins API:
+Is file a real file, a pipe, or a url?
+*/
+typedef enum lsx_io_type
+{
+    lsx_io_file, /**< File is a real file = 0. */
+    lsx_io_pipe, /**< File is a pipe (no seeking) = 1. */
+    lsx_io_url   /**< File is a URL (no seeking) = 2. */
+} lsx_io_type;
+
+/*****************************************************************************
+Macros:
+*****************************************************************************/
+
+/**
+Client API:
+Compute a 32-bit integer API version from three 8-bit parts.
+@param a Major version.
+@param b Minor version.
+@param c Revision or build number.
+@returns 32-bit integer API version 0x000a0b0c.
+*/
+#define SOX_LIB_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c))
+
+/**
+Client API:
+The API version of the sox.h file. It is not meant to follow the version
+number of SoX but it has historically. Please do not count on
+SOX_LIB_VERSION_CODE staying in sync with the libSoX version.
+*/
+#define SOX_LIB_VERSION_CODE   SOX_LIB_VERSION(14, 4, 1)
+
+/**
+Client API:
+Returns the smallest (negative) value storable in a twos-complement signed
+integer with the specified number of bits, cast to an unsigned integer;
+for example, SOX_INT_MIN(8) = 0x80, SOX_INT_MIN(16) = 0x8000, etc.
+@param bits Size of value for which to calculate minimum.
+@returns the smallest (negative) value storable in a twos-complement signed
+integer with the specified number of bits, cast to an unsigned integer.
+*/
+#define SOX_INT_MIN(bits) (1 <<((bits)-1))
+
+/**
+Client API:
+Returns the largest (positive) value storable in a twos-complement signed
+integer with the specified number of bits, cast to an unsigned integer;
+for example, SOX_INT_MAX(8) = 0x7F, SOX_INT_MAX(16) = 0x7FFF, etc.
+@param bits Size of value for which to calculate maximum.
+@returns the largest (positive) value storable in a twos-complement signed
+integer with the specified number of bits, cast to an unsigned integer.
+*/
+#define SOX_INT_MAX(bits) (((unsigned)-1)>>(33-(bits)))
+
+/**
+Client API:
+Returns the largest value storable in an unsigned integer with the specified
+number of bits; for example, SOX_UINT_MAX(8) = 0xFF,
+SOX_UINT_MAX(16) = 0xFFFF, etc.
+@param bits Size of value for which to calculate maximum.
+@returns the largest value storable in an unsigned integer with the specified
+number of bits.
+*/
+#define SOX_UINT_MAX(bits) (SOX_INT_MIN(bits)|SOX_INT_MAX(bits))
+
+/**
+Client API:
+Returns 0x7F.
+*/
+#define SOX_INT8_MAX  SOX_INT_MAX(8)
+
+/**
+Client API:
+Returns 0x7FFF.
+*/
+#define SOX_INT16_MAX SOX_INT_MAX(16)
+
+/**
+Client API:
+Returns 0x7FFFFF.
+*/
+#define SOX_INT24_MAX SOX_INT_MAX(24)
+
+/**
+Client API:
+Returns 0x7FFFFFFF.
+*/
+#define SOX_INT32_MAX SOX_INT_MAX(32)
+
+/**
+Client API:
+Bits in a sox_sample_t = 32.
+*/
+#define SOX_SAMPLE_PRECISION 32
+
+/**
+Client API:
+Max value for sox_sample_t = 0x7FFFFFFF.
+*/
+#define SOX_SAMPLE_MAX (sox_sample_t)SOX_INT_MAX(32)
+
+/**
+Client API:
+Min value for sox_sample_t = 0x80000000.
+*/
+#define SOX_SAMPLE_MIN (sox_sample_t)SOX_INT_MIN(32)
+
+
+/*                Conversions: Linear PCM <--> sox_sample_t
+ *
+ *   I/O      Input    sox_sample_t Clips?   Input    sox_sample_t Clips?
+ *  Format   Minimum     Minimum     I O    Maximum     Maximum     I O
+ *  ------  ---------  ------------ -- --   --------  ------------ -- --
+ *  Float     -inf         -1        y n      inf      1 - 5e-10    y n
+ *  Int8      -128        -128       n n      127     127.9999999   n y
+ *  Int16    -32768      -32768      n n     32767    32767.99998   n y
+ *  Int24   -8388608    -8388608     n n    8388607   8388607.996   n y
+ *  Int32  -2147483648 -2147483648   n n   2147483647 2147483647    n n
+ *
+ * Conversions are as accurate as possible (with rounding).
+ *
+ * Rounding: halves toward +inf, all others to nearest integer.
+ *
+ * Clips? shows whether on not there is the possibility of a conversion
+ * clipping to the minimum or maximum value when inputing from or outputing
+ * to a given type.
+ *
+ * Unsigned integers are converted to and from signed integers by flipping
+ * the upper-most bit then treating them as signed integers.
+ */
+
+/**
+Client API:
+Declares the temporary local variables that are required when using SOX
+conversion macros.
+*/
+#define SOX_SAMPLE_LOCALS sox_sample_t sox_macro_temp_sample LSX_UNUSED; \
+  double sox_macro_temp_double LSX_UNUSED
+
+/**
+Client API:
+Sign bit for sox_sample_t = 0x80000000.
+*/
+#define SOX_SAMPLE_NEG SOX_INT_MIN(32)
+
+/**
+Client API:
+Converts sox_sample_t to an unsigned integer of width (bits).
+@param bits  Width of resulting sample (1 through 32).
+@param d     Input sample to be converted.
+@param clips Variable that is incremented if the result is too big.
+@returns Unsigned integer of width (bits).
+*/
+#define SOX_SAMPLE_TO_UNSIGNED(bits,d,clips) \
+  (sox_uint##bits##_t)(SOX_SAMPLE_TO_SIGNED(bits,d,clips)^SOX_INT_MIN(bits))
+
+/**
+Client API:
+Converts sox_sample_t to a signed integer of width (bits).
+@param bits  Width of resulting sample (1 through 32).
+@param d     Input sample to be converted.
+@param clips Variable that is incremented if the result is too big.
+@returns Signed integer of width (bits).
+*/
+#define SOX_SAMPLE_TO_SIGNED(bits,d,clips) \
+  (sox_int##bits##_t)(LSX_USE_VAR(sox_macro_temp_double),sox_macro_temp_sample=(d),sox_macro_temp_sample>SOX_SAMPLE_MAX-(1<<(31-bits))?++(clips),SOX_INT_MAX(bits):((sox_uint32_t)(sox_macro_temp_sample+(1<<(31-bits))))>>(32-bits))
+
+/**
+Client API:
+Converts signed integer of width (bits) to sox_sample_t.
+@param bits Width of input sample (1 through 32).
+@param d    Input sample to be converted.
+@returns SoX native sample value.
+*/
+#define SOX_SIGNED_TO_SAMPLE(bits,d)((sox_sample_t)(d)<<(32-bits))
+
+/**
+Client API:
+Converts unsigned integer of width (bits) to sox_sample_t.
+@param bits Width of input sample (1 through 32).
+@param d    Input sample to be converted.
+@returns SoX native sample value.
+*/
+#define SOX_UNSIGNED_TO_SAMPLE(bits,d)(SOX_SIGNED_TO_SAMPLE(bits,d)^SOX_SAMPLE_NEG)
+
+/**
+Client API:
+Converts unsigned 8-bit integer to sox_sample_t.
+@param d     Input sample to be converted.
+@param clips The parameter is not used.
+@returns SoX native sample value.
+*/
+#define SOX_UNSIGNED_8BIT_TO_SAMPLE(d,clips) SOX_UNSIGNED_TO_SAMPLE(8,d)
+
+/**
+Client API:
+Converts signed 8-bit integer to sox_sample_t.
+@param d    Input sample to be converted.
+@param clips The parameter is not used.
+@returns SoX native sample value.
+*/
+#define SOX_SIGNED_8BIT_TO_SAMPLE(d,clips) SOX_SIGNED_TO_SAMPLE(8,d)
+
+/**
+Client API:
+Converts unsigned 16-bit integer to sox_sample_t.
+@param d     Input sample to be converted.
+@param clips The parameter is not used.
+@returns SoX native sample value.
+*/
+#define SOX_UNSIGNED_16BIT_TO_SAMPLE(d,clips) SOX_UNSIGNED_TO_SAMPLE(16,d)
+
+/**
+Client API:
+Converts signed 16-bit integer to sox_sample_t.
+@param d    Input sample to be converted.
+@param clips The parameter is not used.
+@returns SoX native sample value.
+*/
+#define SOX_SIGNED_16BIT_TO_SAMPLE(d,clips) SOX_SIGNED_TO_SAMPLE(16,d)
+
+/**
+Client API:
+Converts unsigned 24-bit integer to sox_sample_t.
+@param d     Input sample to be converted.
+@param clips The parameter is not used.
+@returns SoX native sample value.
+*/
+#define SOX_UNSIGNED_24BIT_TO_SAMPLE(d,clips) SOX_UNSIGNED_TO_SAMPLE(24,d)
+
+/**
+Client API:
+Converts signed 24-bit integer to sox_sample_t.
+@param d    Input sample to be converted.
+@param clips The parameter is not used.
+@returns SoX native sample value.
+*/
+#define SOX_SIGNED_24BIT_TO_SAMPLE(d,clips) SOX_SIGNED_TO_SAMPLE(24,d)
+
+/**
+Client API:
+Converts unsigned 32-bit integer to sox_sample_t.
+@param d     Input sample to be converted.
+@param clips The parameter is not used.
+@returns SoX native sample value.
+*/
+#define SOX_UNSIGNED_32BIT_TO_SAMPLE(d,clips) ((sox_sample_t)(d)^SOX_SAMPLE_NEG)
+
+/**
+Client API:
+Converts signed 32-bit integer to sox_sample_t.
+@param d    Input sample to be converted.
+@param clips The parameter is not used.
+@returns SoX native sample value.
+*/
+#define SOX_SIGNED_32BIT_TO_SAMPLE(d,clips) (sox_sample_t)(d)
+
+/**
+Client API:
+Converts 32-bit float to sox_sample_t.
+@param d     Input sample to be converted, range [-1, 1).
+@param clips Variable to increment if the input sample is too large or too small.
+@returns SoX native sample value.
+*/
+#define SOX_FLOAT_32BIT_TO_SAMPLE(d,clips) (sox_sample_t)(LSX_USE_VAR(sox_macro_temp_sample),sox_macro_temp_double=(d)*(SOX_SAMPLE_MAX+1.),sox_macro_temp_double<SOX_SAMPLE_MIN?++(clips),SOX_SAMPLE_MIN:sox_macro_temp_double>=SOX_SAMPLE_MAX+1.?sox_macro_temp_double>SOX_SAMPLE_MAX+1.?++(clips),SOX_SAMPLE_MAX:SOX_SAMPLE_MAX:sox_macro_temp_double)
+
+/**
+Client API:
+Converts 64-bit float to sox_sample_t.
+@param d     Input sample to be converted, range [-1, 1).
+@param clips Variable to increment if the input sample is too large or too small.
+@returns SoX native sample value.
+*/
+#define SOX_FLOAT_64BIT_TO_SAMPLE(d,clips) (sox_sample_t)(LSX_USE_VAR(sox_macro_temp_sample),sox_macro_temp_double=(d)*(SOX_SAMPLE_MAX+1.),sox_macro_temp_double<0?sox_macro_temp_double<=SOX_SAMPLE_MIN-.5?++(clips),SOX_SAMPLE_MIN:sox_macro_temp_double-.5:sox_macro_temp_double>=SOX_SAMPLE_MAX+.5?sox_macro_temp_double>SOX_SAMPLE_MAX+1.?++(clips),SOX_SAMPLE_MAX:SOX_SAMPLE_MAX:sox_macro_temp_double+.5)
+
+/**
+Client API:
+Converts SoX native sample to an unsigned 8-bit integer.
+@param d Input sample to be converted.
+@param clips Variable to increment if input sample is too large.
+*/
+#define SOX_SAMPLE_TO_UNSIGNED_8BIT(d,clips) SOX_SAMPLE_TO_UNSIGNED(8,d,clips)
+
+/**
+Client API:
+Converts SoX native sample to an signed 8-bit integer.
+@param d Input sample to be converted.
+@param clips Variable to increment if input sample is too large.
+*/
+#define SOX_SAMPLE_TO_SIGNED_8BIT(d,clips) SOX_SAMPLE_TO_SIGNED(8,d,clips)
+
+/**
+Client API:
+Converts SoX native sample to an unsigned 16-bit integer.
+@param d Input sample to be converted.
+@param clips Variable to increment if input sample is too large.
+*/
+#define SOX_SAMPLE_TO_UNSIGNED_16BIT(d,clips) SOX_SAMPLE_TO_UNSIGNED(16,d,clips)
+
+/**
+Client API:
+Converts SoX native sample to a signed 16-bit integer.
+@param d Input sample to be converted.
+@param clips Variable to increment if input sample is too large.
+*/
+#define SOX_SAMPLE_TO_SIGNED_16BIT(d,clips) SOX_SAMPLE_TO_SIGNED(16,d,clips)
+
+/**
+Client API:
+Converts SoX native sample to an unsigned 24-bit integer.
+@param d Input sample to be converted.
+@param clips Variable to increment if input sample is too large.
+*/
+#define SOX_SAMPLE_TO_UNSIGNED_24BIT(d,clips) SOX_SAMPLE_TO_UNSIGNED(24,d,clips)
+
+/**
+Client API:
+Converts SoX native sample to a signed 24-bit integer.
+@param d Input sample to be converted.
+@param clips Variable to increment if input sample is too large.
+*/
+#define SOX_SAMPLE_TO_SIGNED_24BIT(d,clips) SOX_SAMPLE_TO_SIGNED(24,d,clips)
+
+/**
+Client API:
+Converts SoX native sample to an unsigned 32-bit integer.
+@param d Input sample to be converted.
+@param clips The parameter is not used.
+*/
+#define SOX_SAMPLE_TO_UNSIGNED_32BIT(d,clips) (sox_uint32_t)((d)^SOX_SAMPLE_NEG)
+
+/**
+Client API:
+Converts SoX native sample to a signed 32-bit integer.
+@param d Input sample to be converted.
+@param clips The parameter is not used.
+*/
+#define SOX_SAMPLE_TO_SIGNED_32BIT(d,clips) (sox_int32_t)(d)
+
+/**
+Client API:
+Converts SoX native sample to a 32-bit float.
+@param d Input sample to be converted.
+@param clips Variable to increment if input sample is too large.
+*/
+#define SOX_SAMPLE_TO_FLOAT_32BIT(d,clips) (LSX_USE_VAR(sox_macro_temp_double),sox_macro_temp_sample=(d),sox_macro_temp_sample>SOX_SAMPLE_MAX-128?++(clips),1:(((sox_macro_temp_sample+128)&~255)*(1./(SOX_SAMPLE_MAX+1.))))
+
+/**
+Client API:
+Converts SoX native sample to a 64-bit float.
+@param d Input sample to be converted.
+@param clips The parameter is not used.
+*/
+#define SOX_SAMPLE_TO_FLOAT_64BIT(d,clips) ((d)*(1./(SOX_SAMPLE_MAX+1.)))
+
+/**
+Client API:
+Clips a value of a type that is larger then sox_sample_t (for example, int64)
+to sox_sample_t's limits and increment a counter if clipping occurs.
+@param samp Value (lvalue) to be clipped, updated as necessary.
+@param clips Value (lvalue) that is incremented if clipping is needed.
+*/
+#define SOX_SAMPLE_CLIP_COUNT(samp, clips) \
+  do { \
+    if (samp > SOX_SAMPLE_MAX) \
+      { samp = SOX_SAMPLE_MAX; clips++; } \
+    else if (samp < SOX_SAMPLE_MIN) \
+      { samp = SOX_SAMPLE_MIN; clips++; } \
+  } while (0)
+
+/**
+Client API:
+Clips a value of a type that is larger then sox_sample_t (for example, int64)
+to sox_sample_t's limits and increment a counter if clipping occurs.
+@param d Value (rvalue) to be clipped.
+@param clips Value (lvalue) that is incremented if clipping is needed.
+@returns Clipped value.
+*/
+#define SOX_ROUND_CLIP_COUNT(d, clips) \
+  ((d) < 0? (d) <= SOX_SAMPLE_MIN - 0.5? ++(clips), SOX_SAMPLE_MIN: (d) - 0.5 \
+        : (d) >= SOX_SAMPLE_MAX + 0.5? ++(clips), SOX_SAMPLE_MAX: (d) + 0.5)
+
+/**
+Client API:
+Clips a value to the limits of a signed integer of the specified width
+and increment a counter if clipping occurs.
+@param bits Width (in bits) of target integer type.
+@param i Value (rvalue) to be clipped.
+@param clips Value (lvalue) that is incremented if clipping is needed.
+@returns Clipped value.
+*/
+#define SOX_INTEGER_CLIP_COUNT(bits,i,clips) ( \
+  (i) >(1 << ((bits)-1))- 1? ++(clips),(1 << ((bits)-1))- 1 : \
+  (i) <-1 << ((bits)-1)    ? ++(clips),-1 << ((bits)-1) : (i))
+
+/**
+Client API:
+Clips a value to the limits of a 16-bit signed integer and increment a counter
+if clipping occurs.
+@param i Value (rvalue) to be clipped.
+@param clips Value (lvalue) that is incremented if clipping is needed.
+@returns Clipped value.
+*/
+#define SOX_16BIT_CLIP_COUNT(i,clips) SOX_INTEGER_CLIP_COUNT(16,i,clips)
+
+/**
+Client API:
+Clips a value to the limits of a 24-bit signed integer and increment a counter
+if clipping occurs.
+@param i Value (rvalue) to be clipped.
+@param clips Value (lvalue) that is incremented if clipping is needed.
+@returns Clipped value.
+*/
+#define SOX_24BIT_CLIP_COUNT(i,clips) SOX_INTEGER_CLIP_COUNT(24,i,clips)
+
+#define SOX_SIZE_MAX ((size_t)(-1)) /**< Client API: Maximum value of size_t. */
+
+#define SOX_UNSPEC 0                         /**< Client API: Members of sox_signalinfo_t are set to SOX_UNSPEC (= 0) if the actual value is not yet known. */
+#define SOX_UNKNOWN_LEN (sox_uint64_t)(-1) /**< Client API: sox_signalinfo_t.length is set to SOX_UNKNOWN_LEN (= -1) within the effects chain if the actual length is not known. Format handlers currently use SOX_UNSPEC instead. */
+#define SOX_IGNORE_LENGTH (sox_uint64_t)(-2) /**< Client API: sox_signalinfo_t.length is set to SOX_IGNORE_LENGTH (= -2) to indicate that a format handler should ignore length information in file headers. */
+
+#define SOX_DEFAULT_CHANNELS  2     /**< Client API: Default channel count is 2 (stereo). */
+#define SOX_DEFAULT_RATE      48000 /**< Client API: Default rate is 48000Hz. */
+#define SOX_DEFAULT_PRECISION 16    /**< Client API: Default precision is 16 bits per sample. */
+#define SOX_DEFAULT_ENCODING  SOX_ENCODING_SIGN2 /**< Client API: Default encoding is SIGN2 (linear 2's complement PCM). */
+
+#define SOX_LOOP_NONE          ((unsigned char)sox_loop_none)          /**< Client API: single-shot = 0 */
+#define SOX_LOOP_8             ((unsigned char)sox_loop_8)             /**< Client API: 8 loops = 32 */
+#define SOX_LOOP_SUSTAIN_DECAY ((unsigned char)sox_loop_sustain_decay) /**< Client API: AIFF style, one sustain & one decay loop = 64 */
+
+#define SOX_MAX_NLOOPS         8 /**< Client API: Maximum number of loops supported by sox_oob_t = 8. */
+
+#define SOX_FILE_NOSTDIO 0x0001 /**< Client API: Does not use stdio routines */
+#define SOX_FILE_DEVICE  0x0002 /**< Client API: File is an audio device */
+#define SOX_FILE_PHONY   0x0004 /**< Client API: Phony file/device (for example /dev/null) */
+#define SOX_FILE_REWIND  0x0008 /**< Client API: File should be rewound to write header */
+#define SOX_FILE_BIT_REV 0x0010 /**< Client API: Is file bit-reversed? */
+#define SOX_FILE_NIB_REV 0x0020 /**< Client API: Is file nibble-reversed? */
+#define SOX_FILE_ENDIAN  0x0040 /**< Client API: Is file format endian? */
+#define SOX_FILE_ENDBIG  0x0080 /**< Client API: For endian file format, is it big endian? */
+#define SOX_FILE_MONO    0x0100 /**< Client API: Do channel restrictions allow mono? */
+#define SOX_FILE_STEREO  0x0200 /**< Client API: Do channel restrictions allow stereo? */
+#define SOX_FILE_QUAD    0x0400 /**< Client API: Do channel restrictions allow quad? */
+
+#define SOX_FILE_CHANS   (SOX_FILE_MONO | SOX_FILE_STEREO | SOX_FILE_QUAD) /**< Client API: No channel restrictions */
+#define SOX_FILE_LIT_END (SOX_FILE_ENDIAN | 0)                             /**< Client API: File is little-endian */
+#define SOX_FILE_BIG_END (SOX_FILE_ENDIAN | SOX_FILE_ENDBIG)               /**< Client API: File is big-endian */
+
+#define SOX_EFF_CHAN     1           /**< Client API: Effect might alter the number of channels */
+#define SOX_EFF_RATE     2           /**< Client API: Effect might alter sample rate */
+#define SOX_EFF_PREC     4           /**< Client API: Effect does its own calculation of output sample precision (otherwise a default value is taken, depending on the presence of SOX_EFF_MODIFY) */
+#define SOX_EFF_LENGTH   8           /**< Client API: Effect might alter audio length (as measured in time units, not necessarily in samples) */
+#define SOX_EFF_MCHAN    16          /**< Client API: Effect handles multiple channels internally */
+#define SOX_EFF_NULL     32          /**< Client API: Effect does nothing (can be optimized out of chain) */
+#define SOX_EFF_DEPRECATED 64        /**< Client API: Effect will soon be removed from SoX */
+#define SOX_EFF_GAIN     128         /**< Client API: Effect does not support gain -r */
+#define SOX_EFF_MODIFY   256         /**< Client API: Effect does not modify sample values (but might remove or duplicate samples or insert zeros) */
+#define SOX_EFF_ALPHA    512         /**< Client API: Effect is experimental/incomplete */
+#define SOX_EFF_INTERNAL 1024        /**< Client API: Effect present in libSoX but not valid for use by SoX command-line tools */
+
+/**
+Client API:
+When used as the "whence" parameter of sox_seek, indicates that the specified
+offset is relative to the beginning of the file.
+*/
+#define SOX_SEEK_SET 0
+
+/*****************************************************************************
+Forward declarations:
+*****************************************************************************/
+
+typedef struct sox_format_t sox_format_t;
+typedef struct sox_effect_t sox_effect_t;
+typedef struct sox_effect_handler_t sox_effect_handler_t;
+typedef struct sox_format_handler_t sox_format_handler_t;
+
+/*****************************************************************************
+Function pointers:
+*****************************************************************************/
+
+/**
+Client API:
+Callback to write a message to an output device (console or log file),
+used by sox_globals_t.output_message_handler.
+*/
+typedef void (LSX_API * sox_output_message_handler_t)(
+    unsigned level,                       /* 1 = FAIL, 2 = WARN, 3 = INFO, 4 = DEBUG, 5 = DEBUG_MORE, 6 = DEBUG_MOST. */
+    LSX_PARAM_IN_Z char const * filename, /* Source code __FILENAME__ from which message originates. */
+    LSX_PARAM_IN_PRINTF char const * fmt, /* Message format string. */
+    LSX_PARAM_IN va_list ap               /* Message format parameters. */
+    );
+
+/**
+Client API:
+Callback to retrieve information about a format handler,
+used by sox_format_tab_t.fn.
+@returns format handler information.
+*/
+typedef sox_format_handler_t const * (LSX_API * sox_format_fn_t)(void);
+
+/**
+Client API:
+Callback to get information about an effect handler,
+used by the table returned from sox_get_effect_fns(void).
+@returns Pointer to information about an effect handler.
+*/
+typedef sox_effect_handler_t const * (LSX_API *sox_effect_fn_t)(void);
+
+/**
+Client API:
+Callback to initialize reader (decoder), used by
+sox_format_handler.startread.
+@returns SOX_SUCCESS if successful.
+*/
+typedef int (LSX_API * sox_format_handler_startread)(
+    LSX_PARAM_INOUT sox_format_t * ft /**< Format pointer. */
+    );
+
+/**
+Client API:
+Callback to read (decode) a block of samples,
+used by sox_format_handler.read.
+@returns number of samples read, or 0 if unsuccessful.
+*/
+typedef size_t (LSX_API * sox_format_handler_read)(
+    LSX_PARAM_INOUT sox_format_t * ft, /**< Format pointer. */
+    LSX_PARAM_OUT_CAP_POST_COUNT(len,return) sox_sample_t *buf, /**< Buffer from which to read samples. */
+    size_t len /**< Number of samples available in buf. */
+    );
+
+/**
+Client API:
+Callback to close reader (decoder),
+used by sox_format_handler.stopread.
+@returns SOX_SUCCESS if successful.
+*/
+typedef int (LSX_API * sox_format_handler_stopread)(
+    LSX_PARAM_INOUT sox_format_t * ft /**< Format pointer. */
+    );
+
+/**
+Client API:
+Callback to initialize writer (encoder),
+used by sox_format_handler.startwrite.
+@returns SOX_SUCCESS if successful.
+*/
+typedef int (LSX_API * sox_format_handler_startwrite)(
+    LSX_PARAM_INOUT sox_format_t * ft /**< Format pointer. */
+    );
+
+/**
+Client API:
+Callback to write (encode) a block of samples,
+used by sox_format_handler.write.
+@returns number of samples written, or 0 if unsuccessful.
+*/
+typedef size_t (LSX_API * sox_format_handler_write)(
+    LSX_PARAM_INOUT sox_format_t * ft, /**< Format pointer. */
+    LSX_PARAM_IN_COUNT(len) sox_sample_t const * buf, /**< Buffer to which samples are written. */
+    size_t len /**< Capacity of buf, measured in samples. */
+    );
+
+/**
+Client API:
+Callback to close writer (decoder),
+used by sox_format_handler.stopwrite.
+@returns SOX_SUCCESS if successful.
+*/
+typedef int (LSX_API * sox_format_handler_stopwrite)(
+    LSX_PARAM_INOUT sox_format_t * ft /**< Format pointer. */
+    );
+
+/**
+Client API:
+Callback to reposition reader,
+used by sox_format_handler.seek.
+@returns SOX_SUCCESS if successful.
+*/
+typedef int (LSX_API * sox_format_handler_seek)(
+    LSX_PARAM_INOUT sox_format_t * ft, /**< Format pointer. */
+    sox_uint64_t offset /**< Sample offset to which reader should be positioned. */
+    );
+
+/**
+Client API:
+Callback to parse command-line arguments (called once per effect),
+used by sox_effect_handler.getopts.
+@returns SOX_SUCCESS if successful.
+*/
+typedef int (LSX_API * sox_effect_handler_getopts)(
+    LSX_PARAM_INOUT sox_effect_t * effp, /**< Effect pointer. */
+    int argc, /**< Number of arguments in argv. */
+    LSX_PARAM_IN_COUNT(argc) char *argv[] /**< Array of command-line arguments. */
+    );
+
+/**
+Client API:
+Callback to initialize effect (called once per flow),
+used by sox_effect_handler.start.
+@returns SOX_SUCCESS if successful.
+*/
+typedef int (LSX_API * sox_effect_handler_start)(
+    LSX_PARAM_INOUT sox_effect_t * effp /**< Effect pointer. */
+    );
+
+/**
+Client API:
+Callback to process samples,
+used by sox_effect_handler.flow.
+@returns SOX_SUCCESS if successful.
+*/
+typedef int (LSX_API * sox_effect_handler_flow)(
+    LSX_PARAM_INOUT sox_effect_t * effp, /**< Effect pointer. */
+    LSX_PARAM_IN_COUNT(*isamp) sox_sample_t const * ibuf, /**< Buffer from which to read samples. */
+    LSX_PARAM_OUT_CAP_POST_COUNT(*osamp,*osamp) sox_sample_t * obuf, /**< Buffer to which samples are written. */
+    LSX_PARAM_INOUT size_t *isamp, /**< On entry, contains capacity of ibuf; on exit, contains number of samples consumed. */
+    LSX_PARAM_INOUT size_t *osamp /**< On entry, contains capacity of obuf; on exit, contains number of samples written. */
+    );
+
+/**
+Client API:
+Callback to finish getting output after input is complete,
+used by sox_effect_handler.drain.
+@returns SOX_SUCCESS if successful.
+*/
+typedef int (LSX_API * sox_effect_handler_drain)(
+    LSX_PARAM_INOUT sox_effect_t * effp, /**< Effect pointer. */
+    LSX_PARAM_OUT_CAP_POST_COUNT(*osamp,*osamp) sox_sample_t *obuf, /**< Buffer to which samples are written. */
+    LSX_PARAM_INOUT size_t *osamp /**< On entry, contains capacity of obuf; on exit, contains number of samples written. */
+    );
+
+/**
+Client API:
+Callback to shut down effect (called once per flow),
+used by sox_effect_handler.stop.
+@returns SOX_SUCCESS if successful.
+*/
+typedef int (LSX_API * sox_effect_handler_stop)(
+    LSX_PARAM_INOUT sox_effect_t * effp /**< Effect pointer. */
+    );
+
+/**
+Client API:
+Callback to shut down effect (called once per effect),
+used by sox_effect_handler.kill.
+@returns SOX_SUCCESS if successful.
+*/
+typedef int (LSX_API * sox_effect_handler_kill)(
+    LSX_PARAM_INOUT sox_effect_t * effp /**< Effect pointer. */
+    );
+
+/**
+Client API:
+Callback called while flow is running (called once per buffer),
+used by sox_flow_effects.callback.
+@returns SOX_SUCCESS to continue, other value to abort flow.
+*/
+typedef int (LSX_API * sox_flow_effects_callback)(
+    sox_bool all_done,
+    void * client_data
+    );
+
+/**
+Client API:
+Callback for enumerating the contents of a playlist,
+used by the sox_parse_playlist function.
+@returns SOX_SUCCESS if successful, any other value to abort playlist enumeration.
+*/
+typedef int (LSX_API * sox_playlist_callback_t)(
+    void * callback_data,
+    LSX_PARAM_IN_Z char const * filename
+    );
+
+/*****************************************************************************
+Structures:
+*****************************************************************************/
+
+/**
+Client API:
+Information about a build of libSoX, returned from the sox_version_info
+function.
+*/
+typedef struct sox_version_info_t {
+    size_t       size;         /**< structure size = sizeof(sox_version_info_t) */
+    sox_version_flags_t flags; /**< feature flags = popen | magic | threads | memopen */
+    sox_uint32_t version_code; /**< version number = 0x140400 */
+    char const * version;      /**< version string = sox_version(), for example, "14.4.0" */
+    char const * version_extra;/**< version extra info or null = "PACKAGE_EXTRA", for example, "beta" */
+    char const * time;         /**< build time = "__DATE__ __TIME__", for example, "Jan  7 2010 03:31:50" */
+    char const * distro;       /**< distro or null = "DISTRO", for example, "Debian" */
+    char const * compiler;     /**< compiler info or null, for example, "msvc 160040219" */
+    char const * arch;         /**< arch, for example, "1248 48 44 L OMP" */
+    /* new info should be added at the end for version backwards-compatibility. */
+} sox_version_info_t;
+
+/**
+Client API:
+Global parameters (for effects & formats), returned from the sox_get_globals
+function.
+*/
+typedef struct sox_globals_t {
+/* public: */
+  unsigned     verbosity; /**< messages are only written if globals.verbosity >= message.level */
+  sox_output_message_handler_t output_message_handler; /**< client-specified message output callback */
+  sox_bool     repeatable; /**< true to use pre-determined timestamps and PRNG seed */
+
+  /**
+  Default size (in bytes) used by libSoX for blocks of sample data.
+  Plugins should use similarly-sized buffers to get best performance.
+  */
+  size_t       bufsiz;
+
+  /**
+  Default size (in bytes) used by libSoX for blocks of input sample data.
+  Plugins should use similarly-sized buffers to get best performance.
+  */
+  size_t       input_bufsiz;
+
+  sox_int32_t  ranqd1; /**< Can be used to re-seed libSoX's PRNG */
+
+  char const * stdin_in_use_by;  /**< Private: tracks the name of the handler currently using stdin */
+  char const * stdout_in_use_by; /**< Private: tracks the name of the handler currently using stdout */
+  char const * subsystem;        /**< Private: tracks the name of the handler currently writing an output message */
+  char       * tmp_path;         /**< Private: client-configured path to use for temporary files */
+  sox_bool     use_magic;        /**< Private: true if client has requested use of 'magic' file-type detection */
+  sox_bool     use_threads;      /**< Private: true if client has requested parallel effects processing */
+} sox_globals_t;
+
+/**
+Client API:
+Signal parameters; members should be set to SOX_UNSPEC (= 0) if unknown.
+*/
+typedef struct sox_signalinfo_t {
+  sox_rate_t       rate;         /**< samples per second, 0 if unknown */
+  unsigned         channels;     /**< number of sound channels, 0 if unknown */
+  unsigned         precision;    /**< bits per sample, 0 if unknown */
+  sox_uint64_t     length;       /**< samples * chans in file, 0 if unknown, -1 if unspecified */
+  double           * mult;       /**< Effects headroom multiplier; may be null */
+} sox_signalinfo_t;
+
+/**
+Client API:
+Basic information about an encoding.
+*/
+typedef struct sox_encodings_info_t {
+  sox_encodings_flags_t flags; /**< lossy once (lossy1), lossy twice (lossy2), or lossless (none). */
+  char const * name;           /**< encoding name. */
+  char const * desc;           /**< encoding description. */
+} sox_encodings_info_t;
+
+/**
+Client API:
+Encoding parameters.
+*/
+typedef struct sox_encodinginfo_t {
+  sox_encoding_t encoding; /**< format of sample numbers */
+  unsigned bits_per_sample;/**< 0 if unknown or variable; uncompressed value if lossless; compressed value if lossy */
+  double compression;      /**< compression factor (where applicable) */
+
+  /**
+  Should bytes be reversed? If this is default during sox_open_read or
+  sox_open_write, libSoX will set them to either no or yes according to the
+  machine or format default.
+  */
+  sox_option_t reverse_bytes;
+
+  /**
+  Should nibbles be reversed? If this is default during sox_open_read or
+  sox_open_write, libSoX will set them to either no or yes according to the
+  machine or format default.
+  */
+  sox_option_t reverse_nibbles;
+
+  /**
+  Should bits be reversed? If this is default during sox_open_read or
+  sox_open_write, libSoX will set them to either no or yes according to the
+  machine or format default.
+  */
+  sox_option_t reverse_bits;
+
+  /**
+  If set to true, the format should reverse its default endianness.
+  */
+  sox_bool opposite_endian;
+} sox_encodinginfo_t;
+
+/**
+Client API:
+Looping parameters (out-of-band data).
+*/
+typedef struct sox_loopinfo_t {
+  sox_uint64_t  start;  /**< first sample */
+  sox_uint64_t  length; /**< length */
+  unsigned      count;  /**< number of repeats, 0=forever */
+  unsigned char type;   /**< 0=no, 1=forward, 2=forward/back (see sox_loop_* for valid values). */
+} sox_loopinfo_t;
+
+/**
+Client API:
+Instrument information.
+*/
+typedef struct sox_instrinfo_t{
+  signed char MIDInote;   /**< for unity pitch playback */
+  signed char MIDIlow;    /**< MIDI pitch-bend low range */
+  signed char MIDIhi;     /**< MIDI pitch-bend high range */
+  unsigned char loopmode; /**< 0=no, 1=forward, 2=forward/back (see sox_loop_* values) */
+  unsigned nloops;  /**< number of active loops (max SOX_MAX_NLOOPS). */
+} sox_instrinfo_t;
+
+/**
+Client API:
+File buffer info.  Holds info so that data can be read in blocks.
+*/
+typedef struct sox_fileinfo_t {
+  char          *buf;                 /**< Pointer to data buffer */
+  size_t        size;                 /**< Size of buffer in bytes */
+  size_t        count;                /**< Count read into buffer */
+  size_t        pos;                  /**< Position in buffer */
+} sox_fileinfo_t;
+
+/**
+Client API:
+Handler structure defined by each format.
+*/
+struct sox_format_handler_t {
+  unsigned     sox_lib_version_code;  /**< Checked on load; must be 1st in struct*/
+  char         const * description;   /**< short description of format */
+  char         const * const * names; /**< null-terminated array of filename extensions that are handled by this format */
+  unsigned int flags;                 /**< File flags (SOX_FILE_* values). */
+  sox_format_handler_startread startread; /**< called to initialize reader (decoder) */
+  sox_format_handler_read read;       /**< called to read (decode) a block of samples */
+  sox_format_handler_stopread stopread; /**< called to close reader (decoder); may be null if no closing necessary */
+  sox_format_handler_startwrite startwrite; /**< called to initialize writer (encoder) */
+  sox_format_handler_write write;     /**< called to write (encode) a block of samples */
+  sox_format_handler_stopwrite stopwrite; /**< called to close writer (decoder); may be null if no closing necessary */
+  sox_format_handler_seek seek;       /**< called to reposition reader; may be null if not supported */
+
+  /**
+  Array of values indicating the encodings and precisions supported for
+  writing (encoding). Precisions specified with default precision first.
+  Encoding, precision, precision, ..., 0, repeat. End with one more 0.
+  Example:
+  unsigned const * formats = {
+    SOX_ENCODING_SIGN2, 16, 24, 0, // Support SIGN2 at 16 and 24 bits, default to 16 bits.
+    SOX_ENCODING_UNSIGNED, 8, 0,   // Support UNSIGNED at 8 bits, default to 8 bits.
+    0 // No more supported encodings.
+  };
+  */
+  unsigned     const * write_formats;
+
+  /**
+  Array of sample rates (samples per second) supported for writing (encoding).
+  NULL if all (or almost all) rates are supported. End with 0.
+  */
+  sox_rate_t   const * write_rates;
+
+  /**
+  SoX will automatically allocate a buffer in which the handler can store data.
+  Specify the size of the buffer needed here. Usually this will be sizeof(your_struct).
+  The buffer will be allocated and zeroed before the call to startread/startwrite.
+  The buffer will be freed after the call to stopread/stopwrite.
+  The buffer will be provided via format.priv in each call to the handler.
+  */
+  size_t       priv_size;
+};
+
+/**
+Client API:
+Comments, instrument info, loop info (out-of-band data).
+*/
+typedef struct sox_oob_t{
+  /* Decoded: */
+  sox_comments_t   comments;              /**< Comment strings in id=value format. */
+  sox_instrinfo_t  instr;                 /**< Instrument specification */
+  sox_loopinfo_t   loops[SOX_MAX_NLOOPS]; /**< Looping specification */
+
+  /* TBD: Non-decoded chunks, etc: */
+} sox_oob_t;
+
+/**
+Client API:
+Data passed to/from the format handler
+*/
+struct sox_format_t {
+  char             * filename;      /**< File name */
+
+  /**
+  Signal specifications for reader (decoder) or writer (encoder):
+  sample rate, number of channels, precision, length, headroom multiplier.
+  Any info specified by the user is here on entry to startread or
+  startwrite. Info will be SOX_UNSPEC if the user provided no info.
+  At exit from startread, should be completely filled in, using
+  either data from the file's headers (if available) or whatever
+  the format is guessing/assuming (if header data is not available).
+  At exit from startwrite, should be completely filled in, using
+  either the data that was specified, or values chosen by the format
+  based on the format's defaults or capabilities.
+  */
+  sox_signalinfo_t signal;
+
+  /**
+  Encoding specifications for reader (decoder) or writer (encoder):
+  encoding (sample format), bits per sample, compression rate, endianness.
+  Should be filled in by startread. Values specified should be used
+  by startwrite when it is configuring the encoding parameters.
+  */
+  sox_encodinginfo_t encoding;
+
+  char             * filetype;      /**< Type of file, as determined by header inspection or libmagic. */
+  sox_oob_t        oob;             /**< comments, instrument info, loop info (out-of-band data) */
+  sox_bool         seekable;        /**< Can seek on this file */
+  char             mode;            /**< Read or write mode ('r' or 'w') */
+  sox_uint64_t     olength;         /**< Samples * chans written to file */
+  sox_uint64_t     clips;           /**< Incremented if clipping occurs */
+  int              sox_errno;       /**< Failure error code */
+  char             sox_errstr[256]; /**< Failure error text */
+  void             * fp;            /**< File stream pointer */
+  lsx_io_type      io_type;         /**< Stores whether this is a file, pipe or URL */
+  sox_uint64_t     tell_off;        /**< Current offset within file */
+  sox_uint64_t     data_start;      /**< Offset at which headers end and sound data begins (set by lsx_check_read_params) */
+  sox_format_handler_t handler;     /**< Format handler for this file */
+  void             * priv;          /**< Format handler's private data area */
+};
+
+/**
+Client API:
+Information about a loaded format handler, including the format name and a
+function pointer that can be invoked to get additional information about the
+format.
+*/
+typedef struct sox_format_tab_t {
+  char *name;         /**< Name of format handler */
+  sox_format_fn_t fn; /**< Function to call to get format handler's information */
+} sox_format_tab_t;
+
+/**
+Client API:
+Global parameters for effects.
+*/
+typedef struct sox_effects_globals_t {
+  sox_plot_t plot;         /**< To help the user choose effect & options */
+  sox_globals_t * global_info; /**< Pointer to associated SoX globals */
+} sox_effects_globals_t;
+
+/**
+Client API:
+Effect handler information.
+*/
+struct sox_effect_handler_t {
+  char const * name;  /**< Effect name */
+  char const * usage; /**< Short explanation of parameters accepted by effect */
+  unsigned int flags; /**< Combination of SOX_EFF_* flags */
+  sox_effect_handler_getopts getopts; /**< Called to parse command-line arguments (called once per effect). */
+  sox_effect_handler_start start;     /**< Called to initialize effect (called once per flow). */
+  sox_effect_handler_flow flow;       /**< Called to process samples. */
+  sox_effect_handler_drain drain;     /**< Called to finish getting output after input is complete. */
+  sox_effect_handler_stop stop;       /**< Called to shut down effect (called once per flow). */
+  sox_effect_handler_kill kill;       /**< Called to shut down effect (called once per effect). */
+  size_t       priv_size;             /**< Size of private data SoX should pre-allocate for effect */
+};
+
+/**
+Client API:
+Effect information.
+*/
+struct sox_effect_t {
+  sox_effects_globals_t    * global_info; /**< global effect parameters */
+  sox_signalinfo_t         in_signal;     /**< Information about the incoming data stream */
+  sox_signalinfo_t         out_signal;    /**< Information about the outgoing data stream */
+  sox_encodinginfo_t       const * in_encoding;  /**< Information about the incoming data encoding */
+  sox_encodinginfo_t       const * out_encoding; /**< Information about the outgoing data encoding */
+  sox_effect_handler_t     handler;   /**< The handler for this effect */
+  sox_sample_t             * obuf;    /**< output buffer */
+  size_t                   obeg;      /**< output buffer: start of valid data section */
+  size_t                   oend;      /**< output buffer: one past valid data section (oend-obeg is length of current content) */
+  size_t               imin;          /**< minimum input buffer content required for calling this effect's flow function; set via lsx_effect_set_imin() */
+  sox_uint64_t         clips;         /**< increment if clipping occurs */
+  size_t               flows;         /**< 1 if MCHAN, number of chans otherwise */
+  size_t               flow;          /**< flow number */
+  void                 * priv;        /**< Effect's private data area (each flow has a separate copy) */
+};
+
+/**
+Client API:
+Chain of effects to be applied to a stream.
+*/
+typedef struct sox_effects_chain_t {
+  sox_effect_t **effects;                  /**< Table of effects to be applied to a stream */
+  unsigned table_size;                     /**< Number of entries in effects table */
+  unsigned length;                         /**< Number of effects to be applied */
+  sox_sample_t **ibufc;                    /**< Channel interleave buffer */
+  sox_sample_t **obufc;                    /**< Channel interleave buffer */
+  sox_effects_globals_t global_info;       /**< Copy of global effects settings */
+  sox_encodinginfo_t const * in_enc;       /**< Input encoding */
+  sox_encodinginfo_t const * out_enc;      /**< Output encoding */
+} sox_effects_chain_t;
+
+/*****************************************************************************
+Functions:
+*****************************************************************************/
+
+/**
+Client API:
+Returns version number string of libSoX, for example, "14.4.0".
+@returns The version number string of libSoX, for example, "14.4.0".
+*/
+LSX_RETURN_VALID_Z LSX_RETURN_PURE
+char const *
+LSX_API
+sox_version(void);
+
+/**
+Client API:
+Returns information about this build of libsox.
+@returns Pointer to a version information structure.
+*/
+LSX_RETURN_VALID LSX_RETURN_PURE
+sox_version_info_t const *
+LSX_API
+sox_version_info(void);
+
+/**
+Client API:
+Returns a pointer to the structure with libSoX's global settings.
+@returns a pointer to the structure with libSoX's global settings.
+*/
+LSX_RETURN_VALID LSX_RETURN_PURE
+sox_globals_t *
+LSX_API
+sox_get_globals(void);
+
+/**
+Client API:
+Deprecated macro that returns the structure with libSoX's global settings
+as an lvalue.
+*/
+#define sox_globals (*sox_get_globals())
+
+/**
+Client API:
+Returns a pointer to the list of available encodings.
+End of list indicated by name == NULL.
+@returns pointer to the list of available encodings.
+*/
+LSX_RETURN_ARRAY LSX_RETURN_PURE
+sox_encodings_info_t const *
+LSX_API
+sox_get_encodings_info(void);
+
+/**
+Client API:
+Deprecated macro that returns the list of available encodings.
+End of list indicated by name == NULL.
+*/
+#define sox_encodings_info (sox_get_encodings_info())
+
+/**
+Client API:
+Fills in an encodinginfo with default values.
+*/
+void
+LSX_API
+sox_init_encodinginfo(
+    LSX_PARAM_OUT sox_encodinginfo_t * e /**< Pointer to uninitialized encoding info structure to be initialized. */
+    );
+
+/**
+Client API:
+Given an encoding (for example, SIGN2) and the encoded bits_per_sample (for
+example, 16), returns the number of useful bits per sample in the decoded data
+(for example, 16), or returns 0 to indicate that the value returned by the
+format handler should be used instead of a pre-determined precision.
+@returns the number of useful bits per sample in the decoded data (for example
+16), or returns 0 to indicate that the value returned by the format handler
+should be used instead of a pre-determined precision.
+*/
+LSX_RETURN_PURE
+unsigned
+LSX_API
+sox_precision(
+    sox_encoding_t encoding,   /**< Encoding for which to lookup precision information. */
+    unsigned bits_per_sample   /**< The number of encoded bits per sample. */
+    );
+
+/**
+Client API:
+Returns the number of items in the metadata block.
+@returns the number of items in the metadata block.
+*/
+size_t
+LSX_API
+sox_num_comments(
+    LSX_PARAM_IN_OPT sox_comments_t comments /**< Metadata block. */
+    );
+
+/**
+Client API:
+Adds an "id=value" item to the metadata block.
+*/
+void
+LSX_API
+sox_append_comment(
+    LSX_PARAM_DEREF_PRE_MAYBENULL LSX_PARAM_DEREF_POST_NOTNULL sox_comments_t * comments, /**< Metadata block. */
+    LSX_PARAM_IN_Z char const * item /**< Item to be added in "id=value" format. */
+    );
+
+/**
+Client API:
+Adds a newline-delimited list of "id=value" items to the metadata block.
+*/
+void
+LSX_API
+sox_append_comments(
+    LSX_PARAM_DEREF_PRE_MAYBENULL LSX_PARAM_DEREF_POST_NOTNULL sox_comments_t * comments, /**< Metadata block. */
+    LSX_PARAM_IN_Z char const * items /**< Newline-separated list of items to be added, for example "id1=value1\\nid2=value2". */
+    );
+
+/**
+Client API:
+Duplicates the metadata block.
+@returns the copied metadata block.
+*/
+LSX_RETURN_OPT
+sox_comments_t
+LSX_API
+sox_copy_comments(
+    LSX_PARAM_IN_OPT sox_comments_t comments /**< Metadata block to copy. */
+    );
+
+/**
+Client API:
+Frees the metadata block.
+*/
+void
+LSX_API
+sox_delete_comments(
+    LSX_PARAM_DEREF_PRE_MAYBENULL LSX_PARAM_DEREF_POST_NULL sox_comments_t * comments /**< Metadata block. */
+    );
+
+/**
+Client API:
+If "id=value" is found, return value, else return null.
+@returns value, or null if value not found.
+*/
+LSX_RETURN_OPT
+char const *
+LSX_API
+sox_find_comment(
+    LSX_PARAM_IN_OPT sox_comments_t comments, /**< Metadata block in which to search. */
+    LSX_PARAM_IN_Z char const * id /**< Id for which to search */
+    );
+
+/**
+Client API:
+Find and load format handler plugins.
+@returns SOX_SUCCESS if successful.
+*/
+int
+LSX_API
+sox_format_init(void);
+
+/**
+Client API:
+Unload format handler plugins.
+*/
+void
+LSX_API
+sox_format_quit(void);
+
+/**
+Client API:
+Initialize effects library.
+@returns SOX_SUCCESS if successful.
+*/
+int
+LSX_API
+sox_init(void);
+
+/**
+Client API:
+Close effects library and unload format handler plugins.
+@returns SOX_SUCCESS if successful.
+*/
+int
+LSX_API
+sox_quit(void);
+
+/**
+Client API:
+Returns the table of format handler names and functions.
+@returns the table of format handler names and functions.
+*/
+LSX_RETURN_ARRAY LSX_RETURN_PURE
+sox_format_tab_t const *
+LSX_API
+sox_get_format_fns(void);
+
+/**
+Client API:
+Deprecated macro that returns the table of format handler names and functions.
+*/
+#define sox_format_fns (sox_get_format_fns())
+
+/**
+Client API:
+Opens a decoding session for a file. Returned handle must be closed with sox_close().
+@returns The handle for the new session, or null on failure.
+*/
+LSX_RETURN_OPT
+sox_format_t *
+LSX_API
+sox_open_read(
+    LSX_PARAM_IN_Z   char               const * path,      /**< Path to file to be opened (required). */
+    LSX_PARAM_IN_OPT sox_signalinfo_t   const * signal,    /**< Information already known about audio stream, or NULL if none. */
+    LSX_PARAM_IN_OPT sox_encodinginfo_t const * encoding,  /**< Information already known about sample encoding, or NULL if none. */
+    LSX_PARAM_IN_OPT_Z char             const * filetype   /**< Previously-determined file type, or NULL to auto-detect. */
+    );
+
+/**
+Client API:
+Opens a decoding session for a memory buffer. Returned handle must be closed with sox_close().
+@returns The handle for the new session, or null on failure.
+*/
+LSX_RETURN_OPT
+sox_format_t *
+LSX_API
+sox_open_mem_read(
+    LSX_PARAM_IN_BYTECOUNT(buffer_size) void  * buffer,     /**< Pointer to audio data buffer (required). */
+    size_t                                      buffer_size,/**< Number of bytes to read from audio data buffer. */
+    LSX_PARAM_IN_OPT sox_signalinfo_t   const * signal,     /**< Information already known about audio stream, or NULL if none. */
+    LSX_PARAM_IN_OPT sox_encodinginfo_t const * encoding,   /**< Information already known about sample encoding, or NULL if none. */
+    LSX_PARAM_IN_OPT_Z char             const * filetype    /**< Previously-determined file type, or NULL to auto-detect. */
+    );
+
+/**
+Client API:
+Returns true if the format handler for the specified file type supports the specified encoding.
+@returns true if the format handler for the specified file type supports the specified encoding.
+*/
+sox_bool
+LSX_API
+sox_format_supports_encoding(
+    LSX_PARAM_IN_OPT_Z char               const * path,       /**< Path to file to be examined (required if filetype is NULL). */
+    LSX_PARAM_IN_OPT_Z char               const * filetype,   /**< Previously-determined file type, or NULL to use extension from path. */
+    LSX_PARAM_IN       sox_encodinginfo_t const * encoding    /**< Encoding for which format handler should be queried. */
+    );
+
+/**
+Client API:
+Gets the format handler for a specified file type.
+@returns The found format handler, or null if not found.
+*/
+LSX_RETURN_OPT
+sox_format_handler_t const *
+LSX_API
+sox_write_handler(
+    LSX_PARAM_IN_OPT_Z char               const * path,         /**< Path to file (required if filetype is NULL). */
+    LSX_PARAM_IN_OPT_Z char               const * filetype,     /**< Filetype for which handler is needed, or NULL to use extension from path. */
+    LSX_PARAM_OUT_OPT  char               const * * filetype1   /**< Receives the filetype that was detected. Pass NULL if not needed. */
+    );
+
+/**
+Client API:
+Opens an encoding session for a file. Returned handle must be closed with sox_close().
+@returns The new session handle, or null on failure.
+*/
+LSX_RETURN_OPT
+sox_format_t *
+LSX_API
+sox_open_write(
+    LSX_PARAM_IN_Z     char               const * path,     /**< Path to file to be written (required). */
+    LSX_PARAM_IN       sox_signalinfo_t   const * signal,   /**< Information about desired audio stream (required). */
+    LSX_PARAM_IN_OPT   sox_encodinginfo_t const * encoding, /**< Information about desired sample encoding, or NULL to use defaults. */
+    LSX_PARAM_IN_OPT_Z char               const * filetype, /**< Previously-determined file type, or NULL to auto-detect. */
+    LSX_PARAM_IN_OPT   sox_oob_t          const * oob,      /**< Out-of-band data to add to file, or NULL if none. */
+    LSX_PARAM_IN_OPT   sox_bool           (LSX_API * overwrite_permitted)(LSX_PARAM_IN_Z char const * filename) /**< Called if file exists to determine whether overwrite is ok. */
+    );
+
+/**
+Client API:
+Opens an encoding session for a memory buffer. Returned handle must be closed with sox_close().
+@returns The new session handle, or null on failure.
+*/
+LSX_RETURN_OPT
+sox_format_t *
+LSX_API
+sox_open_mem_write(
+    LSX_PARAM_OUT_BYTECAP(buffer_size) void                     * buffer,      /**< Pointer to audio data buffer that receives data (required). */
+    LSX_PARAM_IN                       size_t                     buffer_size, /**< Maximum number of bytes to write to audio data buffer. */
+    LSX_PARAM_IN                       sox_signalinfo_t   const * signal,      /**< Information about desired audio stream (required). */
+    LSX_PARAM_IN_OPT                   sox_encodinginfo_t const * encoding,    /**< Information about desired sample encoding, or NULL to use defaults. */
+    LSX_PARAM_IN_OPT_Z                 char               const * filetype,    /**< Previously-determined file type, or NULL to auto-detect. */
+    LSX_PARAM_IN_OPT                   sox_oob_t          const * oob          /**< Out-of-band data to add to file, or NULL if none. */
+    );
+
+/**
+Client API:
+Opens an encoding session for a memstream buffer. Returned handle must be closed with sox_close().
+@returns The new session handle, or null on failure.
+*/
+LSX_RETURN_OPT
+sox_format_t *
+LSX_API
+sox_open_memstream_write(
+    LSX_PARAM_OUT      char                     * * buffer_ptr,    /**< Receives pointer to audio data buffer that receives data (required). */
+    LSX_PARAM_OUT      size_t                   * buffer_size_ptr, /**< Receives size of data written to audio data buffer (required). */
+    LSX_PARAM_IN       sox_signalinfo_t   const * signal,          /**< Information about desired audio stream (required). */
+    LSX_PARAM_IN_OPT   sox_encodinginfo_t const * encoding,        /**< Information about desired sample encoding, or NULL to use defaults. */
+    LSX_PARAM_IN_OPT_Z char               const * filetype,        /**< Previously-determined file type, or NULL to auto-detect. */
+    LSX_PARAM_IN_OPT   sox_oob_t          const * oob              /**< Out-of-band data to add to file, or NULL if none. */
+    );
+
+/**
+Client API:
+Reads samples from a decoding session into a sample buffer.
+@returns Number of samples decoded, or 0 for EOF.
+*/
+size_t
+LSX_API
+sox_read(
+    LSX_PARAM_INOUT sox_format_t * ft, /**< Format pointer. */
+    LSX_PARAM_OUT_CAP_POST_COUNT(len,return) sox_sample_t *buf, /**< Buffer from which to read samples. */
+    size_t len /**< Number of samples available in buf. */
+    );
+
+/**
+Client API:
+Writes samples to an encoding session from a sample buffer.
+@returns Number of samples encoded.
+*/
+size_t
+LSX_API
+sox_write(
+    LSX_PARAM_INOUT sox_format_t * ft, /**< Format pointer. */
+    LSX_PARAM_IN_COUNT(len) sox_sample_t const * buf, /**< Buffer from which to read samples. */
+    size_t len /**< Number of samples available in buf. */
+    );
+
+/**
+Client API:
+Closes an encoding or decoding session.
+@returns SOX_SUCCESS if successful.
+*/
+int
+LSX_API
+sox_close(
+    LSX_PARAM_INOUT sox_format_t * ft /**< Format pointer. */
+    );
+
+/**
+Client API:
+Sets the location at which next samples will be decoded. Returns SOX_SUCCESS if successful.
+@returns SOX_SUCCESS if successful.
+*/
+int
+LSX_API
+sox_seek(
+    LSX_PARAM_INOUT sox_format_t * ft, /**< Format pointer. */
+    sox_uint64_t offset, /**< Sample offset at which to position reader. */
+    int whence /**< Set to SOX_SEEK_SET. */
+    );
+
+/**
+Client API:
+Finds a format handler by name.
+@returns Format handler data, or null if not found.
+*/
+LSX_RETURN_OPT
+sox_format_handler_t const *
+LSX_API
+sox_find_format(
+    LSX_PARAM_IN_Z char const * name, /**< Name of format handler to find. */
+    sox_bool ignore_devices /**< Set to true to ignore device names. */
+    );
+
+/**
+Client API:
+Returns global parameters for effects
+@returns global parameters for effects.
+*/
+LSX_RETURN_VALID LSX_RETURN_PURE
+sox_effects_globals_t *
+LSX_API
+sox_get_effects_globals(void);
+
+/**
+Client API:
+Deprecated macro that returns global parameters for effects.
+*/
+#define sox_effects_globals (*sox_get_effects_globals())
+
+/**
+Client API:
+Finds the effect handler with the given name.
+@returns Effect pointer, or null if not found.
+*/
+LSX_RETURN_OPT LSX_RETURN_PURE
+sox_effect_handler_t const *
+LSX_API
+sox_find_effect(
+    LSX_PARAM_IN_Z char const * name /**< Name of effect to find. */
+    );
+
+/**
+Client API:
+Creates an effect using the given handler.
+@returns The new effect, or null if not found.
+*/
+LSX_RETURN_OPT
+sox_effect_t *
+LSX_API
+sox_create_effect(
+    LSX_PARAM_IN sox_effect_handler_t const * eh /**< Handler to use for effect. */
+    );
+
+/**
+Client API:
+Applies the command-line options to the effect.
+@returns the number of arguments consumed.
+*/
+int
+LSX_API
+sox_effect_options(
+    LSX_PARAM_IN sox_effect_t *effp, /**< Effect pointer on which to set options. */
+    int argc, /**< Number of arguments in argv. */
+    LSX_PARAM_IN_COUNT(argc) char * const argv[] /**< Array of command-line options. */
+    );
+
+/**
+Client API:
+Returns an array containing the known effect handlers.
+@returns An array containing the known effect handlers.
+*/
+LSX_RETURN_VALID_Z LSX_RETURN_PURE
+sox_effect_fn_t const *
+LSX_API
+sox_get_effect_fns(void);
+
+/**
+Client API:
+Deprecated macro that returns an array containing the known effect handlers.
+*/
+#define sox_effect_fns (sox_get_effect_fns())
+
+/**
+Client API:
+Initializes an effects chain. Returned handle must be closed with sox_delete_effects_chain().
+@returns Handle, or null on failure.
+*/
+LSX_RETURN_OPT
+sox_effects_chain_t *
+LSX_API
+sox_create_effects_chain(
+    LSX_PARAM_IN sox_encodinginfo_t const * in_enc, /**< Input encoding. */
+    LSX_PARAM_IN sox_encodinginfo_t const * out_enc /**< Output encoding. */
+    );
+
+/**
+Client API:
+Closes an effects chain.
+*/
+void
+LSX_API
+sox_delete_effects_chain(
+    LSX_PARAM_INOUT sox_effects_chain_t *ecp /**< Effects chain pointer. */
+    );
+
+/**
+Client API:
+Adds an effect to the effects chain, returns SOX_SUCCESS if successful.
+@returns SOX_SUCCESS if successful.
+*/
+int
+LSX_API
+sox_add_effect(
+    LSX_PARAM_INOUT sox_effects_chain_t * chain, /**< Effects chain to which effect should be added . */
+    LSX_PARAM_INOUT sox_effect_t * effp, /**< Effect to be added. */
+    LSX_PARAM_INOUT sox_signalinfo_t * in, /**< Input format. */
+    LSX_PARAM_IN    sox_signalinfo_t const * out /**< Output format. */
+    );
+
+/**
+Client API:
+Runs the effects chain, returns SOX_SUCCESS if successful.
+@returns SOX_SUCCESS if successful.
+*/
+int
+LSX_API
+sox_flow_effects(
+    LSX_PARAM_INOUT  sox_effects_chain_t * chain, /**< Effects chain to run. */
+    LSX_PARAM_IN_OPT sox_flow_effects_callback callback, /**< Callback for monitoring flow progress. */
+    LSX_PARAM_IN_OPT void * client_data /**< Data to pass into callback. */
+    );
+
+/**
+Client API:
+Gets the number of clips that occurred while running an effects chain.
+@returns the number of clips that occurred while running an effects chain.
+*/
+sox_uint64_t
+LSX_API
+sox_effects_clips(
+    LSX_PARAM_IN sox_effects_chain_t * chain /**< Effects chain from which to read clip information. */
+    );
+
+/**
+Client API:
+Shuts down an effect (calls stop on each of its flows).
+@returns the number of clips from all flows.
+*/
+sox_uint64_t
+LSX_API
+sox_stop_effect(
+    LSX_PARAM_INOUT_COUNT(effp->flows) sox_effect_t * effp /**< Effect to stop. */
+    );
+
+/**
+Client API:
+Adds an already-initialized effect to the end of the chain.
+*/
+void
+LSX_API
+sox_push_effect_last(
+    LSX_PARAM_INOUT sox_effects_chain_t * chain, /**< Effects chain to which effect should be added. */
+    LSX_PARAM_INOUT sox_effect_t * effp /**< Effect to be added. */
+    );
+
+/**
+Client API:
+Removes and returns an effect from the end of the chain.
+@returns the removed effect, or null if no effects.
+*/
+LSX_RETURN_OPT
+sox_effect_t *
+LSX_API
+sox_pop_effect_last(
+    LSX_PARAM_INOUT sox_effects_chain_t *chain /**< Effects chain from which to remove an effect. */
+    );
+
+/**
+Client API:
+Shut down and delete an effect.
+*/
+void
+LSX_API
+sox_delete_effect(
+    LSX_PARAM_INOUT_COUNT(effp->flows) sox_effect_t *effp /**< Effect to be deleted. */
+    );
+
+/**
+Client API:
+Shut down and delete the last effect in the chain.
+*/
+void
+LSX_API
+sox_delete_effect_last(
+    LSX_PARAM_INOUT sox_effects_chain_t *chain /**< Effects chain from which to remove the last effect. */
+    );
+
+/**
+Client API:
+Shut down and delete all effects in the chain.
+*/
+void
+LSX_API
+sox_delete_effects(
+    LSX_PARAM_INOUT sox_effects_chain_t *chain /**< Effects chain from which to delete effects. */
+    );
+
+/**
+Client API:
+Gets the sample offset of the start of the trim, useful for efficiently
+skipping the part that will be trimmed anyway (get trim start, seek, then
+clear trim start).
+@returns the sample offset of the start of the trim.
+*/
+sox_uint64_t
+LSX_API
+sox_trim_get_start(
+    LSX_PARAM_IN sox_effect_t * effp /**< Trim effect. */
+    );
+
+/**
+Client API:
+Clears the start of the trim to 0.
+*/
+void
+LSX_API
+sox_trim_clear_start(
+    LSX_PARAM_INOUT sox_effect_t * effp /**< Trim effect. */
+    );
+
+/**
+Client API:
+Returns true if the specified file is a known playlist file type.
+@returns true if the specified file is a known playlist file type.
+*/
+sox_bool
+LSX_API
+sox_is_playlist(
+    LSX_PARAM_IN_Z char const * filename /**< Name of file to examine. */
+    );
+
+/**
+Client API:
+Parses the specified playlist file.
+@returns SOX_SUCCESS if successful.
+*/
+int
+LSX_API
+sox_parse_playlist(
+    LSX_PARAM_IN sox_playlist_callback_t callback, /**< Callback to call for each item in the playlist. */
+    void * p, /**< Data to pass to callback. */
+    LSX_PARAM_IN char const * const listname /**< Filename of playlist file. */
+    );
+
+/**
+Client API:
+Converts a SoX error code into an error string.
+@returns error string corresponding to the specified error code,
+or a generic message if the error code is not recognized.
+*/
+LSX_RETURN_VALID_Z LSX_RETURN_PURE
+char const *
+LSX_API
+sox_strerror(
+    int sox_errno /**< Error code to look up. */
+    );
+
+/**
+Client API:
+Gets the basename of the specified file; for example, the basename of
+"/a/b/c.d" would be "c".
+@returns the number of characters written to base_buffer, excluding the null,
+or 0 on failure.
+*/
+size_t
+LSX_API
+sox_basename(
+    LSX_PARAM_OUT_Z_CAP_POST_COUNT(base_buffer_len,return) char * base_buffer, /**< Buffer into which basename should be written. */
+    size_t base_buffer_len, /**< Size of base_buffer, in bytes. */
+    LSX_PARAM_IN_Z char const * filename /**< Filename from which to extract basename. */
+    );
+
+/*****************************************************************************
+Internal API:
+WARNING - The items in this section are subject to instability. They only
+exist in the public header because sox (the application) currently uses them.
+These may be changed or removed in future versions of libSoX.
+*****************************************************************************/
+
+/**
+Plugins API:
+Print a fatal error in libSoX.
+*/
+void
+LSX_API
+lsx_fail_impl(
+    LSX_PARAM_IN_PRINTF char const * fmt, /**< printf-style format string. */
+    ...)
+    LSX_PRINTF12;
+
+/**
+Plugins API:
+Print a warning in libSoX.
+*/
+void
+LSX_API
+lsx_warn_impl(
+    LSX_PARAM_IN_PRINTF char const * fmt, /**< printf-style format string. */
+    ...)
+    LSX_PRINTF12;
+
+/**
+Plugins API:
+Print an informational message in libSoX.
+*/
+void
+LSX_API
+lsx_report_impl(
+    LSX_PARAM_IN_PRINTF char const * fmt, /**< printf-style format string. */
+    ...)
+    LSX_PRINTF12;
+
+/**
+Plugins API:
+Print a debug message in libSoX.
+*/
+void
+LSX_API
+lsx_debug_impl(
+    LSX_PARAM_IN_PRINTF char const * fmt, /**< printf-style format string. */
+    ...)
+    LSX_PRINTF12;
+
+/**
+Plugins API:
+Report a fatal error in libSoX; printf-style arguments must follow.
+*/
+#define lsx_fail       sox_get_globals()->subsystem=__FILE__,lsx_fail_impl
+
+/**
+Plugins API:
+Report a warning in libSoX; printf-style arguments must follow.
+*/
+#define lsx_warn       sox_get_globals()->subsystem=__FILE__,lsx_warn_impl
+
+/**
+Plugins API:
+Report an informational message in libSoX; printf-style arguments must follow.
+*/
+#define lsx_report     sox_get_globals()->subsystem=__FILE__,lsx_report_impl
+
+/**
+Plugins API:
+Report a debug message in libSoX; printf-style arguments must follow.
+*/
+#define lsx_debug      sox_get_globals()->subsystem=__FILE__,lsx_debug_impl
+
+/**
+Plugins API:
+String name and integer values for enumerated types (type metadata), for use
+with LSX_ENUM_ITEM, lsx_find_enum_text, and lsx_find_enum_value.
+*/
+typedef struct lsx_enum_item {
+    char const *text; /**< String name of enumeration. */
+    unsigned value;   /**< Integer value of enumeration. */
+} lsx_enum_item;
+
+/**
+Plugins API:
+Declares a static instance of an lsx_enum_item structure in format
+{ "item", prefixitem }, for use in declaring lsx_enum_item[] arrays.
+@param prefix The prefix to prepend to the item in the enumeration symbolic name.
+@param item   The user-visible text name of the item (must also be a valid C symbol name).
+*/
+#define LSX_ENUM_ITEM(prefix, item) {#item, prefix##item},
+
+/**
+Plugins API:
+Flags for use with lsx_find_enum_item.
+*/
+enum
+{
+    lsx_find_enum_item_none = 0, /**< Default parameters (case-insensitive). */
+    lsx_find_enum_item_case_sensitive = 1 /**< Enable case-sensitive search. */
+};
+
+/**
+Plugins API:
+Looks up an enumeration by name in an array of lsx_enum_items.
+@returns the corresponding item, or null if not found.
+*/
+LSX_RETURN_OPT LSX_RETURN_PURE
+lsx_enum_item const *
+LSX_API
+lsx_find_enum_text(
+    LSX_PARAM_IN_Z char const * text, /**< Name of enumeration to find. */
+    LSX_PARAM_IN lsx_enum_item const * lsx_enum_items, /**< Array of items to search, with text == NULL for last item. */
+    int flags /**< Search flags: 0 (case-insensitive) or lsx_find_enum_item_case_sensitive (case-sensitive). */
+    );
+
+/**
+Plugins API:
+Looks up an enumeration by value in an array of lsx_enum_items.
+@returns the corresponding item, or null if not found.
+*/
+LSX_RETURN_OPT LSX_RETURN_PURE
+lsx_enum_item const *
+LSX_API
+lsx_find_enum_value(
+    unsigned value, /**< Enumeration value to find. */
+    LSX_PARAM_IN lsx_enum_item const * lsx_enum_items /**< Array of items to search, with text == NULL for last item. */
+    );
+
+/**
+Plugins API:
+Looks up a command-line argument in a set of enumeration names, showing an
+error message if the argument is not found in the set of names.
+@returns The enumeration value corresponding to the matching enumeration, or
+INT_MAX if the argument does not match any enumeration name.
+*/
+LSX_RETURN_PURE
+int
+LSX_API
+lsx_enum_option(
+    int c, /**< Option character to which arg is associated, for example with -a, c would be 'a'. */
+    LSX_PARAM_IN_Z char const * arg, /**< Argument to find in enumeration list. */
+    LSX_PARAM_IN lsx_enum_item const * items /**< Array of items to search, with text == NULL for last item. */
+    );
+
+/**
+Plugins API:
+Determines whether the specified string ends with the specified suffix (case-sensitive).
+@returns true if the specified string ends with the specified suffix.
+*/
+LSX_RETURN_PURE
+sox_bool
+LSX_API
+lsx_strends(
+    LSX_PARAM_IN_Z char const * str, /**< String to search. */
+    LSX_PARAM_IN_Z char const * end  /**< Suffix to search for. */
+    );
+
+/**
+Plugins API:
+Finds the file extension for a filename.
+@returns the file extension, not including the '.', or null if filename does
+not have an extension.
+*/
+LSX_RETURN_VALID_Z LSX_RETURN_PURE
+char const *
+LSX_API
+lsx_find_file_extension(
+    LSX_PARAM_IN_Z char const * pathname /**< Filename to search for extension. */
+    );
+
+/**
+Plugins API:
+Formats the specified number with up to three significant figures and adds a
+metric suffix in place of the exponent, such as 1.23G.
+@returns A static buffer with the formatted number, valid until the next time
+this function is called (note: not thread safe).
+*/
+LSX_RETURN_VALID_Z
+char const *
+LSX_API
+lsx_sigfigs3(
+    double number /**< Number to be formatted. */
+    );
+
+/**
+Plugins API:
+Formats the specified number as a percentage, showing up to three significant
+figures.
+@returns A static buffer with the formatted number, valid until the next time
+this function is called (note: not thread safe).
+*/
+LSX_RETURN_VALID_Z
+char const *
+LSX_API
+lsx_sigfigs3p(
+    double percentage /**< Number to be formatted. */
+    );
+
+/**
+Plugins API:
+Allocates, deallocates, or resizes; like C's realloc, except that this version
+terminates the running application if unable to allocate the requested memory.
+@returns New buffer, or null if buffer was freed.
+*/
+LSX_RETURN_OPT
+void *
+LSX_API
+lsx_realloc(
+    LSX_PARAM_IN_OPT void *ptr, /**< Pointer to be freed or resized, or null if allocating a new buffer. */
+    size_t newsize /**< New size for buffer, or 0 to free the buffer. */
+    );
+
+/**
+Plugins API:
+Like strcmp, except that the characters are compared without regard to case.
+@returns 0 (s1 == s2), negative (s1 < s2), or positive (s1 > s2).
+*/
+LSX_RETURN_PURE
+int
+LSX_API
+lsx_strcasecmp(
+    LSX_PARAM_IN_Z char const * s1, /**< First string. */
+    LSX_PARAM_IN_Z char const * s2  /**< Second string. */
+    );
+
+
+/**
+Plugins API:
+Like strncmp, except that the characters are compared without regard to case.
+@returns 0 (s1 == s2), negative (s1 < s2), or positive (s1 > s2).
+*/
+LSX_RETURN_PURE
+int
+LSX_API
+lsx_strncasecmp(
+    LSX_PARAM_IN_Z char const * s1, /**< First string. */
+    LSX_PARAM_IN_Z char const * s2, /**< Second string. */
+    size_t n /**< Maximum number of characters to examine. */
+    );
+
+/**
+Plugins API:
+Is option argument unsupported, required, or optional.
+*/
+typedef enum lsx_option_arg_t {
+    lsx_option_arg_none, /**< Option does not have an argument. */
+    lsx_option_arg_required, /**< Option requires an argument. */
+    lsx_option_arg_optional /**< Option can optionally be followed by an argument. */
+} lsx_option_arg_t;
+
+/**
+Plugins API:
+lsx_getopt_init options.
+*/
+typedef enum lsx_getopt_flags_t {
+    lsx_getopt_flag_none = 0,      /**< no flags (no output, not long-only) */
+    lsx_getopt_flag_opterr = 1,    /**< if set, invalid options trigger lsx_warn output */
+    lsx_getopt_flag_longonly = 2   /**< if set, recognize -option as a long option */
+} lsx_getopt_flags_t;
+
+/**
+Plugins API:
+lsx_getopt long option descriptor.
+*/
+typedef struct lsx_option_t {
+    char const *     name;    /**< Name of the long option. */
+    lsx_option_arg_t has_arg; /**< Whether the long option supports an argument and, if so, whether the argument is required or optional. */
+    int *            flag;    /**< Flag to set if argument is present. */
+    int              val;     /**< Value to put in flag if argument is present. */
+} lsx_option_t;
+
+/**
+Plugins API:
+lsx_getopt session information (initialization data and state).
+*/
+typedef struct lsx_getopt_t {
+    int                  argc;     /**< IN    argc:      Number of arguments in argv */
+    char * const *       argv;     /**< IN    argv:      Array of arguments */
+    char const *         shortopts;/**< IN    shortopts: Short option characters */
+    lsx_option_t const * longopts; /**< IN    longopts:  Array of long option descriptors */
+    lsx_getopt_flags_t   flags;    /**< IN    flags:     Flags for longonly and opterr */
+    char const *         curpos;   /**< INOUT curpos:    Maintains state between calls to lsx_getopt */
+    int                  ind;      /**< INOUT optind:    Maintains the index of next element to be processed */
+    int                  opt;      /**< OUT   optopt:    Receives the option character that caused error */
+    char const *         arg;      /**< OUT   optarg:    Receives the value of the option's argument */
+    int                  lngind;   /**< OUT   lngind:    Receives the index of the matched long option or -1 if not a long option */
+} lsx_getopt_t;
+
+/**
+Plugins API:
+Initializes an lsx_getopt_t structure for use with lsx_getopt.
+*/
+void
+LSX_API
+lsx_getopt_init(
+    LSX_PARAM_IN             int argc,                      /**< Number of arguments in argv */
+    LSX_PARAM_IN_COUNT(argc) char * const * argv,           /**< Array of arguments */
+    LSX_PARAM_IN_Z           char const * shortopts,        /**< Short options, for example ":abc:def::ghi" (+/- not supported) */
+    LSX_PARAM_IN_OPT         lsx_option_t const * longopts, /**< Array of long option descriptors */
+    LSX_PARAM_IN             lsx_getopt_flags_t flags,      /**< Flags for longonly and opterr */
+    LSX_PARAM_IN             int first,                     /**< First argv to check (usually 1) */
+    LSX_PARAM_OUT            lsx_getopt_t * state           /**< State object to be initialized */
+    );
+
+/**
+Plugins API:
+Gets the next option. Options are parameters that start with "-" or "--".
+If no more options, returns -1. If unrecognized short option, returns '?'.
+If a recognized short option is missing a required argument,
+return (shortopts[0]==':' ? ':' : '?'). If successfully recognized short
+option, return the recognized character. If successfully recognized long
+option, returns (option.flag ? 0 : option.val).
+Note: lsx_getopt does not permute the non-option arguments.
+@returns option character (short), val or 0 (long), or -1 (no more).
+*/
+int
+LSX_API
+lsx_getopt(
+    LSX_PARAM_INOUT lsx_getopt_t * state /**< The getopt state pointer. */
+    );
+
+/* WARNING END */
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif /* SOX_H */
diff --git a/freedv-dev/src/sox/sox_i.h b/freedv-dev/src/sox/sox_i.h
new file mode 100644 (file)
index 0000000..e2cdbae
--- /dev/null
@@ -0,0 +1,415 @@
+/* libSoX Internal header
+ *
+ *   This file is meant for libSoX internal use only
+ *
+ * Copyright 2001-2008 Chris Bagwell and SoX Contributors
+ *
+ * This source code is freely redistributable and may be used for
+ * any purpose.  This copyright notice must be maintained.
+ * Chris Bagwell And SoX Contributors are not responsible for
+ * the consequences of using this software.
+ */
+
+#ifndef SOX_I_H
+#define SOX_I_H
+
+#include "soxomp.h"  /* Note: soxomp.h includes soxconfig.h */
+#include "sox.h"
+
+#if defined HAVE_FMEMOPEN
+#define _GNU_SOURCE
+#endif
+
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "util.h"
+
+#if defined(LSX_EFF_ALIAS)
+#undef lsx_debug
+#undef lsx_fail
+#undef lsx_report
+#undef lsx_warn
+#define lsx_debug sox_globals.subsystem=effp->handler.name,lsx_debug_impl
+#define lsx_fail sox_globals.subsystem=effp->handler.name,lsx_fail_impl
+#define lsx_report sox_globals.subsystem=effp->handler.name,lsx_report_impl
+#define lsx_warn sox_globals.subsystem=effp->handler.name,lsx_warn_impl
+#endif
+
+#define RANQD1 ranqd1(sox_globals.ranqd1)
+#define DRANQD1 dranqd1(sox_globals.ranqd1)
+
+typedef enum {SOX_SHORT, SOX_INT, SOX_FLOAT, SOX_DOUBLE} sox_data_t;
+typedef enum {SOX_WAVE_SINE, SOX_WAVE_TRIANGLE} lsx_wave_t;
+lsx_enum_item const * lsx_get_wave_enum(void);
+
+/* Define fseeko and ftello for platforms lacking them */
+#ifndef HAVE_FSEEKO
+#define fseeko fseek
+#define ftello ftell
+#endif
+
+#ifdef _FILE_OFFSET_BITS
+assert_static(sizeof(off_t) == _FILE_OFFSET_BITS >> 3, OFF_T_BUILD_PROBLEM);
+#endif
+
+FILE * lsx_tmpfile(void);
+
+void lsx_debug_more_impl(char const * fmt, ...) LSX_PRINTF12;
+void lsx_debug_most_impl(char const * fmt, ...) LSX_PRINTF12;
+
+#define lsx_debug_more sox_get_globals()->subsystem=__FILE__,lsx_debug_more_impl
+#define lsx_debug_most sox_get_globals()->subsystem=__FILE__,lsx_debug_most_impl
+
+/* Digitise one cycle of a wave and store it as
+ * a table of samples of a specified data-type.
+ */
+void lsx_generate_wave_table(
+    lsx_wave_t wave_type,
+    sox_data_t data_type,
+    void * table,       /* Really of type indicated by data_type. */
+    size_t table_size,  /* Number of points on the x-axis. */
+    double min,         /* Minimum value on the y-axis. (e.g. -1) */
+    double max,         /* Maximum value on the y-axis. (e.g. +1) */
+    double phase);      /* Phase at 1st point; 0..2pi. (e.g. pi/2 for cosine) */
+char const * lsx_parsesamples(sox_rate_t rate, const char *str, uint64_t *samples, int def);
+int lsx_parse_note(char const * text, char * * end_ptr);
+double lsx_parse_frequency_k(char const * text, char * * end_ptr, int key);
+#define lsx_parse_frequency(a, b) lsx_parse_frequency_k(a, b, INT_MAX)
+FILE * lsx_open_input_file(sox_effect_t * effp, char const * filename);
+
+void lsx_prepare_spline3(double const * x, double const * y, int n,
+    double start_1d, double end_1d, double * y_2d);
+double lsx_spline3(double const * x, double const * y, double const * y_2d,
+    int n, double x1);
+
+double lsx_bessel_I_0(double x);
+int lsx_set_dft_length(int num_taps);
+void init_fft_cache(void);
+void clear_fft_cache(void);
+void lsx_safe_rdft(int len, int type, double * d);
+void lsx_safe_cdft(int len, int type, double * d);
+void lsx_power_spectrum(int n, double const * in, double * out);
+void lsx_power_spectrum_f(int n, float const * in, float * out);
+void lsx_apply_hann_f(float h[], const int num_points);
+void lsx_apply_hann(double h[], const int num_points);
+void lsx_apply_hamming(double h[], const int num_points);
+void lsx_apply_bartlett(double h[], const int num_points);
+void lsx_apply_blackman(double h[], const int num_points, double alpha);
+void lsx_apply_blackman_nutall(double h[], const int num_points);
+double lsx_kaiser_beta(double att);
+void lsx_apply_kaiser(double h[], const int num_points, double beta);
+double * lsx_make_lpf(int num_taps, double Fc, double beta, double scale, sox_bool dc_norm);
+int lsx_lpf_num_taps(double att, double tr_bw, int k);
+double * lsx_design_lpf(
+    double Fp,      /* End of pass-band; ~= 0.01dB point */
+    double Fc,      /* Start of stop-band */
+    double Fn,      /* Nyquist freq; e.g. 0.5, 1, PI */
+    sox_bool allow_aliasing,
+    double att,     /* Stop-band attenuation in dB */
+    int * num_taps, /* (Single phase.)  0: value will be estimated */
+    int k);         /* Number of phases; 0 for single-phase */
+void lsx_fir_to_phase(double * * h, int * len,
+    int * post_len, double phase0);
+#define LSX_TO_6dB .5869
+#define LSX_TO_3dB ((2/3.) * (.5 + LSX_TO_6dB))
+#define LSX_MAX_TBW0 36.
+#define LSX_MAX_TBW0A (LSX_MAX_TBW0 / (1 + LSX_TO_3dB))
+#define LSX_MAX_TBW3 floor(LSX_MAX_TBW0 * LSX_TO_3dB)
+#define LSX_MAX_TBW3A floor(LSX_MAX_TBW0A * LSX_TO_3dB)
+void lsx_plot_fir(double * h, int num_points, sox_rate_t rate, sox_plot_t type, char const * title, double y1, double y2);
+
+#ifdef HAVE_BYTESWAP_H
+#include <byteswap.h>
+#define lsx_swapw(x) bswap_16(x)
+#define lsx_swapdw(x) bswap_32(x)
+#elif defined(_MSC_VER)
+#define lsx_swapw(x) _byteswap_ushort(x)
+#define lsx_swapdw(x) _byteswap_ulong(x)
+#else
+#define lsx_swapw(uw) (((uw >> 8) | (uw << 8)) & 0xffff)
+#define lsx_swapdw(udw) ((udw >> 24) | ((udw >> 8) & 0xff00) | ((udw << 8) & 0xff0000) | (udw << 24))
+#endif
+
+
+
+/*------------------------ Implemented in libsoxio.c -------------------------*/
+
+/* Read and write basic data types from "ft" stream. */
+size_t lsx_readbuf(sox_format_t * ft, void *buf, size_t len);
+int lsx_skipbytes(sox_format_t * ft, size_t n);
+int lsx_padbytes(sox_format_t * ft, size_t n);
+size_t lsx_writebuf(sox_format_t * ft, void const *buf, size_t len);
+int lsx_reads(sox_format_t * ft, char *c, size_t len);
+int lsx_writes(sox_format_t * ft, char const * c);
+void lsx_set_signal_defaults(sox_format_t * ft);
+#define lsx_writechars(ft, chars, len) (lsx_writebuf(ft, chars, len) == len? SOX_SUCCESS : SOX_EOF)
+
+size_t lsx_read_3_buf(sox_format_t * ft, sox_uint24_t *buf, size_t len);
+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);
+
+size_t lsx_write_3_buf(sox_format_t * ft, sox_uint24_t *buf, size_t len);
+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);
+
+int lsx_read3(sox_format_t * ft, sox_uint24_t * u3);
+int lsx_readb(sox_format_t * ft, uint8_t * ub);
+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);
+
+#if 1 /* FIXME: use defines */
+UNUSED static int lsx_readsb(sox_format_t * ft, int8_t * sb)
+{return lsx_readb(ft, (uint8_t *)sb);}
+UNUSED static int lsx_readsw(sox_format_t * ft, int16_t * sw)
+{return lsx_readw(ft, (uint16_t *)sw);}
+#else
+#define lsx_readsb(ft, sb) lsx_readb(ft, (uint8_t *)sb)
+#define lsx_readsw(ft, sw) lsx_readb(ft, (uint16_t *)sw)
+#endif
+
+int lsx_write3(sox_format_t * ft, unsigned u3);
+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);
+
+int lsx_writesb(sox_format_t * ft, signed);
+int lsx_writesw(sox_format_t * ft, signed);
+
+int lsx_eof(sox_format_t * ft);
+int lsx_error(sox_format_t * ft);
+int lsx_flush(sox_format_t * ft);
+int lsx_seeki(sox_format_t * ft, off_t offset, int whence);
+int lsx_unreadb(sox_format_t * ft, unsigned ub);
+uint64_t lsx_filelength(sox_format_t * ft);
+off_t lsx_tell(sox_format_t * ft);
+void lsx_clearerr(sox_format_t * ft);
+void lsx_rewind(sox_format_t * ft);
+
+int lsx_offset_seek(sox_format_t * ft, off_t byte_offset, off_t to_sample);
+
+void lsx_fail_errno(sox_format_t *, int, const char *, ...)
+#ifdef __GNUC__
+__attribute__ ((format (printf, 3, 4)));
+#else
+;
+#endif
+
+typedef struct sox_formats_globals { /* Global parameters (for formats) */
+  sox_globals_t * global_info;
+} sox_formats_globals;
+
+
+
+/*------------------------------ File Handlers -------------------------------*/
+
+int lsx_check_read_params(sox_format_t * ft, unsigned channels,
+    sox_rate_t rate, sox_encoding_t encoding, unsigned bits_per_sample,
+    uint64_t num_samples, sox_bool check_length);
+#define LSX_FORMAT_HANDLER(name) \
+sox_format_handler_t const * lsx_##name##_format_fn(void); \
+sox_format_handler_t const * lsx_##name##_format_fn(void)
+#define div_bits(size, bits) ((uint64_t)(size) * 8 / bits)
+
+/* Raw I/O */
+int lsx_rawstartread(sox_format_t * ft);
+size_t lsx_rawread(sox_format_t * ft, sox_sample_t *buf, size_t nsamp);
+int lsx_rawstopread(sox_format_t * ft);
+int lsx_rawstartwrite(sox_format_t * ft);
+size_t lsx_rawwrite(sox_format_t * ft, const sox_sample_t *buf, size_t nsamp);
+int lsx_rawseek(sox_format_t * ft, uint64_t offset);
+int lsx_rawstart(sox_format_t * ft, sox_bool default_rate, sox_bool default_channels, sox_bool default_length, sox_encoding_t encoding, unsigned bits_per_sample);
+#define lsx_rawstartread(ft) lsx_rawstart(ft, sox_false, sox_false, sox_false, SOX_ENCODING_UNKNOWN, 0)
+#define lsx_rawstartwrite lsx_rawstartread
+#define lsx_rawstopread NULL
+#define lsx_rawstopwrite NULL
+
+extern sox_format_handler_t const * lsx_sndfile_format_fn(void);
+
+char * lsx_cat_comments(sox_comments_t comments);
+
+/*--------------------------------- Effects ----------------------------------*/
+
+int lsx_flow_copy(sox_effect_t * effp, const sox_sample_t * ibuf,
+    sox_sample_t * obuf, size_t * isamp, size_t * osamp);
+int lsx_usage(sox_effect_t * effp);
+char * lsx_usage_lines(char * * usage, char const * const * lines, size_t n);
+#define EFFECT(f) extern sox_effect_handler_t const * lsx_##f##_effect_fn(void);
+#include "effects.h"
+#undef EFFECT
+
+#define NUMERIC_PARAMETER(name, min, max) { \
+  char * end_ptr; \
+  double d; \
+  if (argc == 0) break; \
+  d = strtod(*argv, &end_ptr); \
+  if (end_ptr != *argv) { \
+    if (d < min || d > max || *end_ptr != '\0') {\
+      lsx_fail("parameter `%s' must be between %g and %g", #name, (double)min, (double)max); \
+      return lsx_usage(effp); \
+    } \
+    p->name = d; \
+    --argc, ++argv; \
+  } \
+}
+
+#define TEXTUAL_PARAMETER(name, enum_table) { \
+  lsx_enum_item const * e; \
+  if (argc == 0) break; \
+  e = lsx_find_enum_text(*argv, enum_table, 0); \
+  if (e != NULL) { \
+    p->name = e->value; \
+    --argc, ++argv; \
+  } \
+}
+
+#define GETOPT_NUMERIC(state, ch, name, min, max) case ch:{ \
+  char * end_ptr; \
+  double d = strtod(state.arg, &end_ptr); \
+  if (end_ptr == state.arg || d < min || d > max || *end_ptr != '\0') {\
+    lsx_fail("parameter `%s' must be between %g and %g", #name, (double)min, (double)max); \
+    return lsx_usage(effp); \
+  } \
+  p->name = d; \
+  break; \
+}
+
+int lsx_effect_set_imin(sox_effect_t * effp, size_t imin);
+
+int lsx_effects_init(void);
+int lsx_effects_quit(void);
+
+/*--------------------------------- Dynamic Library ----------------------------------*/
+
+#if defined(HAVE_WIN32_LTDL_H)
+    #include "win32-ltdl.h"
+    #define HAVE_LIBLTDL 1
+    typedef lt_dlhandle lsx_dlhandle;
+#elif defined(HAVE_LIBLTDL)
+    #include <ltdl.h>
+    typedef lt_dlhandle lsx_dlhandle;
+#else
+    struct lsx_dlhandle_tag;
+    typedef struct lsx_dlhandle_tag *lsx_dlhandle;
+#endif
+
+typedef void (*lsx_dlptr)(void);
+
+typedef struct lsx_dlfunction_info
+{
+    const char* name;
+    lsx_dlptr static_func;
+    lsx_dlptr stub_func;
+} lsx_dlfunction_info;
+
+int lsx_open_dllibrary(
+    int show_error_on_failure,
+    const char* library_description,
+    const char * const library_names[],
+    const lsx_dlfunction_info func_infos[],
+    lsx_dlptr selected_funcs[],
+    lsx_dlhandle* pdl);
+
+void lsx_close_dllibrary(
+    lsx_dlhandle dl);
+
+#define LSX_DLENTRIES_APPLY__(entries, f, x) entries(f, x)
+
+#define LSX_DLENTRY_TO_PTR__(unused, func_return, func_name, func_args, static_func, stub_func, func_ptr) \
+    func_return (*func_ptr) func_args;
+
+#define LSX_DLENTRIES_TO_FUNCTIONS__(unused, func_return, func_name, func_args, static_func, stub_func, func_ptr) \
+    func_return func_name func_args;
+
+/* LSX_DLENTRIES_TO_PTRS: Given an ENTRIES macro and the name of the dlhandle
+   variable, declares the corresponding function pointer variables and the
+   dlhandle variable. */
+#define LSX_DLENTRIES_TO_PTRS(entries, dlhandle) \
+    LSX_DLENTRIES_APPLY__(entries, LSX_DLENTRY_TO_PTR__, 0) \
+    lsx_dlhandle dlhandle
+
+/* LSX_DLENTRIES_TO_FUNCTIONS: Given an ENTRIES macro, declares the corresponding
+   functions. */
+#define LSX_DLENTRIES_TO_FUNCTIONS(entries) \
+    LSX_DLENTRIES_APPLY__(entries, LSX_DLENTRIES_TO_FUNCTIONS__, 0)
+
+#define LSX_DLLIBRARY_OPEN1__(unused, func_return, func_name, func_args, static_func, stub_func, func_ptr) \
+    { #func_name, (lsx_dlptr)(static_func), (lsx_dlptr)(stub_func) },
+
+#define LSX_DLLIBRARY_OPEN2__(ptr_container, func_return, func_name, func_args, static_func, stub_func, func_ptr) \
+    (ptr_container)->func_ptr = (func_return (*)func_args)lsx_dlfunction_open_library_funcs[lsx_dlfunction_open_library_index++];
+
+/* LSX_DLLIBRARY_OPEN: Input an ENTRIES macro, the library's description,
+   a null-terminated list of library names (i.e. { "libmp3-0", "libmp3", NULL }),
+   the name of the dlhandle variable, the name of the structure that contains
+   the function pointer and dlhandle variables, and the name of the variable in
+   which the result of the lsx_open_dllibrary call should be stored. This will
+   call lsx_open_dllibrary and copy the resulting function pointers into the
+   structure members. If the library cannot be opened, show a failure message. */
+#define LSX_DLLIBRARY_OPEN(ptr_container, dlhandle, entries, library_description, library_names, return_var) \
+    LSX_DLLIBRARY_TRYOPEN(1, ptr_container, dlhandle, entries, library_description, library_names, return_var)
+
+/* LSX_DLLIBRARY_TRYOPEN: Input an ENTRIES macro, the library's description,
+   a null-terminated list of library names (i.e. { "libmp3-0", "libmp3", NULL }),
+   the name of the dlhandle variable, the name of the structure that contains
+   the function pointer and dlhandle variables, and the name of the variable in
+   which the result of the lsx_open_dllibrary call should be stored. This will
+   call lsx_open_dllibrary and copy the resulting function pointers into the
+   structure members. If the library cannot be opened, show a report or a failure
+   message, depending on whether error_on_failure is non-zero. */
+#define LSX_DLLIBRARY_TRYOPEN(error_on_failure, ptr_container, dlhandle, entries, library_description, library_names, return_var) \
+    do { \
+      lsx_dlfunction_info lsx_dlfunction_open_library_infos[] = { \
+        LSX_DLENTRIES_APPLY__(entries, LSX_DLLIBRARY_OPEN1__, 0) \
+        {NULL,NULL,NULL} }; \
+      int lsx_dlfunction_open_library_index = 0; \
+      lsx_dlptr lsx_dlfunction_open_library_funcs[sizeof(lsx_dlfunction_open_library_infos)/sizeof(lsx_dlfunction_open_library_infos[0])]; \
+      (return_var) = lsx_open_dllibrary((error_on_failure), (library_description), (library_names), lsx_dlfunction_open_library_infos, lsx_dlfunction_open_library_funcs, &(ptr_container)->dlhandle); \
+      LSX_DLENTRIES_APPLY__(entries, LSX_DLLIBRARY_OPEN2__, ptr_container) \
+    } while(0)
+
+#define LSX_DLLIBRARY_CLOSE(ptr_container, dlhandle) \
+    lsx_close_dllibrary((ptr_container)->dlhandle)
+
+  /* LSX_DLENTRY_STATIC: For use in creating an ENTRIES macro. func is
+     expected to be available at link time. If not present, link will fail. */
+#define LSX_DLENTRY_STATIC(f,x, ret, func, args)  f(x, ret, func, args, func, NULL, func)
+
+  /* LSX_DLENTRY_DYNAMIC: For use in creating an ENTRIES macro. func need
+     not be available at link time (and if present, the link time version will
+     not be used). func will be loaded via dlsym. If this function is not
+     found in the shared library, the shared library will not be used. */
+#define LSX_DLENTRY_DYNAMIC(f,x, ret, func, args) f(x, ret, func, args, NULL, NULL, func)
+
+  /* LSX_DLENTRY_STUB: For use in creating an ENTRIES macro. func need not
+     be available at link time (and if present, the link time version will not
+     be used). If using DL_LAME, the func may be loaded via dlopen/dlsym, but
+     if not found, the shared library will still be used if all of the
+     non-stub functions are found. If the function is not found via dlsym (or
+     if we are not loading any shared libraries), the stub will be used. This
+     assumes that the name of the stub function is the name of the function +
+     "_stub". */
+#define LSX_DLENTRY_STUB(f,x, ret, func, args)    f(x, ret, func, args, NULL, func##_stub, func)
+
+  /* LSX_DLFUNC_IS_STUB: returns true if the named function is a do-nothing
+     stub. Assumes that the name of the stub function is the name of the
+     function + "_stub". */
+#define LSX_DLFUNC_IS_STUB(ptr_container, func) ((ptr_container)->func == func##_stub)
+
+#endif
diff --git a/freedv-dev/src/sox/soxconfig.h b/freedv-dev/src/sox/soxconfig.h
new file mode 100644 (file)
index 0000000..199f88c
--- /dev/null
@@ -0,0 +1,386 @@
+/* src/soxconfig.h.  Generated from soxconfig.h.in by configure.  */
+/* src/soxconfig.h.in.  Generated from configure.ac by autoheader.  */
+
+/* Define if building universal (internal helper macro) */
+/* #undef AC_APPLE_UNIVERSAL_BUILD */
+
+/* Define to dlopen() amrnb. */
+/* #undef DL_AMRNB */
+
+/* Define to dlopen() amrwb. */
+/* #undef DL_AMRWB */
+
+/* Define to dlopen() lame. */
+/* #undef DL_LAME */
+
+/* Define to dlopen() mad. */
+/* #undef DL_MAD */
+
+/* Define to dlopen() sndfile. */
+/* #undef DL_SNDFILE */
+
+/* Define to dlopen() libtwolame. */
+/* #undef DL_TWOLAME */
+
+/* Define if you are using an external GSM library */
+#define EXTERNAL_GSM 1
+
+/* Define if you are using an external LPC10 library */
+/* #undef EXTERNAL_LPC10 */
+
+/* Define to 1 if you have alsa. */
+#define HAVE_ALSA 1
+
+/* Define to 1 if you have amrnb. */
+/* #undef HAVE_AMRNB */
+
+/* Define to 1 if you have amrwb. */
+/* #undef HAVE_AMRWB */
+
+/* Define to 1 if you have the <amrwb/dec.h> header file. */
+/* #undef HAVE_AMRWB_DEC_H */
+
+/* Define to 1 if you have ao. */
+#define HAVE_AO 1
+
+/* Define to 1 if you have the <byteswap.h> header file. */
+#define HAVE_BYTESWAP_H 1
+
+/* Define to 1 if you have coreaudio. */
+/* #undef HAVE_COREAUDIO */
+
+/* 1 if DISTRO is defined */
+/* #undef HAVE_DISTRO */
+
+/* Define to 1 if you have the <dlfcn.h> header file. */
+#define HAVE_DLFCN_H 1
+
+/* Define to 1 if you have the <fcntl.h> header file. */
+#define HAVE_FCNTL_H 1
+
+/* Define to 1 if you have ffmpeg. */
+/* #undef HAVE_FFMPEG */
+
+/* Define to 1 if you have the <ffmpeg/avcodec.h> header file. */
+/* #undef HAVE_FFMPEG_AVCODEC_H */
+
+/* Define to 1 if you have the <ffmpeg/avformat.h> header file. */
+/* #undef HAVE_FFMPEG_AVFORMAT_H */
+
+/* Define to 1 if you have flac. */
+/* #undef HAVE_FLAC */
+
+/* Define to 1 if you have the `fmemopen' function. */
+#define HAVE_FMEMOPEN 1
+
+/* Define to 1 if fseeko (and presumably ftello) exists and is declared. */
+#define HAVE_FSEEKO 1
+
+/* Define to 1 if you have the `gettimeofday' function. */
+#define HAVE_GETTIMEOFDAY 1
+
+/* Define to 1 if you have the <glob.h> header file. */
+#define HAVE_GLOB_H 1
+
+/* Define to 1 if you have gsm. */
+#define HAVE_GSM 1
+
+/* Define to 1 if you have the <gsm/gsm.h> header file. */
+#define HAVE_GSM_GSM_H 1
+
+/* Define to 1 if you have the <gsm.h> header file. */
+/* #undef HAVE_GSM_H */
+
+/* Define to 1 if you have id3tag. */
+/* #undef HAVE_ID3TAG */
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+#define HAVE_INTTYPES_H 1
+
+/* 1 if should enable LADSPA */
+/* #undef HAVE_LADSPA_H */
+
+/* Define to 1 if you have the <lame.h> header file. */
+/* #undef HAVE_LAME_H */
+
+/* Define to 1 if lame supports optional ID3 tags. */
+/* #undef HAVE_LAME_ID3TAG */
+
+/* Define to 1 if you have the <lame/lame.h> header file. */
+/* #undef HAVE_LAME_LAME_H */
+
+/* Define to 1 if you have the <libavcodec/avcodec.h> header file. */
+/* #undef HAVE_LIBAVCODEC_AVCODEC_H */
+
+/* Define to 1 if you have the <libavformat/avformat.h> header file. */
+/* #undef HAVE_LIBAVFORMAT_AVFORMAT_H */
+
+/* Define to 1 if you have libltdl */
+/* #undef HAVE_LIBLTDL */
+
+/* Define to 1 if you have the `m' library (-lm). */
+#define HAVE_LIBM 1
+
+/* Define to 1 if you have the <libpng/png.h> header file. */
+/* #undef HAVE_LIBPNG_PNG_H */
+
+/* Define to 1 if you have lpc10. */
+#define HAVE_LPC10 1
+
+/* Define to 1 if you have the <lpc10.h> header file. */
+/* #undef HAVE_LPC10_H */
+
+/* Define to 1 if you have the <ltdl.h> header file. */
+/* #undef HAVE_LTDL_H */
+
+/* Define to 1 if you have the <machine/soundcard.h> header file. */
+/* #undef HAVE_MACHINE_SOUNDCARD_H */
+
+/* Define to 1 if you have the <mad.h> header file. */
+/* #undef HAVE_MAD_H */
+
+/* Define to 1 if you have magic. */
+/* #undef HAVE_MAGIC */
+
+/* Define to 1 if you have the <memory.h> header file. */
+#define HAVE_MEMORY_H 1
+
+/* Define to 1 if you have the `mkstemp' function. */
+#define HAVE_MKSTEMP 1
+
+/* Define to 1 if you have mp3. */
+/* #undef HAVE_MP3 */
+
+/* Define to 1 if you have oggvorbis. */
+/* #undef HAVE_OGG_VORBIS */
+
+/* Define to 1 if you have the <omp.h> header file. */
+/* #undef HAVE_OMP_H */
+
+/* Define to 1 if you have the <opencore-amrnb/interf_dec.h> header file. */
+/* #undef HAVE_OPENCORE_AMRNB_INTERF_DEC_H */
+
+/* Define to 1 if you have the <opencore-amrwb/dec_if.h> header file. */
+/* #undef HAVE_OPENCORE_AMRWB_DEC_IF_H */
+
+/* Define to 1 if you have GOMP. */
+/* #undef HAVE_OPENMP */
+
+/* Define to 1 if you have oss. */
+/* #undef HAVE_OSS */
+
+/* Define to 1 if you have PNG. */
+/* #undef HAVE_PNG */
+
+/* Define to 1 if you have the <png.h> header file. */
+/* #undef HAVE_PNG_H */
+
+/* Define to 1 if you have the `popen' function. */
+#define HAVE_POPEN 1
+
+/* Define to 1 if you have pulseaudio. */
+/* #undef HAVE_PULSEAUDIO */
+
+/* Define if you have libsndfile with SFC_SFC_SET_SCALE_INT_FLOAT_WRITE */
+#define HAVE_SFC_SET_SCALE_INT_FLOAT_WRITE 1
+
+/* Define to 1 if you have sndfile. */
+#define HAVE_SNDFILE 1
+
+/* Define if you have libsndfile >= 1.0.18 */
+#define HAVE_SNDFILE_1_0_18 1
+
+/* Define if you have <sndfile.h> */
+#define HAVE_SNDFILE_H 1
+
+/* Define to 1 if you have sndio. */
+/* #undef HAVE_SNDIO */
+
+/* Define to 1 if you have the <stdint.h> header file. */
+#define HAVE_STDINT_H 1
+
+/* Define to 1 if you have the <stdlib.h> header file. */
+#define HAVE_STDLIB_H 1
+
+/* Define to 1 if you have the `strcasecmp' function. */
+#define HAVE_STRCASECMP 1
+
+/* Define to 1 if you have the `strdup' function. */
+#define HAVE_STRDUP 1
+
+/* Define to 1 if you have the <strings.h> header file. */
+#define HAVE_STRINGS_H 1
+
+/* Define to 1 if you have the <string.h> header file. */
+#define HAVE_STRING_H 1
+
+/* Define to 1 if you have sunaudio. */
+/* #undef HAVE_SUN_AUDIO */
+
+/* Define to 1 if you have the <sun/audioio.h> header file. */
+/* #undef HAVE_SUN_AUDIOIO_H */
+
+/* Define to 1 if you have the <sys/audioio.h> header file. */
+/* #undef HAVE_SYS_AUDIOIO_H */
+
+/* Define to 1 if you have the <sys/soundcard.h> header file. */
+/* #undef HAVE_SYS_SOUNDCARD_H */
+
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#define HAVE_SYS_STAT_H 1
+
+/* Define to 1 if you have the <sys/timeb.h> header file. */
+#define HAVE_SYS_TIMEB_H 1
+
+/* Define to 1 if you have the <sys/time.h> header file. */
+#define HAVE_SYS_TIME_H 1
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#define HAVE_SYS_TYPES_H 1
+
+/* Define to 1 if you have the <sys/utsname.h> header file. */
+#define HAVE_SYS_UTSNAME_H 1
+
+/* Define to 1 if you have the <termios.h> header file. */
+#define HAVE_TERMIOS_H 1
+
+/* Define to 1 if you have the <twolame.h> header file. */
+/* #undef HAVE_TWOLAME_H */
+
+/* Define to 1 if you have the <unistd.h> header file. */
+#define HAVE_UNISTD_H 1
+
+/* Define to 1 if you have the `vsnprintf' function. */
+#define HAVE_VSNPRINTF 1
+
+/* Define to 1 if you have waveaudio. */
+/* #undef HAVE_WAVEAUDIO */
+
+/* Define to 1 if you have wavpack. */
+/* #undef HAVE_WAVPACK */
+
+/* Define to 1 to use win32 glob */
+/* #undef HAVE_WIN32_GLOB_H */
+
+/* Define to 1 to use internal win32 ltdl */
+/* #undef HAVE_WIN32_LTDL_H */
+
+/* Define to the sub-directory in which libtool stores uninstalled libraries.
+   */
+#define LT_OBJDIR ".libs/"
+
+/* Define to 1 if your C compiler doesn't accept -c and -o together. */
+/* #undef NO_MINUS_C_MINUS_O */
+
+/* Name of package */
+#define PACKAGE "sox"
+
+/* Define to the address where bug reports for this package should be sent. */
+#define PACKAGE_BUGREPORT "sox-devel@lists.sourceforge.net"
+
+/* Define to the full name of this package. */
+#define PACKAGE_NAME "SoX"
+
+/* Define to the full name and version of this package. */
+#define PACKAGE_STRING "SoX 14.4.1"
+
+/* Define to the one symbol short name of this package. */
+#define PACKAGE_TARNAME "sox"
+
+/* Define to the home page for this package. */
+#define PACKAGE_URL ""
+
+/* Define to the version of this package. */
+#define PACKAGE_VERSION "14.4.1"
+
+/* Define to 1 if you have static alsa. */
+#define STATIC_ALSA 1
+
+/* Define to 1 if you have static amrnb. */
+/* #undef STATIC_AMRNB */
+
+/* Define to 1 if you have static amrwb. */
+/* #undef STATIC_AMRWB */
+
+/* Define to 1 if you have static ao. */
+#define STATIC_AO 1
+
+/* Define to 1 if you have static coreaudio. */
+/* #undef STATIC_COREAUDIO */
+
+/* Define to 1 if you have static ffmpeg. */
+/* #undef STATIC_FFMPEG */
+
+/* Define to 1 if you have static flac. */
+/* #undef STATIC_FLAC */
+
+/* Define to 1 if you have static gsm. */
+#define STATIC_GSM 1
+
+/* Define to 1 if you have static lpc10. */
+#define STATIC_LPC10 1
+
+/* Define to 1 if you have static mp3. */
+/* #undef STATIC_MP3 */
+
+/* Define to 1 if you have static oggvorbis. */
+/* #undef STATIC_OGG_VORBIS */
+
+/* Define to 1 if you have static oss. */
+/* #undef STATIC_OSS */
+
+/* Define to 1 if you have static pulseaudio. */
+/* #undef STATIC_PULSEAUDIO */
+
+/* Define to 1 if you have static sndfile. */
+#define STATIC_SNDFILE 1
+
+/* Define to 1 if you have static sndio. */
+/* #undef STATIC_SNDIO */
+
+/* Define to 1 if you have static sunaudio. */
+/* #undef STATIC_SUN_AUDIO */
+
+/* Define to 1 if you have static waveaudio. */
+/* #undef STATIC_WAVEAUDIO */
+
+/* Define to 1 if you have static wavpack. */
+/* #undef STATIC_WAVPACK */
+
+/* Define to 1 if you have the ANSI C header files. */
+#define STDC_HEADERS 1
+
+/* Version number of package */
+#define VERSION "14.4.1"
+
+/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most
+   significant byte first (like Motorola and SPARC, unlike Intel). */
+#if defined AC_APPLE_UNIVERSAL_BUILD
+# if defined __BIG_ENDIAN__
+#  define WORDS_BIGENDIAN 1
+# endif
+#else
+# ifndef WORDS_BIGENDIAN
+/* #  undef WORDS_BIGENDIAN */
+# endif
+#endif
+
+/* Enable large inode numbers on Mac OS X 10.5.  */
+#ifndef _DARWIN_USE_64_BIT_INODE
+# define _DARWIN_USE_64_BIT_INODE 1
+#endif
+
+/* Number of bits in a file offset, on hosts where this is settable. */
+/* #undef _FILE_OFFSET_BITS */
+
+/* Define to 1 to make fseeko visible on some hosts (e.g. glibc 2.2). */
+/* #undef _LARGEFILE_SOURCE */
+
+/* Define for large files, on AIX-style hosts. */
+/* #undef _LARGE_FILES */
+
+/* Define to `__inline__' or `__inline' if that's what the C compiler
+   calls it, or to nothing if 'inline' is not supported under any name.  */
+#ifndef __cplusplus
+/* #undef inline */
+#endif
diff --git a/freedv-dev/src/sox/soxomp.h b/freedv-dev/src/sox/soxomp.h
new file mode 100644 (file)
index 0000000..6fce07d
--- /dev/null
@@ -0,0 +1,38 @@
+#include "soxconfig.h"
+
+#ifdef HAVE_OPENMP
+  #include <omp.h>
+#else
+
+typedef int omp_lock_t;
+typedef int omp_nest_lock_t;
+
+#define omp_set_num_threads(int) (void)0
+#define omp_get_num_threads() 1
+#define omp_get_max_threads() 1
+#define omp_get_thread_num() 0
+#define omp_get_num_procs() 1
+#define omp_in_parallel() 1
+
+#define omp_set_dynamic(int) (void)0
+#define omp_get_dynamic() 0
+
+#define omp_set_nested(int) (void)0
+#define omp_get_nested() 0
+
+#define omp_init_lock(omp_lock_t) (void)0
+#define omp_destroy_lock(omp_lock_t) (void)0
+#define omp_set_lock(omp_lock_t) (void)0
+#define omp_unset_lock(omp_lock_t) (void)0
+#define omp_test_lock(omp_lock_t) 0
+
+#define omp_init_nest_lock(omp_nest_lock_t) (void)0
+#define omp_destroy_nest_lock(omp_nest_lock_t) (void)0
+#define omp_set_nest_lock(omp_nest_lock_t) (void)0
+#define omp_unset_nest_lock(omp_nest_lock_t) (void)0
+#define omp_test_nest_lock(omp_nest_lock_t) 0
+
+#define omp_get_wtime() 0
+#define omp_get_wtick() 0
+
+#endif
diff --git a/freedv-dev/src/sox/util.h b/freedv-dev/src/sox/util.h
new file mode 100644 (file)
index 0000000..89bbe75
--- /dev/null
@@ -0,0 +1,231 @@
+/* General purpose, i.e. non SoX specific, utility functions and macros.
+ *
+ * (c) 2006-8 Chris Bagwell and SoX contributors
+ *
+ * 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 <stdio.h>
+#include <stdlib.h>
+#include "soxconfig.h"
+
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h> /* For off_t not found in stdio.h */
+#endif
+
+#ifdef HAVE_SYS_STAT_H
+#include <sys/stat.h> /* Needs to be included before we redefine off_t. */
+#endif
+
+#include "xmalloc.h"
+
+/*---------------------------- Portability stuff -----------------------------*/
+
+#if defined(HAVE_INTTYPES_H)
+  #include <inttypes.h>
+#elif defined(HAVE_STDINT_H)
+  #include <stdint.h>
+#else
+  typedef sox_int8_t   int8_t;
+  typedef sox_uint8_t  uint8_t;
+  typedef sox_int16_t  int16_t;
+  typedef sox_uint16_t uint16_t;
+  typedef sox_int32_t  int32_t;
+  typedef sox_uint32_t uint32_t;
+  typedef sox_int64_t  int64_t;
+  typedef sox_uint64_t uint64_t;
+#endif
+
+/* Define the format specifier to use for int64_t values.
+ * Example: printf("You may have already won $ %" PRId64 " !!!", n64); */
+#ifndef PRId64 /* Maybe <inttypes.h> already defined this. */
+#if defined(_MSC_VER) || defined(__MINGW32__) /* Older versions of msvcrt.dll don't recognize %lld. */
+#define PRId64 "I64d"
+#elif LONG_MAX==9223372036854775807
+#define PRId64 "ld"
+#else
+#define PRId64 "lld"
+#endif
+#endif /* PRId64 */
+
+/* Define the format specifier to use for uint64_t values. */
+#ifndef PRIu64 /* Maybe <inttypes.h> already defined this. */
+#if defined(_MSC_VER) || defined(__MINGW32__) /* Older versions of msvcrt.dll don't recognize %llu. */
+#define PRIu64 "I64u"
+#elif ULONG_MAX==0xffffffffffffffff
+#define PRIu64 "lu"
+#else
+#define PRIu64 "llu"
+#endif
+#endif /* PRIu64 */
+
+/* Define the format specifier to use for size_t values.
+ * Example: printf("Sizeof(x) = %" PRIuPTR " bytes", sizeof(x)); */
+#ifndef PRIuPTR /* Maybe <inttypes.h> already defined this. */
+#if defined(_MSC_VER) || defined(__MINGW32__) /* Older versions of msvcrt.dll don't recognize %zu. */
+#define PRIuPTR "Iu"
+#else
+#define PRIuPTR "zu"
+#endif
+#endif /* PRIuPTR */
+
+#ifdef __GNUC__
+#define NORET __attribute__((noreturn))
+#define UNUSED __attribute__ ((unused))
+#else
+#define NORET
+#define UNUSED
+#endif
+
+#ifdef _MSC_VER
+
+#define __STDC__ 1
+#define O_BINARY _O_BINARY
+#define O_CREAT _O_CREAT
+#define O_RDWR _O_RDWR
+#define O_TRUNC _O_TRUNC
+#define S_IFMT _S_IFMT
+#define S_IFREG _S_IFREG
+#define S_IREAD _S_IREAD
+#define S_IWRITE _S_IWRITE
+#define close _close
+#define dup _dup
+#define fdopen _fdopen
+#define fileno _fileno
+
+#ifdef _fstati64
+#define fstat _fstati64
+#else
+#define fstat _fstat
+#endif
+
+#define ftime _ftime
+#define inline __inline
+#define isatty _isatty
+#define kbhit _kbhit
+#define mktemp _mktemp
+#define off_t _off_t
+#define open _open
+#define pclose _pclose
+#define popen _popen
+#define setmode _setmode
+#define snprintf _snprintf
+
+#ifdef _stati64
+#define stat _stati64
+#else
+#define stat _stat
+#endif
+
+#define strdup _strdup
+#define timeb _timeb
+#define unlink _unlink
+
+#if defined(HAVE__FSEEKI64) && !defined(HAVE_FSEEKO)
+#undef off_t
+#define fseeko _fseeki64
+#define ftello _ftelli64
+#define off_t __int64
+#define HAVE_FSEEKO 1
+#endif
+
+#elif defined(__MINGW32__)
+
+#if !defined(HAVE_FSEEKO)
+#undef off_t
+#define fseeko fseeko64
+#define fstat _fstati64
+#define ftello ftello64
+#define off_t off64_t
+#define stat _stati64
+#define HAVE_FSEEKO 1
+#endif
+
+#endif
+
+#if defined(DOS) || defined(WIN32) || defined(__NT__) || defined(__DJGPP__) || defined(__OS2__)
+  #define LAST_SLASH(path) max(strrchr(path, '/'), strrchr(path, '\\'))
+  #define IS_ABSOLUTE(path) ((path)[0] == '/' || (path)[0] == '\\' || (path)[1] == ':')
+  #define SET_BINARY_MODE(file) setmode(fileno(file), O_BINARY)
+  #define POPEN_MODE "rb"
+#else
+  #define LAST_SLASH(path) strrchr(path, '/')
+  #define IS_ABSOLUTE(path) ((path)[0] == '/')
+  #define SET_BINARY_MODE(file)
+#endif
+
+#ifdef WORDS_BIGENDIAN
+  #define MACHINE_IS_BIGENDIAN 1
+  #define MACHINE_IS_LITTLEENDIAN 0
+#else
+  #define MACHINE_IS_BIGENDIAN 0
+  #define MACHINE_IS_LITTLEENDIAN 1
+#endif
+
+/*--------------------------- Language extensions ----------------------------*/
+
+/* Compile-time ("static") assertion */
+/*   e.g. assert_static(sizeof(int) >= 4, int_type_too_small)    */
+#define assert_static(e,f) enum {assert_static__##f = 1/(e)}
+#define array_length(a) (sizeof(a)/sizeof(a[0]))
+#define field_offset(type, field) ((size_t)&(((type *)0)->field))
+#define unless(x) if (!(x))
+
+/*------------------------------- Maths stuff --------------------------------*/
+
+#include <math.h>
+
+#ifdef min
+#undef min
+#endif
+#define min(a, b) ((a) <= (b) ? (a) : (b))
+
+#ifdef max
+#undef max
+#endif
+#define max(a, b) ((a) >= (b) ? (a) : (b))
+
+#define range_limit(x, lower, upper) (min(max(x, lower), upper))
+
+#ifndef M_PI
+#define M_PI    3.14159265358979323846
+#endif
+#ifndef M_PI_2
+#define M_PI_2  1.57079632679489661923  /* pi/2 */
+#endif
+#ifndef M_LN10
+#define M_LN10  2.30258509299404568402  /* natural log of 10 */
+#endif
+#ifndef M_SQRT2
+#define M_SQRT2  sqrt(2.)
+#endif
+
+#define sqr(a) ((a) * (a))
+#define sign(x) ((x) < 0? -1 : 1)
+
+/* Numerical Recipes in C, p. 284 */
+#define ranqd1(x) ((x) = 1664525L * (x) + 1013904223L) /* int32_t x */
+#define dranqd1(x) (ranqd1(x) * (1. / (65536. * 32768.))) /* [-1,1) */
+
+#define dB_to_linear(x) exp((x) * M_LN10 * 0.05)
+#define linear_to_dB(x) (log10(x) * 20)
+
+extern int lsx_strcasecmp(const char *s1, const char *st);
+extern int lsx_strncasecmp(char const *s1, char const *s2, size_t n);
+
+#ifndef HAVE_STRCASECMP
+#define strcasecmp(s1, s2) lsx_strcasecmp((s1), (s2))
+#define strncasecmp(s1, s2, n) lsx_strncasecmp((s1), (s2), (n))
+#endif
diff --git a/freedv-dev/src/sox/xmalloc.c b/freedv-dev/src/sox/xmalloc.c
new file mode 100644 (file)
index 0000000..9bf1596
--- /dev/null
@@ -0,0 +1,43 @@
+/* SoX Memory allocation functions
+ *
+ * Copyright (c) 2005-2006 Reuben Thomas.  All rights reserved.
+ *
+ * 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 <stdlib.h>
+
+/* Resize an allocated memory area; abort if not possible.
+ *
+ * For malloc, `If the size of the space requested is zero, the behavior is
+ * implementation defined: either a null pointer is returned, or the
+ * behavior is as if the size were some nonzero value, except that the
+ * returned pointer shall not be used to access an object'
+ */
+void *lsx_realloc(void *ptr, size_t newsize)
+{
+  if (ptr && newsize == 0) {
+    free(ptr);
+    return NULL;
+  }
+
+  if ((ptr = realloc(ptr, newsize)) == NULL) {
+    lsx_fail("out of memory");
+    exit(2);
+  }
+
+  return ptr;
+}
diff --git a/freedv-dev/src/sox/xmalloc.h b/freedv-dev/src/sox/xmalloc.h
new file mode 100644 (file)
index 0000000..9ee77f6
--- /dev/null
@@ -0,0 +1,34 @@
+/* libSoX Memory allocation functions
+ *
+ * Copyright (c) 2005-2006 Reuben Thomas.  All rights reserved.
+ *
+ * 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
+ */
+
+#ifndef LSX_MALLOC_H
+#define LSX_MALLOC_H
+
+#include <stddef.h>
+#include <string.h>
+
+#define lsx_malloc(size) lsx_realloc(NULL, (size))
+#define lsx_calloc(n,s) (((n)*(s))? memset(lsx_malloc((n)*(s)),0,(n)*(s)) : NULL)
+#define lsx_Calloc(v,n)  v = lsx_calloc(n,sizeof(*(v)))
+#define lsx_strdup(p) ((p)? strcpy((char *)lsx_malloc(strlen(p) + 1), p) : NULL)
+#define lsx_memdup(p,s) ((p)? memcpy(lsx_malloc(s), p, s) : NULL)
+#define lsx_valloc(v,n)  v = lsx_malloc((n)*sizeof(*(v)))
+#define lsx_revalloc(v,n)  v = lsx_realloc(v, (n)*sizeof(*(v)))
+
+#endif
index f5a0913cf693154000637d319a1570e062479f55..ab19660ce39fd3573d206b84d9a939dda9f4e5de 100644 (file)
@@ -5,9 +5,13 @@
 // Authors:         David Rowe
 // 
 // To test:
-//          $ gcc sox_biquad.c -o sox_biquad -DSOX_BIQUAD_UNITTEST -Wall \
-//            /path/to/sox-14.4.0/src/.libs/libsox.a -lm -lsndfile
-//          $ ./sox_biquad
+/*
+          $ gcc sox_biquad.c sox/effects_i.c sox/effects.c sox/formats_i.c \
+            sox/biquad.c sox/biquads.c sox/xmalloc.c sox/libsox.c \
+            -o sox_biquad -DSOX_BIQUAD_UNITTEST -D__FREEDV__ \
+            -Wall -lm -lsndfile -g
+          $ ./sox_biquad
+*/
 //
 // License:
 //
@@ -104,7 +108,7 @@ void sox_biquad_filter(void *sbq, short out[], short in[], int n)
 #define N 20
 int main(void) {
     void *sbq;
-    char *argv[10];
+    const char *argv[] = {"highpass", "1000"};
     short in[N];
     short out[N];
     int   i, argc;;
@@ -114,7 +118,8 @@ int main(void) {
     in[0] = 8000;
 
     sox_biquad_start();
-    argv[0] = "highpass"; argv[1]="1000"; argc=1;
+    //argv[0] = "highpass"; argv[1]="1000"; 
+    argc=1;
     sbq = sox_biquad_create(argc, argv);
 
     sox_biquad_filter(sbq, out, in, N);