[PATCH 1/2] Use C locale when reading ReplayGain tag

Ulrich Klauer ulrich at chirlu.de
Thu Apr 11 13:07:49 PDT 2013


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



More information about the flac-dev mailing list