ref: 38f21528d72f4fc3f5408fcd5104190d1d4e588c
parent: 2423ba7e9e5941c6e4549e27f2d7c9a6d2e7da23
author: robs <robs>
date: Sun Feb 17 15:33:21 EST 2008
heuristic to set album replay-gain mode
--- a/ChangeLog
+++ b/ChangeLog
@@ -38,6 +38,8 @@
o Added soxi utility to extract/display file header fields. (robs)
o Added pkg-config support. (Pascal Giard)
o Added simple V.U. meter. (robs)
+ o Added simple heuristic to detect when playing an album and set
+ the default replay-gain mode to `album'. (robs)
Bug fixes:
--- a/sox.1
+++ b/sox.1
@@ -542,11 +542,19 @@
\fB\-\-replay\-gain track\fR\^|\^\fBalbum\fR\^|\^\fBoff\fR
Select whether or not to apply replay-gain adjustment to input files.
The default is
+.B off
+for
+.B sox
+and
+.BR rec ,
+.B album
+for
+.B play
+where (at least) the first two input files are tagged with the same Artist and
+Album names, and
.B track
for
.B play
-and
-.B off
otherwise.
.TP
\fB\-S\fR, \fB\-\-show\-progress\fR
--- a/src/sox.c
+++ b/src/sox.c
@@ -76,6 +76,11 @@
static sox_bool interactive = sox_false;
static sox_bool uservolume = sox_false;
typedef enum {RG_off, RG_track, RG_album} rg_mode;
+static enum_item const rg_modes[] = {
+ ENUM_ITEM(RG_,off)
+ ENUM_ITEM(RG_,track)
+ ENUM_ITEM(RG_,album)
+ {0, 0}};
static rg_mode replay_gain_mode = RG_off;
static sox_option_t show_progress = SOX_OPTION_DEFAULT;
@@ -91,6 +96,7 @@
sox_signalinfo_t signal;
double volume;
double replay_gain;
+ rg_mode replay_gain_mode;
comments_t comments;
sox_format_t * ft; /* libSoX file descriptor */
@@ -227,7 +233,8 @@
}
if (f && f->replay_gain != HUGE_VAL)
- fprintf(output, "Replay gain : %+g dB\n" , f->replay_gain);
+ fprintf(output, "Replay gain : %+g dB (%s)\n" , f->replay_gain,
+ find_enum_value(f->replay_gain_mode, rg_modes)->text);
if (f && f->volume != HUGE_VAL)
fprintf(output, "Level adjust : %g (linear gain)\n" , f->volume);
@@ -1035,12 +1042,6 @@
ENUM_ITEM(sox_,merge)
{0, 0}};
-static enum_item const rg_modes[] = {
- ENUM_ITEM(RG_,off)
- ENUM_ITEM(RG_,track)
- ENUM_ITEM(RG_,album)
- {0, 0}};
-
enum {ENDIAN_little, ENDIAN_big, ENDIAN_swap};
static enum_item const endian_options[] = {
ENUM_ITEM(ENDIAN_,little)
@@ -1422,6 +1423,7 @@
for (i = 0; i < n; ++i) {
if (strncasecmp(comments[i], target, strlen(target)) == 0) {
f->replay_gain = atof(comments[i] + strlen(target));
+ f->replay_gain_mode = rg;
return;
}
}
@@ -1438,6 +1440,11 @@
}
}
+static sox_bool cmp_comment_text(char const * c1, char const * c2)
+{
+ return c1 && c2 && !strcasecmp(c1, c2);
+}
+
int main(int argc, char **argv)
{
size_t i;
@@ -1508,8 +1515,19 @@
(files[j]->ft->handler->flags & SOX_FILE_DEVICE) != 0 &&
(files[j]->ft->handler->flags & SOX_FILE_PHONY) == 0)
show_progress = SOX_OPTION_YES;
- set_replay_gain(files[j]->ft->comments, f);
}
+ /* Simple heuristic to determine if replay-gain should be in album mode */
+ if (sox_mode == sox_play && replay_gain_mode == RG_track && input_count > 1 &&
+ cmp_comment_text(
+ find_comment(files[0]->ft->comments, "artist"),
+ find_comment(files[1]->ft->comments, "artist")) &&
+ cmp_comment_text(
+ find_comment(files[0]->ft->comments, "album"),
+ find_comment(files[1]->ft->comments, "album")))
+ replay_gain_mode = RG_album;
+
+ for (i = 0; i < input_count; i++)
+ set_replay_gain(files[i]->ft->comments, files[i]);
signal(SIGINT, SIG_DFL);
/* Loop through the rest of the arguments looking for effects */
--- a/src/sox_i.h
+++ b/src/sox_i.h
@@ -239,6 +239,7 @@
comments_t copy_comments(comments_t comments);
void delete_comments(comments_t * comments);
char * cat_comments(comments_t comments);
+char const * find_comment(comments_t comments, char const * id);
--- a/src/util.c
+++ b/src/util.c
@@ -221,3 +221,13 @@
}
return result;
}
+
+char const * find_comment(comments_t comments, char const * id)
+{
+ size_t len = strlen(id);
+
+ if (comments) for (;*comments; ++comments)
+ if (!strncasecmp(*comments, id, len) && (*comments)[len] == '=')
+ return *comments + len + 1;
+ return NULL;
+}