ref: ff89831f6f212180a15d1dfca0e95c8a31e91b8a
parent: 48282e9cf5e3ed139bdf5b355213d22623e6c300
author: robs <robs>
date: Sun Jun 10 13:48:43 EDT 2007
Peter Samuelson's rabbit streaming support. Fix a couple of bugs in the effects chain. A few clean-ups.
--- a/src/biquad.c
+++ b/src/biquad.c
@@ -44,10 +44,8 @@
(n > fc_pos && (sscanf(argv[fc_pos], "%lf %c", &p->fc, &dummy) != 1 || p->fc <= 0)) ||
(n > width_pos && ((unsigned)(sscanf(argv[width_pos], "%lf%c %c", &p->width, &width_type, &dummy)-1) > 1 || p->width <= 0)) ||
(n > gain_pos && sscanf(argv[gain_pos], "%lf %c", &p->gain, &dummy) != 1) ||
- !strchr(allowed_width_types, width_type) || (width_type == 's' && p->width > 1)) {
- sox_fail(effp->handler.usage);
- return SOX_EOF;
- }
+ !strchr(allowed_width_types, width_type) || (width_type == 's' && p->width > 1))
+ return sox_usage(effp);
p->width_type = strchr(all_width_types, width_type) - all_width_types;
if (p->width_type >= strlen(all_width_types))
p->width_type = 0;
--- a/src/biquads.c
+++ b/src/biquads.c
@@ -314,7 +314,7 @@
#define BIQUAD_EFFECT(name,group,usage,flags) \
sox_effect_handler_t const * sox_##name##_effect_fn(void) { \
static sox_effect_handler_t handler = { \
- #name, "Usage: " #name " " usage, flags, \
+ #name, usage, flags, \
group##_getopts, start, sox_biquad_flow, 0, 0, 0, \
}; \
return &handler; \
@@ -331,4 +331,4 @@
BIQUAD_EFFECT(treble, tone, "gain [frequency [width[s|h|q|o]]]", 0)
BIQUAD_EFFECT(equalizer, equalizer,"frequency width[q|o|h] gain", 0)
BIQUAD_EFFECT(band, band, "[-n] center [width[h|q|o]]", 0)
-BIQUAD_EFFECT(deemph, deemph, "takes no options", 0)
+BIQUAD_EFFECT(deemph, deemph, NULL, 0)
--- a/src/chorus.c
+++ b/src/chorus.c
@@ -99,10 +99,7 @@
i = 0;
if ( ( n < 7 ) || (( n - 2 ) % 5 ) )
- {
- sox_fail(effp->handler.usage);
- return (SOX_EOF);
- }
+ return sox_usage(effp);
sscanf(argv[i++], "%f", &chorus->in_gain);
sscanf(argv[i++], "%f", &chorus->out_gain);
@@ -121,10 +118,7 @@
else if ( ! strcmp(argv[i], "-t"))
chorus->modulation[chorus->num_chorus] = MOD_TRIANGLE;
else
- {
- sox_fail(effp->handler.usage);
- return (SOX_EOF);
- }
+ return sox_usage(effp);
i++;
chorus->num_chorus++;
}
@@ -338,7 +332,7 @@
static sox_effect_handler_t sox_chorus_effect = {
"chorus",
- "Usage: chorus gain-in gain-out delay decay speed depth [ -s | -t ]",
+ "gain-in gain-out delay decay speed depth [ -s | -t ]",
SOX_EFF_LENGTH,
sox_chorus_getopts,
sox_chorus_start,
--- a/src/compand.c
+++ b/src/compand.c
@@ -33,7 +33,7 @@
* -------
*/
#define compand_usage \
- "Usage: compand attack1,decay1{,attack2,decay2} [soft-knee-dB:]in-dB1[,out-dB1]{,in-dB2,out-dB2} [gain [initial-volume-dB [delay]]]\n" \
+ "attack1,decay1{,attack2,decay2} [soft-knee-dB:]in-dB1[,out-dB1]{,in-dB2,out-dB2} [gain [initial-volume-dB [delay]]]\n" \
"\twhere {} means optional and repeatable and [] means optional.\n" \
"\tdB values are floating point or -inf'; times are in seconds."
/*
@@ -66,10 +66,8 @@
char dummy; /* To check for extraneous chars. */
unsigned pairs, i, j, commas;
- if (n < 2 || n > 5) {
- sox_fail(effp->handler.usage);
- return SOX_EOF;
- }
+ if (n < 2 || n > 5)
+ return sox_usage(effp);
/* Start by checking the attack and decay rates */
for (s = argv[0], commas = 0; *s; ++s) if (*s == ',') ++commas;
@@ -131,7 +129,6 @@
compand_t l = (compand_t) effp->priv;
unsigned i, j;
- sox_debug("Starting compand effect; rate %i", effp->outinfo.rate);
sox_debug("%i input channel(s) expected: actually %i",
l->expectedChannels, effp->outinfo.channels);
for (i = 0; i < l->expectedChannels; ++i)
--- a/src/dcshift.c
+++ b/src/dcshift.c
@@ -35,24 +35,15 @@
dcs->uselimiter = 0; /* default is no limiter */
if (n < 1)
- {
- sox_fail(effp->handler.usage);
- return SOX_EOF;
- }
+ return sox_usage(effp);
if (n && (!sscanf(argv[0], "%lf", &dcs->dcshift)))
- {
- sox_fail(effp->handler.usage);
- return SOX_EOF;
- }
+ return sox_usage(effp);
if (n>1)
{
if (!sscanf(argv[1], "%lf", &dcs->limitergain))
- {
- sox_fail(effp->handler.usage);
- return SOX_EOF;
- }
+ return sox_usage(effp);
dcs->uselimiter = 1; /* ok, we'll use it */
/* The following equation is derived so that there is no
@@ -77,18 +68,6 @@
if (dcs->dcshift == 0)
return SOX_EFF_NULL;
- if (effp->outinfo.channels != effp->ininfo.channels) {
- sox_fail("DCSHIFT 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("DCSHIFT cannot handle different rates (in=%ld, out=%ld)"
- " use resample or rate", effp->ininfo.rate, effp->outinfo.rate);
- return SOX_EOF;
- }
-
dcs->clipped = 0;
dcs->limited = 0;
dcs->totalprocessed = 0;
@@ -193,7 +172,7 @@
static sox_effect_handler_t sox_dcshift_effect = {
"dcshift",
- "Usage: dcshift shift [ limitergain ]\n"
+ "shift [ limitergain ]\n"
" The peak limiter has a gain much less than 1.0 (ie 0.05 or 0.02) which is only\n"
" used on peaks to prevent clipping. (default is no limiter)",
SOX_EFF_MCHAN,
--- a/src/dither.c
+++ b/src/dither.c
@@ -27,10 +27,8 @@
{
dither_t dither = (dither_t) effp->priv;
- if (n > 1) {
- sox_fail(effp->handler.usage);
- return SOX_EOF;
- }
+ if (n > 1)
+ return sox_usage(effp);
dither->amount = sqrt(2.); /* M_SQRT2 missing in some places */ /* Default to half a bit. */
if (n == 1) {
@@ -39,10 +37,8 @@
int scanned = sscanf(*argv, "%lf %c", &amount, &dummy);
if (scanned == 1 && amount > 0)
dither->amount *= amount;
- else {
- sox_fail(effp->handler.usage);
- return SOX_EOF;
- }
+ else
+ return sox_usage(effp);
}
return SOX_SUCCESS;
@@ -83,7 +79,7 @@
sox_effect_handler_t const * sox_dither_effect_fn(void)
{
static sox_effect_handler_t handler = {
- "dither", "Usage: dither [amount]", SOX_EFF_MCHAN,
+ "dither", "[amount]", SOX_EFF_MCHAN | SOX_EFF_PREC,
getopts, start, flow, 0, 0, 0
};
return &handler;
@@ -92,7 +88,7 @@
sox_effect_handler_t const * sox_mask_effect_fn(void)
{
static sox_effect_handler_t handler = {
- "mask", "Usage: mask [amount]", SOX_EFF_MCHAN | SOX_EFF_DEPRECATED,
+ "mask", "[amount]", SOX_EFF_MCHAN | SOX_EFF_PREC | SOX_EFF_DEPRECATED,
getopts, start, flow, 0, 0, 0
};
return &handler;
--- a/src/earwax.c
+++ b/src/earwax.c
@@ -164,7 +164,7 @@
static sox_effect_handler_t sox_earwax_effect = {
"earwax",
- "Usage: The earwax filtering effect takes no options",
+ NULL,
SOX_EFF_MCHAN|SOX_EFF_LENGTH,
NULL,
sox_earwax_start,
--- a/src/echo.c
+++ b/src/echo.c
@@ -88,10 +88,7 @@
echo->num_delays = 0;
if ((n < 4) || (n % 2))
- {
- sox_fail(effp->handler.usage);
- return (SOX_EOF);
- }
+ return sox_usage(effp);
i = 0;
sscanf(argv[i++], "%f", &echo->in_gain);
@@ -265,7 +262,7 @@
static sox_effect_handler_t sox_echo_effect = {
"echo",
- "Usage: echo gain-in gain-out delay decay [ delay decay ... ]",
+ "gain-in gain-out delay decay [ delay decay ... ]",
SOX_EFF_LENGTH,
sox_echo_getopts,
sox_echo_start,
--- a/src/echos.c
+++ b/src/echos.c
@@ -78,10 +78,7 @@
echos->num_delays = 0;
if ((n < 4) || (n % 2))
- {
- sox_fail(effp->handler.usage);
- return (SOX_EOF);
- }
+ return sox_usage(effp);
i = 0;
sscanf(argv[i++], "%f", &echos->in_gain);
@@ -269,7 +266,7 @@
static sox_effect_handler_t sox_echos_effect = {
"echos",
- "Usage: echos gain-in gain-out delay decay [ delay decay ... ]",
+ "gain-in gain-out delay decay [ delay decay ... ]",
SOX_EFF_LENGTH,
sox_echos_getopts,
sox_echos_start,
--- a/src/effects.c
+++ b/src/effects.c
@@ -28,6 +28,14 @@
#define sox_report sox_message_filename=effp->handler.name,sox_report
+int sox_usage(sox_effect_t * effp)
+{
+ if (effp->handler.usage)
+ sox_fail("usage: %s", effp->handler.usage);
+ else
+ sox_fail("this effect takes no parameters");
+ return SOX_EOF;
+}
/* Default effect handler functions for do-nothing situations: */
@@ -54,11 +62,7 @@
/* Check that no parameters have been given */
static int default_getopts(sox_effect_t * effp, int argc, char **argv UNUSED)
{
- if (argc) {
- sox_fail("takes no parameters");
- return SOX_EOF;
- }
- return SOX_SUCCESS;
+ return argc? sox_usage(effp) : SOX_SUCCESS;
}
/* Partially initialise the effect structure; signal info will come later */
@@ -102,22 +106,30 @@
* ready for the next effect in the chain.
*/
int sox_add_effect(sox_effect_t * effp, sox_signalinfo_t * in, sox_signalinfo_t
- const * out) { int ret, (*start)(sox_effect_t * effp) =
- effp->handler.start; unsigned f;
+ const * out)
+{
+ int ret, (*start)(sox_effect_t * effp) = effp->handler.start;
+ unsigned f;
+ sox_effect_t eff0; /* Copy of effect for flow 0 before calling start */
if (effp->handler.flags & SOX_EFF_NULL) {
sox_report("has no effect (is a proxy effect)");
return SOX_EFF_NULL;
}
- effp->outinfo = effp->ininfo = *in;
- if (effp->handler.flags & SOX_EFF_CHAN)
- effp->outinfo.channels = out->channels;
- if (effp->handler.flags & SOX_EFF_RATE)
- effp->outinfo.rate = out->rate;
+ effp->ininfo = *in;
+ effp->outinfo = *out;
+ if (!(effp->handler.flags & SOX_EFF_CHAN))
+ effp->outinfo.channels = in->channels;
+ if (!(effp->handler.flags & SOX_EFF_RATE))
+ effp->outinfo.rate = in->rate;
+ if (!(effp->handler.flags & SOX_EFF_PREC))
+ effp->outinfo.size = in->size;
+
effp->flows =
(effp->handler.flags & SOX_EFF_MCHAN)? 1 : effp->ininfo.channels;
effp->clips = 0;
effp->imin = 0;
+ eff0 = *effp;
ret = start(effp);
if (ret == SOX_EFF_NULL) {
sox_report("has no effect in this configuration");
@@ -125,6 +137,7 @@
}
if (ret != SOX_SUCCESS)
return SOX_EOF;
+
*in = effp->outinfo;
if (sox_neffects == SOX_MAX_EFFECTS) {
@@ -136,7 +149,7 @@
sox_effects[sox_neffects][0] = *effp;
for (f = 1; f < effp->flows; ++f) {
- sox_effects[sox_neffects][f] = *effp;
+ sox_effects[sox_neffects][f] = eff0;
sox_effects[sox_neffects][f].flow = f;
if (start(&sox_effects[sox_neffects][f]) != SOX_SUCCESS)
return SOX_EOF;
--- a/src/fade.c
+++ b/src/fade.c
@@ -51,10 +51,7 @@
int t_argno;
if (n < 1 || n > 4)
- { /* Wrong number of arguments. */
- sox_fail(effp->handler.usage);
- return(SOX_EOF);
- }
+ return sox_usage(effp);
/* because sample rate is unavailable at this point we store the
* string off for later computations.
@@ -79,10 +76,7 @@
strcpy(fade->in_stop_str,argv[0]);
/* Do a dummy parse to see if it will fail */
if (sox_parsesamples(0, fade->in_stop_str, &fade->in_stop, 't') == NULL)
- {
- sox_fail(effp->handler.usage);
- return(SOX_EOF);
- }
+ return sox_usage(effp);
fade->out_start_str = fade->out_stop_str = 0;
@@ -96,10 +90,8 @@
/* Do a dummy parse to see if it will fail */
if (sox_parsesamples(0, fade->out_stop_str,
- &fade->out_stop, 't') == NULL) {
- sox_fail(effp->handler.usage);
- return(SOX_EOF);
- }
+ &fade->out_stop, 't') == NULL)
+ return sox_usage(effp);
}
else
{
@@ -108,10 +100,8 @@
/* Do a dummy parse to see if it will fail */
if (sox_parsesamples(0, fade->out_start_str,
- &fade->out_start, 't') == NULL) {
- sox_fail(effp->handler.usage);
- return(SOX_EOF);
- }
+ &fade->out_start, 't') == NULL)
+ return sox_usage(effp);
}
} /* End for(t_argno) */
@@ -130,10 +120,7 @@
fade->in_start = 0;
if (sox_parsesamples(effp->ininfo.rate, fade->in_stop_str,
&fade->in_stop, 't') == NULL)
- {
- sox_fail(effp->handler.usage);
- return(SOX_EOF);
- }
+ return sox_usage(effp);
fade->do_out = 0;
/* See if user specified a stop time */
@@ -142,10 +129,7 @@
fade->do_out = 1;
if (sox_parsesamples(effp->ininfo.rate, fade->out_stop_str,
&fade->out_stop, 't') == NULL)
- {
- sox_fail(effp->handler.usage);
- return(SOX_EOF);
- }
+ return sox_usage(effp);
/* See if user wants to fade out. */
if (fade->out_start_str)
@@ -152,10 +136,7 @@
{
if (sox_parsesamples(effp->ininfo.rate, fade->out_start_str,
&fade->out_start, 't') == NULL)
- {
- sox_fail(effp->handler.usage);
- return(SOX_EOF);
- }
+ return sox_usage(effp);
/* Fade time is relative to stop time. */
fade->out_start = fade->out_stop - fade->out_start;
@@ -371,7 +352,7 @@
static sox_effect_handler_t sox_fade_effect = {
"fade",
- "Usage: fade [ type ] fade-in-length [ stop-time [ fade-out-length ] ]\n"
+ "[ type ] fade-in-length [ stop-time [ fade-out-length ] ]\n"
" Time is in hh:mm:ss.frac format.\n"
" Fade type one of q, h, t, l or p.",
SOX_EFF_MCHAN,
--- a/src/filter.c
+++ b/src/filter.c
@@ -74,16 +74,10 @@
}
sox_debug("freq: %d-%d", f->freq0, f->freq1);
if (f->freq0 == 0 && f->freq1 == 0)
- {
- sox_fail(effp->handler.usage);
- return (SOX_EOF);
- }
+ return sox_usage(effp);
if ((n >= 2) && !sscanf(argv[1], "%ld", &f->Nwin))
- {
- sox_fail(effp->handler.usage);
- return (SOX_EOF);
- }
+ return sox_usage(effp);
else if (f->Nwin < 4) {
sox_fail("filter: window length (%ld) <4 is too short", f->Nwin);
return (SOX_EOF);
@@ -90,10 +84,7 @@
}
if ((n >= 3) && !sscanf(argv[2], "%lf", &f->beta))
- {
- sox_fail(effp->handler.usage);
- return (SOX_EOF);
- }
+ return sox_usage(effp);
sox_debug("filter opts: %d-%d, window-len %d, beta %f", f->freq0, f->freq1, f->Nwin, f->beta);
return (SOX_SUCCESS);
@@ -311,7 +302,7 @@
static sox_effect_handler_t sox_filter_effect = {
"filter",
- "Usage: filter low-high [ windowlength [ beta ] ]",
+ "low-high [ windowlength [ beta ] ]",
0,
sox_filter_getopts,
sox_filter_start,
--- a/src/flanger.c
+++ b/src/flanger.c
@@ -17,7 +17,7 @@
/* Effect: Stereo Flanger (c) 2006 robs@users.sourceforge.net */
#define sox_flanger_usage \
- "Usage: flanger [delay depth regen width speed shape phase interp]\n"
+ "[delay depth regen width speed shape phase interp]\n"
/*
" .\n" \
" /|regen\n" \
@@ -109,10 +109,8 @@
if (argc == 0) break; \
d = strtod(*argv, &end_ptr); \
if (end_ptr != *argv) { \
- if (d < min || d > max || *end_ptr != '\0') { \
- sox_fail(effp->handler.usage); \
- return SOX_EOF; \
- } \
+ if (d < min || d > max || *end_ptr != '\0') \
+ return sox_usage(effp); \
f->p = d; \
--argc, ++argv; \
} \
@@ -153,10 +151,8 @@
TEXTUAL_PARAMETER(interpolation, interp_enum)
} while (0);
- if (argc != 0) {
- sox_fail(effp->handler.usage);
- return SOX_EOF;
- }
+ if (argc != 0)
+ return sox_usage(effp);
sox_report("parameters:\n"
"delay = %gms\n"
--- a/src/ladspa.c
+++ b/src/ladspa.c
@@ -176,10 +176,8 @@
l_st->control[i] = ladspa_default(&(l_st->desc->PortRangeHints[i]));
sox_debug("default argument for port %d is %f", i, l_st->control[i]);
} else {
- if (!sscanf(argv[0], "%lf", &arg)) {
- sox_fail(effp->handler.usage);
- return SOX_EOF;
- }
+ if (!sscanf(argv[0], "%lf", &arg))
+ return sox_usage(effp);
l_st->control[i] = (LADSPA_Data)arg;
sox_debug("argument for port %d is %f", i, l_st->control[i]);
n--; argv++;
@@ -188,12 +186,7 @@
}
/* Stop if we have any unused arguments */
- if (n > 0) {
- sox_fail(sox_ladspa_effect.usage);
- return SOX_EOF;
- }
-
- return SOX_SUCCESS;
+ return n? sox_usage(effp) : SOX_SUCCESS;
}
/*
@@ -298,7 +291,7 @@
static sox_effect_handler_t sox_ladspa_effect = {
"ladspa",
- "Usage: ladspa MODULE [PLUGIN] [ARGUMENT...]",
+ "MODULE [PLUGIN] [ARGUMENT...]",
0,
sox_ladspa_getopts,
sox_ladspa_start,
--- a/src/mcompand.c
+++ b/src/mcompand.c
@@ -624,7 +624,7 @@
static sox_effect_handler_t sox_mcompand_effect = {
"mcompand",
- "Usage: mcompand quoted_compand_args [crossover_frequency quoted_compand_args [...]]\n"
+ "quoted_compand_args [crossover_frequency quoted_compand_args [...]]\n"
"\n"
"quoted_compand_args are as for the compand effect:\n"
"\n"
--- a/src/misc.c
+++ b/src/misc.c
@@ -368,6 +368,12 @@
return str_len >= end_len && !strcasecmp(str + str_len - end_len, end);
}
+sox_bool strends(char const * str, char const * end)
+{
+ size_t str_len = strlen(str), end_len = strlen(end);
+ return str_len >= end_len && !strcmp(str + str_len - end_len, end);
+}
+
#ifndef HAVE_STRDUP
/*
* Portable strdup() function
--- a/src/mixer.c
+++ b/src/mixer.c
@@ -79,10 +79,8 @@
else if (!strcmp(argv[0], "-4"))
mixer->mix = MIX_RIGHT_BACK;
else if (argv[0][0] == '-' && !isdigit((int)argv[0][1])
- && argv[0][1] != '.') {
- sox_fail(effp->handler.usage);
- return (SOX_EOF);
- }
+ && argv[0][1] != '.')
+ return sox_usage(effp);
else {
int commas;
char *s;
@@ -104,10 +102,8 @@
else if (n == 0) {
mixer->mix = MIX_CENTER;
}
- else {
- sox_fail(effp->handler.usage);
- return SOX_EOF;
- }
+ else
+ return sox_usage(effp);
return (SOX_SUCCESS);
}
@@ -540,7 +536,7 @@
{
static sox_effect_handler_t handler = {
"mixer",
- "Usage: mixer [ -l | -r | -f | -b | -1 | -2 | -3 | -4 | n,n,n...,n ]",
+ "[ -l | -r | -f | -b | -1 | -2 | -3 | -4 | n,n,n...,n ]",
SOX_EFF_MCHAN | SOX_EFF_CHAN,
getopts, start, flow, 0, 0, 0
};
@@ -549,22 +545,17 @@
sox_effect_handler_t const * sox_avg_effect_fn(void)
{
- static sox_effect_handler_t handler = {
- "avg",
- "Usage: avg [ -l | -r | -f | -b | -1 | -2 | -3 | -4 | n,n,n...,n ]",
- SOX_EFF_MCHAN | SOX_EFF_CHAN | SOX_EFF_DEPRECATED,
- getopts, start, flow, 0, 0, 0
- };
+ static sox_effect_handler_t handler;
+ handler = *sox_mixer_effect_fn();
+ handler.name = "avg";
+ handler.flags |= SOX_EFF_DEPRECATED;
return &handler;
}
sox_effect_handler_t const * sox_pick_effect_fn(void)
{
- static sox_effect_handler_t handler = {
- "pick",
- "Usage: pick [ -l | -r | -f | -b | -1 | -2 | -3 | -4 | n,n,n...,n ]",
- SOX_EFF_MCHAN | SOX_EFF_CHAN | SOX_EFF_DEPRECATED,
- getopts, start, flow, 0, 0, 0
- };
+ static sox_effect_handler_t handler;
+ handler = *sox_avg_effect_fn();
+ handler.name = "pick";
return &handler;
}
--- a/src/noiseprof.c
+++ b/src/noiseprof.c
@@ -43,10 +43,8 @@
if (n == 1) {
data->output_filename = argv[0];
- } else if (n > 1) {
- sox_fail(effp->handler.usage);
- return (SOX_EOF);
- }
+ } else if (n > 1)
+ return sox_usage(effp);
return (SOX_SUCCESS);
}
@@ -212,7 +210,7 @@
static sox_effect_handler_t sox_noiseprof_effect = {
"noiseprof",
- "Usage: noiseprof [profile-file]",
+ "[profile-file]",
SOX_EFF_MCHAN,
sox_noiseprof_getopts,
sox_noiseprof_start,
--- a/src/noisered.c
+++ b/src/noisered.c
@@ -22,10 +22,8 @@
if (argc == 0) break; \
d = strtod(*argv, &end_ptr); \
if (end_ptr != *argv) { \
- if (d < min || d > max || *end_ptr != '\0') { \
- sox_fail(effp->handler.usage); \
- return SOX_EOF; \
- } \
+ if (d < min || d > max || *end_ptr != '\0') \
+ return sox_usage(effp); \
this->p = d; \
--argc, ++argv; \
} \
@@ -66,11 +64,7 @@
NUMERIC_PARAMETER(threshold, 0, 1);
} while (0);
- if (argc != 0) {
- sox_fail(effp->handler.usage);
- return SOX_EOF;
- }
- return SOX_SUCCESS;
+ return argc? sox_usage(effp) : SOX_SUCCESS;
}
/*
@@ -345,7 +339,7 @@
static sox_effect_handler_t sox_noisered_effect = {
"noisered",
- "Usage: noisered [profile-file [amount]]",
+ "[profile-file [amount]]",
SOX_EFF_MCHAN|SOX_EFF_LENGTH,
sox_noisered_getopts,
sox_noisered_start,
--- a/src/noisered.h
+++ b/src/noisered.h
@@ -18,4 +18,5 @@
#include <math.h>
#define WINDOWSIZE 2048
-#define FREQCOUNT (WINDOWSIZE/2+1)
+#define HALFWINDOW (WINDOWSIZE / 2)
+#define FREQCOUNT (HALFWINDOW + 1)
--- a/src/pad.c
+++ b/src/pad.c
@@ -55,10 +55,8 @@
}
if (i > 0 && p->pads[i].start <= p->pads[i-1].start) break;
}
- if (i < p->npads) {
- sox_fail(effp->handler.usage);
- return SOX_EOF;
- }
+ if (i < p->npads)
+ return sox_usage(effp);
return SOX_SUCCESS;
}
@@ -141,7 +139,7 @@
sox_effect_handler_t const * sox_pad_effect_fn(void)
{
static sox_effect_handler_t handler = {
- "pad", "Usage: pad {length[@position]}", SOX_EFF_MCHAN|SOX_EFF_LENGTH,
+ "pad", "{length[@position]}", SOX_EFF_MCHAN|SOX_EFF_LENGTH,
create, start, flow, drain, stop, kill
};
return &handler;
--- a/src/pan.c
+++ b/src/pan.c
@@ -36,10 +36,7 @@
if (n && (!sscanf(argv[0], "%lf", &pan->dir) ||
pan->dir < -1.0 || pan->dir > 1.0))
- {
- sox_fail(effp->handler.usage);
- return SOX_EOF;
- }
+ return sox_usage(effp);
return SOX_SUCCESS;
}
@@ -51,14 +48,6 @@
{
if (effp->outinfo.channels==1)
sox_warn("PAN onto a mono channel...");
-
- if (effp->outinfo.rate != effp->ininfo.rate)
- {
- sox_fail("PAN cannot handle different rates (in=%ld, out=%ld)"
- " use resample or rate", effp->ininfo.rate, effp->outinfo.rate);
- return SOX_EOF;
- }
-
return SOX_SUCCESS;
}
@@ -411,7 +400,7 @@
static sox_effect_handler_t sox_pan_effect = {
"pan",
- "Usage: pan direction (in [-1.0 .. 1.0])",
+ "direction (in [-1.0 .. 1.0])",
SOX_EFF_MCHAN | SOX_EFF_CHAN,
sox_pan_getopts,
sox_pan_start,
--- a/src/phaser.c
+++ b/src/phaser.c
@@ -84,10 +84,7 @@
phaser_t phaser = (phaser_t) effp->priv;
if (!((n == 5) || (n == 6)))
- {
- sox_fail(effp->handler.usage);
- return (SOX_EOF);
- }
+ return sox_usage(effp);
sscanf(argv[0], "%f", &phaser->in_gain);
sscanf(argv[1], "%f", &phaser->out_gain);
@@ -101,10 +98,7 @@
else if ( ! strcmp(argv[5], "-t"))
phaser->modulation = MOD_TRIANGLE;
else
- {
- sox_fail(effp->handler.usage);
- return (SOX_EOF);
- }
+ return sox_usage(effp);
}
return (SOX_SUCCESS);
}
@@ -261,7 +255,7 @@
static sox_effect_handler_t sox_phaser_effect = {
"phaser",
- "Usage: phaser gain-in gain-out delay decay speed [ -s | -t ]",
+ "gain-in gain-out delay decay speed [ -s | -t ]",
SOX_EFF_LENGTH,
sox_phaser_getopts,
sox_phaser_start,
--- a/src/pitch.c
+++ b/src/pitch.c
@@ -252,18 +252,12 @@
pitch->shift = 0.0; /* default is no change */
if (n && !sscanf(argv[0], "%lf", &pitch->shift))
- {
- sox_fail(effp->handler.usage);
- return SOX_EOF;
- }
+ return sox_usage(effp);
/* sweep size in ms */
pitch->width = PITCH_DEFAULT_WIDTH;
if (n>1 && !sscanf(argv[1], "%lf", &pitch->width))
- {
- sox_fail(effp->handler.usage);
- return SOX_EOF;
- }
+ return sox_usage(effp);
/* interpole option */
pitch->interopt = PITCH_INTERPOLE_DEFAULT;
@@ -280,8 +274,7 @@
pitch->interopt = PITCH_INTERPOLE_CUB;
break;
default:
- sox_fail(effp->handler.usage);
- return SOX_EOF;
+ return sox_usage(effp);
}
}
@@ -308,8 +301,7 @@
pitch->fadeopt = PITCH_FADE_COS;
break;
default:
- sox_fail(effp->handler.usage);
- return SOX_EOF;
+ return sox_usage(effp);
}
}
@@ -316,10 +308,7 @@
pitch->coef = 0.25;
if (n>4 && (!sscanf(argv[4], "%lf", &pitch->coef) ||
pitch->coef<0.0 || pitch->coef>0.5))
- {
- sox_fail(effp->handler.usage);
- return SOX_EOF;
- }
+ return sox_usage(effp);
return SOX_SUCCESS;
}
@@ -333,22 +322,6 @@
register int sample_rate = effp->outinfo.rate;
unsigned int i;
- /* check constraints. sox does already take care of that I guess?
- */
- if (effp->outinfo.rate != effp->ininfo.rate)
- {
- sox_fail("PITCH cannot handle different rates (in=%ld, out=%ld)"
- " use resample or rate", effp->ininfo.rate, effp->outinfo.rate);
- return SOX_EOF;
- }
-
- if (effp->outinfo.channels != effp->ininfo.channels)
- {
- sox_fail("PITCH cannot handle different channels (in=%ld, out=%ld)"
- " use avg or pan", effp->ininfo.channels, effp->outinfo.channels);
- return SOX_EOF;
- }
-
/* computer inner stuff... */
pitch->state = pi_input;
@@ -574,7 +547,7 @@
static sox_effect_handler_t sox_pitch_effect = {
"pitch",
- "Usage: pitch shift width interpole fade\n"
+ "shift width interpole fade\n"
" (in cents, in ms, cub/lin, cos/ham/lin/trap)"
" (defaults: 0 20 c c)",
SOX_EFF_LENGTH,
--- a/src/polyphas.c
+++ b/src/polyphas.c
@@ -619,7 +619,7 @@
static sox_effect_handler_t sox_polyphase_effect = {
"polyphase",
- "Usage: -w {nut|ham} window type\n"
+ "-w {nut|ham} window type\n"
" -width n window width in samples [default 1024]\n"
"\n"
" -cutoff float frequency cutoff for base bandwidth [default 0.95]",
--- a/src/rabbit.c
+++ b/src/rabbit.c
@@ -17,15 +17,8 @@
* Foundation, Fifth Floor, 51 Franklin Street, Boston, MA 02111-1301,
* USA. */
-/* FIXME: Make more efficient by resampling piece by piece rather than
- all in one go. The code is as it is at present because before SoX
- had global clipping detection, rabbit used to do its own based on
- sndfile-resample. */
-
#include "sox_i.h"
-#ifdef HAVE_SAMPLERATE_H
-
#include <limits.h>
#include <stdlib.h>
#include <string.h>
@@ -37,14 +30,13 @@
int converter_type; /* SRC converter type */
SRC_STATE *state; /* SRC state struct */
SRC_DATA *data; /* SRC_DATA control struct */
- sox_size_t samples; /* Number of samples read so far */
- sox_size_t outsamp; /* Next output sample */
+ sox_size_t i_alloc, o_alloc; /* Samples allocated in data->data_{in,out} */
} *rabbit_t;
/*
* Process options
*/
-static int sox_rabbit_getopts(sox_effect_t * effp, int n, char **argv)
+static int getopts(sox_effect_t * effp, int n, char **argv)
{
rabbit_t r = (rabbit_t) effp->priv;
@@ -69,10 +61,8 @@
}
}
- if (n >= 1) {
- sox_fail(effp->handler.usage);
- return SOX_EOF;
- }
+ if (n >= 1)
+ return sox_usage(effp);
return SOX_SUCCESS;
}
@@ -80,9 +70,10 @@
/*
* Prepare processing.
*/
-static int sox_rabbit_start(sox_effect_t * effp)
+static int start(sox_effect_t * effp)
{
rabbit_t r = (rabbit_t) effp->priv;
+ int err = 0;
/* The next line makes the "speed" effect accurate; it's needed because
* ininfo.rate (sox_rate_t) isn't floating point (but it's probably not worth
@@ -100,38 +91,79 @@
r->data = (SRC_DATA *)xcalloc(1, sizeof(SRC_DATA));
r->data->src_ratio = (double)effp->outinfo.rate / in_rate;
- r->data->input_frames_used = 0;
- r->data->output_frames_gen = 0;
+ r->i_alloc = r->o_alloc = 0;
+ r->state = src_new(r->converter_type, effp->ininfo.channels, &err);
+ if (err) {
+ free(r->data);
+ sox_fail("cannot initialise rabbit: %s", src_strerror(err));
+ return SOX_EOF;
+ }
return SOX_SUCCESS;
}
/*
- * Read all the data.
+ * Read, convert, return data.
*/
-static int sox_rabbit_flow(sox_effect_t * effp, const sox_ssample_t *ibuf, sox_ssample_t *obuf UNUSED,
+static int flow(sox_effect_t * effp, const sox_ssample_t *ibuf, sox_ssample_t *obuf UNUSED,
sox_size_t *isamp, sox_size_t *osamp)
{
rabbit_t r = (rabbit_t) effp->priv;
- int channels = effp->ininfo.channels;
- sox_size_t i, newsamples;
+ SRC_DATA *d = r->data;
+ unsigned int channels = effp->ininfo.channels;
+ sox_size_t i;
- newsamples = r->samples + *isamp;
- if (newsamples / channels > INT_MAX) {
- sox_fail("input data size %d too large for libsamplerate", newsamples);
- return SOX_EOF;
+ if (isamp && *isamp > 0) {
+ sox_size_t isamples0 = d->input_frames * channels;
+ sox_size_t isamples = isamples0 + *isamp;
+ sox_size_t osamples = isamples * (d->src_ratio + 0.01) + 8;
+
+ if (osamples > sox_bufsiz) {
+ osamples = sox_bufsiz;
+ isamples = (osamples - 8) / (d->src_ratio + 0.01);
+ }
+
+ if (r->i_alloc < isamples) {
+ d->data_in = xrealloc(d->data_in, isamples * sizeof(float));
+ r->i_alloc = isamples;
+ }
+ if (r->o_alloc < osamples) {
+ d->data_out = xrealloc(d->data_out, osamples * sizeof(float));
+ r->o_alloc = osamples;
+ d->output_frames = osamples / channels;
+ }
+
+ for (i = 0; i < isamples - isamples0; i++)
+ d->data_in[isamples0 + i] = SOX_SAMPLE_TO_FLOAT_32BIT(ibuf[i], effp->clips);
+
+ *isamp = isamples - isamples0;
+ d->input_frames = isamples / channels;
}
- r->data->data_in = (float *)xrealloc(r->data->data_in, newsamples * sizeof(float));
+ *osamp = 0;
+ while (d->input_frames > 0 || d->end_of_input != 0) {
+ if (src_process(r->state, r->data) != 0) {
+ sox_fail("%s", src_strerror(src_error(r->state)));
+ return SOX_EOF;
+ }
+ if (d->input_frames_used) {
+ d->input_frames -= d->input_frames_used;
+ if (d->input_frames)
+ memcpy(d->data_in,
+ d->data_in + d->input_frames_used * sizeof(float),
+ d->input_frames * sizeof(float));
+ }
- for (i = 0 ; i < *isamp; i++)
- r->data->data_in[r->samples + i] = SOX_SAMPLE_TO_FLOAT_32BIT(ibuf[i], effp->clips);
+ *osamp = d->output_frames_gen * channels;
+ if (! *osamp)
+ break;
- r->samples = newsamples;
- r->data->input_frames = r->samples / channels;
- r->outsamp = 0;
+ for (i = 0; i < (sox_size_t)d->output_frames_gen * channels; i++)
+ obuf[i] = SOX_FLOAT_32BIT_TO_SAMPLE(d->data_out[i], effp->clips);
- *osamp = 0; /* Signal that we didn't produce any output */
+ if (d->end_of_input)
+ break;
+ }
return SOX_SUCCESS;
}
@@ -139,52 +171,17 @@
/*
* Process samples and write output.
*/
-static int sox_rabbit_drain(sox_effect_t * effp, sox_ssample_t *obuf, sox_size_t *osamp)
+static int drain(sox_effect_t * effp, sox_ssample_t *obuf, sox_size_t *osamp)
{
rabbit_t r = (rabbit_t) effp->priv;
- int channels = effp->ininfo.channels;
- sox_size_t i, outsamps;
-
- /* On first call, process the data */
- if (r->data->data_out == NULL) {
- /* Guess maximum number of possible output frames */
- sox_size_t outframes = r->data->input_frames * (r->data->src_ratio + 0.01) + 8;
- int error;
-
- if (outframes > INT_MAX) {
- sox_fail("too many output frames (%d) for libsamplerate", outframes);
- return SOX_EOF;
- }
- r->data->output_frames = outframes;
- r->data->data_out = (float *)xmalloc(r->data->output_frames * channels * sizeof(float));
-
- /* Process the data */
- if ((error = src_simple(r->data, r->converter_type, channels))) {
- sox_fail("libsamplerate processing failed: %s", src_strerror(error));
- return SOX_EOF;
- }
- }
-
- /* Return the data one bufferful at a time */
- if (*osamp > INT_MAX) {
- sox_fail("output buffer size %d too large for libsamplerate", *osamp);
- return SOX_EOF;
- }
-
- outsamps = min(r->data->output_frames_gen * channels - r->outsamp, *osamp);
- for (i = 0; i < outsamps; i++)
- obuf[i] = SOX_FLOAT_32BIT_TO_SAMPLE(r->data->data_out[r->outsamp + i], effp->clips);
- *osamp = (sox_size_t)outsamps;
- r->outsamp += outsamps;
-
- return SOX_SUCCESS;
+ r->data->end_of_input = 1;
+ return flow(effp, NULL, obuf, NULL, osamp);
}
/*
* Do anything required when you stop reading samples.
- * Don't close input file!
*/
-static int sox_rabbit_stop(sox_effect_t * effp)
+static int stop(sox_effect_t * effp)
{
rabbit_t r = (rabbit_t) effp->priv;
@@ -193,21 +190,13 @@
return SOX_SUCCESS;
}
-static sox_effect_handler_t sox_rabbit_effect = {
- "rabbit",
- "Usage: rabbit [-c0|-c1|-c2|-c3|-c4]",
- SOX_EFF_RATE | SOX_EFF_MCHAN,
- sox_rabbit_getopts,
- sox_rabbit_start,
- sox_rabbit_flow,
- sox_rabbit_drain,
- sox_rabbit_stop,
- NULL
-};
-
const sox_effect_handler_t *sox_rabbit_effect_fn(void)
{
- return &sox_rabbit_effect;
-}
+ static sox_effect_handler_t handler = {
+ "rabbit", "[-c0|-c1|-c2|-c3|-c4]",
+ SOX_EFF_RATE | SOX_EFF_MCHAN,
+ getopts, start, flow, drain, stop, NULL
+ };
-#endif /* HAVE_SAMPLERATE */
+ return &handler;
+}
--- a/src/repeat.c
+++ b/src/repeat.c
@@ -36,10 +36,8 @@
{
repeat_t repeat = (repeat_t)effp->priv;
- if (n != 1) {
- sox_fail(effp->handler.usage);
- return (SOX_EOF);
- }
+ if (n != 1)
+ return sox_usage(effp);
if (!(sscanf(argv[0], "%i", &repeat->repeats))) {
sox_fail("could not parse repeat parameter");
@@ -196,7 +194,7 @@
static sox_effect_handler_t sox_repeat_effect = {
"repeat",
- "Usage: repeat count",
+ "count",
SOX_EFF_MCHAN | SOX_EFF_LENGTH,
sox_repeat_getopts,
sox_repeat_start,
--- a/src/resample.c
+++ b/src/resample.c
@@ -169,16 +169,15 @@
}
if ((n >= 1) && (sscanf(argv[0], "%lf", &r->rolloff) != 1)) {
- sox_fail(effp->handler.usage);
- return (SOX_EOF);
+ return sox_usage(effp);
} else if ((r->rolloff <= 0.01) || (r->rolloff >= 1.0)) {
sox_fail("rolloff factor (%f) no good, should be 0.01<x<1.0", r->rolloff);
return(SOX_EOF);
}
+
if ((n >= 2) && !sscanf(argv[1], "%lf", &r->beta)) {
- sox_fail(effp->handler.usage);
- return (SOX_EOF);
+ return sox_usage(effp);
} else if (r->beta <= 2.0) {
r->beta = 0;
sox_debug("opts: Nuttall window, cutoff %f", r->rolloff);
@@ -724,7 +723,7 @@
const sox_effect_handler_t *sox_resample_effect_fn(void)
{
static sox_effect_handler_t handler = {
- "resample", "Usage: resample [ -qs | -q | -ql ] [ rolloff [ beta ] ]",
+ "resample", "[ -qs | -q | -ql ] [ rolloff [ beta ] ]",
SOX_EFF_RATE, getopts, start, flow, drain, stop, NULL
};
return &handler;
--- a/src/reverb.c
+++ b/src/reverb.c
@@ -122,10 +122,7 @@
reverb->maxsamples = 0;
if ( n < 3 )
- {
- sox_fail(effp->handler.usage);
- return (SOX_EOF);
- }
+ return sox_usage(effp);
if ( n - 2 > MAXREVERBS )
{
@@ -282,7 +279,7 @@
static sox_effect_handler_t sox_reverb_effect = {
"reverb",
- "Usage: reverb gain-out reverb-time delay [ delay ... ]",
+ "gain-out reverb-time delay [ delay ... ]",
SOX_EFF_LENGTH,
sox_reverb_getopts,
sox_reverb_start,
--- a/src/reverse.c
+++ b/src/reverse.c
@@ -131,7 +131,7 @@
static sox_effect_handler_t sox_reverse_effect = {
"reverse",
- "Usage: Reverse effect takes no options",
+ NULL,
0,
NULL,
sox_reverse_start,
--- a/src/silence.c
+++ b/src/silence.c
@@ -94,18 +94,12 @@
}
if (n < 1)
- {
- sox_fail(effp->handler.usage);
- return (SOX_EOF);
- }
+ return sox_usage(effp);
/* Parse data related to trimming front side */
silence->start = sox_false;
if (sscanf(argv[0], "%d", &silence->start_periods) != 1)
- {
- sox_fail(effp->handler.usage);
- return(SOX_EOF);
- }
+ return sox_usage(effp);
if (silence->start_periods < 0)
{
sox_fail("Periods must not be negative");
@@ -118,10 +112,7 @@
{
silence->start = sox_true;
if (n < 2)
- {
- sox_fail(effp->handler.usage);
- return SOX_EOF;
- }
+ return sox_usage(effp);
/* We do not know the sample rate so we can not fully
* parse the duration info yet. So save argument off
@@ -132,18 +123,12 @@
/* Perform a fake parse to do error checking */
if (sox_parsesamples(0,silence->start_duration_str,
&silence->start_duration,'s') == NULL)
- {
- sox_fail(effp->handler.usage);
- return(SOX_EOF);
- }
+ return sox_usage(effp);
parse_count = sscanf(argv[1], "%lf%c", &silence->start_threshold,
&silence->start_unit);
if (parse_count < 1)
- {
- sox_fail(effp->handler.usage);
- return SOX_EOF;
- }
+ return sox_usage(effp);
else if (parse_count < 2)
silence->start_unit = '%';
@@ -156,15 +141,9 @@
if (n > 0)
{
if (n < 3)
- {
- sox_fail(effp->handler.usage);
- return SOX_EOF;
- }
+ return sox_usage(effp);
if (sscanf(argv[0], "%d", &silence->stop_periods) != 1)
- {
- sox_fail(effp->handler.usage);
- return SOX_EOF;
- }
+ return sox_usage(effp);
if (silence->stop_periods < 0)
{
silence->stop_periods = -silence->stop_periods;
@@ -185,18 +164,12 @@
/* Perform a fake parse to do error checking */
if (sox_parsesamples(0,silence->stop_duration_str,
&silence->stop_duration,'s') == NULL)
- {
- sox_fail(effp->handler.usage);
- return(SOX_EOF);
- }
+ return sox_usage(effp);
parse_count = sscanf(argv[1], "%lf%c", &silence->stop_threshold,
&silence->stop_unit);
if (parse_count < 1)
- {
- sox_fail(effp->handler.usage);
- return SOX_EOF;
- }
+ return sox_usage(effp);
else if (parse_count < 2)
silence->stop_unit = '%';
@@ -210,8 +183,7 @@
if ((silence->start_unit != '%') && (silence->start_unit != 'd'))
{
sox_fail("Invalid unit specified");
- sox_fail(effp->handler.usage);
- return(SOX_EOF);
+ return sox_usage(effp);
}
if ((silence->start_unit == '%') && ((silence->start_threshold < 0.0)
|| (silence->start_threshold > 100.0)))
@@ -268,19 +240,13 @@
{
if (sox_parsesamples(effp->ininfo.rate, silence->start_duration_str,
&silence->start_duration, 's') == NULL)
- {
- sox_fail(effp->handler.usage);
- return(SOX_EOF);
- }
+ return sox_usage(effp);
}
if (silence->stop)
{
if (sox_parsesamples(effp->ininfo.rate,silence->stop_duration_str,
&silence->stop_duration,'s') == NULL)
- {
- sox_fail(effp->handler.usage);
- return(SOX_EOF);
- }
+ return sox_usage(effp);
}
if (silence->start)
@@ -714,7 +680,7 @@
static sox_effect_handler_t sox_silence_effect = {
"silence",
- "Usage: silence [ -l ] above_periods [ duration thershold[d|%%] ] [ below_periods duration threshold[d|%%]]",
+ "[ -l ] above_periods [ duration thershold[d|%%] ] [ below_periods duration threshold[d|%%]]",
SOX_EFF_MCHAN,
sox_silence_getopts,
sox_silence_start,
--- a/src/skeleff.c
+++ b/src/skeleff.c
@@ -37,10 +37,8 @@
{
skeleff_t skeleff = (skeleff_t)effp->priv;
- if (n && n != 1) {
- sox_fail(effp->handler.usage);
- return SOX_EOF;
- }
+ if (n && n != 1)
+ return sox_usage(effp);
return SOX_SUCCESS;
}
@@ -132,7 +130,7 @@
*/
static sox_effect_handler_t sox_skel_effect = {
"skel",
- "Usage: skel [OPTION]",
+ "[OPTION]",
SOX_EFF_MCHAN,
getopts,
start,
--- a/src/sox.c
+++ b/src/sox.c
@@ -504,17 +504,13 @@
atexit(cleanup);
sox_output_message_handler = output_message;
- /* Read command-line and argv[0] options */
- i = strlen(myname);
- if (i >= sizeof("play") - 1 &&
- strcmp(myname + i - (sizeof("play") - 1), "play") == 0) {
+ if (strends(myname, "play")) {
play = sox_true;
replay_gain_mode = RG_track;
combine_method = sox_sequence;
- } else if (i >= sizeof("rec") - 1 &&
- strcmp(myname + i - (sizeof("rec") - 1), "rec") == 0) {
- rec = sox_true;
}
+ else if (strends(myname, "rec"))
+ rec = sox_true;
parse_options_and_filenames(argc, argv);
@@ -631,7 +627,7 @@
if (show_progress) {
if (user_abort)
fprintf(stderr, "Aborted.\n");
- else if (user_skip)
+ else if (user_skip && !rec)
fprintf(stderr, "Skipped.\n");
else
fprintf(stderr, "Done.\n");
@@ -748,33 +744,6 @@
return p->value;
}
-static void optimize_trim(void)
-{
- /* Speed hack. If the "trim" effect is the first effect then
- * peek inside its "effect descriptor" and see what the
- * start location is. This has to be done after its start()
- * is called to have the correct location.
- * Also, only do this when only working with one input file.
- * This is because the logic to do it for multiple files is
- * complex and problably never used.
- * This hack is a huge time savings when trimming
- * gigs of audio data into managable chunks
- */
- if (input_count == 1 && sox_neffects > 1 && strcmp(sox_effects[1][0].handler.name, "trim") == 0) {
- if ((files[0]->ft->handler->flags & SOX_FILE_SEEK) && files[0]->ft->seekable){
- sox_size_t offset = sox_trim_get_start(&sox_effects[1][0]);
- if (sox_seek(files[0]->ft, offset, SOX_SEEK_SET) != SOX_EOF) {
- read_wide_samples = offset / files[0]->ft->signal.channels;
- /* Assuming a failed seek stayed where it was. If the
- * seek worked then reset the start location of
- * trim so that it thinks user didn't request a skip.
- */
- sox_trim_clear_start(&sox_effects[1][0]);
- }
- }
- }
-}
-
static sox_bool doopts(file_t f, int argc, char **argv)
{
while (sox_true) {
@@ -1274,12 +1243,39 @@
for (i = 0; i < sox_neffects; ++i) {
sox_effect_t * effp = &sox_effects[i][0];
- sox_report("effects chain: %-10s %uHz %u channels %s",
- effp->handler.name, effp->ininfo.rate, effp->ininfo.channels,
+ sox_report("effects chain: %-10s %uHz %u channels %u bits %s",
+ effp->handler.name, effp->ininfo.rate, effp->ininfo.channels, effp->ininfo.size * 8,
(effp->handler.flags & SOX_EFF_MCHAN)? "(multi)" : "");
}
}
+static void optimize_trim(void)
+{
+ /* Speed hack. If the "trim" effect is the first effect then
+ * peek inside its "effect descriptor" and see what the
+ * start location is. This has to be done after its start()
+ * is called to have the correct location.
+ * Also, only do this when only working with one input file.
+ * This is because the logic to do it for multiple files is
+ * complex and problably never used.
+ * This hack is a huge time savings when trimming
+ * gigs of audio data into managable chunks
+ */
+ if (input_count == 1 && sox_neffects > 1 && strcmp(sox_effects[1][0].handler.name, "trim") == 0) {
+ if ((files[0]->ft->handler->flags & SOX_FILE_SEEK) && files[0]->ft->seekable){
+ sox_size_t offset = sox_trim_get_start(&sox_effects[1][0]);
+ if (sox_seek(files[0]->ft, offset, SOX_SEEK_SET) != SOX_EOF) {
+ read_wide_samples = offset / files[0]->ft->signal.channels;
+ /* Assuming a failed seek stayed where it was. If the
+ * seek worked then reset the start location of
+ * trim so that it thinks user didn't request a skip.
+ */
+ sox_trim_clear_start(&sox_effects[1][0]);
+ }
+ }
+ }
+}
+
static void open_output_file(sox_size_t olen)
{
sox_loopinfo_t loops[SOX_MAX_NLOOPS];
@@ -1432,7 +1428,7 @@
static sox_size_t total_clips(void)
{
- unsigned i, f;
+ unsigned i;
sox_size_t clips = 0;
for (i = 0; i < file_count; ++i)
clips += files[i]->ft->clips + files[i]->volume_clips;
@@ -1595,7 +1591,6 @@
static void usage_effect(char *effect)
{
int i;
- const sox_effect_handler_t *e;
printf("%s: ", myname);
printf("v%s\n\n", PACKAGE_VERSION);
@@ -1603,14 +1598,10 @@
printf("Effect usage:\n\n");
for (i = 0; sox_effect_fns[i]; i++) {
- e = sox_effect_fns[i]();
- if (e && e->name && (!strcmp("all", effect) || !strcmp(e->name, effect))) {
- char *p = strstr(e->usage, "Usage: ");
- printf("%s\n\n", p ? p + 7 : e->usage);
+ const sox_effect_handler_t *e = sox_effect_fns[i]();
+ if (e && e->name && (!strcmp("all", effect) || !strcmp(e->name, effect))) {
+ printf("%s %s\n\n", e->name, e->usage? e->usage : "");
}
}
-
- if (!effect)
- printf("see --help-effect=effect for effopts ('all' for effopts of all effects)\n\n");
exit(1);
}
--- a/src/sox.h
+++ b/src/sox.h
@@ -81,10 +81,10 @@
* Format Minimum Minimum I O Maximum Maximum I O
* ------ --------- ------------ -- -- -------- ------------ -- --
* Float -1 -1.00000000047 y y 1 1 y n
- * Byte -128 -128 n n 127 127.9999999 n y
- * Word -32768 -32768 n n 32767 32767.99998 n y
- * 24bit -8388608 -8388608 n n 8388607 8388607.996 n y
- * Dword -2147483648 -2147483648 n n 2147483647 2147483647 n n
+ * Int8 -128 -128 n n 127 127.9999999 n y
+ * Int16 -32768 -32768 n n 32767 32767.99998 n y
+ * Int24 -8388608 -8388608 n n 8388607 8388607.996 n y
+ * Int32 -2147483648 -2147483648 n n 2147483647 2147483647 n n
*
* Conversions are as accurate as possible (with rounding).
*
@@ -401,10 +401,11 @@
#define SOX_EFF_CHAN 1 /* Effect can alter # of channels */
#define SOX_EFF_RATE 2 /* Effect can alter sample rate */
-#define SOX_EFF_LENGTH 4 /* Effect can alter audio length */
-#define SOX_EFF_MCHAN 8 /* Effect can handle multi-channel */
-#define SOX_EFF_NULL 16 /* Effect does nothing */
-#define SOX_EFF_DEPRECATED 32 /* Effect is living on borrowed time */
+#define SOX_EFF_PREC 4 /* Effect can alter sample precision */
+#define SOX_EFF_LENGTH 8 /* Effect can alter audio length */
+#define SOX_EFF_MCHAN 16 /* Effect can handle multi-channel */
+#define SOX_EFF_NULL 32 /* Effect does nothing */
+#define SOX_EFF_DEPRECATED 64 /* Effect is living on borrowed time */
typedef struct sox_effect sox_effect_t;
@@ -449,6 +450,8 @@
int sox_effect_set_imin(sox_effect_t * effp, sox_size_t imin);
int sox_add_effect(sox_effect_t * effp, sox_signalinfo_t * in, sox_signalinfo_t const * out);
int sox_flow_effects(int (* callback)(sox_bool all_done));
+sox_size_t sox_effects_clips(void);
+sox_size_t sox_stop_effect(sox_size_t e);
void sox_delete_effects(void);
char const * sox_parsesamples(sox_rate_t rate, const char *str, sox_size_t *samples, int def);
--- a/src/sox_i.h
+++ b/src/sox_i.h
@@ -124,6 +124,7 @@
#endif
sox_bool strcaseends(char const * str, char const * end);
+sox_bool strends(char const * str, char const * end);
#ifndef HAVE_STRDUP
char *strdup(const char *s);
@@ -291,6 +292,7 @@
*-----------------------------------------------------------------------------
*/
+int sox_usage(sox_effect_t * effp);
typedef const sox_effect_handler_t *(*sox_effect_fn_t)(void);
extern sox_effect_fn_t sox_effect_fns[];
#define EFFECT(f) extern sox_effect_handler_t const * sox_##f##_effect_fn(void);
--- a/src/speed.c
+++ b/src/speed.c
@@ -47,14 +47,13 @@
}
}
}
- sox_fail(effp->handler.usage);
- return SOX_EOF;
+ return sox_usage(effp);
}
sox_effect_handler_t const *sox_speed_effect_fn(void)
{
static sox_effect_handler_t handler = {
- "speed", "Usage: speed factor[c]", SOX_EFF_NULL|SOX_EFF_LENGTH,
+ "speed", "factor[c]", SOX_EFF_NULL|SOX_EFF_LENGTH,
getopts, 0, 0, 0, 0, 0};
return &handler;
}
--- a/src/stat.c
+++ b/src/stat.c
@@ -320,7 +320,7 @@
static sox_effect_handler_t sox_stat_effect = {
"stat",
- "Usage: [ -s N ] [ -rms ] [-freq] [ -v ] [ -d ]",
+ "[ -s N ] [ -rms ] [-freq] [ -v ] [ -d ]",
SOX_EFF_MCHAN,
sox_stat_getopts,
sox_stat_start,
--- a/src/stretch.c
+++ b/src/stretch.c
@@ -72,7 +72,6 @@
*/
static int sox_stretch_getopts(sox_effect_t * effp, int n, char **argv)
{
- char usage[1024];
stretch_t stretch = (stretch_t) effp->priv;
/* default options */
@@ -81,15 +80,13 @@
stretch->fade = sox_linear_fading;
if (n > 0 && !sscanf(argv[0], "%lf", &stretch->factor)) {
- sprintf(usage, "%s\n\terror while parsing factor", effp->handler.usage);
- sox_fail(usage);
- return SOX_EOF;
+ sox_fail("error while parsing factor");
+ return sox_usage(effp);
}
if (n > 1 && !sscanf(argv[1], "%lf", &stretch->window)) {
- sprintf(usage, "%s\n\terror while parsing window size", effp->handler.usage);
- sox_fail(usage);
- return SOX_EOF;
+ sox_fail("error while parsing window size");
+ return sox_usage(effp);
}
if (n > 2) {
@@ -99,9 +96,8 @@
stretch->fade = sox_linear_fading;
break;
default:
- sprintf (usage, "%s\n\terror while parsing fade type", effp->handler.usage);
- sox_fail(usage);
- return SOX_EOF;
+ sox_fail("error while parsing fade type");
+ return sox_usage(effp);
}
}
@@ -110,15 +106,13 @@
DEFAULT_FAST_SHIFT_RATIO: DEFAULT_SLOW_SHIFT_RATIO;
if (n > 3 && !sscanf(argv[3], "%lf", &stretch->shift)) {
- sprintf (usage, "%s\n\terror while parsing shift ratio", effp->handler.usage);
- sox_fail(usage);
- return SOX_EOF;
+ sox_fail("error while parsing shift ratio");
+ return sox_usage(effp);
}
if (stretch->shift > 1.0 || stretch->shift <= 0.0) {
- sprintf(usage, "%s\n\terror with shift ratio value", effp->handler.usage);
- sox_fail(usage);
- return SOX_EOF;
+ sox_fail("error with shift ratio value");
+ return sox_usage(effp);
}
/* default fading stuff...
@@ -131,15 +125,13 @@
stretch->fading = 0.5;
if (n > 4 && !sscanf(argv[4], "%lf", &stretch->fading)) {
- sprintf(usage, "%s\n\terror while parsing fading ratio", effp->handler.usage);
- sox_fail(usage);
- return SOX_EOF;
+ sox_fail("error while parsing fading ratio");
+ return sox_usage(effp);
}
if (stretch->fading > 0.5 || stretch->fading < 0.0) {
- sprintf(usage, "%s\n\terror with fading ratio value", effp->handler.usage);
- sox_fail(usage);
- return SOX_EOF;
+ sox_fail("error with fading ratio value");
+ return sox_usage(effp);
}
return SOX_SUCCESS;
@@ -156,19 +148,6 @@
if (stretch->factor == 1)
return SOX_EFF_NULL;
- /* FIXME: not necessary. taken care by effect processing? */
- if (effp->outinfo.channels != effp->ininfo.channels) {
- sox_fail("stretch 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("stretch cannot handle different rates (in=%ld, out=%ld)"
- " use resample or rate", effp->ininfo.rate, effp->outinfo.rate);
- return SOX_EOF;
- }
-
stretch->state = input_state;
stretch->size = (int)(effp->outinfo.rate * 0.001 * stretch->window);
@@ -356,7 +335,7 @@
static sox_effect_handler_t sox_stretch_effect = {
"stretch",
- "Usage: stretch factor [window fade shift fading]\n"
+ "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,
--- a/src/swap.c
+++ b/src/swap.c
@@ -33,10 +33,7 @@
{
swap->def_opts = 0;
if (n != 2 && n != 4)
- {
- sox_fail(effp->handler.usage);
- return (SOX_EOF);
- }
+ return sox_usage(effp);
else if (n == 2)
{
sscanf(argv[0],"%d",&swap->order[0]);
@@ -183,7 +180,7 @@
static sox_effect_handler_t sox_swap_effect = {
"swap",
- "Usage: swap [1 2 | 1 2 3 4]",
+ "[1 2 | 1 2 3 4]",
SOX_EFF_MCHAN,
sox_swap_getopts,
sox_swap_start,
--- a/src/synth.c
+++ b/src/synth.c
@@ -290,10 +290,8 @@
synth->length_str = xmalloc(strlen(argv[argn]) + 1);
strcpy(synth->length_str, argv[argn]);
/* Do a dummy parse of to see if it will fail */
- if (sox_parsesamples(0, synth->length_str, &synth->samples_to_do, 't') == NULL) {
- sox_fail(effp->handler.usage);
- return SOX_EOF;
- }
+ if (sox_parsesamples(0, synth->length_str, &synth->samples_to_do, 't') == NULL)
+ return sox_usage(effp);
argn++;
}
@@ -392,10 +390,8 @@
synth->samples_done = 0;
if (synth->length_str)
- if (sox_parsesamples(effp->ininfo.rate, synth->length_str, &synth->samples_to_do, 't') == NULL) {
- sox_fail(effp->handler.usage);
- return SOX_EOF;
- }
+ if (sox_parsesamples(effp->ininfo.rate, synth->length_str, &synth->samples_to_do, 't') == NULL)
+ return sox_usage(effp);
synth->number_of_channels = effp->ininfo.channels;
synth->channels = xcalloc(synth->number_of_channels, sizeof(*synth->channels));
@@ -600,8 +596,8 @@
{
static sox_effect_handler_t handler = {
"synth",
- "Usage: synth [len] {type [combine] [freq[-freq2] [off [ph [p1 [p2 [p3]]]]]]}",
- SOX_EFF_MCHAN, getopts, start, flow, 0, stop, kill
+ "[len] {type [combine] [freq[-freq2] [off [ph [p1 [p2 [p3]]]]]]}",
+ SOX_EFF_MCHAN | SOX_EFF_PREC, getopts, start, flow, 0, stop, kill
};
return &handler;
}
--- a/src/tremolo.c
+++ b/src/tremolo.c
@@ -28,10 +28,8 @@
if (n < 1 || n > 2 ||
sscanf(argv[0], "%lf %c", &speed, &dummy) != 1 || speed < 0 ||
(n > 1 && sscanf(argv[1], "%lf %c", &depth, &dummy) != 1) ||
- depth <= 0 || depth > 100) {
- sox_fail(effp->handler.usage);
- return SOX_EOF;
- }
+ depth <= 0 || depth > 100)
+ return sox_usage(effp);
args[2] = argv[0];
sprintf(offset, "%g", 100 - depth / 2);
args[3] = offset;
@@ -43,7 +41,7 @@
static sox_effect_handler_t handler;
handler = *sox_synth_effect_fn();
handler.name = "tremolo";
- handler.usage = "Usage: tremolo speed_Hz [depth_percent]";
+ handler.usage = "speed_Hz [depth_percent]";
handler.getopts = getopts;
return &handler;
}
--- a/src/trim.c
+++ b/src/trim.c
@@ -40,24 +40,16 @@
strcpy(trim->length_str,argv[1]);
/* Do a dummy parse to see if it will fail */
if (sox_parsesamples(0, trim->length_str, &trim->length, 't') == NULL)
- {
- sox_fail(effp->handler.usage);
- return(SOX_EOF);
- }
+ return sox_usage(effp);
case 1:
trim->start_str = (char *)xmalloc(strlen(argv[0])+1);
strcpy(trim->start_str,argv[0]);
/* Do a dummy parse to see if it will fail */
if (sox_parsesamples(0, trim->start_str, &trim->start, 't') == NULL)
- {
- sox_fail(effp->handler.usage);
- return(SOX_EOF);
- }
+ return sox_usage(effp);
break;
default:
- sox_fail(effp->handler.usage);
- return SOX_EOF;
- break;
+ return sox_usage(effp);
}
return (SOX_SUCCESS);
@@ -72,10 +64,7 @@
if (sox_parsesamples(effp->ininfo.rate, trim->start_str,
&trim->start, 't') == NULL)
- {
- sox_fail(effp->handler.usage);
- return(SOX_EOF);
- }
+ return sox_usage(effp);
/* Account for # of channels */
trim->start *= effp->ininfo.channels;
@@ -83,10 +72,7 @@
{
if (sox_parsesamples(effp->ininfo.rate, trim->length_str,
&trim->length, 't') == NULL)
- {
- sox_fail(effp->handler.usage);
- return(SOX_EOF);
- }
+ return sox_usage(effp);
}
else
trim->length = 0;
@@ -185,7 +171,7 @@
static sox_effect_handler_t sox_trim_effect = {
"trim",
- "Usage: trim start [length]",
+ "start [length]",
SOX_EFF_MCHAN|SOX_EFF_LENGTH,
sox_trim_getopts,
sox_trim_start,
--- a/src/vibro.c
+++ b/src/vibro.c
@@ -28,10 +28,8 @@
if (n < 1 || n > 2 ||
sscanf(argv[0], "%lf %c", &speed, &dummy) != 1 || speed < 0 ||
(n > 1 && sscanf(argv[1], "%lf %c", &depth, &dummy) != 1) ||
- depth <= 0 || depth > 1) {
- sox_fail(effp->handler.usage);
- return SOX_EOF;
- }
+ depth <= 0 || depth > 1)
+ return sox_usage(effp);
args[2] = argv[0];
sprintf(offset, "%g", 100 - 50 * depth);
args[3] = offset;
@@ -43,7 +41,7 @@
static sox_effect_handler_t handler;
handler = *sox_synth_effect_fn();
handler.name = "vibro";
- handler.usage = "Usage: vibro speed [depth]";
+ handler.usage = "speed [depth]";
handler.getopts = getopts;
handler.flags |= SOX_EFF_DEPRECATED;
return &handler;
--- a/src/vol.c
+++ b/src/vol.c
@@ -8,7 +8,7 @@
* FIXME: deprecate or remove the limiter in favour of compand.
*/
#define vol_usage \
- "Usage: vol GAIN [TYPE [LIMITERGAIN]]\n" \
+ "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" \
@@ -51,10 +51,8 @@
vol->uselimiter = sox_false; /* Default is no limiter. */
/* 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->handler.usage);
- return SOX_EOF;
- }
+ if (!argc || (have_type = sscanf(argv[0], "%lf %10s %c", &vol->gain, type_string, &dummy) - 1) > 1)
+ return sox_usage(effp);
++argv, --argc;
/* No type yet? Get it from the next arg: */
@@ -66,10 +64,8 @@
if (have_type) {
enum_item const * p = find_enum_text(type_ptr, vol_types);
- if (!p) {
- sox_fail(effp->handler.usage);
- return SOX_EOF;
- }
+ if (!p)
+ return sox_usage(effp);
switch (p->value) {
case vol_dB: vol->gain = exp(vol->gain*LOG_10_20); break;
case vol_power: /* power to amplitude, keep phase change */
@@ -79,10 +75,8 @@
}
if (argc) {
- if (fabs(vol->gain) < 1 || sscanf(*argv, "%lf %c", &vol->limitergain, &dummy) != 1 || vol->limitergain <= 0 || vol->limitergain >= 1) {
- sox_fail(effp->handler.usage);
- return SOX_EOF;
- }
+ if (fabs(vol->gain) < 1 || sscanf(*argv, "%lf %c", &vol->limitergain, &dummy) != 1 || vol->limitergain <= 0 || vol->limitergain >= 1)
+ return sox_usage(effp);
vol->uselimiter = sox_true;
/* The following equation is derived so that there is no