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;