shithub: sox

Download patch

ref: cd6dc8f00eea262044ec515c241b0b7b143cd213
parent: 9c6314bd3f97519c1f56153c9f704843447314ca
author: rrt <rrt>
date: Sat Nov 25 18:12:33 EST 2006

Remove the rate effect. Rationale: resample also does a linear rate
change (as does rabbit), and since its introduction it has been the
main focus of development, receiving many bug fixes and improvements.
Rate is admittedly rather lousy (if fast). We have too many rate
changing effects!

Hence, I've also removed preview mode (whose only effect was to use
rate instead of resample).

The rate effect is retained for backwards compatibility, but just does
resample.

Document -V better.

Fix some typos in the command-line help.

Move resampl.h into resample.c as it's not used anywhere else.

--- a/Changelog
+++ b/Changelog
@@ -50,6 +50,10 @@
   o Add AIFF-C output support.  (shashimoto)
   o -V now gives only user-relevant messages, use -V -V to get
     developer-relevant messages.  (robs)
+  o Old and new rate code removed; the "rate" effect is implemented
+    for backwards compatibility by "resample".
+  o Preview mode now removed, as all it did was use rate rather than
+    resample, and rate has been removed.
 
 sox-12.18.2
 -----------
--- a/sox.1
+++ b/sox.1
@@ -97,7 +97,7 @@
 .br
 does the same format translation but also 
 lowers the amplitude by 1/2, changes
-the sampling rate to 12000 hertz, and applies the \fBmask\fR sound effect
+the sampling rate to 12000 Hz, and applies the \fBmask\fR sound effect
 to the audio data.
 .P
 The following will mix two sound files together to to produce a single sound
@@ -137,15 +137,8 @@
 .br
 	octave plot.m
 .TP 10
-\fB-p\fR
-Run in preview mode and run fast.  This will somewhat speed up
-SoX when the output format has a different number of channels and
-a different rate than the input file.  Currently, this defaults to
-using the \fBrate\fR effect instead of the \fBresample\fR effect for sample
-rate changes.
-.TP 10
 \fB-q\fR
-Run in quite mode when SoX wouldn't otherwise do that.  Inverse of \fB-S\fR
+Run in quiet mode when SoX wouldn't otherwise do that.  Inverse of \fB-S\fR
 option.
 .TP
 \fB-S\fR
@@ -230,13 +223,14 @@
 to the input file.  This is mainly useful with the \fBstat\fR effect.
 .TP 10
 \fB-r \fIrate\fR
-Gives the sample rate in Hertz of the file.  To cause the output file to have
+Gives the sample rate in Hz of the file.  To cause the output file to have
 a different sample rate than the input file, include this option as a part
 of the output format options.
 .br
 If the input and output files have
 different rates then a sample rate change effect must be ran.  Since SoX has
-multiple rate changing effects, the user can specify which to use as an effect.  If no rate change effect is specified then a default one will be chosen.
+multiple rate changing effects, the user can specify which to use as an effect.
+If no rate change effect is specified then a default one will be chosen.
 .TP 10
 \fB-t \fIfiletype\fR
 gives the file type of the sound sample file.  Useful when file extension 
