shithub: sox

Download patch

ref: 1a4da74823561e9ba7be153f9a3609ff5423d90c
parent: c2749992b232e8459354dd4763155b1ff3e0d228
author: robs <robs>
date: Wed Sep 10 14:17:16 EDT 2008

remove deprecated pitch & stretch

--- a/ChangeLog
+++ b/ChangeLog
@@ -7,13 +7,19 @@
 sox-14.1.1	2008-TBD
 ----------
 
+Previously deprecated features that have been removed in this release:
+
+  Deprec-  Feature    [O(ption)]
+  ated in  [F(ormat)] [E(ffect)]   Replacement
+  -------  ----------------------  ----------------------
+  14.0.0   E stretch               ~= tempo
+  14.0.0   E pitch                 new pitch = old key
+
 Previously deprecated features (to be removed in future):
 
   Deprec-  Feature    [O(ption)]                           Removal
   ated in  [F(ormat)] [E(ffect)]   Replacement             due after
   -------  ----------------------  ----------------------  -------
-  14.0.0   E stretch               ~= tempo                2008-09-11
-  14.0.0   E pitch                 ~= key                  2008-09-11
   14.1.0   F flac: libFLAC 1.1.1   libFLAC > 1.1.1         2009-01-29
   14.1.0   F wve (native)          wve (libsndfile)        2009-07-29
   14.1.0   E resample              ~= rate                 2009-07-29
@@ -23,13 +29,22 @@
            sox -V file(s) -n
            doesn't read to EOF.
 
+Newly deprecated features (to be removed in future):
+
+  Deprec-  Feature    [O(ption)]                           Removal
+  ated in  [F(ormat)] [E(ffect)]   Replacement             due after
+  -------  ----------------------  ----------------------  -------
+  14.1.1   E key                   pitch                   14.1.1 + 6 months
+
 Other new features:
 
   o New --output option to write to multiple files in one run.
     Only useful with certain effects like trim and silence. (cbagwell)
   o Display SoX build environment information with -V -V.  (robs)
-  o Change to intermediate phase for `rate' effect; phase, band-width
-    and aliasing now configurable.  (robs)
+  o For `rate' effect, change default phase to intermediate; phase,
+    band-width and aliasing now configurable.  (robs)
+  o New -b option for the norm effect; can be used to fix stereo
+    imbalance.  (robs)
 
 Other bug fixes:
 
--- a/README
+++ b/README
@@ -128,7 +128,7 @@
     o fade		Apply a fade-in and/or fade-out to the audio
     o gain		Apply gain or attenuation
     o mcompand		Multi-band compression/expansion/limiting
-    o norm		Normalise the audio to 0dB or to a specified value
+    o norm		Normalise to 0dB (or other), or fix imbalance
     o vol		Adjust audio volume
 
   o Editting effects
@@ -143,10 +143,10 @@
     o remix		Produce arbirarily mixed output channels
     o swap		Swap stereo channels
 
-  o Key/tempo effects
-    o key		Adjust key (= pitch) without changing tempo
-    o speed		Adjust key & tempo together
-    o tempo		Adjust tempo without changing key
+  o Pitch/tempo effects
+    o pitch		Adjust pitch (= key) without changing tempo
+    o speed		Adjust pitch & tempo together
+    o tempo		Adjust tempo without changing pitch
 
   o Mastering effects
     o dither		Add dither noise to increase SNR of <= 16-bit audio
--- a/soxeffect.7
+++ b/soxeffect.7
@@ -641,17 +641,10 @@
 See also \fBfilter\fR for filters with a steeper roll-off.
 .TP
 \fBkey \fR[\fB\-q\fR] \fIshift\fR [\fIsegment\fR [\fIsearch\fR [\fIoverlap\fR]]]
-Change the audio key (i.e. pitch but not tempo) using a WSOLA algorithm.
-.SP
-.I shift
-gives the key shift as positive or negative `cents' (i.e. 100ths of a
-semitone).  See the
-.B tempo
-effect for a description of the other parameters.
-.SP
-See also
+Change the audio key (i.e. pitch but not tempo).
+This is just an alias for the
 .B pitch
-for a similar effect.
+effect.
 .TP
 \fBladspa\fR \fBmodule\fR [\fBplugin\fR] [\fBargument\fR...]
 Apply a LADSPA [5] (Linux Audio Developer's Simple Plugin API) plugin.
@@ -929,6 +922,15 @@
 	play snare.flac phaser 0.6 0.66 3 0.6 2 -t
 .EE
 .TP
+\fBpitch \fR[\fB\-q\fR] \fIshift\fR [\fIsegment\fR [\fIsearch\fR [\fIoverlap\fR]]]
+Change the audio pitch (but not tempo).
+.SP
+.I shift
+gives the pitch shift as positive or negative `cents' (i.e. 100ths of a
+semitone).  See the
+.B tempo
+effect for a description of the other parameters.
+.TP
 \fBrate\fR [\fB\-q\fR\^|\^\fB\-l\fR\^|\^\fB\-m\fR\^|\^\fB\-h\fR\^|\^\fB\-v\fR] [\fB\-p\fR \fIPHASE\fR\^|\^\fB\-M\fR\^|\^\fB\-I\fR\^|\^\fB\-L\fR] [\fB\-b\fR \fIBANDWIDTH\fR] [\fB\-a\fR] [\fIRATE\fR[\fBk\fR]]
 Change the audio sampling rate (i.e. resample the audio) to the given
 .I RATE
@@ -1798,7 +1800,7 @@
 ends; default=60.
 .TP
 \fBtempo \fR[\fB\-q\fR] \fIfactor\fR [\fIsegment\fR [\fIsearch\fR [\fIoverlap\fR]]]
