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