diff --git a/doc/html/changelog.html b/doc/html/changelog.html
index d154b2cc..9d4db2b3 100644
--- a/doc/html/changelog.html
+++ b/doc/html/changelog.html
@@ -101,6 +101,7 @@
plugins:
+ - When ReplayGain is on, if tags for the preferred kind of gain (album/track) are not in a stream, the other kind will be used.
- Fixed UTF-8 decoder to disallow non-shortest-form and surrogate sequences (see here).
diff --git a/doc/html/documentation.html b/doc/html/documentation.html
index 384e6a7c..6b807d47 100644
--- a/doc/html/documentation.html
+++ b/doc/html/documentation.html
@@ -457,7 +457,7 @@
a|t
- Specify 'a' to use the album gain, or 't' to use the track gain
+ Specify 'a' to use the album gain, or 't' to use the track gain. If tags for the preferred kind (album/track) do not exist but tags for the other (track/album) do, those will be used instead.
l|L
diff --git a/include/share/grabbag/replaygain.h b/include/share/grabbag/replaygain.h
index e8af2d01..ac845fca 100644
--- a/include/share/grabbag/replaygain.h
+++ b/include/share/grabbag/replaygain.h
@@ -59,7 +59,7 @@ const char *grabbag__replaygain_store_to_file(const char *filename, float album_
const char *grabbag__replaygain_store_to_file_album(const char *filename, float album_gain, float album_peak, FLAC__bool preserve_modtime);
const char *grabbag__replaygain_store_to_file_title(const char *filename, float title_gain, float title_peak, FLAC__bool preserve_modtime);
-FLAC__bool grabbag__replaygain_load_from_vorbiscomment(const FLAC__StreamMetadata *block, FLAC__bool album_mode, double *gain, double *peak);
+FLAC__bool grabbag__replaygain_load_from_vorbiscomment(const FLAC__StreamMetadata *block, FLAC__bool album_mode, FLAC__bool strict, double *gain, double *peak);
double grabbag__replaygain_compute_scale_factor(double peak, double gain, double preamp, FLAC__bool prevent_clipping);
#ifdef __cplusplus
diff --git a/src/flac/decode.c b/src/flac/decode.c
index e582de3a..2296db25 100644
--- a/src/flac/decode.c
+++ b/src/flac/decode.c
@@ -1106,8 +1106,8 @@ void metadata_callback(const void *decoder, const FLAC__StreamMetadata *metadata
else if(metadata->type == FLAC__METADATA_TYPE_VORBIS_COMMENT) {
if (decoder_session->replaygain.spec.apply) {
double gain, peak;
- if (!(decoder_session->replaygain.apply = grabbag__replaygain_load_from_vorbiscomment(metadata, decoder_session->replaygain.spec.use_album_gain, &gain, &peak))) {
- flac__utils_printf(stderr, 1, "%s: WARNING: can't get %s ReplayGain tag\n", decoder_session->inbasefilename, decoder_session->replaygain.spec.use_album_gain? "album":"track");
+ if (!(decoder_session->replaygain.apply = grabbag__replaygain_load_from_vorbiscomment(metadata, decoder_session->replaygain.spec.use_album_gain, /*strict=*/false, &gain, &peak))) {
+ flac__utils_printf(stderr, 1, "%s: WARNING: can't get %s (or even %s) ReplayGain tags\n", decoder_session->inbasefilename, decoder_session->replaygain.spec.use_album_gain? "album":"track", decoder_session->replaygain.spec.use_album_gain? "track":"album");
}
else {
const char *ls[] = { "no", "peak", "hard" };
diff --git a/src/plugin_winamp2/playback.c b/src/plugin_winamp2/playback.c
index 9648c340..6f23386d 100644
--- a/src/plugin_winamp2/playback.c
+++ b/src/plugin_winamp2/playback.c
@@ -77,7 +77,7 @@ static void metadata_callback(const FLAC__FileDecoder *decoder, const FLAC__Stre
else if (metadata->type == FLAC__METADATA_TYPE_VORBIS_COMMENT)
{
double gain, peak;
- if (grabbag__replaygain_load_from_vorbiscomment(metadata, cfg.replaygain.album_mode, &gain, &peak))
+ if (grabbag__replaygain_load_from_vorbiscomment(metadata, cfg.replaygain.album_mode, /*strict=*/false, &gain, &peak))
{
file_info->has_replaygain = true;
file_info->replay_scale = grabbag__replaygain_compute_scale_factor(peak, gain, (double)cfg.replaygain.preamp, !cfg.replaygain.hard_limit);
diff --git a/src/plugin_xmms/plugin.c b/src/plugin_xmms/plugin.c
index 73257858..343038ec 100644
--- a/src/plugin_xmms/plugin.c
+++ b/src/plugin_xmms/plugin.c
@@ -798,7 +798,7 @@ void metadata_callback_(const void *decoder, const FLAC__StreamMetadata *metadat
}
else if(metadata->type == FLAC__METADATA_TYPE_VORBIS_COMMENT) {
double gain, peak;
- if(grabbag__replaygain_load_from_vorbiscomment(metadata, flac_cfg.output.replaygain.album_mode, &gain, &peak)) {
+ if(grabbag__replaygain_load_from_vorbiscomment(metadata, flac_cfg.output.replaygain.album_mode, /*strict=*/false, &gain, &peak)) {
file_info->has_replaygain = true;
file_info->replay_scale = grabbag__replaygain_compute_scale_factor(peak, gain, (double)flac_cfg.output.replaygain.preamp, /*prevent_clipping=*/!flac_cfg.output.replaygain.hard_limit);
}
diff --git a/src/share/grabbag/replaygain.c b/src/share/grabbag/replaygain.c
index 251e0e6d..4a707960 100644
--- a/src/share/grabbag/replaygain.c
+++ b/src/share/grabbag/replaygain.c
@@ -581,7 +581,7 @@ static FLAC__bool parse_double_(const FLAC__StreamMetadata_VorbisComment_Entry *
return true;
}
-FLAC__bool grabbag__replaygain_load_from_vorbiscomment(const FLAC__StreamMetadata *block, FLAC__bool album_mode, double *gain, double *peak)
+FLAC__bool grabbag__replaygain_load_from_vorbiscomment(const FLAC__StreamMetadata *block, FLAC__bool album_mode, FLAC__bool strict, double *gain, double *peak)
{
int gain_offset, peak_offset;
@@ -589,14 +589,14 @@ FLAC__bool grabbag__replaygain_load_from_vorbiscomment(const FLAC__StreamMetadat
FLAC__ASSERT(block->type == FLAC__METADATA_TYPE_VORBIS_COMMENT);
if(0 > (gain_offset = FLAC__metadata_object_vorbiscomment_find_entry_from(block, /*offset=*/0, (const char *)(album_mode? GRABBAG__REPLAYGAIN_TAG_ALBUM_GAIN : GRABBAG__REPLAYGAIN_TAG_TITLE_GAIN))))
- return false;
+ return !strict && grabbag__replaygain_load_from_vorbiscomment(block, !album_mode, /*strict=*/true, gain, peak);
if(0 > (peak_offset = FLAC__metadata_object_vorbiscomment_find_entry_from(block, /*offset=*/0, (const char *)(album_mode? GRABBAG__REPLAYGAIN_TAG_ALBUM_PEAK : GRABBAG__REPLAYGAIN_TAG_TITLE_PEAK))))
- return false;
+ return !strict && grabbag__replaygain_load_from_vorbiscomment(block, !album_mode, /*strict=*/true, gain, peak);
if(!parse_double_(block->data.vorbis_comment.comments + gain_offset, gain))
- return false;
+ return !strict && grabbag__replaygain_load_from_vorbiscomment(block, !album_mode, /*strict=*/true, gain, peak);
if(!parse_double_(block->data.vorbis_comment.comments + peak_offset, peak))
- return false;
+ return !strict && grabbag__replaygain_load_from_vorbiscomment(block, !album_mode, /*strict=*/true, gain, peak);
return true;
}