-Change the audio tempo (but not its pitch) using a `WSOLA' algorithm.
+Change the audio tempo (but not its pitch).
 The audio is chopped up into segments which are then shifted in the time
 domain and overlapped (cross-faded) at points where their waveforms are
 most similar (as determined by measurement of `least squares').
@@ -1832,12 +1834,10 @@
 parameter gives the segment overlap length in milliseconds (default 12).
 .SP
 See also
-.B stretch
-for a similar effect,
 .B speed
-for an effect that changes tempo and key together, and
-.B key
-for an effect that changes key without changing tempo.
+for an effect that changes tempo and pitch together, and
+.B pitch
+for an effect that changes pitch without changing tempo.
 .TP
 \fBtreble \fIgain\fR [\fIfrequency\fR[\fBk\fR]\fR [\fIwidth\fR[\fBs\fR\^|\^\fBh\fR\^|\^\fBk\fR\^|\^\fBo\fR\^|\^\fBq\fR]]]
 Apply a treble tone-control effect.
@@ -1942,28 +1942,6 @@
 included in another effect; they continue to work in this version of
 SoX but may be removed in future.
 .TP
-\fBpitch \fIshift\fR [\fIwidth interpolate fade\fR]
-Change the audio pitch (but not its duration).
-This effect is equivalent to the
-.B key
-effect with
-.I search
-set to zero, so its results are comparatively poor;
-it is retained for backwards compatibility only.
-.SP
-Change by cross-fading shifted samples.
-.I shift
-is given in cents.  Use a positive value to shift to treble, negative value to shift to bass.
-Default shift is 0.
-.I width
-of window is in ms.  Default width is 20ms.  Try 30ms to lower pitch,
-and 10ms to raise pitch.
-.I interpolate
-option, can be \fBcubic\fR or \fBlinear\fR.  Default is \fBcubic\fR.  The
-.I fade
-option, can be \fBcos\fR, \fBhamming\fR, \fBlinear\fR or
-\fBtrapezoid\fR; the default is \fBcos\fR.
-.TP
 \fBpolyphase\fR [\fB\-w nut\fR\^|\^\fBham\fR] [\fB\-width \fIn\fR] [\fB\-cut-off \fIc\fR]
 Change the sampling rate using `polyphase interpolation', a DSP algorithm.
 \fBpolyphase\fR copes with only certain rational fraction resampling ratios,
@@ -2102,29 +2080,6 @@
 \fBresample\fR and \fBpolyphase\fR at
 http://leute.server.de/wilde/resample.html; see \fBrabbit\fR for a
 pointer to its own documentation.
-.TP
-\fBstretch \fIfactor\fR [\fIwindow fade shift fading\fR]
-Change the audio duration (but not its pitch).
-This effect is equivalent to the
-.B tempo
-effect with (\fIfactor\fR inverted and)
-.I search
-set to zero, so its results are comparatively poor;
-it is retained for backwards compatibility only.
-.SP
-.I factor
-of stretching: >1 lengthen, <1 shorten duration.
-.I window
-size is in ms.  Default is 20ms.  The
-.I fade
-option, can be `lin'.
-.I shift
-ratio, in [0 1].  Default depends on stretch factor. 1
-to shorten, 0\*d8 to lengthen.  The
-.I fading
-ratio, in [0 0\*d5].  The amount of a fade's default depends on
-.I factor
-and \fIshift\fR.
 .SH SEE ALSO
 .BR sox (1),
 .BR soxi (1),
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -28,16 +28,16 @@
 
 # Format with: !xargs echo|tr ' ' '\n'|sort|column|expand|sed 's/^/  /'
 set(effects_srcs
-  biquad          echo            mixer           rate            stat
-  biquads         echos           noiseprof       remix           stretch
-  chorus          fade            noisered        repeat          swap
-  compand         FFT             normalise       resample        synth
-  compandt        fft4g           output          reverb          tempo
-  contrast        filter          pad             reverse         tremolo
-  dcshift         flanger         pan             silence         trim
-  delay           input           phaser          skeleff         vol
-  dither          key             pitch           speed
-  earwax          mcompand        polyphas        splice
+  biquad          echo            noiseprof       remix           swap
+  biquads         echos           noisered        repeat          synth
+  chorus          fade            normalise       resample        tempo
+  compand         FFT             output          reverb          tremolo
+  compandt        fft4g           pad             reverse         trim
+  contrast        filter          pan             silence         vol
+  dcshift         flanger         phaser          skeleff
+  delay           input           pitch           speed
+  dither          mcompand        polyphas        splice
+  earwax          mixer           rate            stat
 )
 set(formats_srcs
   8svx            dat             ima-fmt         s3-fmt          u4-fmt
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -252,12 +252,12 @@
 	band.h biquad.c biquad.h biquads.c chorus.c compand.c compandt.c \
 	compandt.h contrast.c dcshift.c delay.c dither.c earwax.c echo.c \
 	echos.c effects.c effects.h effects_i.c fade.c fft4g.c fft4g.h FFT.c \
-	FFT.h fifo.h filter.c flanger.c input.c key.c ladspa.c mcompand.c \
+	FFT.h fifo.h filter.c flanger.c input.c ladspa.c mcompand.c \
 	mixer.c noiseprof.c noisered.c noisered.h normalise.c output.c pad.c \
 	pan.c phaser.c pitch.c polyphas.c rabbit.c rate.c \
 	rate_filters.h rate_half_fir.h rate_poly_fir0.h rate_poly_fir.h \
 	remix.c repeat.c resample.c reverb.c reverse.c silence.c skeleff.c \
-	speed.c	splice.c stat.c stretch.c swap.c synth.c tempo.c tremolo.c \
+	speed.c	splice.c stat.c swap.c synth.c tempo.c tremolo.c \
 	trim.c vol.c
 if HAVE_PNG
     libsfx_la_SOURCES += spectrogram.c
--- a/src/effects.h
+++ b/src/effects.h
@@ -70,7 +70,6 @@
   EFFECT(speed)
   EFFECT(splice)
   EFFECT(stat)
-  EFFECT(stretch)
   EFFECT(swap)
   EFFECT(synth)
   EFFECT(tempo)
--- a/src/key.c
+++ /dev/null
@@ -1,51 +1,0 @@
-/* libSoX effect: change the audio key (i.e. change pitch but not tempo)
- * Copyright (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
- *
- *
- * Adjustment is given as a number of cents (100ths of a semitone) to
- * change.  Implementation comprises a tempo change (performed by tempo)
- * and a speed change performed by whichever resampling effect is in effect.
- */
-
-#include "sox_i.h"
-#include <string.h>
-
-static int getopts(sox_effect_t * effp, int argc, char **argv)
-{
-  double d;
-  char dummy, arg[100];
-  int pos = (argc && !strcmp(*argv, "-q"))? 1 : 0;
-
-  if (argc <= pos || sscanf(argv[pos], "%lf %c", &d, &dummy) != 1)
-    return lsx_usage(effp);
-
-  effp->global_info->speed *= d = pow(2., d / 1200);  /* cents --> factor */
-  sprintf(arg, "%g", 1 / d);
-  argv[pos] = arg;
-  return sox_tempo_effect_fn()->getopts(effp, argc, argv);
-}
-
-sox_effect_handler_t const * sox_key_effect_fn(void)
-{
-  static sox_effect_handler_t handler;
-  handler = *sox_tempo_effect_fn();
-  handler.name = "key";
-  handler.usage = "[-q] shift-in-cents [segment-ms [search-ms [overlap-ms]]]",
-  handler.getopts = getopts;
-  handler.flags &= ~SOX_EFF_LENGTH;
-  return &handler;
-}
--- a/src/pitch.c
+++ b/src/pitch.c
@@ -1,7 +1,6 @@
-/* (c) Fabien Coelho <fabien@coelho.net> 03/2000 for sox.
+/* libSoX effect: change the audio pitch (i.e. change pitch but not tempo)
+ * Copyright (c) 2007 robs@users.sourceforge.net
  *
- * pitch shifting.
- *
  * 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
@@ -16,560 +15,46 @@
  * along with this library; if not, write to the Free Software Foundation,
  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
  *
- * I found a code on the Computer Music Journal web site
- * <http://mitpress.mit.edu/e-journals/Computer_Music_Journal/>
- * for pitch shifting the AD 1848 PC soundcards, with
- * a lot of (unclear) pointer and integer arithmetics, and
- * combine effects (feedback, delay, mixing).
  *
- * I tried to understand the code, dropped the other effects,
- * translated the stuff in float so it's easier to understand,
- * drop one of the lookup tables (I know that sin(pi/2-x) = cos(x)),
- * and added interpolation and fade options of my own.
- * cross fading is always symetric.
- *
- * Basically, the algorithm performs a resampling at the desire rate
- * to achieve the shift (interpolation function) on small overlapping windows,
- * and successive windows are faded in/out one into the other to
- * rebuild the final signal.
- *
- * I'm quite disappointed. At first thought, I looked for an FT-based
- * algorithm, something like "switch the signal to frequencies, shift
- * frequencies, and come back to time", but it does not seem to work
- * that way... at least not so easily. Or maybe my attempt was buggy.
- *
- * Here is the result. It can certainly be improved.
- * The result buzzes some time.
- * Lot of options available so than one can adjust the result.
- *
- * so as to lower the pitch, a larger window sounds better (30ms)?
- * so as to upper the pitch, a smaller window... (10ms)?
- *
- * Some speed-optimization could be added at code size expanse/expense?
+ * Adjustment is given as a number of cents (100ths of a semitone) to
+ * change.  Implementation comprises a tempo change (performed by tempo)
+ * and a speed change performed by whichever resampling effect is in effect.
  */
 
 #include "sox_i.h"
-
-#include <stdlib.h>
 #include <string.h>
 
-/* cross fading options for transitions
- */
-#define PITCH_FADE_COS 0 /* cosine */
-#define PITCH_FADE_HAM 1 /* Hamming */
-#define PITCH_FADE_LIN 2 /* linear */
-#define PITCH_FADE_TRA 3 /* trapezoid */
-
-#define PITCH_FADE_DEFAULT PITCH_FADE_COS
-
-/* interpolation options
- */
-#define PITCH_INTERPOLE_CUB 0 /* cubic */
-#define PITCH_INTERPOLE_LIN 1 /* linear */
-
-#define PITCH_INTERPOLE_DEFAULT PITCH_INTERPOLE_CUB
-
-/* default window width
- */
-#define PITCH_DEFAULT_WIDTH ((double)(20.0e0)) /* 20 ms */
-
-/* linear factors for the Hamming window
-   0<=i<=n: HAM_n(i) = HAM0 + HAM1*cos(i*PI/n)
- */
-#define HAM1               ((double)(0.46e0))
-#define HAM0               ((double)(0.54e0))
-
-/* state of buffer management... */
-typedef enum { pi_input, pi_compute, pi_output } pitch_state_t;
-
-/* structure hold by the effect descriptor. */
-typedef struct {
-    /* OPTIONS
-     */
-    double shift;   /* shift in cents, >0 to treble, <0 to bass */
-
-    double width;   /* sweep size in ms */
-
-    int interopt;        /* interpole option */
-
-    int fadeopt;         /* fade option */
-    double coef;    /* coefficient used by trapezoid */
-    /* what about coef1/coef2 for hamming... */
-
-    /* COMPUTATION
-     */
-    double rate;    /* sweep rate, around 1.0 */
-
-    unsigned int step;   /* size of half a sweep, rounded to integer... */
-    double * fade;  /* fading factors table lookup, ~ 1.0 -> ~ 0.0 */
-
-    int overlap;         /* needed overlap */
-
-    double * tmp;   /* temporary buffer */
-    double * acc;   /* accumulation buffer */
-
-    unsigned int iacc;   /* part of acc already output */
-
-    size_t size;      /* size of buffer for processing chunks. */
-    unsigned int index;  /* index of next empty input item. */
-    sox_sample_t *buf;    /* bufferize input */
-
-    pitch_state_t state; /* buffer management status. */
-
-} priv_t;
-
-/* // debug functions
-
-static char * fadeoptname(int opt)
+static int getopts(sox_effect_t * effp, int argc, char **argv)
 {
-    switch (opt)
-    {
-    case PITCH_FADE_COS: return "cosine";
-    case PITCH_FADE_HAM: return "hamming";
-    case PITCH_FADE_LIN: return "linear";
-    case PITCH_FADE_TRA: return "trapezoid";
-    default: return "UNEXPECTED";
-    }
-}
+  double d;
+  char dummy, arg[100];
+  int pos = (argc && !strcmp(*argv, "-q"))? 1 : 0;
 
-static void debug(priv_t * pitch, char * where)
-{
-  sox_debug("%s: ind=%d sz=%ld step=%d o=%d rate=%f ia=%d st=%d fo=%s",
-  where, pitch->index, pitch->size, pitch->step, pitch->overlap,
-  pitch->rate, pitch->iacc, pitch->state, fadeoptname(pitch->fadeopt));
-}
-*/
+  if (argc <= pos || sscanf(argv[pos], "%lf %c", &d, &dummy) != 1)
+    return lsx_usage(effp);
 
-/* compute f(x) as a linear interpolation...
- */
-static double lin(
-  double f0,  /* f(0)  */
-  double f1,  /* f(1)  */
-  double x)   /* 0.0 <= x < 1.0 */
-{
-    return f0 * (1.0 - x) + f1 * x;
+  effp->global_info->speed *= d = pow(2., d / 1200);  /* cents --> factor */
+  sprintf(arg, "%g", 1 / d);
+  argv[pos] = arg;
+  return sox_tempo_effect_fn()->getopts(effp, argc, argv);
 }
 
-/* compute f(x) as a cubic function...
- */
-static double cub(
-  double fm1, /* f(-1) */
-  double f0,  /* f(0)  */
-  double f1,  /* f(1)  */
-  double f2,  /* f(2)  */
-  double x)   /* 0.0 <= x < 1.0 */
+sox_effect_handler_t const * sox_pitch_effect_fn(void)
 {
-    /* a x^3 + b x^2 + c x + d */
-    register double a, b, c, d;
-
-    d = f0;
-    b = 0.5 * (f1+fm1) - f0;
-    a = (1.0/6.0) * (f2-f1+fm1-f0-4.0*b);
-    c = f1 - a - b - d;
-
-    return ((a * x + b) * x + c) * x + d;
+  static sox_effect_handler_t handler;
+  handler = *sox_tempo_effect_fn();
+  handler.name = "pitch";
+  handler.usage = "[-q] shift-in-cents [segment-ms [search-ms [overlap-ms]]]",
+  handler.getopts = getopts;
+  handler.flags &= ~SOX_EFF_LENGTH;
+  return &handler;
 }
 
-/* interpolate a quarter (half a window)
- *
- * ibuf buffer of ilen length is swept at rate speed.
- * result put in output buffer obuf of size olen.
- */
-static void interpolation(
-  priv_t * pitch,
-  const sox_sample_t *ibuf, size_t ilen,
-  double * out, size_t olen,
-  double rate) /* signed */
+sox_effect_handler_t const * sox_key_effect_fn(void) /* old name for pitch */
 {
-    register int i, size;
-    register double index;
-
-    size = pitch->step; /* size == olen? */
-
-    if (rate>0) /* sweep forwards */
-    {
-        for (index=0.0, i=0; i<(int)olen; i++, index+=rate)
-        {
-            register int ifl = (int) index; /* FLOOR */
-            register double frac = index - ifl;
-
-            if (pitch->interopt==PITCH_INTERPOLE_LIN)
-                out[i] = lin((double) ibuf[ifl],
-                             (double) ibuf[ifl+1],
-                             frac);
-            else
-                out[i] = cub((double) ibuf[ifl-1],
-                             (double) ibuf[ifl],
-                             (double) ibuf[ifl+1],
-                             (double) ibuf[ifl+2],
-                             frac);
-        }
-    }
-    else /* rate < 0, sweep backwards */
-    {
-        for (index=ilen-1, i=olen-1; i>=0; i--, index+=rate)
-        {
-            register int ifl = (int) index; /* FLOOR */
-            register double frac = index - ifl;
-
-            if (pitch->interopt==PITCH_INTERPOLE_LIN)
-                out[i] = lin((double) ibuf[ifl],
-                             (double) ibuf[ifl+1],
-                             frac);
-            else
-                out[i] = cub((double) ibuf[ifl-1],
-                             (double) ibuf[ifl],
-                             (double) ibuf[ifl+1],
-                             (double) ibuf[ifl+2],
-                             frac);
-        }
-    }
-}
-
-/* from input buffer to acc
- */
-static void process_intput_buffer(priv_t * pitch)
-{
-    register int i, len = pitch->step;
-
-    /* forwards sweep */
-    interpolation(pitch,
-                  pitch->buf+pitch->overlap, (size_t)(pitch->step+pitch->overlap),
-                  pitch->tmp, (size_t)pitch->step,
-                  pitch->rate);
-
-    for (i=0; i<len; i++)
-        pitch->acc[i] = pitch->fade[i]*pitch->tmp[i];
-
-    /* backwards sweep */
-    interpolation(pitch,
-                  pitch->buf, (size_t)(pitch->step+pitch->overlap),
-                  pitch->tmp, (size_t)pitch->step,
-                  -pitch->rate);
-
-    for (i=0; i<len; i++)
-        pitch->acc[i] += pitch->fade[pitch->step-i-1]*pitch->tmp[i];
-}
-
-/*
- * Process options
- */
-static int sox_pitch_getopts(sox_effect_t * effp, int n, char **argv)
-{
-    priv_t * pitch = (priv_t *) effp->priv;
-
-    /* get pitch shift */
-    pitch->shift = 0.0; /* default is no change */
-
-    if (n && !sscanf(argv[0], "%lf", &pitch->shift))
-      return lsx_usage(effp);
-
-    /* sweep size in ms */
-    pitch->width = PITCH_DEFAULT_WIDTH;
-    if (n>1 && !sscanf(argv[1], "%lf", &pitch->width))
-      return lsx_usage(effp);
-
-    /* interpole option */
-    pitch->interopt = PITCH_INTERPOLE_DEFAULT;
-    if (n>2)
-    {
-        switch(argv[2][0])
-        {
-        case 'l':
-        case 'L':
-            pitch->interopt = PITCH_INTERPOLE_LIN;
-            break;
-        case 'c':
-        case 'C':
-            pitch->interopt = PITCH_INTERPOLE_CUB;
-            break;
-        default:
-            return lsx_usage(effp);
-        }
-    }
-
-    /* fade option */
-    pitch->fadeopt = PITCH_FADE_DEFAULT; /* default */
-    if (n>3)
-    {
-        switch (argv[3][0]) /* what a parser;-) */
-        {
-        case 'l':
-        case 'L':
-            pitch->fadeopt = PITCH_FADE_LIN;
-            break;
-        case 't':
-        case 'T':
-            pitch->fadeopt = PITCH_FADE_TRA;
-            break;
-        case 'h':
-        case 'H':
-            pitch->fadeopt = PITCH_FADE_HAM;
-            break;
-        case 'c':
-        case 'C':
-            pitch->fadeopt = PITCH_FADE_COS;
-            break;
-        default:
-            return lsx_usage(effp);
-        }
-    }
-
-    pitch->coef = 0.25;
-    if (n>4 && (!sscanf(argv[4], "%lf", &pitch->coef) ||
-                pitch->coef<0.0 || pitch->coef>0.5))
-      return lsx_usage(effp);
-
-    return SOX_SUCCESS;
-}
-
-/*
- * Start processing
- */
-static int sox_pitch_start(sox_effect_t * effp)
-{
-    priv_t * pitch = (priv_t *) effp->priv;
-    register int sample_rate = effp->out_signal.rate;
-    unsigned int i;
-
-    /* computer inner stuff... */
-
-    pitch->state = pi_input;
-
-    /* Should I trust pow?
-     * BTW, the twelfth root of two is 1.0594630943592952645618252,
-     * if we consider an equal temperament.
-     */
-    pitch->rate = pow(2.0, pitch->shift/1200.0);
-
-    /* size is half of the actual target window size, because of symetry.
-     */
-    pitch->step = ((pitch->width*(0.0005))*sample_rate);
-
-    /* make size odd? do we care? */
-    /* if (!(size & 1)) size++; */
-
-    /* security for safe cubic interpolation */
-    if (pitch->rate > 1.0)
-        pitch->overlap = (int) ((pitch->rate-1.0)*pitch->step) + 2;
-    else
-        pitch->overlap = 2;
-
-    pitch->size = pitch->step + 2*pitch->overlap;
-
-    pitch->fade = lsx_malloc(pitch->step*sizeof(double));
-    pitch->tmp  = lsx_malloc(pitch->step*sizeof(double));
-    pitch->acc  = lsx_malloc(pitch->step*sizeof(double));
-    pitch->buf  = lsx_malloc(pitch->size*sizeof(sox_sample_t));
-    pitch->index = pitch->overlap;
-
-    /* default initial signal */
-    for (i=0; i<pitch->size; i++)
-        pitch->buf[i] = 0;
-
-    if (pitch->fadeopt == PITCH_FADE_HAM)
-    {
-        /* does it make sense to have such an option? */
-        register double pi_step = M_PI / (pitch->step-1);
-
-        for (i=0; i<pitch->step; i++)
-            pitch->fade[i] = (double) (HAM0 + HAM1*cos(pi_step*i));
-    }
-    else if (pitch->fadeopt == PITCH_FADE_COS)
-    {
-        register double pi_2_step = M_PI_2 / (pitch->step-1);
-
-        pitch->fade[0] = 1.0; /* cos(0) == 1.0 */
-        for (i=1; i<pitch->step-1; i++)
-            pitch->fade[i]  = (double) cos(pi_2_step*i);
-        pitch->fade[pitch->step-1] = 0.0; /* cos(PI/2) == 0.0 */
-    }
-    else if (pitch->fadeopt == PITCH_FADE_LIN)
-    {
-        register double stepth = 1.0 / (pitch->step-1);
-
-        pitch->fade[0] = 1.0;
-        for (i=1; i<pitch->step-1; i++)
-            pitch->fade[i] = (pitch->step-i-1) * stepth;
-        pitch->fade[pitch->step-1] = 0.0;
-    }
-    else if (pitch->fadeopt == PITCH_FADE_TRA)
-    {
-        /* 0 <= coef <= 0.5 */
-        register unsigned int plat = (int) (pitch->step*pitch->coef);
-        register double slope = 1.0 / (pitch->step - 2*plat);
-
-        for (i=0; i<plat; i++)
-            pitch->fade[i] = 1.0;
-
-        for (; i<pitch->step-plat; i++)
-            pitch->fade[i] = slope * (pitch->step-plat-i-1);
-
-        for (; i<pitch->step; i++)
-            pitch->fade[i] = 0.0;
-    }
-    else
-    {
-        sox_fail("unexpected PITCH_FADE parameter %d", pitch->fadeopt);
-        return SOX_EOF;
-    }
-
-    if (pitch->shift == 0)
-      return SOX_EFF_NULL;
-
-    return SOX_SUCCESS;
-}
-
-/* Processes input.
- */
-static int sox_pitch_flow(sox_effect_t * effp, const sox_sample_t *ibuf, sox_sample_t *obuf,
-                size_t *isamp, size_t *osamp)
-{
-    priv_t * pitch = (priv_t *) effp->priv;
-    int i, size;
-    size_t len, iindex, oindex;
-
-    size = pitch->size;
-    /* size to process */
-    len = min(*isamp, *osamp);
-    iindex = 0;
-    oindex = 0;
-
-    /* warning:
-       because of the asynchronous nature of buffering,
-       the output index can reach the buffer limits before full consumption.
-       I put the input index just in case.
-       If the code is correct, eithier len or iindex is redundant.
-    */
-    while (len>0 && iindex<*isamp && oindex<*osamp)
-    {
-        if (pitch->state == pi_input)
-        {
-            register int tocopy = min(pitch->size-pitch->index, len);
-
-            memcpy(pitch->buf+pitch->index, ibuf+iindex, tocopy*sizeof(sox_sample_t));
-
-            len -= tocopy;
-            pitch->index += tocopy;
-            iindex += tocopy;
-
-            if (pitch->index==pitch->size)
-                pitch->state = pi_compute;
-        }
-
-        if (pitch->state == pi_compute)
-        {
-            process_intput_buffer(pitch);
-            pitch->state = pi_output;
-            pitch->iacc = 0;
-        }
-
-        if (pitch->state == pi_output)
-        {
-            int toout = min(*osamp-oindex, pitch->step-pitch->iacc);
-
-            for (i=0; i<toout; i++)
-            {
-                float f;
-
-                f = pitch->acc[pitch->iacc++];
-                SOX_SAMPLE_CLIP_COUNT(f, effp->clips);
-                obuf[oindex++] = f;
-            }
-
-            if (pitch->iacc == pitch->step)
-            {
-                pitch->state = pi_input;
-
-                /* shift input buffer. memmove? */
-                for (i=0; i<2*pitch->overlap; i++)
-                    pitch->buf[i] = pitch->buf[i+pitch->step];
-
-                pitch->index = 2*pitch->overlap;
-            }
-        }
-    }
-
-    /* report consumption. */
-    *isamp = iindex;
-    *osamp = oindex;
-
-    return SOX_SUCCESS;
-}
-
-/* at the end...
- */
-static int sox_pitch_drain(sox_effect_t * effp, sox_sample_t *obuf, size_t *osamp)
-{
-    priv_t * pitch = (priv_t *) effp->priv;
-    size_t i;
-
-    if (pitch->state == pi_input)
-    {
-        /* complete input buffer content with 0. */
-        for (i=pitch->index; i<pitch->size; i++)
-            pitch->buf[i] = 0;
-
-        pitch->state = pi_compute;
-    }
-
-    if (pitch->state == pi_compute)
-    {
-        process_intput_buffer(pitch);
-        pitch->state = pi_output;
-        pitch->iacc = 0;
-    }
-
-    /* (pitch->state == pi_output) */
-    for (i=0; i<*osamp && i<pitch->index-pitch->overlap;)
-    {
-        float f;
-
-        f = pitch->acc[pitch->iacc++];
-        SOX_SAMPLE_CLIP_COUNT(f, effp->clips);
-        obuf[i++] = f;
-    }
-
-    /* report... */
-    *osamp = i;
-
-    if ((pitch->index - pitch->overlap) == 0)
-        return SOX_EOF;
-    else
-        return SOX_SUCCESS;
-}
-
-/*
- * Do anything required when you stop reading samples.
- * Don't close input file!
- */
-static int sox_pitch_stop(sox_effect_t * effp)
-{
-    priv_t * pitch = (priv_t *) effp->priv;
-
-    free(pitch->fade);
-    free(pitch->tmp);
-    free(pitch->acc);
-    free(pitch->buf);
-
-    return SOX_SUCCESS;
-}
-
-static sox_effect_handler_t sox_pitch_effect = {
-  "pitch",
-  "shift width interpole fade\n"
-  "       (in cents, in ms, cub/lin, cos/ham/lin/trap)"
-  "       (defaults: 0 20 c c)",
-  SOX_EFF_LENGTH | SOX_EFF_DEPRECATED,
-  sox_pitch_getopts,
-  sox_pitch_start,
-  sox_pitch_flow,
-  sox_pitch_drain,
-  sox_pitch_stop,
-  NULL, sizeof(priv_t)
-};
-
-const sox_effect_handler_t *sox_pitch_effect_fn(void)
-{
-    return &sox_pitch_effect;
+  static sox_effect_handler_t handler;
+  handler = *sox_pitch_effect_fn();
+  handler.name = "key";
+  handler.flags |= SOX_EFF_DEPRECATED;
+  return &handler;
 }
--- a/src/stretch.c
+++ /dev/null
@@ -1,352 +1,0 @@
-/* libSoX Basic time stretcher.
- * (c) march/april 2000 Fabien COELHO <fabien@coelho.net> for sox.
- *
- * cross fade samples so as to go slower or faster.
- *
- * The filter is based on 6 parameters:
- * - stretch factor f
- * - window size w
- * - input step i
- *   output step o=f*i
- * - steady state of window s, ss = s*w
- * - type of cross fading
- *
- * I decided of the default values of these parameters based
- * on some small non extensive tests. maybe better defaults
- * can be suggested.
- *
- * It cannot handle different number of channels.
- * It cannot handle rate change.
- */
-#include "sox_i.h"
-
-#include <stdlib.h>
-#include <string.h>
-#include <assert.h>
-
-#define DEFAULT_SLOW_SHIFT_RATIO        0.8
-#define DEFAULT_FAST_SHIFT_RATIO        1.0
-
-#define DEFAULT_STRETCH_WINDOW          20.0  /* ms */
-
-/* I'm planing to put some common fading stuff outside.
-   It's also used in pitch.c
- */
-typedef enum { sox_linear_fading } sox_fading_t;
-
-#define DEFAULT_FADING sox_linear_fading
-
-typedef enum { input_state, output_state } stretch_status_t;
-
-typedef struct {
-  /* options
-   * FIXME: maybe shift could be allowed > 1.0 with factor < 1.0 ???
-   */
-  double factor;   /* strech factor. 1.0 means copy. */
-  double window;   /* window in ms */
-  sox_fading_t fade;       /* type of fading */
-  double shift;    /* shift ratio wrt window. <1.0 */
-  double fading;   /* fading ratio wrt window. <0.5 */
-
-  /* internal stuff */
-  stretch_status_t state; /* automaton status */
-
-  size_t size;         /* buffer size */
-  size_t index;        /* next available element */
-  sox_sample_t *ibuf;      /* input buffer */
-  size_t ishift;       /* input shift */
-
-  size_t oindex;       /* next evailable element */
-  double * obuf;   /* output buffer */
-  size_t oshift;       /* output shift */
-
-  size_t fsize;        /* fading size */
-  double * fbuf;   /* fading, 1.0 -> 0.0 */
-
-} priv_t;
-
-/*
- * Process options
- */
-static int sox_stretch_getopts(sox_effect_t * effp, int n, char **argv)
-{
-  priv_t * stretch = (priv_t *) effp->priv;
-
-  /* default options */
-  stretch->factor = 1.0; /* default is no change */
-  stretch->window = DEFAULT_STRETCH_WINDOW;
-  stretch->fade = sox_linear_fading;
-
-  if (n > 0 && !sscanf(argv[0], "%lf", &stretch->factor)) {
-    sox_fail("error while parsing factor");
-    return lsx_usage(effp);
-  }
-
-  if (n > 1 && !sscanf(argv[1], "%lf", &stretch->window)) {
-    sox_fail("error while parsing window size");
-    return lsx_usage(effp);
-  }
-
-  if (n > 2) {
-    switch (argv[2][0]) {
-    case 'l':
-    case 'L':
-      stretch->fade = sox_linear_fading;
-      break;
-    default:
-      sox_fail("error while parsing fade type");
-      return lsx_usage(effp);
-    }
-  }
-
-  /* default shift depends whether we go slower or faster */
-  stretch->shift = (stretch->factor <= 1.0) ?
-    DEFAULT_FAST_SHIFT_RATIO: DEFAULT_SLOW_SHIFT_RATIO;
-
-  if (n > 3 && !sscanf(argv[3], "%lf", &stretch->shift)) {
-    sox_fail("error while parsing shift ratio");
-    return lsx_usage(effp);
-  }
-
-  if (stretch->shift > 1.0 || stretch->shift <= 0.0) {
-    sox_fail("error with shift ratio value");
-    return lsx_usage(effp);
-  }
-
-  /* default fading stuff...
-     it makes sense for factor >= 0.5 */
-  if (stretch->factor < 1.0)
-    stretch->fading = 1.0 - (stretch->factor * stretch->shift);
-  else
-    stretch->fading = 1.0 - stretch->shift;
-  if (stretch->fading > 0.5)
-    stretch->fading = 0.5;
-
-  if (n > 4 && !sscanf(argv[4], "%lf", &stretch->fading)) {
-    sox_fail("error while parsing fading ratio");
-    return lsx_usage(effp);
-  }
-
-  if (stretch->fading > 0.5 || stretch->fading < 0.0) {
-    sox_fail("error with fading ratio value");
-    return lsx_usage(effp);
-  }
-
-  return SOX_SUCCESS;
-}
-
-/*
- * Start processing
- */
-static int sox_stretch_start(sox_effect_t * effp)
-{
-  priv_t * stretch = (priv_t *)effp->priv;
-  size_t i;
-
-  if (stretch->factor == 1)
-    return SOX_EFF_NULL;
-
-  stretch->state = input_state;
-
-  stretch->size = (int)(effp->out_signal.rate * 0.001 * stretch->window);
-  /* start in the middle of an input to avoid initial fading... */
-  stretch->index = stretch->size / 2;
-  stretch->ibuf = lsx_malloc(stretch->size * sizeof(sox_sample_t));
-
-  /* the shift ratio deal with the longest of ishift/oshift
-     hence ishift<=size and oshift<=size. */
-  if (stretch->factor < 1.0) {
-    stretch->ishift = stretch->shift * stretch->size;
-    stretch->oshift = stretch->factor * stretch->ishift;
-  } else {
-    stretch->oshift = stretch->shift * stretch->size;
-    stretch->ishift = stretch->oshift / stretch->factor;
-  }
-  assert(stretch->ishift <= stretch->size);
-  assert(stretch->oshift <= stretch->size);
-
-  stretch->oindex = stretch->index; /* start as synchronized */
-  stretch->obuf = lsx_malloc(stretch->size * sizeof(double));
-  stretch->fsize = (int)(stretch->fading * stretch->size);
-  stretch->fbuf = lsx_malloc(stretch->fsize * sizeof(double));
-
-  /* initialize buffers */
-  for (i = 0; i<stretch->size; i++)
-    stretch->ibuf[i] = 0;
-
-  for (i = 0; i<stretch->size; i++)
-    stretch->obuf[i] = 0.0;
-
-  if (stretch->fsize>1) {
-    double slope = 1.0 / (stretch->fsize - 1);
-    stretch->fbuf[0] = 1.0;
-    for (i = 1; i < stretch->fsize - 1; i++)
-      stretch->fbuf[i] = slope * (stretch->fsize - i - 1);
-    stretch->fbuf[stretch->fsize - 1] = 0.0;
-  } else if (stretch->fsize == 1)
-    stretch->fbuf[0] = 1.0;
-
-  sox_debug("start: (f=%.2f w=%.2f r=%.2f f=%.2f)"
-           " st=%d s=%lu ii=%lu is=%lu oi=%lu os=%lu fs=%lu\n", stretch->factor,
-      stretch->window, stretch->shift, stretch->fading, stretch->state,
-      (unsigned long)stretch->size, (unsigned long)stretch->index,
-      (unsigned long)stretch->ishift, (unsigned long)stretch->oindex,
-      (unsigned long)stretch->oshift, (unsigned long)stretch->fsize);
-
-  return SOX_SUCCESS;
-}
-
-/* accumulates input ibuf to output obuf with fading fbuf */
-static void combine(priv_t * stretch)
-{
-  int i, size, fsize;
-
-  size = stretch->size;
-  fsize = stretch->fsize;
-
-  /* fade in */
-  for (i = 0; i < fsize; i++)
-    stretch->obuf[i] += stretch->fbuf[fsize - i - 1] * stretch->ibuf[i];
-
-  /* steady state */
-  for (; i < size - fsize; i++)
-    stretch->obuf[i] += stretch->ibuf[i];
-
-  /* fade out */
-  for (; i<size; i++)
-    stretch->obuf[i] += stretch->fbuf[i - size + fsize] * stretch->ibuf[i];
-}
-
-/*
- * Processes flow.
- */
-static int sox_stretch_flow(sox_effect_t * effp, const sox_sample_t *ibuf, sox_sample_t *obuf,
-                    size_t *isamp, size_t *osamp)
-{
-  priv_t * stretch = (priv_t *) effp->priv;
-  size_t iindex = 0, oindex = 0;
-  size_t i;
-
-  while (iindex<*isamp && oindex<*osamp) {
-    if (stretch->state == input_state) {
-      size_t tocopy = min(*isamp-iindex,
-                             stretch->size-stretch->index);
-
-      memcpy(stretch->ibuf + stretch->index, ibuf + iindex, tocopy * sizeof(sox_sample_t));
-
-      iindex += tocopy;
-      stretch->index += tocopy;
-
-      if (stretch->index == stretch->size) {
-        /* compute */
-        combine(stretch);
-
-        /* shift input */
-        for (i = 0; i + stretch->ishift < stretch->size; i++)
-          stretch->ibuf[i] = stretch->ibuf[i+stretch->ishift];
-
-        stretch->index -= stretch->ishift;
-
-        /* switch to output state */
-        stretch->state = output_state;
-      }
-    }
-
-    if (stretch->state == output_state) {
-      while (stretch->oindex < stretch->oshift && oindex < *osamp) {
-        float f;
-        f = stretch->obuf[stretch->oindex++];
-        SOX_SAMPLE_CLIP_COUNT(f, effp->clips);
-        obuf[oindex++] = f;
-      }
-
-      if (stretch->oindex >= stretch->oshift && oindex<*osamp) {
-        stretch->oindex -= stretch->oshift;
-
-        /* shift internal output buffer */
-        for (i = 0; i + stretch->oshift < stretch->size; i++)
-          stretch->obuf[i] = stretch->obuf[i + stretch->oshift];
-
-        /* pad with 0 */
-        for (; i < stretch->size; i++)
-          stretch->obuf[i] = 0.0;
-
-        stretch->state = input_state;
-      }
-    }
-  }
-
-  *isamp = iindex;
-  *osamp = oindex;
-
-  return SOX_SUCCESS;
-}
-
-
-/*
- * Drain buffer at the end
- * maybe not correct ? end might be artificially faded?
- */
-static int sox_stretch_drain(sox_effect_t * effp, sox_sample_t *obuf, size_t *osamp)
-{
-  priv_t * stretch = (priv_t *) effp->priv;
-  size_t i;
-  size_t oindex = 0;
-
-  if (stretch->state == input_state) {
-    for (i=stretch->index; i<stretch->size; i++)
-      stretch->ibuf[i] = 0;
-
-    combine(stretch);
-
-    stretch->state = output_state;
-  }
-
-  while (oindex<*osamp && stretch->oindex<stretch->index) {
-    float f = stretch->obuf[stretch->oindex++];
-    SOX_SAMPLE_CLIP_COUNT(f, effp->clips);
-    obuf[oindex++] = f;
-  }
-
-  *osamp = oindex;
-
-  if (stretch->oindex == stretch->index)
-    return SOX_EOF;
-  else
-    return SOX_SUCCESS;
-}
-
-
-/*
- * Do anything required when you stop reading samples.
- * Don't close input file!
- */
-static int sox_stretch_stop(sox_effect_t * effp)
-{
-  priv_t * stretch = (priv_t *) effp->priv;
-
-  free(stretch->ibuf);
-  free(stretch->obuf);
-  free(stretch->fbuf);
-
-  return SOX_SUCCESS;
-}
-
-static sox_effect_handler_t sox_stretch_effect = {
-  "stretch",
-  "factor [window fade shift fading]\n"
-  "       (expansion, frame in ms, lin/..., unit<1.0, unit<0.5)\n"
-  "       (defaults: 1.0 20 lin ...)",
-  SOX_EFF_LENGTH | SOX_EFF_DEPRECATED,
-  sox_stretch_getopts,
-  sox_stretch_start,
-  sox_stretch_flow,
-  sox_stretch_drain,
-  sox_stretch_stop,
-  NULL, sizeof(priv_t)
-};
-
-const sox_effect_handler_t *sox_stretch_effect_fn(void)
-{
-  return &sox_stretch_effect;
-}