ref: 91033aaa79f6a103dea8c72e31966354f8f573b2
parent: 6d17ce4e3707629ec730368569aa2af1223b73ac
author: robs <robs>
date: Mon Jan 22 18:08:09 EST 2007
Apply input file replay-gain.
--- a/ChangeLog
+++ b/ChangeLog
@@ -63,8 +63,9 @@
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.
- o Improved synth usage (by introducing --) and improved the synth
- entry in the man-page. (robs)
+ o Improved synth usage and improved the synth entry in the man-
+ page. (robs)
+ o sox man-page overhaul, new soxexam man-page entries. (robs)
o Added command line options for specifying the output file
comment. (robs)
o Improved the accuracy of integer and floating point PCM
@@ -94,6 +95,9 @@
o Build system overhaul to use the full set of GNU autotools.
(Reuben Thomas)
o New file formats via libsndfile. (Reuben Thomas)
+ o Display (auto-)selected effects with -V. (robs)
+ o Options to apply replay-gain on input; enabled by default
+ with `play'. (robs)
sox-12.18.2
-----------
--- a/sox.1
+++ b/sox.1
@@ -412,6 +412,24 @@
\fB\-q\fR, \fB\-\-no\-show\-progress\fR
Run in quiet mode when SoX wouldn't otherwise do so;
this is the converse of the \fB\-S\fR option.
+.PP
+\fB\-\-replay\-gain=track\fR
+.br
+\fB\-\-replay\-gain=album\fR
+.br
+\fB\-\-replay\-gain=off\fR
+.if t .sp -.5
+.if n .sp -1
+.TP
+\
+Select whether or not to apply replay-gain adjustment to input files.
+The default is
+.B track
+for
+.B play
+and
+.B off
+otherwise.
.TP
\fB\-S\fR, \fB\-\-show\-progress\fR
Display input file format/header information and input file(s)
--- a/src/sox.c
+++ b/src/sox.c
@@ -61,6 +61,8 @@
static st_bool interactive = st_false;
static st_globalinfo_t globalinfo = {st_false, 1};
static st_bool uservolume = st_false;
+typedef enum {RG_OFF, RG_TRACK, RG_ALBUM} rg_t;
+static rg_t replay_gain_mode;
static int user_abort = 0;
static int success = 0;
@@ -81,6 +83,7 @@
char *filetype;
st_signalinfo_t signal;
double volume;
+ double replay_gain;
char *comment;
st_size_t volume_clips;
} *file_info_t;
@@ -217,6 +220,7 @@
fi->signal.reverse_bits = ST_OPTION_DEFAULT;
fi->signal.compression = HUGE_VAL;
fi->volume = HUGE_VAL;
+ fi->replay_gain = HUGE_VAL;
fi->volume_clips = 0;
return fi;
@@ -237,6 +241,27 @@
#endif
}
+static void set_replay_gain(char const * comment, file_info_t fi)
+{
+ rg_t rg = replay_gain_mode;
+ int try = 2;
+
+ if (rg != RG_OFF) while (try--) {
+ char const * p = comment;
+ char const * target =
+ rg == RG_TRACK? "REPLAYGAIN_TRACK_GAIN=" : "REPLAYGAIN_ALBUM_GAIN=";
+ do {
+ if (strncasecmp(p, target, strlen(target)) == 0) {
+ fi->replay_gain = atof(p + strlen(target));
+ return;
+ }
+ while (*p && *p!= '\n') ++p;
+ while (*p && strchr("\r\n\t\f ", *p)) ++p;
+ } while (*p);
+ rg ^= RG_TRACK ^ RG_ALBUM;
+ }
+}
+
int main(int argc, char **argv)
{
size_t i;
@@ -251,6 +276,7 @@
if (i >= sizeof("play") - 1 &&
strcmp(myname + i - (sizeof("play") - 1), "play") == 0) {
play = st_true;
+ replay_gain_mode = RG_TRACK;
} else if (i >= sizeof("rec") - 1 &&
strcmp(myname + i - (sizeof("rec") - 1), "rec") == 0) {
rec = st_true;
@@ -339,7 +365,7 @@
* make sure no clipping will occur. Users probably won't be happy with
* this, and will override it, possibly causing clipping to occur. */
if (combine_method == SOX_MIX && !uservolume)
- file_opts[j]->volume = 1.0 / input_count;
+ fi->volume = 1.0 / input_count;
if (rec && !j) { /* Set the recording sample rate & # of channels: */
if (input_count > 1) { /* Get them from the next input file: */
@@ -360,6 +386,8 @@
(file_desc[j]->h->flags & ST_FILE_DEVICE) != 0 &&
(file_desc[j]->h->flags & ST_FILE_PHONY) == 0)
show_progress = ST_OPTION_YES;
+ if (file_desc[j]->comment)
+ set_replay_gain(file_desc[j]->comment, fi);
}
/* Loop through the rest of the arguments looking for effects */
@@ -439,6 +467,7 @@
{"help-effect" , required_argument, NULL, 0},
{"lua-script" , required_argument, NULL, 0},
{"octave" , no_argument, NULL, 0},
+ {"replay-gain" , required_argument, NULL, 0},
{"version" , no_argument, NULL, 0},
{"channels" , required_argument, NULL, 'c'},
@@ -508,6 +537,19 @@
break;
case 7:
+ if (!strcmp(optarg, "track"))
+ replay_gain_mode = RG_TRACK;
+ else if (!strcmp(optarg, "album"))
+ replay_gain_mode = RG_ALBUM;
+ else if (!strcmp(optarg, "off"))
+ replay_gain_mode = RG_OFF;
+ else {
+ st_fail("Replay gain '%s' is not track|album|off", optarg);
+ exit(1);
+ }
+ break;
+
+ case 8:
printf("%s: v%s\n", myname, st_version());
exit(0);
break;
@@ -622,9 +664,11 @@
}
}
-static void display_file_info(ft_t f, double volume, double speed, st_bool full)
+static void display_file_info(int file_no, double speed, st_bool full)
{
static char const * const no_yes[] = {"no", "yes"};
+ ft_t f = file_desc[file_no];
+ file_info_t fo = file_opts[file_no];
fprintf(stderr, "\n%s: '%s'",
f->mode == 'r'? "Input File " : "Output File ", f->filename);
@@ -651,8 +695,10 @@
no_yes[f->signal.reverse_nibbles],
no_yes[f->signal.reverse_bits]);
- if (volume != HUGE_VAL && volume != 1)
- fprintf(stderr, "Level adjust : %g (linear gain)\n" , volume);
+ if (fo->replay_gain != HUGE_VAL)
+ fprintf(stderr, "Replay gain : %+g dB\n" , fo->replay_gain);
+ if (fo->volume != HUGE_VAL)
+ fprintf(stderr, "Level adjust : %g (linear gain)\n" , fo->volume);
if (!(f->h->flags & ST_FILE_DEVICE) && f->comment) {
if (strchr(f->comment, '\n'))
@@ -663,17 +709,21 @@
fprintf(stderr, "\n");
}
-static void report_file_info(ft_t f, double volume)
+static void report_file_info(int f)
{
if (st_output_verbosity_level > 2)
- display_file_info(f, volume, 1, st_true);
+ display_file_info(f, 1, st_true);
}
-static void show_file_progress(int f)
+static void progress_to_file(int f)
{
if (show_progress && (st_output_verbosity_level < 3 ||
(combine_method == SOX_CONCAT && input_count > 1)))
- display_file_info(file_desc[f], 1, globalinfo.speed, st_false);
+ display_file_info(f, globalinfo.speed, st_false);
+ if (file_opts[f]->volume == HUGE_VAL)
+ file_opts[f]->volume = 1;
+ if (file_opts[f]->replay_gain != HUGE_VAL)
+ file_opts[f]->volume *= pow(10, file_opts[f]->replay_gain / 20);
}
/*
@@ -688,7 +738,7 @@
st_sample_t *ibuf[MAX_INPUT_FILES];
for (f = 0; f < input_count; f++) { /* Report all inputs first, then check */
- report_file_info(file_desc[f], file_opts[f]->volume);
+ report_file_info(f);
if (combine_method == SOX_MERGE)
file_desc[f]->signal.channels *= input_count;
}
@@ -755,7 +805,7 @@
show_progress = (ofile->h->flags & ST_FILE_DEVICE) != 0 &&
(ofile->h->flags & ST_FILE_PHONY) == 0;
- report_file_info(ofile, 1);
+ report_file_info(file_count - 1);
}
/* Adjust the input rate for the speed effect */
@@ -786,12 +836,12 @@
file_desc[f]->signal.channels /= input_count;
}
ibuf[f] = (st_sample_t *)xmalloc(alloc_size);
- show_file_progress(f);
+ progress_to_file(f);
}
} else {
current_input = 0;
input_samples = file_desc[current_input]->length;
- show_file_progress(current_input);
+ progress_to_file(current_input);
}
/*
@@ -840,7 +890,7 @@
current_input++;
input_samples = file_desc[current_input]->length;
read_samples = 0;
- show_file_progress(current_input);
+ progress_to_file(current_input);
continue;
}
}
@@ -1512,7 +1562,7 @@
/* Adjust volume based on value specified by the -v option for this file. */
static void volumechange(st_sample_t * buf, st_ssize_t len, file_info_t fi)
{
- if (fi->volume != HUGE_VAL && fi->volume != 1)
+ if (fi->volume != 1)
while (len--) {
double d = fi->volume * *buf;
*buf++ = ST_ROUND_CLIP_COUNT(d, fi->volume_clips);
@@ -1548,6 +1598,7 @@
"-M, --merge merge multiple input files (instead of concatenating)\n"
"--octave generate Octave commands to plot response of filter effect\n"
"-q, --quiet run in quiet mode; opposite of -S\n"
+ "--replay-gain track|album|off default: off (sox, rec), track (play)\n"
"-R use default random numbers (same on each run of SoX)\n"
"-S, --show-progress display progress while processing audio data\n"
"--version display version number of SoX and exit\n"
@@ -1566,6 +1617,7 @@
"-C compression compression factor for variably compressing output formats\n"
"--comment text Specify comment text for the output file\n"
"--comment-file filename file containing comment text for the output file\n"
+ "--endian little|big|swap set endianness; swap means opposite to default\n"
"--lua-script filename file containing script for a `lua' format\n"
"-r, --rate rate sample rate of audio\n"
"-t, --type filetype file type of audio\n"