@@ -1081,9 +1075,7 @@
 .TP 10
           [ \fI-cutoff # \fR ]
 Translate input sampling rate to output sampling rate via polyphase
-interpolation, a DSP algorithm.  This method is slow and uses lots
-of RAM, but gives much better results than 
-.B rate.
+interpolation, a DSP algorithm.  This method is relatively slow and memory intensive.
 
 .br
 -w < nut / ham > : select either a Nuttall (~90 dB stopband) or Hamming
@@ -1115,49 +1107,34 @@
 
 .TP 10
 rabbit [ \fI-c0\fR | \fI-c1\fR | \fI-c2\fR | \fI-c3\fR | \fI-c4\fR ]
-Resample using libsamplerate, aka Secret Rabbit Code. This effect is optional
-and must have been selected at compile time of \fISoX\fR.
-See http://www.mega-nerd.com/SRC/ for details of the algorithm. Algorithms
+Resample using libsamplerate, aka Secret Rabbit Code. This effect is
+optional and must have been selected at compile time of \fISoX\fR. See
+http://www.mega-nerd.com/SRC/ for details of the algorithm. Algorithms
 0 through 2 are progressively faster and lower quality versions of the
 sinc algorithm; the default is \fI-c0\fR, which is probably the best
 quality algorithm for general use currently available in sox.
-Algorithm 3 is zero-order hold, and 4 is linear interpolation, which
-is only included for completeness. See the \fIresample\fR effect for
-more discussion of resampling.
+Algorithm 3 is zero-order hold, and 4 is linear interpolation. See the
+\fIresample\fR effect for more discussion of resampling.
 
 .TP 10
 rate
-Translate input sampling rate to output sampling rate
-via linear interpolation to the Least Common Multiple
-of the two sampling rates.
-This is the default effect 
-if the two files have different sampling rates and the preview options
-was specified.
-This is fast but noisy:
-the spectrum of the original sound will be shifted upwards
-and duplicated faintly when up-translating by a multiple.
+Does the same as \fBresample\fR with no arguments; it exists for
+backwards compatibility.
 
-Lerp-ing is acceptable for cheap 8-bit sound hardware,
-but for CD-quality sound you should instead use either
-.B resample,
-.B rabbit
-or
-.B polyphase.
-If you are wondering which rate changing effects to use, you will want to read a
-detailed analysis of all of them at http://leute.server.de/wilde/resample.html
 .TP 10
 repeat \fIcount\fR
 Repeats the audio data \fIcount\fR times.  Requires disk space to store the data to be repeated.
 .TP 10
 resample [ \fI-qs\fR | \fI-q\fR | \fI-ql\fR ] [ \fIrolloff\fR [ \fIbeta\fR ] ]
-Translate input sampling rate to output sampling rate
-via simulated analog filtration.
-This method is slower than 
-.B rate,
-but gives much better results.
+Translate input sampling rate to output sampling rate via simulated
+analog filtration. Other rate changing effects available are
+\fBpolyphase\fR and \fBrabbit\fR. There is a detailed analysis of
+\fBresample\fR and \fBpolyphase\fR at
+http://leute.server.de/wilde/resample.html; see \fBrabbit\fR for a
+pointer to its own documentation.
 
 By default, linear interpolation is used,
-with a window width about 45 samples at the lower of the two rate.
+with a window width about 45 samples at the lower of the two rates.
 This gives an accuracy of about 16 bits, but insufficient stopband rejection
 in the case that you want to have rolloff greater than about 0.80 of
 the Nyquist frequency.
@@ -1249,7 +1226,6 @@
                       &&
 .br
   output_rate/gcd(input_rate,output_rate) <= 511
-.br
 .TP 10
 reverb \fIgain-out reverb-time delay \fR[ \fIdelay ... \fR]
 Add reverberation to a sound sample.  Each delay is given 
--- a/src/rate.c
+++ b/src/rate.c
@@ -1,184 +1,28 @@
 /*
- * August 21, 1998
- * Copyright 1998 Fabrice Bellard.
+ * Sound Tools rate change effect.
  *
- * [Rewrote completely the code of Lance Norskog And Sundry
- * Contributors with a more efficient algorithm.]
- *
- * 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.  
+ * Now obsolete, and implemented by resample. Name retained for
+ * backwards compatibility.
  */
 
-/*
- * Sound Tools rate change effect file.
- */
-
 #include "st_i.h"
+ 
+int st_resample_getopts(eff_t effp, int n, char **argv);
+int st_resample_start(eff_t effp);
+int st_resample_flow(eff_t effp, st_sample_t *ibuf, st_sample_t *obuf, 
+                     st_size_t *isamp, st_size_t *osamp);
+int st_resample_drain(eff_t effp, st_sample_t *obuf, st_size_t *osamp);
+int st_resample_stop(eff_t effp);
 
-#include <math.h>
-/*
- * Linear Interpolation.
- *
- * The use of fractional increment allows us to use no buffer. It
- * avoid the problems at the end of the buffer we had with the old
- * method which stored a possibly big buffer of size
- * lcm(in_rate,out_rate).
- *
- * Limited to 16 bit samples and sampling frequency <= 65535 Hz. If
- * the input & output frequencies are equal, a delay of one sample is
- * introduced.  Limited to processing 32-bit count worth of samples.
- *
- * 1 << FRAC_BITS evaluating to zero in several places.  Changed with
- * an (unsigned long) cast to make it safe.  MarkMLl 2/1/99
- */
-
-#define FRAC_BITS 16
-
-/* Private data */
-typedef struct ratestuff {
-        unsigned long opos_frac;  /* fractional position of the output stream in input stream unit */
-        unsigned long opos;
-
-        unsigned long opos_inc_frac;  /* fractional position increment in the output stream */
-        unsigned long opos_inc; 
-
-        unsigned long ipos;      /* position in the input stream (integer) */
-
-        st_sample_t ilast; /* last sample in the input stream */
-} *rate_t;
-
-/*
- * Process options
- */
-int st_rate_getopts(eff_t effp, int n, char **argv) 
-{
-        if (n)
-        {
-                st_fail("Rate effect takes no options.");
-                return (ST_EOF);
-        }
-        return (ST_SUCCESS);
-}
-
-/*
- * Prepare processing.
- */
-int st_rate_start(eff_t effp)
-{
-        rate_t rate = (rate_t) effp->priv;
-        unsigned long incr;
-
-        if (effp->ininfo.rate == effp->outinfo.rate)
-        {
-            st_fail("Input and Output rates must be different to use rate effect");
-            return(ST_EOF);
-        }
-
-        if (effp->ininfo.rate >= 65535 || effp->outinfo.rate >= 65535)
-        {
-            st_fail("rate effect can only handle rates <= 65535");
-            return (ST_EOF);
-        }
-        if (effp->ininfo.size == ST_SIZE_DWORD || 
-            effp->ininfo.size == ST_SIZE_DDWORD)
-        {
-            st_warn("rate effect reduces data to 16 bits");
-        }
-
-        rate->opos_frac=0;
-        rate->opos=0;
-
-        /* increment */
-        incr=(unsigned long)((double)effp->ininfo.rate / (double)effp->outinfo.rate * 
-                   (double) ((unsigned long) 1 << FRAC_BITS));
-
-        rate->opos_inc_frac = incr & (((unsigned long) 1 << FRAC_BITS)-1);
-        rate->opos_inc = incr >> FRAC_BITS;
-        
-        rate->ipos=0;
-
-        rate->ilast = 0;
-        return (ST_SUCCESS);
-}
-
-/*
- * Processed signed long samples from ibuf to obuf.
- * Return number of samples processed.
- */
-int st_rate_flow(eff_t effp, st_sample_t *ibuf, st_sample_t *obuf, 
-                 st_size_t *isamp, st_size_t *osamp)
-{
-        rate_t rate = (rate_t) effp->priv;
-        st_sample_t *istart,*iend;
-        st_sample_t *ostart,*oend;
-        st_sample_t ilast,icur,out;
-        unsigned long tmp;
-        double t;
-
-        ilast=rate->ilast;
-
-        istart = ibuf;
-        iend = ibuf + *isamp;
-        
-        ostart = obuf;
-        oend = obuf + *osamp;
-
-        while (obuf < oend) {
-
-                /* Safety catch to make sure we have input samples.  */
-                if (ibuf >= iend) goto the_end;
-
-                /* read as many input samples so that ipos > opos */
-        
-                while (rate->ipos <= rate->opos) {
-                        ilast = *ibuf++;
-                        rate->ipos++;
-                        /* See if we finished the input buffer yet */
-                        if (ibuf >= iend) goto the_end;
-                }
-
-                icur = *ibuf;
-        
-                /* interpolate */
-                t=(double) rate->opos_frac / ((unsigned long) 1 << FRAC_BITS);
-                out = (double) ilast * (1.0 - t) + (double) icur * t;
-
-                /* output sample & increment position */
-                
-                *obuf++=(st_sample_t) out;
-                
-                tmp = rate->opos_frac + rate->opos_inc_frac;
-                rate->opos = rate->opos + rate->opos_inc + (tmp >> FRAC_BITS);
-                rate->opos_frac = tmp & (((unsigned long) 1 << FRAC_BITS)-1);
-        }
-the_end:
-        *isamp = ibuf - istart;
-        *osamp = obuf - ostart;
-        rate->ilast = ilast;
-        return (ST_SUCCESS);
-}
-
-/*
- * Do anything required when you stop reading samples.  
- * Don't close input file! 
- */
-int st_rate_stop(eff_t effp)
-{
-        /* nothing to do */
-    return (ST_SUCCESS);
-}
-
 static st_effect_t st_rate_effect = {
   "rate",
   "Usage: Rate effect takes no options",
   ST_EFF_RATE,
-  st_rate_getopts,
-  st_rate_start,
-  st_rate_flow,
-  st_effect_nothing_drain,
-  st_effect_nothing
+  st_resample_getopts,
+  st_resample_start,
+  st_resample_flow,
+  st_resample_drain,
+  st_resample_stop
 };
 
 const st_effect_t *st_rate_effect_fn(void)
--- a/src/resampl.h
+++ /dev/null
@@ -1,61 +1,0 @@
-/*
- * FILE: resample.h
- *   BY: Julius Smith (at CCRMA, Stanford U)
- * C BY: translated from SAIL to C by Christopher Lee Fraley
- *          (cf0v@andrew.cmu.edu)
- * DATE: 7-JUN-88
- * VERS: 2.0  (17-JUN-88, 3:00pm)
- */
-
-/*
- * October 29, 1999
- * Various changes, bugfixes(?), increased precision, by Stan Brooks.
- *
- * This source code 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.
- *
- */
-
-/* Conversion constants */
-#define Lc        7
-#define Nc       (1<<Lc)
-#define La        16
-#define Na       (1<<La)
-#define Lp       (Lc+La)
-#define Np       (1<<Lp)
-#define Amask    (Na-1)
-#define Pmask    (Np-1)
-
-#define MAXNWING  (80<<Lc)
-/* Description of constants:
- *
- * Nc - is the number of look-up values available for the lowpass filter
- *    between the beginning of its impulse response and the "cutoff time"
- *    of the filter.  The cutoff time is defined as the reciprocal of the
- *    lowpass-filter cut off frequence in Hz.  For example, if the
- *    lowpass filter were a sinc function, Nc would be the index of the
- *    impulse-response lookup-table corresponding to the first zero-
- *    crossing of the sinc function.  (The inverse first zero-crossing
- *    time of a sinc function equals its nominal cutoff frequency in Hz.)
- *    Nc must be a power of 2 due to the details of the current
- *    implementation. The default value of 128 is sufficiently high that
- *    using linear interpolation to fill in between the table entries
- *    gives approximately 16-bit precision, and quadratic interpolation
- *    gives about 23-bit (float) precision in filter coefficients.
- *
- * Lc - is log base 2 of Nc.
- *
- * La - is the number of bits devoted to linear interpolation of the
- *    filter coefficients.
- *
- * Lp - is La + Lc, the number of bits to the right of the binary point
- *    in the integer "time" variable. To the left of the point, it indexes
- *    the input array (X), and to the right, it is interpreted as a number
- *    between 0 and 1 sample of the input X.  The default value of 23 is
- *    about right.  There is a constraint that the filter window must be
- *    "addressable" in a int32_t, more precisely, if Nmult is the number
- *    of sinc zero-crossings in the right wing of the filter window, then
- *    (Nwing<<Lp) must be expressible in 31 bits.
- *
- */
--- a/src/resample.c
+++ b/src/resample.c
@@ -1,13 +1,4 @@
 /*
- * 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.
- */
-
-/*
  * Sound Tools rate change effect file.
  * Spiffy rate changer using Smith & Wesson Bandwidth-Limited Interpolation.
  * The algorithm is described in "Bandlimited Interpolation -
@@ -19,12 +10,17 @@
  * at ftp://ccrma-ftp.stanford.edu/pub/NeXT/
  * under the name of resample-version.number.tar.Z
  *
- * NOTE: There is a newer version of the resample routine then what
- * this file was originally based on.  Those adventurous might be
- * interested in reviewing its improvesments and porting it to this
- * version.
  */
 
+/*
+ * 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.
+ */
+
 /* Fixed bug: roll off frequency was wrong, too high by 2 when upsampling,
  * too low by 2 when downsampling.
  * Andreas Wilde, 12. Feb. 1999, andreas@eakaw2.et.tu-dresden.de
@@ -39,16 +35,6 @@
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  *
  */
-/*
- * SJB: [11/25/99]
- * TODO: another idea for improvement...
- * note that upsampling usually doesn't require interpolation,
- * therefore is faster and more accurate than downsampling.
- * Downsampling by an integer factor is also simple, since
- * it just involves decimation if the input is already 
- * lowpass-filtered to the output Nyquist freqency.
- * Get the idea? :)
- */
 
 #include <math.h>
 #include <stdlib.h>
@@ -55,8 +41,67 @@
 #include <string.h>
 #include "st_i.h"
 
-/* resample includes */
-#include "resampl.h"
+/*
+ * FILE: resample.h
+ *   BY: Julius Smith (at CCRMA, Stanford U)
+ * C BY: translated from SAIL to C by Christopher Lee Fraley
+ *          (cf0v@andrew.cmu.edu)
+ * DATE: 7-JUN-88
+ * VERS: 2.0  (17-JUN-88, 3:00pm)
+ */
+
+/*
+ * October 29, 1999
+ * Various changes, bugfixes(?), increased precision, by Stan Brooks.
+ *
+ * This source code 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.
+ *
+ */
+
+/* Conversion constants */
+#define Lc        7
+#define Nc       (1<<Lc)
+#define La        16
+#define Na       (1<<La)
+#define Lp       (Lc+La)
+#define Np       (1<<Lp)
+#define Amask    (Na-1)
+#define Pmask    (Np-1)
+
+#define MAXNWING  (80<<Lc)
+/* Description of constants:
+ *
+ * Nc - is the number of look-up values available for the lowpass filter
+ *    between the beginning of its impulse response and the "cutoff time"
+ *    of the filter.  The cutoff time is defined as the reciprocal of the
+ *    lowpass-filter cut off frequence in Hz.  For example, if the
+ *    lowpass filter were a sinc function, Nc would be the index of the
+ *    impulse-response lookup-table corresponding to the first zero-
+ *    crossing of the sinc function.  (The inverse first zero-crossing
+ *    time of a sinc function equals its nominal cutoff frequency in Hz.)
+ *    Nc must be a power of 2 due to the details of the current
+ *    implementation. The default value of 128 is sufficiently high that
+ *    using linear interpolation to fill in between the table entries
+ *    gives approximately 16-bit precision, and quadratic interpolation
+ *    gives about 23-bit (float) precision in filter coefficients.
+ *
+ * Lc - is log base 2 of Nc.
+ *
+ * La - is the number of bits devoted to linear interpolation of the
+ *    filter coefficients.
+ *
+ * Lp - is La + Lc, the number of bits to the right of the binary point
+ *    in the integer "time" variable. To the left of the point, it indexes
+ *    the input array (X), and to the right, it is interpreted as a number
+ *    between 0 and 1 sample of the input X.  The default value of 23 is
+ *    about right.  There is a constraint that the filter window must be
+ *    "addressable" in a int32_t, more precisely, if Nmult is the number
+ *    of sinc zero-crossings in the right wing of the filter window, then
+ *    (Nwing<<Lp) must be expressible in 31 bits.
+ *
+ */
 
 static st_effect_t st_resample_effect;
 
--- a/src/sox.c
+++ b/src/sox.c
@@ -77,7 +77,6 @@
  
 static int clipped = 0;         /* Volume change clipping errors */
 static int writing = 1;         /* are we writing to a file? assume yes. */
-static int soxpreview = 0;      /* preview mode */
 static st_globalinfo_t globalinfo;
 
 static int user_abort = 0;
@@ -349,10 +348,6 @@
                 globalinfo.octave_plot_effect = true;
                 break;
 
-            case 'p':
-                soxpreview++;
-                break;
-
             case 'h':
                 usage((char *)0);
                 /* no return from above */
@@ -936,7 +931,6 @@
             exit(2);
         }
 
