Index: /libmpc/branches/r2d/include/mpc/mpcdec.h
===================================================================
--- /libmpc/branches/r2d/include/mpc/mpcdec.h	(revision 211)
+++ /libmpc/branches/r2d/include/mpc/mpcdec.h	(revision 212)
@@ -88,4 +88,7 @@
 void mpc_decoder_scale_output(mpc_decoder *p_dec, double scale_factor);
 
+void setReplayLevel(mpc_demux * d, float level, mpc_bool_t use_gain,
+					mpc_bool_t use_title, mpc_bool_t clip_prevention);
+
 /// Actually reads data from previously initialized stream.  Call
 /// this iteratively to decode the mpc stream.
Index: /libmpc/branches/r2d/include/mpc/streaminfo.h
===================================================================
--- /libmpc/branches/r2d/include/mpc/streaminfo.h	(revision 211)
+++ /libmpc/branches/r2d/include/mpc/streaminfo.h	(revision 212)
@@ -69,6 +69,6 @@
     /// @name Replaygain properties
     //@{
-    mpc_int16_t          gain_title;         ///< Replaygain title value
-    mpc_int16_t          gain_album;         ///< Replaygain album value
+    mpc_uint16_t         gain_title;         ///< Replaygain title value
+    mpc_uint16_t         gain_album;         ///< Replaygain album value
     mpc_uint16_t         peak_album;         ///< Peak album loudness level
     mpc_uint16_t         peak_title;         ///< Peak title loudness level
Index: /libmpc/branches/r2d/libmpcdec/mpc_demux.c
===================================================================
--- /libmpc/branches/r2d/libmpcdec/mpc_demux.c	(revision 211)
+++ /libmpc/branches/r2d/libmpcdec/mpc_demux.c	(revision 212)
@@ -33,4 +33,5 @@
 */
 
+#include <math.h>
 #include <string.h>
 #include <mpc/streaminfo.h>
@@ -353,6 +354,4 @@
 	memcpy(i, &d->si, sizeof d->si);
 }
-
-#include <stdio.h>
 
 void mpc_demux_decode(mpc_demux * d, mpc_frame_info * i)
@@ -471,2 +470,26 @@
 }
 
+void setReplayLevel(mpc_demux * d, float level, mpc_bool_t use_gain,
+					mpc_bool_t use_title, mpc_bool_t clip_prevention)
+{
+	float peak = use_title ? d->si.peak_title : d->si.peak_album;
+	float gain = use_title ? d->si.gain_title : d->si.gain_album;
+
+	if(!use_gain && !clip_prevention)
+		return;
+
+	if(!peak)
+		peak = 1.;
+	else
+		peak = (1 << 15) / __builtin_powf(10, peak / (20 * 256));
+
+	if(!gain)
+		gain = 1.;
+	else
+		gain = __builtin_powf(10, (level - gain / 256) / 20);
+
+	if(clip_prevention && (peak < gain || !use_gain))
+		gain = peak;
+
+	mpc_decoder_scale_output(d->d, gain);
+}
Index: /libmpc/branches/r2d/libmpcdec/streaminfo.c
===================================================================
--- /libmpc/branches/r2d/libmpcdec/streaminfo.c	(revision 211)
+++ /libmpc/branches/r2d/libmpcdec/streaminfo.c	(revision 212)
@@ -35,4 +35,5 @@
 /// Implementation of streaminfo reading functions.
 
+#include <math.h>
 #include <mpc/mpcdec.h>
 #include <mpc/streaminfo.h>
@@ -125,4 +126,23 @@
 	si->block_pwr          = 0;
 
+	// convert gain info
+	if (si->gain_title != 0) {
+		int tmp = (int)((65. - si->gain_title / 100.) * 256);
+		if (tmp >= (1 << 16) || tmp < 0) tmp = 0;
+		si->gain_title = (mpc_int16_t) tmp;
+	}
+
+	if (si->gain_album != 0) {
+		int tmp = (int)((65. - si->gain_album / 100.) * 256);
+		if (tmp >= (1 << 16) || tmp < 0) tmp = 0;
+		si->gain_album = (mpc_int16_t) tmp;
+	}
+
+	if (si->peak_title != 0)
+ 		si->peak_title = (mpc_uint16_t) (__builtin_log10(si->peak_title) * 20 * 256);
+
+	if (si->peak_album != 0)
+		si->peak_album = (mpc_uint16_t) (__builtin_log10(si->peak_album) * 20 * 256);
+
 	mpc_get_encoder_string(si);
 
@@ -146,5 +166,4 @@
 
 	mpc_bits_read(&r, 8); // gain version
-	// FIXME : add gain conversion
 	si->gain_title         = (mpc_uint16_t) mpc_bits_read(&r, 16);
 	si->peak_title         = (mpc_uint16_t) mpc_bits_read(&r, 16);
Index: /libmpc/branches/r2d/libmpcenc/encode_sv7.c
===================================================================
--- /libmpc/branches/r2d/libmpcenc/encode_sv7.c	(revision 211)
+++ /libmpc/branches/r2d/libmpcenc/encode_sv7.c	(revision 212)
@@ -60,11 +60,15 @@
 
 // writes replay gain info
