ref: 615fa4b79b233395393258f0c0893b6c19ad263f
parent: 3466e693fbb673e9c446acf8027086be378d905c
author: cbagwell <cbagwell>
date: Sat Sep 13 21:47:01 EDT 2008
Add support for specifying effects with a text file instead of command line.
--- a/ChangeLog
+++ b/ChangeLog
@@ -45,6 +45,8 @@
o New -b option for the norm effect; can be used to fix stereo
imbalance. (robs)
o Fix broken audio pass-through with noiseprof effect. (robs)
+ o New --effects-file option to read effects and arguments from
+ a file instead of command line. (cbagwell)
Other new features:
--- a/sox.1
+++ b/sox.1
@@ -560,6 +560,26 @@
Show information about the specified file format. The name
\fBall\fR can be used to show information on all formats.
.TP
+\fB\-\-buffer\fR \fBBYTES\fR, \fB\-\-input\-buffer\fR \fBBYTES\fR
+Set the size in bytes of the buffers used for processing audio (default 8192).
+.B \-\-buffer
+applies to input, effects, and output processing;
+.B \-\-input\-buffer
+applies only to input processing (for which it overrides
+.B \-\-buffer
+if both are given).
+.SP
+Be aware that large values for
+.B \-\-buffer
+will cause SoX to be become slow to respond to requests to terminate or to skip
+the current input file.
+.TP
+\fB\-\--effects\-file=\fIFILENAME\fR
+Specify a file containing the effects and their arguments to be used.
+Only the first line of the file is read and its format should be the same as when specifying effects on the command line.
+Each time a new input or output file is opened, the effects file
+is reread for latest values.
+.TP
\fB\-\-interactive\fR
Prompt before overwriting an existing file with the same name as that
given for the output file.
@@ -578,20 +598,6 @@
option is strongly recommended; a `shell' alias, script, or batch file
may be an appropriate way of permanently enabling it.
.TP
-\fB\-\-buffer\fR \fBBYTES\fR, \fB\-\-input\-buffer\fR \fBBYTES\fR
-Set the size in bytes of the buffers used for processing audio (default 8192).
-.B \-\-buffer
-applies to input, effects, and output processing;
-.B \-\-input\-buffer
-applies only to input processing (for which it overrides
-.B \-\-buffer
-if both are given).
-.SP
-Be aware that large values for
-.B \-\-buffer
-will cause SoX to be become slow to respond to requests to terminate or to skip
-the current input file.
-.TP
\fB\-m\fR\^|\^\fB\-M\fR\^|\^\fB\-\-combine concatenate\fR\^|\^\fBmerge\fR\^|\^\fBmix\fR\^|\^\fBmix\-power\fR\^|\^\fBsequence\fR
Select the input file combining method;
.B \-m
@@ -601,6 +607,11 @@
.SP
See \fBInput File Combining\fR above for a description of the different
combining methods.
+.TP
+\fB\-\-output single\fR\^|\^\fBmultiple\fR
+Select single or multiple output file mode.
+See \fBOutput Files\fR above for a description of the different
+output modes.
.TP
\fB\-\-plot gnuplot\fR\^|\^\fBoctave\fR\^|\^\fBoff\fR
If not set to
--- a/src/sox.c
+++ b/src/sox.c
@@ -134,8 +134,9 @@
static sox_effect_t *user_efftab[MAX_USER_EFF];
static unsigned nuser_effects;
static sox_effects_chain_t *effects_chain = NULL;
+static char *effects_filename = NULL;
+static void parse_effects(int argc, char **argv);
-
/* Flowing */
static sox_signalinfo_t combiner_signal, ofile_signal_options;
@@ -564,6 +565,122 @@
exit(2); /* The effects chain should have displayed an error message */
}
+static void delete_user_effects(void)
+{
+ unsigned i;
+ int j;
+
+ for (i = 0; i < nuser_effects; i++)
+ {
+ if (user_effargs[i].name)
+ free(user_effargs[i].name);
+ user_effargs[i].name = NULL;
+ for (j = 0; j < user_effargs[i].argc; j++)
+ {
+ if (user_effargs[i].argv[j])
+ free(user_effargs[i].argv[j]);
+ user_effargs[i].argv[i] = NULL;
+ }
+ user_effargs[i].argc = 0;
+ }
+ nuser_effects = 0;
+} /* delete_user_effects */
+
+static int strtoargv(char *s, char *(*argv)[])
+{
+ int argc = 0;
+
+ if (!s) return 0;
+
+ while (*s)
+ {
+ int quote_mode;
+
+ /* Skip past any white space */
+ while (*s == ' ' || *s == '\t')
+ s++;
+
+ /* Stop processing if no more data */
+ if (!*s)
+ break;
+
+ /* If starts with quote then start quote mode. This
+ * will ignore seperators until a final quote is seen.
+ * Don't put quote into the argument.
+ */
+ if (*s == '"')
+ {
+ quote_mode = 1;
+ s++;
+ }
+ else
+ quote_mode = 0;
+
+ (*argv)[argc] = s;
+
+ /* Scan for seperator and when overwrite with 0 */
+ while (*s)
+ {
+ /* Treat quote as final seperator; even if there is
+ * more data right after it.
+ * TODO: Process \" and \\ so that user can
+ * have quotes inside quotes. Tricky to do though.
+ */
+ if (quote_mode && *s == '"')
+ break;
+
+ if (!quote_mode && (*s == ' ' || *s == '\t'))
+ break;
+ s++;
+ }
+ *s = 0;
+ s++;
+ argc += 1;
+ }
+
+ return argc;
+} /* strtoargv */
+
+static void read_user_effects(char *filename)
+{
+ FILE *file = fopen(filename, "rt");
+ char s[1025];
+ int argc;
+ char *argv[256];
+ int len;
+
+ delete_user_effects();
+
+ if (file == NULL)
+ {
+ sox_fail("Cannot open effects file %s", filename);
+ exit(1);
+ }
+
+ sox_report("Reading effects from file %s", filename);
+
+ if (fgets(s, 1024, file) == NULL)
+ {
+ sox_fail("Error reading effects file %s", filename);
+ exit(2);
+ }
+ len = strlen(s);
+ if (s[len-1] == '\n')
+ s[len-1] = 0;
+
+ argc = strtoargv(s, &argv);
+
+ /* parse_effects normally parses options from command line.
+ * Reset opt index so it thinks its back at beginning of
+ * main()'s argv[].
+ */
+ optind = 0;
+ parse_effects(argc, argv);
+
+ fclose(file);
+
+} /* read_user_effects */
+
/* Creates users effects and passes in user specified options.
* This is done without putting anything into the effects chain
* because an effect may set the effp->in_format and we may want
@@ -580,6 +697,16 @@
unsigned i;
sox_effect_t *effp;
+ /* If user specified an effects filename then use that file
+ * to load user effects. Free any previously specified options
+ * from the command line. This also means that effects will
+ * be reloaded each time a new input or output file is opened.
+ */
+ if (effects_filename)
+ {
+ read_user_effects(effects_filename);
+ }
+
for (i = 0; i < nuser_effects; i++)
{
effp = sox_create_effect(sox_find_effect(user_effargs[i].name));
@@ -1200,6 +1327,7 @@
"--buffer BYTES set the size of all processing buffers (default 8192)",
"--combine concatenate concatenate multiple input files (default for sox, rec)",
"--combine sequence sequence multiple input files (default for play)",
+"--effects-file FILENAME file containing effects and options",
"-h, --help display version number and usage information",
"--help-effect NAME display usage of specified effect; use `all' to display all",
"--help-format NAME display info on specified format; use `all' to display all",
@@ -1408,6 +1536,7 @@
{"replay-gain" , required_argument, NULL, 0},
{"version" , no_argument, NULL, 0},
{"output" , required_argument, NULL, 0},
+ {"effects-file" , required_argument, NULL, 0},
{"channels" , required_argument, NULL, 'c'},
{"compression" , required_argument, NULL, 'C'},
@@ -1558,6 +1687,11 @@
case 13:
output_method = enum_option(option_index, output_methods);
break;
+
+ case 14:
+ effects_filename = strdup(optarg);
+ break;
+
}
break;
@@ -2029,6 +2163,7 @@
else process();
sox_delete_effects_chain(effects_chain);
+ delete_user_effects();
for (i = 0; i < file_count; ++i)
if (files[i]->ft->clips != 0)