-
         /* Skip past effect name */
         optind++;
 
@@ -1047,10 +1041,7 @@
     if (needrate && !(hasrate) &&
         (file_desc[0]->info.rate > file_desc[file_count-1]->info.rate))
     {
-        if (soxpreview)
-            st_geteffect(&efftab[neffects], "rate");
-        else
-            st_geteffect(&efftab[neffects], "resample");
+        st_geteffect(&efftab[neffects], "resample");
 
         /* set up & give default opts for added effects */
         status = (* efftab[neffects].h->getopts)(&efftab[neffects],(int)0,
@@ -1111,10 +1102,7 @@
      */
     if (needrate && !(effects_mask & ST_EFF_RATE))
     {
-        if (soxpreview)
-            st_geteffect(&efftab[neffects], "rate");
-        else
-            st_geteffect(&efftab[neffects], "resample");
+        st_geteffect(&efftab[neffects], "resample");
 
         /* set up & give default opts for added effects */
         status = (* efftab[neffects].h->getopts)(&efftab[neffects],(int)0,
@@ -1754,13 +1742,12 @@
 "\n"
 "-h              print version number and usage information\n"
 "--help          same as -h\n"
-"--help-efffect=name\n"
+"--help-effect=name\n"
 "                print usage of specified effect.  use 'all' to print all\n"
-"-p              run in preview mode and run fast\n"
-"-q              run in quite mode.  Inverse of -S option\n"
+"-q              run in quiet mode.  Inverse of -S option\n"
 "-S              print status while processing audio data.\n"
 "--version       print version number of SoX and exit\n"
-"-V              verbose mode.  print a description during processing phase\n"
+"-V [level]      increase verbosity (or set level).\n"
 "\n"
 "Format options (fopts):\n"
 "\n"