Index: bmp-musepack/trunk/src/libmpc.cpp
===================================================================
--- bmp-musepack/trunk/src/libmpc.cpp	(revision 34)
+++ bmp-musepack/trunk/src/libmpc.cpp	(revision 455)
@@ -2,22 +2,22 @@
  * Copyright (c) 2005, The Musepack Development Team
  * All rights reserved.
- * 
+ *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions are
  * met:
- * 
+ *
  *     * Redistributions of source code must retain the above copyright
  *       notice, this list of conditions and the following disclaimer.
- * 
+ *
  *     * Redistributions in binary form must reproduce the above
  *       copyright notice, this list of conditions and the following
  *       disclaimer in the documentation and/or other materials provided
  *       with the distribution.
- * 
+ *
  *     * Neither the name of the The Musepack Development Team nor the
  *       names of its contributors may be used to endorse or promote
  *       products derived from this software without specific prior
  *       written permission.
- * 
+ *
  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
@@ -111,6 +111,6 @@
     {
         char* titleText      = g_strdup_printf("Musepack Decoder Plugin %s", VERSION);
-        char* contentText = "Plugin code by\nBenoit Amiaux\nMartin Spuler\nKuniklo\n\nGet latest version at http://musepack.net\n";
-        char* buttonText  = "Nevermind";
+        const char* contentText = "Plugin code by\nBenoit Amiaux\nMartin Spuler\nKuniklo\n\nGet latest version at http://musepack.net\n";
+	    const char* buttonText  = "Nevermind";
         aboutBox = xmms_show_message(titleText, contentText, buttonText, FALSE, NULL, NULL);
         widgets.aboutBox = aboutBox;
@@ -313,19 +313,16 @@
 static void mpcGetSongInfo(char* p_Filename, char** p_Title, int* p_Length)
 {
-    FILE* input = fopen(p_Filename, "rb");
-    if(input)
-    {
+	mpc_reader reader;
+	mpc_demux * demux;
+	if (mpc_reader_init_stdio(&reader, p_Filename) == MPC_STATUS_OK && (demux = mpc_demux_init(&reader))) {
         MpcInfo tags = getTags(p_Filename);
         *p_Title = mpcGenerateTitle(tags, p_Filename);
         freeTags(tags);
-        mpc_streaminfo info;
-        mpc_reader_file reader;
-        mpc_reader_setup_file_reader(&reader, input);
-        mpc_streaminfo_read(&info, &reader.reader);
-        *p_Length = static_cast<int> (1000 * mpc_streaminfo_get_length(&info));
-        fclose(input);
-    }
-    else
-    {
+		mpc_streaminfo info;
+		mpc_demux_get_info(demux, &info);
+		*p_Length = static_cast<int> (1000 * mpc_streaminfo_get_length(&info));
+		mpc_demux_exit(demux);
+		mpc_reader_exit_stdio(&reader);
+    } else {
         char* temp = g_strdup_printf("[xmms-musepack] mpcGetSongInfo is unable to open %s\n", p_Filename);
         perror(temp);
@@ -474,5 +471,7 @@
         GtkWidget* streamLabel    = mpcGtkLabel(infoVbox);
         GtkWidget* encoderLabel   = mpcGtkLabel(infoVbox);
-        GtkWidget* profileLabel   = mpcGtkLabel(infoVbox);
+		GtkWidget* profileLabel   = mpcGtkLabel(infoVbox);
+		GtkWidget* pnsLabel       = mpcGtkLabel(infoVbox);
+		GtkWidget* gaplessLabel   = mpcGtkLabel(infoVbox);
         GtkWidget* bitrateLabel   = mpcGtkLabel(infoVbox);
         GtkWidget* rateLabel      = mpcGtkLabel(infoVbox);
@@ -485,11 +484,9 @@
         GtkWidget* albumGainLabel = mpcGtkLabel(infoVbox);
 
-        FILE* input = fopen(p_Filename, "rb");
-        if(input)
-        {
+		mpc_reader reader;
+		mpc_demux * demux;
+		if (mpc_reader_init_stdio(&reader, p_Filename) == MPC_STATUS_OK && (demux = mpc_demux_init(&reader))) {
             mpc_streaminfo info;
-            mpc_reader_file reader;
-            mpc_reader_setup_file_reader(&reader, input);
-            mpc_streaminfo_read(&info, &reader.reader);
+			mpc_demux_get_info(demux, &info);
 
             int time = static_cast<int> (mpc_streaminfo_get_length(&info));
@@ -499,14 +496,16 @@
             mpcGtkPrintLabel(streamLabel,    "Streamversion %d", info.stream_version);
             mpcGtkPrintLabel(encoderLabel,   "Encoder: \%s", info.encoder);
-            mpcGtkPrintLabel(profileLabel,   "Profile: \%s", info.profile_name);
+			mpcGtkPrintLabel(profileLabel,   "Profile: \%s (q=%0.2f)", info.profile_name, info.profile - 5);
+			mpcGtkPrintLabel(pnsLabel,       "PNS: \%s", info.pns == 0xFF ? "unknow" : info.pns ? "on" : "off");
+			mpcGtkPrintLabel(gaplessLabel,   "Gapless: \%s", info.is_true_gapless ? "on" : "off");
             mpcGtkPrintLabel(bitrateLabel,   "Average bitrate: \%6.1f kbps", info.average_bitrate * 1.e-3);
             mpcGtkPrintLabel(rateLabel,      "Samplerate: \%d Hz", info.sample_freq);
             mpcGtkPrintLabel(channelsLabel,  "Channels: \%d", info.channels);
-            mpcGtkPrintLabel(lengthLabel,    "Length: \%d:\%.2d", minutes, seconds);
+			mpcGtkPrintLabel(lengthLabel,    "Length: \%d:\%.2d (%u samples)", minutes, seconds, (mpc_uint32_t)mpc_streaminfo_get_length_samples(&info));
             mpcGtkPrintLabel(fileSizeLabel,  "File size: \%d Bytes", info.total_file_length);
-            mpcGtkPrintLabel(trackPeakLabel, "Track Peak: \%5u", info.peak_title);
-            mpcGtkPrintLabel(trackGainLabel, "Track Gain: \%-+2.2f dB", 0.01 * info.gain_title);
-            mpcGtkPrintLabel(albumPeakLabel, "Album Peak: \%5u", info.peak_album);
-            mpcGtkPrintLabel(albumGainLabel, "Album Gain: \%-+5.2f dB", 0.01 * info.gain_album);
+			mpcGtkPrintLabel(trackPeakLabel, "Track Peak: \%2.2f dB", info.peak_title / 256.);
+			mpcGtkPrintLabel(trackGainLabel, "Track Gain: \%2.2f dB", info.gain_title / 256.);
+			mpcGtkPrintLabel(albumPeakLabel, "Album Peak: \%2.2f dB", info.peak_album / 256.);
+			mpcGtkPrintLabel(albumGainLabel, "Album Gain: \%2.2f dB", info.gain_album / 256.);
 
             MpcInfo tags = getTags(p_Filename);
@@ -526,5 +525,6 @@
             free(entry);
             freeTags(tags);
-            fclose(input);
+			mpc_demux_exit(demux);
+			mpc_reader_exit_stdio(&reader);
         }
         else
@@ -709,41 +709,33 @@
 {
     lockAcquire();
-    char* filename = static_cast<char*> (data);
-    FILE* input = fopen(filename, "rb");
-    if (!input)
-    {
+	const char* filename = static_cast<const char*> (data);
+	mpc_reader reader;
+	if (mpc_reader_init_stdio(&reader, filename) != MPC_STATUS_OK) {
         mpcDecoder.isError = g_strdup_printf("[xmms-musepack] decodeStream is unable to open %s", filename);
-        return endThread(filename, input, true);
-    }
-
-    mpc_reader_file reader;
-    mpc_reader_setup_file_reader(&reader, input);
-
-    mpc_streaminfo info;
-    if (mpc_streaminfo_read(&info, &reader.reader) != ERROR_CODE_OK)
-    {
-        mpcDecoder.isError = g_strdup_printf("[xmms-musepack] decodeStream is unable to read %s", filename);
-        return endThread(filename, input, true);
-    }
-
-    MpcInfo tags     = getTags(filename);
-    track.display    = mpcGenerateTitle(tags, filename);
-    track.length     = static_cast<int> (1000 * mpc_streaminfo_get_length(&info));
-    track.bitrate    = static_cast<int> (info.average_bitrate);
-    track.sampleFreq = info.sample_freq;
-    track.channels   = info.channels;
+        return endThread(filename, 0, true);
+	}
+
+	mpc_demux * demux = 0;
+	demux = mpc_demux_init(&reader);
+
+	if ( demux == 0 ) {
+		mpcDecoder.isError = g_strdup_printf("[xmms-musepack] decodeStream is unable to initialize decoder on %s", filename);
+		mpc_reader_exit_stdio(&reader);
+		return endThread(filename, 0, true);
+	}
+
+	mpc_streaminfo info;
+	mpc_demux_get_info(demux, &info);
+	MpcInfo tags     = getTags(filename);
+	track.display    = mpcGenerateTitle(tags, filename);
+	track.length     = static_cast<int> (1000 * mpc_streaminfo_get_length(&info));
+	track.bitrate    = static_cast<int> (info.average_bitrate);
+	track.sampleFreq = info.sample_freq;
+	track.channels   = info.channels;
     freeTags(tags);
 
     MpcPlugin.set_info(track.display, track.length, track.bitrate, track.sampleFreq, track.channels);
 
-    mpc_decoder decoder;
-    mpc_decoder_setup(&decoder, &reader.reader);
-    if (!mpc_decoder_initialize(&decoder, &info))
-    {
-        mpcDecoder.isError = g_strdup_printf("[xmms-musepack] decodeStream is unable to initialize decoder on %s", filename);
-        return endThread(filename, input, true);
-    }
-
-    setReplaygain(info, decoder);
+    setReplaygain(demux);
 
     MPC_SAMPLE_FORMAT sampleBuffer[MPC_DECODER_BUFFER_LENGTH];
@@ -752,6 +744,7 @@
     if (!MpcPlugin.output->open_audio(FMT_S16_LE, track.sampleFreq, track.channels))
     {
-        mpcDecoder.isError = g_strdup_printf("[xmms-musepack] decodeStream is unable to open an audio output");
-        return endThread(filename, input, true);
+		mpcDecoder.isError = g_strdup_printf("[xmms-musepack] decodeStream is unable to open an audio output");
+		mpc_reader_exit_stdio(&reader);
+        return endThread(filename, 0, true);
     }
     else
@@ -762,11 +755,13 @@
     lockRelease();
 
-    int counter = 2 * track.sampleFreq / 3;
+	int counter = 2 * track.sampleFreq / 3;
+	int status = 0;
     while (isAlive())
     {
         if (getOffset() != -1)
         {
-            mpc_decoder_seek_seconds(&decoder, mpcDecoder.offset);
+			mpc_demux_seek_second(demux, mpcDecoder.offset);
             setOffset(-1);
+			status = 0;
         }
 
@@ -774,84 +769,61 @@
         short iPlaying = MpcPlugin.output->buffer_playing()? 1 : 0;
         int iFree = MpcPlugin.output->buffer_free();
-        if (!mpcDecoder.isPause &&  iFree >= ((1152 * 4) << iPlaying))
+        if (!mpcDecoder.isPause &&  iFree >= ((1152 * 4) << iPlaying) && status != -1)
         {
-            unsigned status = processBuffer(sampleBuffer, xmmsBuffer, decoder);
-            if (status == (unsigned) (-1))
-            {
-                mpcDecoder.isError = g_strdup_printf("[xmms-musepack] error from internal decoder on %s", filename);
-                return endThread(filename, input, true);
-            }
-            else if (status == 0)
-            {
-                //mpcDecoder.isError = g_strdup_printf("[xmms-musepack] null output from internal decoder on %s", filename);
-                return endThread(filename, input, true);
-            }
-            lockRelease();
-
-            if(pluginConfig.dynamicBitrate)
-            {
-                counter -= status;
-                if(counter < 0)
-                {
-                    MpcPlugin.set_info(track.display, track.length, track.bitrate, track.sampleFreq, track.channels);
-                    counter = 2 * track.sampleFreq / 3;
-                }
-            }
+			status = processBuffer(sampleBuffer, xmmsBuffer, *demux);
+			lockRelease();
+
+			if(pluginConfig.dynamicBitrate) {
+				counter -= status;
+				if(counter < 0) {
+					MpcPlugin.set_info(track.display, track.length, track.bitrate, track.sampleFreq, track.channels);
+					counter = 2 * track.sampleFreq / 3;
+				}
+			}
         }
         else
         {
-            lockRelease();
-            xmms_usleep(10000);
-        }
-    }
-    return endThread(filename, input, false);
-}
-
-static int processBuffer(MPC_SAMPLE_FORMAT* sampleBuffer, char* xmmsBuffer, mpc_decoder& decoder)
-{
-    mpc_uint32_t vbrAcc = 0;
-    mpc_uint32_t vbrUpd = 0;
-
-    unsigned status  = mpc_decoder_decode(&decoder, sampleBuffer, &vbrAcc, &vbrUpd);
-    copyBuffer(sampleBuffer, xmmsBuffer, status);
+			lockRelease();
+			if (mpcDecoder.isPause == FALSE && status == -1 &&
+						 MpcPlugin.output->buffer_playing() == FALSE)
+				break;
+            xmms_usleep(100000);
+		}
+	}
+	mpc_demux_exit(demux);
+	mpc_reader_exit_stdio(&reader);
+    return endThread(filename, 0, false);
+}
+
+static int processBuffer(MPC_SAMPLE_FORMAT* sampleBuffer, char* xmmsBuffer, mpc_demux& demux)
+{
+	mpc_frame_info info;
+
+	info.buffer = sampleBuffer;
+	mpc_demux_decode(&demux, &info);
+
+	if (info.bits == -1) return -1; // end of stream
+
+    copyBuffer(sampleBuffer, xmmsBuffer, info.samples * track.channels);
 
     if (pluginConfig.dynamicBitrate)
     {
-        track.bitrate = static_cast<int> (vbrUpd * track.sampleFreq / 1152);
+        track.bitrate = static_cast<int> (info.bits * track.sampleFreq / 1152);
     }
 
     if (pluginConfig.isEq)
     {
-        iir(xmmsBuffer, 4 * status);
-    }
-
-    MpcPlugin.add_vis_pcm(MpcPlugin.output->written_time(), FMT_S16_LE, track.channels, status * 4, xmmsBuffer);
-    MpcPlugin.output->write_audio(xmmsBuffer, status * 4);
-    return status;
-}
-
-static void setReplaygain(mpc_streaminfo& info, mpc_decoder& decoder)
-{
-    if(!pluginConfig.replaygain && !pluginConfig.clipPrevention)
-        return;
-
-    int peak    = pluginConfig.albumGain ? info.peak_album : info.peak_title;
-    double gain = pluginConfig.albumGain ? info.gain_album : info.gain_title;
-
-    if(!peak)
-        peak = 32767;
-    if(!gain)
-        gain = 1.;
-
-    double clip = 32767. / peak;
-    gain = exp((M_LN10 / 2000.) * gain);
-
-    if(pluginConfig.clipPrevention && !pluginConfig.replaygain)
-        gain = clip;
-    else if(pluginConfig.replaygain && pluginConfig.clipPrevention)
-        if(clip < gain)
-            gain = clip;
-
-    mpc_decoder_scale_output(&decoder, gain);
+		iir(xmmsBuffer, 4 * info.samples);
+    }
+
+	MpcPlugin.add_vis_pcm(MpcPlugin.output->written_time(), FMT_S16_LE, track.channels, info.samples * 2 * track.channels, xmmsBuffer);
+	MpcPlugin.output->write_audio(xmmsBuffer, info.samples * 2 * track.channels);
+	return info.samples;
+}
+
+static void setReplaygain(mpc_demux * d)
+{
+	mpc_set_replay_level(d, MPC_OLD_GAIN_REF, pluginConfig.replaygain,
+						 !pluginConfig.albumGain, pluginConfig.clipPrevention);
 }
 
