shithub: sox

Download patch

ref: c257c17491b4c80dee135dd2021da14685d34ab2
parent: 4a47abb5a2a4560924523383bb05e88c52797a7a
author: robs <robs>
date: Sun May 13 03:54:45 EDT 2007

Changing rate & channels is opt-in, not opt-out.
A few other doc/code clean-ups including Reuben's suggestion for the
usage message.

--- a/soxeffect.7
+++ b/soxeffect.7
@@ -1040,7 +1040,7 @@
 it.  A value of 8000s will wait until 8000 samples are read before
 starting to process audio.
 .TP
-\fBvol \fIgain\fR[[ ]\fItype\fR [\fIlimitergain\fR]]
+\fBvol \fIgain\fR [\fItype\fR [\fIlimitergain\fR]]
 Apply an amplification or an attenuation to the audio signal.
 Unlike the
 .B \-v
@@ -1086,6 +1086,13 @@
 Beware of
 .B Clipping
 when the increasing the volume.
+.SP
+The
+.I gain
+and the
+.I type
+parameters can be concatenated if desired, e.g.
+.BR "vol 10dB" .
 .SP
 An optional \fIlimitergain\fR value can be specified and should be a
 value much less
--- a/src/vol.c
+++ b/src/vol.c
@@ -1,83 +1,84 @@
 /*
- * (c) 20/03/2000 Fabien COELHO <fabien@coelho.net> for sox.
+ * Copyright (c) 20/03/2000 Fabien COELHO <fabien@coelho.net>
+ * Copyright (c) 2000-2007 SoX contributers
  *
- * Change volume of sound file, with basic linear amplitude formula.
- * Beware of saturations! clipping is checked and reported.
- * Cannot handle different number of channels.
- * Cannot handle rate change.
+ * SoX vol effect; change volume with basic linear amplitude formula.
+ * Beware of saturations!  Clipping is checked and reported.
+ *
+ * FIXME: deprecate or remove the limiter in favour of compand.
  */
 #define vol_usage \
-  "Usage: vol gain[[ ]type [limitergain]]\n" \
-  "\t(default type=amplitude: 1 is constant, < 0 change phase;\n" \
-  "\ttype=power 1 is constant; type=dB: 0 is constant, +6 doubles ampl.)\n" \
-  "\tThe peak limiter has a gain much less than 1 (e.g. 0.05 or 0.02) and is\n" \
-  "\tonly used on peaks (to prevent clipping); default is no limiter."
+  "Usage: vol GAIN [TYPE [LIMITERGAIN]]\n" \
+  "\t(default TYPE=amplitude: 1 is constant, < 0 change phase;\n" \
+  "\tTYPE=power 1 is constant; TYPE=dB: 0 is constant, +6 doubles ampl.)\n" \
+  "\tThe peak limiter has a gain much less than 1 (e.g. 0.05 or 0.02) and\n" \
+  "\tis only used on peaks (to prevent clipping); default is no limiter."
 
 #include "sox_i.h"
+#include <math.h>
 
-#include <math.h>   /* exp(), sqrt() */
-
 #define LOG_10_20 ((double)(0.1151292546497022842009e0))
 
 typedef struct {
-    double gain; /* amplitude gain. */
-    
-    sox_bool uselimiter;
-    double limiterthreshhold;
-    double limitergain;
-    int limited; /* number of limited values to report. */
-    int totalprocessed;
+  double    gain; /* amplitude gain. */
+  sox_bool  uselimiter;
+  double    limiterthreshhold;
+  double    limitergain;
+  int       limited; /* number of limited values to report. */
+  int       totalprocessed;
 } * vol_t;
 
-enum {VOL_amplitude, VOL_dB, VOL_power};
+enum {vol_amplitude, vol_dB, vol_power};
 
 static enum_item const vol_types[] = {
-  ENUM_ITEM(VOL_,amplitude)
-  ENUM_ITEM(VOL_,dB)
-  ENUM_ITEM(VOL_,power)
+  ENUM_ITEM(vol_,amplitude)
+  ENUM_ITEM(vol_,dB)
+  ENUM_ITEM(vol_,power)
   {0, 0}};
 
 /*
  * Process options: gain (float) type (amplitude, power, dB)
  */
-static int getopts(eff_t effp, int n, char **argv) 
+static int getopts(eff_t effp, int argc, char **argv) 
 {
-  vol_t vol = (vol_t) effp->priv; 
-  char string[11];
-  char * q = string;
-  char dummy;          /* To check for extraneous chars. */
-  unsigned have_type;
+  vol_t     vol = (vol_t) effp->priv; 
+  char      type_string[11];
+  char *    type_ptr = type_string;
+  char      dummy;             /* To check for extraneous chars. */
+  sox_bool  have_type;
 
-  vol->gain = 1;       /* Default is no change. */
+  vol->gain = 1;               /* Default is no change. */
   vol->uselimiter = sox_false; /* Default is no limiter. */
   
-  if (!n || (have_type = sscanf(argv[0], "%lf %10s %c", &vol->gain, string, &dummy) - 1) > 1) {
+  /* Get the vol, and the type if it's in the same arg. */
+  if (!argc || (have_type = sscanf(argv[0], "%lf %10s %c", &vol->gain, type_string, &dummy) - 1) > 1) {
     sox_fail(effp->h->usage);
     return SOX_EOF;
   }
-  ++argv, --n;
+  ++argv, --argc;
 
-  if (!have_type && n) {
-    ++have_type;
-    q = *argv;
-    ++argv, --n;
+  /* No type yet? Get it from the next arg: */
+  if (!have_type && argc) {
+    have_type = sox_true;
+    type_ptr = *argv;
+    ++argv, --argc;
   }
 
   if (have_type) {
-    enum_item const * p = find_enum_text(q, vol_types);
+    enum_item const * p = find_enum_text(type_ptr, vol_types);
     if (!p) {
       sox_fail(effp->h->usage);
       return SOX_EOF;
     }
     switch (p->value) {
-      case VOL_dB: vol->gain = exp(vol->gain*LOG_10_20); break;
-      case VOL_power: /* power to amplitude, keep phase change */
+      case vol_dB: vol->gain = exp(vol->gain*LOG_10_20); break;
+      case vol_power: /* power to amplitude, keep phase change */
         vol->gain = vol->gain > 0 ? sqrt(vol->gain) : -sqrt(-vol->gain);
         break;
     }
   }
 
-  if (n) {
+  if (argc) {
     if (fabs(vol->gain) < 1 || sscanf(*argv, "%lf %c", &vol->limitergain, &dummy) != 1 || vol->limitergain <= 0 || vol->limitergain >= 1) {
       sox_fail(effp->h->usage);
       return SOX_EOF;                  
@@ -105,18 +106,6 @@
     
     if (vol->gain == 1)
       return SOX_EFF_NULL;
-
-    if (effp->outinfo.channels != effp->ininfo.channels) {
-        sox_fail("vol cannot handle different channels (in %d, out %d)"
-             " use avg or pan", effp->ininfo.channels, effp->outinfo.channels);
-        return SOX_EOF;
-    }
-
-    if (effp->outinfo.rate != effp->ininfo.rate) {
-        sox_fail("vol cannot handle different rates (in %ld, out %ld)"
-             " use resample", effp->ininfo.rate, effp->outinfo.rate);
-        return SOX_EOF;
-    }
 
     vol->limited = 0;
     vol->totalprocessed = 0;