When a locale is in effect that does not use the point as the decimal mark (e.g., sv_SE or de_DE, which use a comma) and a ReplayGain tag is read for --apply-replaygain-which-is-not-lossless, the gain value was misinterpreted (e.g., "-2.29" truncated to "-2"). This is fixed by resetting the locale to "C" temporarily, based on Josh Coalson's fix of the dual case (writing ReplayGain tag) in commit cda02d3. Patch by hhaamu at gmail.com, taken from the Debian patch tracker for flac 1.2.1-6 (13_replaygain_c_locale.patch). http://sourceforge.net/p/flac/bugs/380/ --- src/share/grabbag/replaygain.c | 32 +++++++++++++++++++++++++------- 1 file changed, 25 insertions(+), 7 deletions(-) diff --git a/src/share/grabbag/replaygain.c b/src/share/grabbag/replaygain.c index 43f1be0..347319f 100644 --- a/src/share/grabbag/replaygain.c +++ b/src/share/grabbag/replaygain.c @@ -606,6 +606,8 @@ static FLAC__bool parse_double_(const FLAC__StreamMetadata_VorbisComment_Entry * FLAC__bool grabbag__replaygain_load_from_vorbiscomment(const FLAC__StreamMetadata *block, FLAC__bool album_mode, FLAC__bool strict, double *reference, double *gain, double *peak) { int reference_offset, gain_offset, peak_offset; + char *saved_locale; + FLAC__bool res = true; FLAC__ASSERT(0 != block); FLAC__ASSERT(0 != reference); @@ -618,20 +620,36 @@ FLAC__bool grabbag__replaygain_load_from_vorbiscomment(const FLAC__StreamMetadat */ *reference = ReplayGainReferenceLoudness; + /* + * We need to save the old locale and switch to "C" because the locale + * influences the formatting of %f and we want it a certain way. + */ + saved_locale = strdup(setlocale(LC_ALL, 0)); + if (0 == saved_locale) + return false; + setlocale(LC_ALL, "C"); + if(0 <= (reference_offset = FLAC__metadata_object_vorbiscomment_find_entry_from(block, /*offset=*/0, (const char *)GRABBAG__REPLAYGAIN_TAG_REFERENCE_LOUDNESS))) (void)parse_double_(block->data.vorbis_comment.comments + reference_offset, reference); 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 !strict && grabbag__replaygain_load_from_vorbiscomment(block, !album_mode, /*strict=*/true, reference, gain, peak); + res = false; 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 !strict && grabbag__replaygain_load_from_vorbiscomment(block, !album_mode, /*strict=*/true, reference, gain, peak); + res = false; - if(!parse_double_(block->data.vorbis_comment.comments + gain_offset, gain)) - return !strict && grabbag__replaygain_load_from_vorbiscomment(block, !album_mode, /*strict=*/true, reference, gain, peak); - if(!parse_double_(block->data.vorbis_comment.comments + peak_offset, peak)) - return !strict && grabbag__replaygain_load_from_vorbiscomment(block, !album_mode, /*strict=*/true, reference, gain, peak); + if(res && !parse_double_(block->data.vorbis_comment.comments + gain_offset, gain)) + res = false; + if(res && !parse_double_(block->data.vorbis_comment.comments + peak_offset, peak)) + res = false; - return true; + setlocale(LC_ALL, saved_locale); + free(saved_locale); + + /* something failed; retry with strict */ + if (!res && !strict) + res = grabbag__replaygain_load_from_vorbiscomment(block, !album_mode, /*strict=*/true, reference, gain, peak); + + return res; } double grabbag__replaygain_compute_scale_factor(double peak, double gain, double preamp, FLAC__bool prevent_clipping) -- 1.7.10.4 --=_7J5dbEMyC4hUWNBkUU9jXQ2 Content-Type: text/x-patch; charset=us-ascii; name=0002-Fix-path-to-HTML-documentation.patch Content-Disposition: attachment; filename=0002-Fix-path-to-HTML-documentation.patch; size=1032