-static void writeGainInfo ( mpc_encoder_t * e )
+static void writeGainInfo ( mpc_encoder_t * e,
+							unsigned short t_gain,
+							unsigned short t_peak,
+							unsigned short a_gain,
+							unsigned short a_peak)
 {
 	writeBits ( e, 1,  8 ); // version
-	writeBits ( e, 0,  16 ); // Title gain
-	writeBits ( e, 0,  16 ); // Title peak
-	writeBits ( e, 0,  16 ); // Album gain
-	writeBits ( e, 0,  16 ); // Album peak
+	writeBits ( e, t_gain,  16 ); // Title gain
+	writeBits ( e, t_peak,  16 ); // Title peak
+	writeBits ( e, a_gain,  16 ); // Album gain
+	writeBits ( e, a_peak,  16 ); // Album peak
 }
 
@@ -76,5 +80,9 @@
                   const unsigned int  SamplesCount,
                   const unsigned int  SampleFreq,
-				  const unsigned int  ChannelCount)
+				  const unsigned int  ChannelCount,
+				  unsigned short t_gain,
+				  unsigned short t_peak,
+				  unsigned short a_gain,
+				  unsigned short a_peak)
 {
 	unsigned char tmp[10];
@@ -104,5 +112,5 @@
 	writeBits ( e, FRAMES_PER_BLOCK_PWR >> 1,  3 );    // frames per block (log4 unit)
 
-	writeGainInfo(e);
+	writeGainInfo(e, t_gain, t_peak, a_gain, a_peak);
 }
 
Index: /libmpc/branches/r2d/libmpcenc/libmpcenc.h
===================================================================
--- /libmpc/branches/r2d/libmpcenc/libmpcenc.h	(revision 211)
+++ /libmpc/branches/r2d/libmpcenc/libmpcenc.h	(revision 212)
@@ -80,5 +80,9 @@
 						const unsigned int  SamplesCount,
 						const unsigned int  SampleFreq,
-						const unsigned int  ChannelCount);
+						const unsigned int  ChannelCount,
+						unsigned short t_gain,
+						unsigned short t_peak,
+						unsigned short a_gain,
+						unsigned short a_peak);
  void writeEncoderInfo ( mpc_encoder_t * e,
 						 const float profile,
Index: /libmpc/branches/r2d/mpc2sv8/mpc2sv8.c
===================================================================
--- /libmpc/branches/r2d/mpc2sv8/mpc2sv8.c	(revision 211)
+++ /libmpc/branches/r2d/mpc2sv8/mpc2sv8.c	(revision 212)
@@ -123,5 +123,6 @@
 	writeMagic(&e);
 	writeStreamInfo( &e, si.max_band, si.ms > 0, si.samples, si.sample_freq,
-					  si.channels); // FIXME : convert replay gain info
+					  si.channels, si.gain_title, si.gain_album, si.peak_title,
+					  si.peak_album);
 	si_size = writeBlock(&e, "SI", MPC_TRUE, 0);
 	writeEncoderInfo(&e, si.profile, si.pns, si.encoder_version / 100,
@@ -159,5 +160,6 @@
 		fseek(e.outputFile, e.seek_ref + 4, SEEK_SET);
 		writeStreamInfo( &e, si.max_band, si.ms > 0, demux->d->samples,
-						  si.sample_freq, si.channels);
+						  si.sample_freq, si.channels, si.gain_title,
+						  si.gain_album, si.peak_title, si.peak_album);
 		writeBlock(&e, "SI", MPC_TRUE, si_size);
 		fseek(e.outputFile, 0, SEEK_END);
Index: /libmpc/branches/r2d/mpcdec/Makefile.am
===================================================================
--- /libmpc/branches/r2d/mpcdec/Makefile.am	(revision 211)
+++ /libmpc/branches/r2d/mpcdec/Makefile.am	(revision 212)
@@ -3,4 +3,4 @@
 bin_PROGRAMS = mpcdec
 mpcdec_SOURCES = mpcdec.c
-mpcdec_LDADD = $(top_builddir)/libwavformat/libwavformat.a\
-	$(top_builddir)/libmpcdec/libmpcdec.la
+mpcdec_LDADD = $(top_builddir)/libwavformat/libwavformat.a \
+	$(top_builddir)/libmpcdec/libmpcdec.la -lm
Index: /libmpc/branches/r2d/mpcenc/mpcenc.c
===================================================================
--- /libmpc/branches/r2d/mpcenc/mpcenc.c	(revision 211)
+++ /libmpc/branches/r2d/mpcenc/mpcenc.c	(revision 212)
@@ -1610,5 +1610,5 @@
 	writeMagic(&e);
 	writeStreamInfo ( &e, m.Max_Band, m.MS_Channelmode > 0, SamplesInWAVE,
-					   m.SampleFreq, Wave.Channels > 2 ? 2 : Wave.Channels);
+					   m.SampleFreq, Wave.Channels > 2 ? 2 : Wave.Channels, 0, 0, 0, 0);
 	writeBlock(&e, "SI", MPC_TRUE, 0);
 	writeEncoderInfo(&e, m.FullQual, m.PNS > 0, MPPENC_MAJOR, MPPENC_MINOR,
