changeset 1695:3cf80d8a6d8d trunk

[svn] - Removed .cpp.o target since we don't have any .cpp files anymore. - A test build then revealed that we still had two .cpp files in Plugins/Input/musepack, fixed that. - Moved nenolod's fix from init.mk to objective.mk. - Removed call to ldconfig in Makefile and replaced it with a hint to call ldconfig manually, since ldconfig without parameters breaks some systems (mainly OpenBSD). - I hope I did not forget to list a change I did ;)
author js
date Fri, 15 Sep 2006 06:36:26 -0700
parents 02d3d6d7f223
children cd8711f34c88
files ChangeLog Makefile Plugins/Input/flac/plugin_common/Makefile.in Plugins/Input/musepack/Makefile.in Plugins/Input/musepack/equalizer.cpp Plugins/Input/musepack/equalizer.cxx Plugins/Input/musepack/libmpc.cpp Plugins/Input/musepack/libmpc.cxx mk/init.mk mk/objective.mk
diffstat 10 files changed, 1099 insertions(+), 1085 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog	Thu Sep 14 14:06:45 2006 -0700
+++ b/ChangeLog	Fri Sep 15 06:36:26 2006 -0700
@@ -1,3 +1,12 @@
+2006-09-14 21:06:45 +0000  William Pitcock <nenolod@nenolod.net>
+  revision [2325]
+  - enforce support of our file extensions through use of the .SUFFIXES target
+  
+
+  Changes:        Modified:
+  +2 -0           trunk/mk/init.mk  
+
+
 2006-09-14 20:56:35 +0000  Jonathan Schleifer <js@h3c.de>
   revision [2323]
   * One more .cpp -> .cxx
--- a/Makefile	Thu Sep 14 14:06:45 2006 -0700
+++ b/Makefile	Fri Sep 15 06:36:26 2006 -0700
@@ -9,9 +9,12 @@
 
 install-posthook:
 	@if test `whoami` = 'root' && test -z "$(DESTDIR)"; then \
-		echo "[running ldconfig to update system library cache]"; \
-		/sbin/ldconfig; \
-		echo "[system library cache updated]"; \
+		echo; \
+		echo "WARNING:"; \
+		echo "On some systems, it might be required that you run"; \
+		echo "ldconfig. However, this isn't done automatically"; \
+		echo "because some ldconfig versions might break the system"; \
+		echo "if it's called without any parameters."; \
 	fi
 
 OBJECTIVE_DATA =							\
--- a/Plugins/Input/flac/plugin_common/Makefile.in	Thu Sep 14 14:06:45 2006 -0700
+++ b/Plugins/Input/flac/plugin_common/Makefile.in	Fri Sep 15 06:36:26 2006 -0700
@@ -20,4 +20,7 @@
 
 OBJECTS = ${SOURCES:.c=.o}
 
+libplugin_common.a: $(OBJECTS)
+	$(AR) cq $@ $(OBJECTS)
+
 include ../../../../mk/objective.mk
--- a/Plugins/Input/musepack/Makefile.in	Thu Sep 14 14:06:45 2006 -0700
+++ b/Plugins/Input/musepack/Makefile.in	Fri Sep 15 06:36:26 2006 -0700
@@ -5,11 +5,11 @@
 
 LIBDIR = $(plugindir)/$(INPUT_PLUGIN_DIR)
 
-SOURCES = equalizer.cpp libmpc.cpp
+SOURCES = equalizer.cxx libmpc.cxx
 
 LIBADD = -lmpcdec $(TAGLIB_LIBS) $(GTK_LIBS)
 
-OBJECTS = ${SOURCES:.cpp=.o}
+OBJECTS = ${SOURCES:.cxx=.o}
 
 CXXFLAGS += $(PICFLAGS) $(GTK_CFLAGS) $(TAGLIB_CFLAGS) -I../../../intl -I../../..
 
--- a/Plugins/Input/musepack/equalizer.cpp	Thu Sep 14 14:06:45 2006 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,196 +0,0 @@
-/*
- *   Thanks to Felipe Rivera for letting us use some code from his
- *   EQU-Plugin (http://equ.sourceforge.net/) for our Equalizer.
- */
-
-#include <math.h>
-#include <string.h>
-#include <stdlib.h>
-#include <glib.h>
-#include "equalizer.h"
-
-// Fixed Point Fractional bits
-#define FP_FRBITS 28
-
-// Conversions
-#define EQ_REAL(x) ((gint)((x) * (1 << FP_FRBITS)))
-
-/* Floating point */
-typedef struct {
-    float beta;
-    float alpha;
-    float gamma;
-} sIIRCoefficients;
-
-/* Coefficient history for the IIR filter */
-typedef struct {
-    float x[3];                 /* x[n], x[n-1], x[n-2] */
-    float y[3];                 /* y[n], y[n-1], y[n-2] */
-} sXYData;
-
-/* BETA, ALPHA, GAMMA */
-static sIIRCoefficients iir_cforiginal10[] = {
-    {(9.9421504945e-01), (2.8924752745e-03), (1.9941421835e+00)},   /*    60.0 Hz */
-    {(9.8335039428e-01), (8.3248028618e-03), (1.9827686547e+00)},   /*   170.0 Hz */
-    {(9.6958094144e-01), (1.5209529281e-02), (1.9676601546e+00)},   /*   310.0 Hz */
-    {(9.4163923306e-01), (2.9180383468e-02), (1.9345490229e+00)},   /*   600.0 Hz */
-    {(9.0450844499e-01), (4.7745777504e-02), (1.8852109613e+00)},   /*  1000.0 Hz */
-    {(7.3940088234e-01), (1.3029955883e-01), (1.5829158753e+00)},   /*  3000.0 Hz */
-    {(5.4697667908e-01), (2.2651166046e-01), (1.0153238114e+00)},   /*  6000.0 Hz */
-    {(3.1023210589e-01), (3.4488394706e-01), (-1.8142472036e-01)},  /* 12000.0 Hz */
-    {(2.6718639778e-01), (3.6640680111e-01), (-5.2117742267e-01)},  /* 14000.0 Hz */
-    {(2.4201241845e-01), (3.7899379077e-01), (-8.0847117831e-01)},  /* 16000.0 Hz */
-};
-
-/* History for two filters */
-static sXYData data_history[EQ_MAX_BANDS][EQ_CHANNELS];
-static sXYData data_history2[EQ_MAX_BANDS][EQ_CHANNELS];
-
-/* Coefficients */
-static sIIRCoefficients *iir_cf;
-
-/* Gain for each band
- * values should be between -0.2 and 1.0 */
-static float gain[10];
-static float preamp;
-
-int round_trick(float floatvalue_to_round);
-
-
-static void
-output_set_eq(gboolean active, gfloat pre, gfloat * bands)
-{
-    int i;
-
-    preamp = 1.0 + 0.0932471 * pre + 0.00279033 * pre * pre;
-    for (i = 0; i < 10; ++i)
-        gain[i] = 0.03 * bands[i] + 0.000999999 * bands[i] * bands[i];
-}
-
-/* Init the filter */
-void
-init_iir(int on, float preamp_ctrl, float *eq_ctrl)
-{
-    iir_cf = iir_cforiginal10;
-
-    /* Zero the history arrays */
-    memset(data_history, 0, sizeof(sXYData) * EQ_MAX_BANDS * EQ_CHANNELS);
-    memset(data_history2, 0, sizeof(sXYData) * EQ_MAX_BANDS * EQ_CHANNELS);
-
-    output_set_eq(on, preamp_ctrl, eq_ctrl);
-}
-
-int
-iir(char *d, gint length)
-{
-    gint16 *data = (gint16 *) d;
-
-    /* Indexes for the history arrays
-     * These have to be kept between calls to this function
-     * hence they are static */
-    static gint i = 0, j = 2, k = 1;
-
-    gint index, band, channel;
-    gint tempgint, halflength;
-    float out[EQ_CHANNELS], pcm[EQ_CHANNELS];
-
-    /**
-	 * IIR filter equation is
-	 * y[n] = 2 * (alpha*(x[n]-x[n-2]) + gamma*y[n-1] - beta*y[n-2])
-	 *
-	 * NOTE: The 2 factor was introduced in the coefficients to save
-	 * 			a multiplication
-	 *
-	 * This algorithm cascades two filters to get nice filtering
-	 * at the expense of extra CPU cycles
-	 */
-    /* 16bit, 2 bytes per sample, so divide by two the length of
-     * the buffer (length is in bytes)
-     */
-    halflength = (length >> 1);
-    for (index = 0; index < halflength; index += 2) {
-        /* For each channel */
-        for (channel = 0; channel < EQ_CHANNELS; channel++) {
-            /* No need to scale when processing the PCM with the filter */
-            pcm[channel] = data[index + channel];
-            /* Preamp gain */
-            pcm[channel] *= preamp;
-
-            out[channel] = 0;
-            /* For each band */
-            for (band = 0; band < 10; band++) {
-                /* Store Xi(n) */
-                data_history[band][channel].x[i] = pcm[channel];
-                /* Calculate and store Yi(n) */
-                data_history[band][channel].y[i] =
-                    (iir_cf[band].alpha * (data_history[band][channel].x[i]
-                                           - data_history[band][channel].x[k])
-                     + iir_cf[band].gamma * data_history[band][channel].y[j]
-                     - iir_cf[band].beta * data_history[band][channel].y[k]
-                    );
-                /*
-                 * The multiplication by 2.0 was 'moved' into the coefficients to save
-                 * CPU cycles here */
-                /* Apply the gain  */
-                out[channel] += data_history[band][channel].y[i] * gain[band];  // * 2.0;
-            }                   /* For each band */
-
-            if (false) {
-                /* Filter the sample again */
-                for (band = 0; band < 10; band++) {
-                    /* Store Xi(n) */
-                    data_history2[band][channel].x[i] = out[channel];
-                    /* Calculate and store Yi(n) */
-                    data_history2[band][channel].y[i] =
-                        (iir_cf[band].alpha *
-                         (data_history2[band][channel].x[i]
-                          - data_history2[band][channel].x[k])
-                         +
-                         iir_cf[band].gamma *
-                         data_history2[band][channel].y[j]
-                         -
-                         iir_cf[band].beta * data_history2[band][channel].y[k]
-                        );
-                    /* Apply the gain */
-                    out[channel] +=
-                        data_history2[band][channel].y[i] * gain[band];
-                }               /* For each band */
-            }
-
-            /* Volume stuff
-               Scale down original PCM sample and add it to the filters
-               output. This substitutes the multiplication by 0.25
-             */
-
-            out[channel] += (data[index + channel] >> 2);
-
-            //printf("out[channel] = %f\n", out[channel]);
-            tempgint = (int) out[channel];
-
-            //printf("iir: old=%d new=%d\n", data[index+channel], tempgint);
-            /* Limit the output */
-            if (tempgint < -32768)
-                data[index + channel] = -32768;
-            else if (tempgint > 32767)
-                data[index + channel] = 32767;
-            else
-                data[index + channel] = tempgint;
-        }                       /* For each channel */
-
-        i++;
-        j++;
-        k++;
-
-        /* Wrap around the indexes */
-        if (i == 3)
-            i = 0;
-        else if (j == 3)
-            j = 0;
-        else
-            k = 0;
-
-
-    }                           /* For each pair of samples */
-
-    return length;
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Plugins/Input/musepack/equalizer.cxx	Fri Sep 15 06:36:26 2006 -0700
@@ -0,0 +1,196 @@
+/*
+ *   Thanks to Felipe Rivera for letting us use some code from his
+ *   EQU-Plugin (http://equ.sourceforge.net/) for our Equalizer.
+ */
+
+#include <math.h>
+#include <string.h>
+#include <stdlib.h>
+#include <glib.h>
+#include "equalizer.h"
+
+// Fixed Point Fractional bits
+#define FP_FRBITS 28
+
+// Conversions
+#define EQ_REAL(x) ((gint)((x) * (1 << FP_FRBITS)))
+
+/* Floating point */
+typedef struct {
+    float beta;
+    float alpha;
+    float gamma;
+} sIIRCoefficients;
+
+/* Coefficient history for the IIR filter */
+typedef struct {
+    float x[3];                 /* x[n], x[n-1], x[n-2] */
+    float y[3];                 /* y[n], y[n-1], y[n-2] */
+} sXYData;
+
+/* BETA, ALPHA, GAMMA */
+static sIIRCoefficients iir_cforiginal10[] = {
+    {(9.9421504945e-01), (2.8924752745e-03), (1.9941421835e+00)},   /*    60.0 Hz */
+    {(9.8335039428e-01), (8.3248028618e-03), (1.9827686547e+00)},   /*   170.0 Hz */
+    {(9.6958094144e-01), (1.5209529281e-02), (1.9676601546e+00)},   /*   310.0 Hz */
+    {(9.4163923306e-01), (2.9180383468e-02), (1.9345490229e+00)},   /*   600.0 Hz */
+    {(9.0450844499e-01), (4.7745777504e-02), (1.8852109613e+00)},   /*  1000.0 Hz */
+    {(7.3940088234e-01), (1.3029955883e-01), (1.5829158753e+00)},   /*  3000.0 Hz */
+    {(5.4697667908e-01), (2.2651166046e-01), (1.0153238114e+00)},   /*  6000.0 Hz */
+    {(3.1023210589e-01), (3.4488394706e-01), (-1.8142472036e-01)},  /* 12000.0 Hz */
+    {(2.6718639778e-01), (3.6640680111e-01), (-5.2117742267e-01)},  /* 14000.0 Hz */
+    {(2.4201241845e-01), (3.7899379077e-01), (-8.0847117831e-01)},  /* 16000.0 Hz */
+};
+
+/* History for two filters */
+static sXYData data_history[EQ_MAX_BANDS][EQ_CHANNELS];
+static sXYData data_history2[EQ_MAX_BANDS][EQ_CHANNELS];
+
+/* Coefficients */
+static sIIRCoefficients *iir_cf;
+
+/* Gain for each band
+ * values should be between -0.2 and 1.0 */
+static float gain[10];
+static float preamp;
+
+int round_trick(float floatvalue_to_round);
+
+
+static void
+output_set_eq(gboolean active, gfloat pre, gfloat * bands)
+{
+    int i;
+
+    preamp = 1.0 + 0.0932471 * pre + 0.00279033 * pre * pre;
+    for (i = 0; i < 10; ++i)
+        gain[i] = 0.03 * bands[i] + 0.000999999 * bands[i] * bands[i];
+}
+
+/* Init the filter */
+void
+init_iir(int on, float preamp_ctrl, float *eq_ctrl)
+{
+    iir_cf = iir_cforiginal10;
+
+    /* Zero the history arrays */
+    memset(data_history, 0, sizeof(sXYData) * EQ_MAX_BANDS * EQ_CHANNELS);
+    memset(data_history2, 0, sizeof(sXYData) * EQ_MAX_BANDS * EQ_CHANNELS);
+
+    output_set_eq(on, preamp_ctrl, eq_ctrl);
+}
+
+int
+iir(char *d, gint length)
+{
+    gint16 *data = (gint16 *) d;
+
+    /* Indexes for the history arrays
+     * These have to be kept between calls to this function
+     * hence they are static */
+    static gint i = 0, j = 2, k = 1;
+
+    gint index, band, channel;
+    gint tempgint, halflength;
+    float out[EQ_CHANNELS], pcm[EQ_CHANNELS];
+
+    /**
+	 * IIR filter equation is
+	 * y[n] = 2 * (alpha*(x[n]-x[n-2]) + gamma*y[n-1] - beta*y[n-2])
+	 *
+	 * NOTE: The 2 factor was introduced in the coefficients to save
+	 * 			a multiplication
+	 *
+	 * This algorithm cascades two filters to get nice filtering
+	 * at the expense of extra CPU cycles
+	 */
+    /* 16bit, 2 bytes per sample, so divide by two the length of
+     * the buffer (length is in bytes)
+     */
+    halflength = (length >> 1);
+    for (index = 0; index < halflength; index += 2) {
+        /* For each channel */
+        for (channel = 0; channel < EQ_CHANNELS; channel++) {
+            /* No need to scale when processing the PCM with the filter */
+            pcm[channel] = data[index + channel];
+            /* Preamp gain */
+            pcm[channel] *= preamp;
+
+            out[channel] = 0;
+            /* For each band */
+            for (band = 0; band < 10; band++) {
+                /* Store Xi(n) */
+                data_history[band][channel].x[i] = pcm[channel];
+                /* Calculate and store Yi(n) */
+                data_history[band][channel].y[i] =
+                    (iir_cf[band].alpha * (data_history[band][channel].x[i]
+                                           - data_history[band][channel].x[k])
+                     + iir_cf[band].gamma * data_history[band][channel].y[j]
+                     - iir_cf[band].beta * data_history[band][channel].y[k]
+                    );
+                /*
+                 * The multiplication by 2.0 was 'moved' into the coefficients to save
+                 * CPU cycles here */
+                /* Apply the gain  */
+                out[channel] += data_history[band][channel].y[i] * gain[band];  // * 2.0;
+            }                   /* For each band */
+
+            if (false) {
+                /* Filter the sample again */
+                for (band = 0; band < 10; band++) {
+                    /* Store Xi(n) */
+                    data_history2[band][channel].x[i] = out[channel];
+                    /* Calculate and store Yi(n) */
+                    data_history2[band][channel].y[i] =
+                        (iir_cf[band].alpha *
+                         (data_history2[band][channel].x[i]
+                          - data_history2[band][channel].x[k])
+                         +
+                         iir_cf[band].gamma *
+                         data_history2[band][channel].y[j]
+                         -
+                         iir_cf[band].beta * data_history2[band][channel].y[k]
+                        );
+                    /* Apply the gain */
+                    out[channel] +=
+                        data_history2[band][channel].y[i] * gain[band];
+                }               /* For each band */
+            }
+
+            /* Volume stuff
+               Scale down original PCM sample and add it to the filters
+               output. This substitutes the multiplication by 0.25
+             */
+
+            out[channel] += (data[index + channel] >> 2);
+
+            //printf("out[channel] = %f\n", out[channel]);
+            tempgint = (int) out[channel];
+
+            //printf("iir: old=%d new=%d\n", data[index+channel], tempgint);
+            /* Limit the output */
+            if (tempgint < -32768)
+                data[index + channel] = -32768;
+            else if (tempgint > 32767)
+                data[index + channel] = 32767;
+            else
+                data[index + channel] = tempgint;
+        }                       /* For each channel */
+
+        i++;
+        j++;
+        k++;
+
+        /* Wrap around the indexes */
+        if (i == 3)
+            i = 0;
+        else if (j == 3)
+            j = 0;
+        else
+            k = 0;
+
+
+    }                           /* For each pair of samples */
+
+    return length;
+}
--- a/Plugins/Input/musepack/libmpc.cpp	Thu Sep 14 14:06:45 2006 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,880 +0,0 @@
-#include "libmpc.h"
-
-#define FORCED_THREAD_STACKSIZE 1024 * 1000
-#define REMOVE_NONEXISTANT_TAG(x)   if (!*x) { x = NULL; }
-
-using TagLib::MPC::File;
-using TagLib::Tag;
-using TagLib::String;
-using TagLib::APE::ItemListMap;
-
-InputPlugin MpcPlugin = {
-    NULL,           //File Handle               FILE* handle
-    NULL,           //Filename                  char* filename
-    NULL,           //Name of Plugin            char* filename
-    mpcOpenPlugin,  //Open Plugin               [CALLBACK]
-    mpcAboutBox,    //Show About box            [CALLBACK]
-    mpcConfigBox,   //Show Configure box        [CALLBACK]
-    mpcIsOurFile,   //Check if it's our file    [CALLBACK]
-    NULL,           //Scan the directory        [UNUSED]
-    mpcPlay,        //Play                      [CALLBACK]
-    mpcStop,        //Stop                      [CALLBACK]
-    mpcPause,       //Pause                     [CALLBACK]
-    mpcSeek,        //Seek                      [CALLBACK]
-    mpcSetEq,       //Set EQ                    [CALLBACK]
-    mpcGetTime,     //Get Time                  [CALLBACK]
-    NULL,           //Get Volume                [UNUSED]
-    NULL,           //Set Volume                [UNUSED]
-    NULL,           //Close Plugin              [UNUSED]
-    NULL,           //Obsolete                  [UNUSED]
-    NULL,           //Visual plugins            add_vis_pcm(int time, AFormat fmt, int nch, int length, void *ptr)
-    NULL,           //Set Info Settings         set_info(char *title, int length, int rate, int freq, int nch)
-    NULL,           //set Info Text             set_info_text(char* text)
-    mpcGetSongInfo, //Get Title String callback [CALLBACK]
-    mpcFileInfoBox, //Show File Info Box        [CALLBACK]
-    NULL,           //Output Plugin Handle      OutputPlugin output
-    mpcGetSongTuple,
-};
-
-extern "C"
-InputPlugin* get_iplugin_info()
-{
-    MpcPlugin.description = g_strdup_printf("Musepack Audio Plugin");
-    return &MpcPlugin;
-}
-
-static PluginConfig pluginConfig = {0};
-static Widgets      widgets      = {0};
-static MpcDecoder   mpcDecoder   = {0};
-static TrackInfo    track        = {0};
-
-static GThread            *threadHandle;
-GStaticMutex threadMutex = G_STATIC_MUTEX_INIT;
-
-static void mpcOpenPlugin()
-{
-    ConfigDb *cfg;
-    cfg = bmp_cfg_db_open();
-    bmp_cfg_db_get_bool(cfg, "musepack", "clipPrevention", &pluginConfig.clipPrevention);
-    bmp_cfg_db_get_bool(cfg, "musepack", "albumGain",      &pluginConfig.albumGain);
-    bmp_cfg_db_get_bool(cfg, "musepack", "dynamicBitrate", &pluginConfig.dynamicBitrate);
-    bmp_cfg_db_get_bool(cfg, "musepack", "replaygain",     &pluginConfig.replaygain);
-    bmp_cfg_db_close(cfg);
-}
-
-static void mpcAboutBox()
-{
-    GtkWidget* aboutBox = widgets.aboutBox;
-    if (aboutBox)
-        gdk_window_raise(aboutBox->window);
-    else
-    {
-        char* titleText      = g_strdup_printf("Musepack Decoder Plugin 1.2");
-        char* contentText = "Plugin code by\nBenoit Amiaux\nMartin Spuler\nKuniklo\n\nGet latest version at http://musepack.net\n";
-        char* buttonText  = "Nevermind";
-        aboutBox = xmms_show_message(titleText, contentText, buttonText, FALSE, NULL, NULL);
-        widgets.aboutBox = aboutBox;
-        g_signal_connect(G_OBJECT(aboutBox), "destroy", G_CALLBACK(gtk_widget_destroyed), &widgets.aboutBox);
-    }
-}
-
-static void mpcConfigBox()
-{
-    GtkWidget* configBox = widgets.configBox;
-    if(configBox)
-        gdk_window_raise(configBox->window);
-    else
-    {
-        configBox = gtk_window_new(GTK_WINDOW_TOPLEVEL);
-        gtk_window_set_type_hint(GTK_WINDOW(configBox), GDK_WINDOW_TYPE_HINT_DIALOG);
-        widgets.configBox = configBox;
-        g_signal_connect(G_OBJECT(configBox), "destroy", G_CALLBACK(gtk_widget_destroyed), &widgets.configBox);
-        gtk_window_set_title(GTK_WINDOW(configBox), "Musepack Decoder Configuration");
-        gtk_window_set_policy(GTK_WINDOW(configBox), FALSE, FALSE, FALSE);
-        gtk_container_border_width(GTK_CONTAINER(configBox), 10);
-
-        GtkWidget* notebook = gtk_notebook_new();
-        GtkWidget* vbox = gtk_vbox_new(FALSE, 10);
-        gtk_box_pack_start(GTK_BOX(vbox), notebook, TRUE, TRUE, 0);
-        gtk_container_add(GTK_CONTAINER(configBox), vbox);
-
-        //General Settings Tab
-        GtkWidget* generalSet = gtk_frame_new("General Settings");
-        gtk_container_border_width(GTK_CONTAINER(generalSet), 5);
-
-        GtkWidget* gSvbox = gtk_vbox_new(FALSE, 10);
-        gtk_container_border_width(GTK_CONTAINER(gSvbox), 5);
-        gtk_container_add(GTK_CONTAINER(generalSet), gSvbox);
-
-        GtkWidget* bitrateCheck = gtk_check_button_new_with_label("Enable Dynamic Bitrate Display");
-        widgets.bitrateCheck = bitrateCheck;
-        gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(bitrateCheck), pluginConfig.dynamicBitrate);
-        gtk_box_pack_start(GTK_BOX(gSvbox), bitrateCheck, FALSE, FALSE, 0);
-        gtk_notebook_append_page(GTK_NOTEBOOK(notebook), generalSet, gtk_label_new("Plugin"));
-
-        //ReplayGain Settings Tab
-        GtkWidget* replaygainSet = gtk_frame_new("ReplayGain Settings");
-        gtk_container_border_width(GTK_CONTAINER(replaygainSet), 5);
-
-        GtkWidget* rSVbox = gtk_vbox_new(FALSE, 10);
-        gtk_container_border_width(GTK_CONTAINER(rSVbox), 5);
-        gtk_container_add(GTK_CONTAINER(replaygainSet), rSVbox);
-
-        GtkWidget* clippingCheck = gtk_check_button_new_with_label("Enable Clipping Prevention");
-        widgets.clippingCheck = clippingCheck;
-        gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(clippingCheck), pluginConfig.clipPrevention);
-        gtk_box_pack_start(GTK_BOX(rSVbox), clippingCheck, FALSE, FALSE, 0);
-
-        GtkWidget* replaygainCheck = gtk_check_button_new_with_label("Enable ReplayGain");
-        widgets.replaygainCheck = replaygainCheck;
-        gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(replaygainCheck), pluginConfig.replaygain);
-        gtk_box_pack_start(GTK_BOX(rSVbox), replaygainCheck, FALSE, FALSE, 0);
-
-        GtkWidget* replaygainType = gtk_frame_new("ReplayGain Type");
-        gtk_box_pack_start(GTK_BOX(rSVbox), replaygainType, FALSE, FALSE, 0);
-        g_signal_connect(G_OBJECT(replaygainCheck), "toggled", G_CALLBACK(toggleSwitch), replaygainType);
-
-        GtkWidget* rgVbox = gtk_vbox_new(FALSE, 5);
-        gtk_container_set_border_width(GTK_CONTAINER(rgVbox), 5);
-        gtk_container_add(GTK_CONTAINER(replaygainType), rgVbox);
-
-        GtkWidget* trackCheck = gtk_radio_button_new_with_label(NULL, "Use Track Gain");
-        gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(trackCheck), !pluginConfig.albumGain);
-        gtk_box_pack_start(GTK_BOX(rgVbox), trackCheck, FALSE, FALSE, 0);
-
-        GtkWidget* albumCheck = gtk_radio_button_new_with_label(gtk_radio_button_group(GTK_RADIO_BUTTON(trackCheck)), "Use Album Gain");
-        widgets.albumCheck = albumCheck;
-        gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(albumCheck), pluginConfig.albumGain);
-        gtk_box_pack_start(GTK_BOX(rgVbox), albumCheck, FALSE, FALSE, 0);
-        gtk_widget_set_sensitive(replaygainType, pluginConfig.replaygain);
-        gtk_notebook_append_page(GTK_NOTEBOOK(notebook), replaygainSet, gtk_label_new("ReplayGain"));
-
-        //Buttons
-        GtkWidget* buttonBox = gtk_hbutton_box_new();
-        gtk_button_box_set_layout(GTK_BUTTON_BOX(buttonBox), GTK_BUTTONBOX_END);
-        gtk_button_box_set_spacing(GTK_BUTTON_BOX(buttonBox), 5);
-        gtk_box_pack_start(GTK_BOX(vbox), buttonBox, FALSE, FALSE, 0);
-
-        GtkWidget* okButton = gtk_button_new_with_label("Ok");
-        g_signal_connect(G_OBJECT(okButton), "clicked", G_CALLBACK(saveConfigBox), NULL);
-        GTK_WIDGET_SET_FLAGS(okButton, GTK_CAN_DEFAULT);
-        gtk_box_pack_start(GTK_BOX(buttonBox), okButton, TRUE, TRUE, 0);
-
-        GtkWidget* cancelButton = gtk_button_new_with_label("Cancel");
-        g_signal_connect_swapped(G_OBJECT(cancelButton), "clicked", G_CALLBACK(gtk_widget_destroy), GTK_OBJECT(widgets.configBox));
-        GTK_WIDGET_SET_FLAGS(cancelButton, GTK_CAN_DEFAULT);
-        gtk_widget_grab_default(cancelButton);
-        gtk_box_pack_start(GTK_BOX(buttonBox), cancelButton, TRUE, TRUE, 0);
-
-        gtk_widget_show_all(configBox);
-    }
-}
-
-static void toggleSwitch(GtkWidget* p_Widget, gpointer p_Data)
-{
-    gtk_widget_set_sensitive(GTK_WIDGET(p_Data), gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(p_Widget)));
-}
-
-static void saveConfigBox(GtkWidget* p_Widget, gpointer p_Data)
-{
-    ConfigDb* cfg;
-    GtkToggleButton* tb;
-
-    tb = GTK_TOGGLE_BUTTON(widgets.replaygainCheck);
-    pluginConfig.replaygain = gtk_toggle_button_get_active(tb);
-    tb = GTK_TOGGLE_BUTTON(widgets.clippingCheck);
-    pluginConfig.clipPrevention = gtk_toggle_button_get_active(tb);
-    tb = GTK_TOGGLE_BUTTON(widgets.bitrateCheck);
-    pluginConfig.dynamicBitrate = gtk_toggle_button_get_active(tb);
-    tb = GTK_TOGGLE_BUTTON(widgets.albumCheck);
-    pluginConfig.albumGain = gtk_toggle_button_get_active(tb);
-
-    cfg = bmp_cfg_db_open();
-
-    bmp_cfg_db_set_bool(cfg, "musepack", "clipPrevention", pluginConfig.clipPrevention);
-    bmp_cfg_db_set_bool(cfg, "musepack", "albumGain",      pluginConfig.albumGain);
-    bmp_cfg_db_set_bool(cfg, "musepack", "dynamicBitrate", pluginConfig.dynamicBitrate);
-    bmp_cfg_db_set_bool(cfg, "musepack", "replaygain",     pluginConfig.replaygain);
-
-    bmp_cfg_db_close(cfg);
-
-    gtk_widget_destroy (widgets.configBox);
-}
-
-static int mpcIsOurFile(char* p_Filename)
-{
-   VFSFile *file;
-   gchar magic[3];
-   if ((file = vfs_fopen(p_Filename, "rb"))) {
-       vfs_fread(magic, 1, 3, file);
-       if (!strncmp(magic, "MP+", 3)) {
-            vfs_fclose(file);
-            return 1;
-       }
-       vfs_fclose(file);
-   }
-   return 0;
-}
-
-static void mpcPlay(char* p_Filename)
-{
-    mpcDecoder.offset   = -1;
-    mpcDecoder.isAlive  = true;
-    mpcDecoder.isOutput = false;
-    mpcDecoder.isPause  = false;
-    threadHandle = g_thread_create(GThreadFunc(decodeStream), (void *) g_strdup(p_Filename), TRUE, NULL);
-}
-
-static void mpcStop()
-{
-    setAlive(false);
-    if (threadHandle)
-    {
-        g_thread_join(threadHandle);
-        if (mpcDecoder.isOutput)
-        {
-            MpcPlugin.output->buffer_free();
-            MpcPlugin.output->close_audio();
-            mpcDecoder.isOutput = false;
-        }
-    }
-}
-
-static void mpcPause(short p_Pause)
-{
-    lockAcquire();
-    mpcDecoder.isPause = p_Pause;
-    MpcPlugin.output->pause(p_Pause);
-    lockRelease();
-}
-
-static void mpcSeek(int p_Offset)
-{
-    lockAcquire();
-    mpcDecoder.offset = static_cast<double> (p_Offset);
-    MpcPlugin.output->flush(1000 * p_Offset);
-    lockRelease();
-}
-
-static void mpcSetEq(int on, float preamp, float* eq)
-{
-    pluginConfig.isEq = static_cast<bool> (on);
-    init_iir(on, preamp, eq);
-}
-
-static int mpcGetTime()
-{
-    if(!isAlive())
-        return -1;
-    return MpcPlugin.output->output_time();
-}
-
-static TitleInput *mpcGetSongTuple(char* p_Filename)
-{
-    FILE* input = fopen(p_Filename, "rb");
-    TitleInput *tuple = NULL;
-
-    if(input)
-    {
-        tuple = bmp_title_input_new();
-        gchar *filename_proxy = g_strdup(p_Filename);
-
-        tuple->file_name = g_path_get_basename(filename_proxy);
-        tuple->file_path = g_path_get_dirname(filename_proxy);
-        tuple->file_ext = "mpc";		// XXX: I can't be assed. -nenolod
-
-        MpcInfo tags = getTags(p_Filename);
-
-        tuple->date         = g_strdup(tags.date);
-        tuple->track_name   = g_strdup(tags.title);
-        tuple->performer    = g_strdup(tags.artist);
-        tuple->album_name   = g_strdup(tags.album);
-        tuple->track_number = tags.track;
-        tuple->year         = tags.year;
-        tuple->genre        = g_strdup(tags.genre);
-        tuple->comment      = g_strdup(tags.comment);
-
-        freeTags(tags);
-
-        mpc_streaminfo info;
-        mpc_reader_file reader;
-        mpc_reader_setup_file_reader(&reader, input);
-        mpc_streaminfo_read(&info, &reader.reader);
-
-        tuple->length = static_cast<int> (1000 * mpc_streaminfo_get_length(&info));
-        fclose(input);
-    }
-    else
-    {
-        char* temp = g_strdup_printf("[xmms-musepack] mpcGetSongInfo is unable to open %s\n", p_Filename);
-        perror(temp);
-        free(temp);
-    }
-
-    return tuple;
-}
-
-static void mpcGetSongInfo(char* p_Filename, char** p_Title, int* p_Length)
-{
-    FILE* input = fopen(p_Filename, "rb");
-    if(input)
-    {
-        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
-    {
-        char* temp = g_strdup_printf("[xmms-musepack] mpcGetSongInfo is unable to open %s\n", p_Filename);
-        perror(temp);
-        free(temp);
-    }
-}
-
-static void freeTags(MpcInfo& tags)
-{
-    free(tags.title);
-    free(tags.artist);
-    free(tags.album);
-    free(tags.comment);
-    free(tags.genre);
-    free(tags.date);
-}
-
-static MpcInfo getTags(const char* p_Filename)
-{
-    File oFile(p_Filename, false);
-    Tag* poTag = oFile.tag();
-    MpcInfo tags = {0};
-    tags.title   = g_strdup(poTag->title().toCString(true));
-    REMOVE_NONEXISTANT_TAG(tags.title);
-    tags.artist  = g_strdup(poTag->artist().toCString(true));
-    REMOVE_NONEXISTANT_TAG(tags.artist);
-    tags.album   = g_strdup(poTag->album().toCString(true));
-    REMOVE_NONEXISTANT_TAG(tags.album);
-    tags.genre   = g_strdup(poTag->genre().toCString(true));
-    REMOVE_NONEXISTANT_TAG(tags.genre);
-    tags.comment = g_strdup(poTag->comment().toCString(true));
-    REMOVE_NONEXISTANT_TAG(tags.comment);
-    tags.year    = poTag->year();
-    tags.track   = poTag->track();
-    TagLib::APE::Tag* ape = oFile.APETag(false);
-    if(ape)
-    {
-        ItemListMap map = ape->itemListMap();
-        if(map.contains("YEAR"))
-        {
-            tags.date = g_strdup(map["YEAR"].toString().toCString(true));
-        }
-        else
-        {
-            tags.date = g_strdup_printf("%d", tags.year);
-        }
-    }
-    return tags;
-}
-
-static void mpcFileInfoBox(char* p_Filename)
-{
-    GtkWidget* infoBox = widgets.infoBox;
-
-    if(infoBox)
-        gdk_window_raise(infoBox->window);
-    else
-    {
-        infoBox = gtk_window_new(GTK_WINDOW_TOPLEVEL);
-        gtk_window_set_type_hint(GTK_WINDOW(infoBox), GDK_WINDOW_TYPE_HINT_DIALOG);
-        widgets.infoBox = infoBox;
-        gtk_window_set_policy(GTK_WINDOW(infoBox), FALSE, FALSE, FALSE);
-        g_signal_connect(G_OBJECT(infoBox), "destroy", G_CALLBACK(closeInfoBox), NULL);
-        gtk_container_set_border_width(GTK_CONTAINER(infoBox), 10);
-
-        GtkWidget* iVbox = gtk_vbox_new(FALSE, 10);
-        gtk_container_add(GTK_CONTAINER(infoBox), iVbox);
-
-        GtkWidget* filenameHbox = gtk_hbox_new(FALSE, 5);
-        gtk_box_pack_start(GTK_BOX(iVbox), filenameHbox, FALSE, TRUE, 0);
-
-        GtkWidget* fileLabel = gtk_label_new("Filename:");
-        gtk_box_pack_start(GTK_BOX(filenameHbox), fileLabel, FALSE, TRUE, 0);
-
-        GtkWidget* fileEntry = gtk_entry_new();
-        widgets.fileEntry = fileEntry;
-        gtk_editable_set_editable(GTK_EDITABLE(fileEntry), FALSE);
-        gtk_box_pack_start(GTK_BOX(filenameHbox), fileEntry, TRUE, TRUE, 0);
-
-        GtkWidget* iHbox = gtk_hbox_new(FALSE, 10);
-        gtk_box_pack_start(GTK_BOX(iVbox), iHbox, FALSE, TRUE, 0);
-
-        GtkWidget* leftBox = gtk_vbox_new(FALSE, 10);
-        gtk_box_pack_start(GTK_BOX(iHbox), leftBox, FALSE, FALSE, 0);
-
-        //Tag labels
-        GtkWidget* tagFrame = gtk_frame_new("Musepack Tag");
-        gtk_box_pack_start(GTK_BOX(leftBox), tagFrame, FALSE, FALSE, 0);
-        gtk_widget_set_sensitive(tagFrame, TRUE);
-
-        GtkWidget* iTable = gtk_table_new(5, 5, FALSE);
-        gtk_container_set_border_width(GTK_CONTAINER(iTable), 5);
-        gtk_container_add(GTK_CONTAINER(tagFrame), iTable);
-
-        mpcGtkTagLabel("Title:", 0, 1, 0, 1, iTable);
-        GtkWidget* titleEntry = mpcGtkTagEntry(1, 4, 0, 1, 0, iTable);
-        widgets.titleEntry = titleEntry;
-
-        mpcGtkTagLabel("Artist:", 0, 1, 1, 2, iTable);
-        GtkWidget* artistEntry = mpcGtkTagEntry(1, 4, 1, 2, 0, iTable);
-        widgets.artistEntry = artistEntry;
-
-        mpcGtkTagLabel("Album:", 0, 1, 2, 3, iTable);
-        GtkWidget* albumEntry = mpcGtkTagEntry(1, 4, 2, 3, 0, iTable);
-        widgets.albumEntry = albumEntry;
-
-        mpcGtkTagLabel("Comment:", 0, 1, 3, 4, iTable);
-        GtkWidget* commentEntry = mpcGtkTagEntry(1, 4, 3, 4, 0, iTable);
-        widgets.commentEntry = commentEntry;
-
-        mpcGtkTagLabel("Year:", 0, 1, 4, 5, iTable);
-        GtkWidget* yearEntry = mpcGtkTagEntry(1, 2, 4, 5, 4, iTable);
-        widgets.yearEntry = yearEntry;
-        gtk_widget_set_usize(yearEntry, 4, -1);
-
-        mpcGtkTagLabel("Track:", 2, 3, 4, 5, iTable);
-        GtkWidget* trackEntry = mpcGtkTagEntry(3, 4, 4, 5, 4, iTable);
-        widgets.trackEntry = trackEntry;
-        gtk_widget_set_usize(trackEntry, 3, -1);
-
-        mpcGtkTagLabel("Genre:", 0, 1, 5, 6, iTable);
-        GtkWidget* genreEntry = mpcGtkTagEntry(1, 4, 5, 6, 0, iTable);
-        widgets.genreEntry = genreEntry;
-        gtk_widget_set_usize(genreEntry, 20, -1);
-
-        //Buttons
-        GtkWidget* buttonBox = gtk_hbutton_box_new();
-        gtk_button_box_set_layout(GTK_BUTTON_BOX(buttonBox), GTK_BUTTONBOX_END);
-        gtk_button_box_set_spacing(GTK_BUTTON_BOX(buttonBox), 5);
-        gtk_box_pack_start(GTK_BOX(leftBox), buttonBox, FALSE, FALSE, 0);
-
-        GtkWidget* saveButton = mpcGtkButton("Save", buttonBox);
-        g_signal_connect(G_OBJECT(saveButton), "clicked", G_CALLBACK(saveTags), NULL);
-
-        GtkWidget* removeButton = mpcGtkButton("Remove Tag", buttonBox);
-        g_signal_connect_swapped(G_OBJECT(removeButton), "clicked", G_CALLBACK(removeTags), NULL);
-
-        GtkWidget* cancelButton = mpcGtkButton("Cancel", buttonBox);
-        g_signal_connect_swapped(G_OBJECT(cancelButton), "clicked", G_CALLBACK(closeInfoBox), NULL);
-        gtk_widget_grab_default(cancelButton);
-
-        //File information
-        GtkWidget* infoFrame = gtk_frame_new("Musepack Info");
-        gtk_box_pack_start(GTK_BOX(iHbox), infoFrame, FALSE, FALSE, 0);
-
-        GtkWidget* infoVbox = gtk_vbox_new(FALSE, 5);
-        gtk_container_add(GTK_CONTAINER(infoFrame), infoVbox);
-        gtk_container_set_border_width(GTK_CONTAINER(infoVbox), 10);
-        gtk_box_set_spacing(GTK_BOX(infoVbox), 0);
-
-        GtkWidget* streamLabel    = mpcGtkLabel(infoVbox);
-        GtkWidget* encoderLabel   = mpcGtkLabel(infoVbox);
-        GtkWidget* profileLabel   = mpcGtkLabel(infoVbox);
-        GtkWidget* bitrateLabel   = mpcGtkLabel(infoVbox);
-        GtkWidget* rateLabel      = mpcGtkLabel(infoVbox);
-        GtkWidget* channelsLabel  = mpcGtkLabel(infoVbox);
-        GtkWidget* lengthLabel    = mpcGtkLabel(infoVbox);
-        GtkWidget* fileSizeLabel  = mpcGtkLabel(infoVbox);
-        GtkWidget* trackPeakLabel = mpcGtkLabel(infoVbox);
-        GtkWidget* trackGainLabel = mpcGtkLabel(infoVbox);
-        GtkWidget* albumPeakLabel = mpcGtkLabel(infoVbox);
-        GtkWidget* albumGainLabel = mpcGtkLabel(infoVbox);
-
-        FILE* input = fopen(p_Filename, "rb");
-        if(input)
-        {
-            mpc_streaminfo info;
-            mpc_reader_file reader;
-            mpc_reader_setup_file_reader(&reader, input);
-            mpc_streaminfo_read(&info, &reader.reader);
-
-            int time = static_cast<int> (mpc_streaminfo_get_length(&info));
-            int minutes = time / 60;
-            int seconds = time % 60;
-
-            mpcGtkPrintLabel(streamLabel,    "Streamversion %d", info.stream_version);
-            mpcGtkPrintLabel(encoderLabel,   "Encoder: \%s", info.encoder);
-            mpcGtkPrintLabel(profileLabel,   "Profile: \%s", info.profile_name);
-            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(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);
-
-            MpcInfo tags = getTags(p_Filename);
-            gtk_entry_set_text(GTK_ENTRY(titleEntry),   tags.title);
-            gtk_entry_set_text(GTK_ENTRY(artistEntry),  tags.artist);
-            gtk_entry_set_text(GTK_ENTRY(albumEntry),   tags.album);
-            gtk_entry_set_text(GTK_ENTRY(commentEntry), tags.comment);
-            gtk_entry_set_text(GTK_ENTRY(genreEntry),   tags.genre);
-            char* entry = g_strdup_printf ("%d", tags.track);
-            gtk_entry_set_text(GTK_ENTRY(trackEntry), entry);
-            free(entry);
-            entry = g_strdup_printf ("%d", tags.year);
-            gtk_entry_set_text(GTK_ENTRY(yearEntry), entry);
-            free(entry);
-            entry = g_filename_display_name(p_Filename);
-            gtk_entry_set_text(GTK_ENTRY(fileEntry), entry);
-            free(entry);
-            freeTags(tags);
-            fclose(input);
-        }
-        else
-        {
-            char* temp = g_strdup_printf("[xmms-musepack] mpcFileInfoBox is unable to read tags from %s", p_Filename);
-            perror(temp);
-            free(temp);
-        }
-
-	char* name = g_filename_display_basename(p_Filename);
-        char* text = g_strdup_printf("File Info - %s", name);
-        free(name);
-        gtk_window_set_title(GTK_WINDOW(infoBox), text);
-        free(text);
-
-        gtk_widget_show_all(infoBox);
-    }
-}
-
-static void mpcGtkPrintLabel(GtkWidget* widget, char* format,...)
-{
-    va_list args;
-
-    va_start(args, format);
-    char* temp = g_strdup_vprintf(format, args);
-    va_end(args);
-
-    gtk_label_set_text(GTK_LABEL(widget), temp);
-    free(temp);
-}
-
-static GtkWidget* mpcGtkTagLabel(char* p_Text, int a, int b, int c, int d, GtkWidget* p_Box)
-{
-    GtkWidget* label = gtk_label_new(p_Text);
-    gtk_misc_set_alignment(GTK_MISC(label), 1, 0.5);
-    gtk_table_attach(GTK_TABLE(p_Box), label, a, b, c, d, GTK_FILL, GTK_FILL, 5, 5);
-    return label;
-}
-
-static GtkWidget* mpcGtkTagEntry(int a, int b, int c, int d, int p_Size, GtkWidget* p_Box)
-{
-    GtkWidget* entry;
-    if(p_Size == 0)
-        entry = gtk_entry_new();
-    else
-        entry = gtk_entry_new_with_max_length(p_Size);
-    gtk_table_attach(GTK_TABLE(p_Box), entry, a, b, c, d,
-                    (GtkAttachOptions) (GTK_FILL | GTK_EXPAND | GTK_SHRINK),
-                    (GtkAttachOptions) (GTK_FILL | GTK_EXPAND | GTK_SHRINK), 0, 5);
-    return entry;
-}
-
-static GtkWidget* mpcGtkLabel(GtkWidget* p_Box)
-{
-    GtkWidget* label = gtk_label_new("");
-    gtk_misc_set_alignment(GTK_MISC(label), 0, 0);
-    gtk_label_set_justify(GTK_LABEL(label), GTK_JUSTIFY_LEFT);
-    gtk_box_pack_start(GTK_BOX(p_Box), label, FALSE, FALSE, 0);
-    return label;
-}
-
-static GtkWidget* mpcGtkButton(char* p_Text, GtkWidget* p_Box)
-{
-    GtkWidget* button = gtk_button_new_with_label(p_Text);
-    GTK_WIDGET_SET_FLAGS(button, GTK_CAN_DEFAULT);
-    gtk_box_pack_start(GTK_BOX(p_Box), button, TRUE, TRUE, 0);
-    return button;
-}
-
-static void removeTags(GtkWidget * w, gpointer data)
-{
-    File oFile(gtk_entry_get_text(GTK_ENTRY(widgets.fileEntry)));
-    oFile.remove();
-    oFile.save();
-    closeInfoBox(NULL, NULL);
-}
-
-static void saveTags(GtkWidget* w, gpointer data)
-{
-    File oFile(gtk_entry_get_text(GTK_ENTRY(widgets.fileEntry)));
-    Tag* poTag = oFile.tag();
-
-    char* cAlbum   = g_strdup(gtk_entry_get_text(GTK_ENTRY(widgets.albumEntry)));
-    char* cArtist  = g_strdup(gtk_entry_get_text(GTK_ENTRY(widgets.artistEntry)));
-    char* cTitle   = g_strdup(gtk_entry_get_text(GTK_ENTRY(widgets.titleEntry)));
-    char* cGenre   = g_strdup(gtk_entry_get_text(GTK_ENTRY(widgets.genreEntry)));
-    char* cComment = g_strdup(gtk_entry_get_text(GTK_ENTRY(widgets.commentEntry)));
-
-    const String album   = String(cAlbum,   TagLib::String::UTF8);
-    const String artist  = String(cArtist,  TagLib::String::UTF8);
-    const String title   = String(cTitle,   TagLib::String::UTF8);
-    const String genre   = String(cGenre,   TagLib::String::UTF8);
-    const String comment = String(cComment, TagLib::String::UTF8);
-
-    poTag->setAlbum(album);
-    poTag->setArtist(artist);
-    poTag->setTitle(title);
-    poTag->setGenre(genre);
-    poTag->setComment(comment);
-    poTag->setYear(atoi(gtk_entry_get_text(GTK_ENTRY(widgets.yearEntry))));
-    poTag->setTrack(atoi(gtk_entry_get_text(GTK_ENTRY(widgets.trackEntry))));
-
-    free(cAlbum);
-    free(cArtist);
-    free(cTitle);
-    free(cGenre);
-    free(cComment);
-
-    oFile.save();
-    closeInfoBox(NULL, NULL);
-}
-
-static void closeInfoBox(GtkWidget* w, gpointer data)
-{
-    gtk_widget_destroy(widgets.infoBox);
-    widgets.infoBox = NULL;
-}
-
-static char* mpcGenerateTitle(const MpcInfo& p_Tags, char* p_Filename)
-{
-    TitleInput* tuple = mpcGetSongTuple(p_Filename);
-
-    char* title = xmms_get_titlestring (xmms_get_gentitle_format(), tuple);
-    if(!title)
-        title = g_strdup(tuple->file_name);
-    else if (!*title)
-        title = g_strdup(tuple->file_name);
-
-    bmp_title_input_free(tuple);
-    return title;
-}
-
-static void* endThread(char* p_FileName, FILE* p_FileHandle, bool release)
-{
-    free(p_FileName);
-    if(release)
-        lockRelease();
-    if(mpcDecoder.isError)
-    {
-        perror(mpcDecoder.isError);
-        free(mpcDecoder.isError);
-        mpcDecoder.isError = NULL;
-    }
-    setAlive(false);
-    if(p_FileHandle)
-        fclose(p_FileHandle);
-    if(track.display)
-    {
-        free(track.display);
-        track.display = NULL;
-    }
-    g_thread_exit(NULL);
-    return 0;
-}
-
-static void* decodeStream(void* data)
-{
-    lockAcquire();
-    char* filename = static_cast<char*> (data);
-    FILE* input = fopen(filename, "rb");
-    if (!input)
-    {
-        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;
-    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);
-
-    MPC_SAMPLE_FORMAT sampleBuffer[MPC_DECODER_BUFFER_LENGTH];
-    char xmmsBuffer[MPC_DECODER_BUFFER_LENGTH * 4];
-
-    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);
-    }
-    else
-    {
-        mpcDecoder.isOutput = true;
-    }
-
-    lockRelease();
-
-    int counter = 2 * track.sampleFreq / 3;
-    while (isAlive())
-    {
-        if (getOffset() != -1)
-        {
-            mpc_decoder_seek_seconds(&decoder, mpcDecoder.offset);
-            setOffset(-1);
-        }
-
-        lockAcquire();
-        short iPlaying = MpcPlugin.output->buffer_playing()? 1 : 0;
-        int iFree = MpcPlugin.output->buffer_free();
-        if (!mpcDecoder.isPause &&  iFree >= ((1152 * 4) << iPlaying))
-        {
-            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);
-            }
-            if (status == 0 && iPlaying == 0)
-                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;
-                }
-            }
-        }
-        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);
-
-    if (pluginConfig.dynamicBitrate)
-    {
-        track.bitrate = static_cast<int> (vbrUpd * track.sampleFreq / 1152);
-    }
-
-    produce_audio(MpcPlugin.output->written_time(), FMT_S16_LE, track.channels, status * 4, xmmsBuffer, NULL);
-    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);
-}
-
-inline static void lockAcquire()
-{
-    g_static_mutex_lock(&threadMutex);
-}
-
-inline static void lockRelease()
-{
-    g_static_mutex_unlock(&threadMutex);
-}
-
-inline static bool isAlive()
-{
-    lockAcquire();
-    bool isAlive = mpcDecoder.isAlive;
-    lockRelease();
-    return isAlive;
-}
-
-inline static bool isPause()
-{
-    lockAcquire();
-    bool isPause = mpcDecoder.isPause;
-    lockRelease();
-    return isPause;
-}
-
-inline static void setAlive(bool isAlive)
-{
-    lockAcquire();
-    mpcDecoder.isAlive = isAlive;
-    lockRelease();
-}
-
-inline static double getOffset()
-{
-    lockAcquire();
-    double offset = mpcDecoder.offset;
-    lockRelease();
-    return offset;
-}
-
-inline static void setOffset(double offset)
-{
-    lockAcquire();
-    mpcDecoder.offset = offset;
-    lockRelease();
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Plugins/Input/musepack/libmpc.cxx	Fri Sep 15 06:36:26 2006 -0700
@@ -0,0 +1,880 @@
+#include "libmpc.h"
+
+#define FORCED_THREAD_STACKSIZE 1024 * 1000
+#define REMOVE_NONEXISTANT_TAG(x)   if (!*x) { x = NULL; }
+
+using TagLib::MPC::File;
+using TagLib::Tag;
+using TagLib::String;
+using TagLib::APE::ItemListMap;
+
+InputPlugin MpcPlugin = {
+    NULL,           //File Handle               FILE* handle
+    NULL,           //Filename                  char* filename
+    NULL,           //Name of Plugin            char* filename
+    mpcOpenPlugin,  //Open Plugin               [CALLBACK]
+    mpcAboutBox,    //Show About box            [CALLBACK]
+    mpcConfigBox,   //Show Configure box        [CALLBACK]
+    mpcIsOurFile,   //Check if it's our file    [CALLBACK]
+    NULL,           //Scan the directory        [UNUSED]
+    mpcPlay,        //Play                      [CALLBACK]
+    mpcStop,        //Stop                      [CALLBACK]
+    mpcPause,       //Pause                     [CALLBACK]
+    mpcSeek,        //Seek                      [CALLBACK]
+    mpcSetEq,       //Set EQ                    [CALLBACK]
+    mpcGetTime,     //Get Time                  [CALLBACK]
+    NULL,           //Get Volume                [UNUSED]
+    NULL,           //Set Volume                [UNUSED]
+    NULL,           //Close Plugin              [UNUSED]
+    NULL,           //Obsolete                  [UNUSED]
+    NULL,           //Visual plugins            add_vis_pcm(int time, AFormat fmt, int nch, int length, void *ptr)
+    NULL,           //Set Info Settings         set_info(char *title, int length, int rate, int freq, int nch)
+    NULL,           //set Info Text             set_info_text(char* text)
+    mpcGetSongInfo, //Get Title String callback [CALLBACK]
+    mpcFileInfoBox, //Show File Info Box        [CALLBACK]
+    NULL,           //Output Plugin Handle      OutputPlugin output
+    mpcGetSongTuple,
+};
+
+extern "C"
+InputPlugin* get_iplugin_info()
+{
+    MpcPlugin.description = g_strdup_printf("Musepack Audio Plugin");
+    return &MpcPlugin;
+}
+
+static PluginConfig pluginConfig = {0};
+static Widgets      widgets      = {0};
+static MpcDecoder   mpcDecoder   = {0};
+static TrackInfo    track        = {0};
+
+static GThread            *threadHandle;
+GStaticMutex threadMutex = G_STATIC_MUTEX_INIT;
+
+static void mpcOpenPlugin()
+{
+    ConfigDb *cfg;
+    cfg = bmp_cfg_db_open();
+    bmp_cfg_db_get_bool(cfg, "musepack", "clipPrevention", &pluginConfig.clipPrevention);
+    bmp_cfg_db_get_bool(cfg, "musepack", "albumGain",      &pluginConfig.albumGain);
+    bmp_cfg_db_get_bool(cfg, "musepack", "dynamicBitrate", &pluginConfig.dynamicBitrate);
+    bmp_cfg_db_get_bool(cfg, "musepack", "replaygain",     &pluginConfig.replaygain);
+    bmp_cfg_db_close(cfg);
+}
+
+static void mpcAboutBox()
+{
+    GtkWidget* aboutBox = widgets.aboutBox;
+    if (aboutBox)
+        gdk_window_raise(aboutBox->window);
+    else
+    {
+        char* titleText      = g_strdup_printf("Musepack Decoder Plugin 1.2");
+        char* contentText = "Plugin code by\nBenoit Amiaux\nMartin Spuler\nKuniklo\n\nGet latest version at http://musepack.net\n";
+        char* buttonText  = "Nevermind";
+        aboutBox = xmms_show_message(titleText, contentText, buttonText, FALSE, NULL, NULL);
+        widgets.aboutBox = aboutBox;
+        g_signal_connect(G_OBJECT(aboutBox), "destroy", G_CALLBACK(gtk_widget_destroyed), &widgets.aboutBox);
+    }
+}
+
+static void mpcConfigBox()
+{
+    GtkWidget* configBox = widgets.configBox;
+    if(configBox)
+        gdk_window_raise(configBox->window);
+    else
+    {
+        configBox = gtk_window_new(GTK_WINDOW_TOPLEVEL);
+        gtk_window_set_type_hint(GTK_WINDOW(configBox), GDK_WINDOW_TYPE_HINT_DIALOG);
+        widgets.configBox = configBox;
+        g_signal_connect(G_OBJECT(configBox), "destroy", G_CALLBACK(gtk_widget_destroyed), &widgets.configBox);
+        gtk_window_set_title(GTK_WINDOW(configBox), "Musepack Decoder Configuration");
+        gtk_window_set_policy(GTK_WINDOW(configBox), FALSE, FALSE, FALSE);
+        gtk_container_border_width(GTK_CONTAINER(configBox), 10);
+
+        GtkWidget* notebook = gtk_notebook_new();
+        GtkWidget* vbox = gtk_vbox_new(FALSE, 10);
+        gtk_box_pack_start(GTK_BOX(vbox), notebook, TRUE, TRUE, 0);
+        gtk_container_add(GTK_CONTAINER(configBox), vbox);
+
+        //General Settings Tab
+        GtkWidget* generalSet = gtk_frame_new("General Settings");
+        gtk_container_border_width(GTK_CONTAINER(generalSet), 5);
+
+        GtkWidget* gSvbox = gtk_vbox_new(FALSE, 10);
+        gtk_container_border_width(GTK_CONTAINER(gSvbox), 5);
+        gtk_container_add(GTK_CONTAINER(generalSet), gSvbox);
+
+        GtkWidget* bitrateCheck = gtk_check_button_new_with_label("Enable Dynamic Bitrate Display");
+        widgets.bitrateCheck = bitrateCheck;
+        gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(bitrateCheck), pluginConfig.dynamicBitrate);
+        gtk_box_pack_start(GTK_BOX(gSvbox), bitrateCheck, FALSE, FALSE, 0);
+        gtk_notebook_append_page(GTK_NOTEBOOK(notebook), generalSet, gtk_label_new("Plugin"));
+
+        //ReplayGain Settings Tab
+        GtkWidget* replaygainSet = gtk_frame_new("ReplayGain Settings");
+        gtk_container_border_width(GTK_CONTAINER(replaygainSet), 5);
+
+        GtkWidget* rSVbox = gtk_vbox_new(FALSE, 10);
+        gtk_container_border_width(GTK_CONTAINER(rSVbox), 5);
+        gtk_container_add(GTK_CONTAINER(replaygainSet), rSVbox);
+
+        GtkWidget* clippingCheck = gtk_check_button_new_with_label("Enable Clipping Prevention");
+        widgets.clippingCheck = clippingCheck;
+        gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(clippingCheck), pluginConfig.clipPrevention);
+        gtk_box_pack_start(GTK_BOX(rSVbox), clippingCheck, FALSE, FALSE, 0);
+
+        GtkWidget* replaygainCheck = gtk_check_button_new_with_label("Enable ReplayGain");
+        widgets.replaygainCheck = replaygainCheck;
+        gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(replaygainCheck), pluginConfig.replaygain);
+        gtk_box_pack_start(GTK_BOX(rSVbox), replaygainCheck, FALSE, FALSE, 0);
+
+        GtkWidget* replaygainType = gtk_frame_new("ReplayGain Type");
+        gtk_box_pack_start(GTK_BOX(rSVbox), replaygainType, FALSE, FALSE, 0);
+        g_signal_connect(G_OBJECT(replaygainCheck), "toggled", G_CALLBACK(toggleSwitch), replaygainType);
+
+        GtkWidget* rgVbox = gtk_vbox_new(FALSE, 5);
+        gtk_container_set_border_width(GTK_CONTAINER(rgVbox), 5);
+        gtk_container_add(GTK_CONTAINER(replaygainType), rgVbox);
+
+        GtkWidget* trackCheck = gtk_radio_button_new_with_label(NULL, "Use Track Gain");
+        gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(trackCheck), !pluginConfig.albumGain);
+        gtk_box_pack_start(GTK_BOX(rgVbox), trackCheck, FALSE, FALSE, 0);
+
+        GtkWidget* albumCheck = gtk_radio_button_new_with_label(gtk_radio_button_group(GTK_RADIO_BUTTON(trackCheck)), "Use Album Gain");
+        widgets.albumCheck = albumCheck;
+        gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(albumCheck), pluginConfig.albumGain);
+        gtk_box_pack_start(GTK_BOX(rgVbox), albumCheck, FALSE, FALSE, 0);
+        gtk_widget_set_sensitive(replaygainType, pluginConfig.replaygain);
+        gtk_notebook_append_page(GTK_NOTEBOOK(notebook), replaygainSet, gtk_label_new("ReplayGain"));
+
+        //Buttons
+        GtkWidget* buttonBox = gtk_hbutton_box_new();
+        gtk_button_box_set_layout(GTK_BUTTON_BOX(buttonBox), GTK_BUTTONBOX_END);
+        gtk_button_box_set_spacing(GTK_BUTTON_BOX(buttonBox), 5);
+        gtk_box_pack_start(GTK_BOX(vbox), buttonBox, FALSE, FALSE, 0);
+
+        GtkWidget* okButton = gtk_button_new_with_label("Ok");
+        g_signal_connect(G_OBJECT(okButton), "clicked", G_CALLBACK(saveConfigBox), NULL);
+        GTK_WIDGET_SET_FLAGS(okButton, GTK_CAN_DEFAULT);
+        gtk_box_pack_start(GTK_BOX(buttonBox), okButton, TRUE, TRUE, 0);
+
+        GtkWidget* cancelButton = gtk_button_new_with_label("Cancel");
+        g_signal_connect_swapped(G_OBJECT(cancelButton), "clicked", G_CALLBACK(gtk_widget_destroy), GTK_OBJECT(widgets.configBox));
+        GTK_WIDGET_SET_FLAGS(cancelButton, GTK_CAN_DEFAULT);
+        gtk_widget_grab_default(cancelButton);
+        gtk_box_pack_start(GTK_BOX(buttonBox), cancelButton, TRUE, TRUE, 0);
+
+        gtk_widget_show_all(configBox);
+    }
+}
+
+static void toggleSwitch(GtkWidget* p_Widget, gpointer p_Data)
+{
+    gtk_widget_set_sensitive(GTK_WIDGET(p_Data), gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(p_Widget)));
+}
+
+static void saveConfigBox(GtkWidget* p_Widget, gpointer p_Data)
+{
+    ConfigDb* cfg;
+    GtkToggleButton* tb;
+
+    tb = GTK_TOGGLE_BUTTON(widgets.replaygainCheck);
+    pluginConfig.replaygain = gtk_toggle_button_get_active(tb);
+    tb = GTK_TOGGLE_BUTTON(widgets.clippingCheck);
+    pluginConfig.clipPrevention = gtk_toggle_button_get_active(tb);
+    tb = GTK_TOGGLE_BUTTON(widgets.bitrateCheck);
+    pluginConfig.dynamicBitrate = gtk_toggle_button_get_active(tb);
+    tb = GTK_TOGGLE_BUTTON(widgets.albumCheck);
+    pluginConfig.albumGain = gtk_toggle_button_get_active(tb);
+
+    cfg = bmp_cfg_db_open();
+
+    bmp_cfg_db_set_bool(cfg, "musepack", "clipPrevention", pluginConfig.clipPrevention);
+    bmp_cfg_db_set_bool(cfg, "musepack", "albumGain",      pluginConfig.albumGain);
+    bmp_cfg_db_set_bool(cfg, "musepack", "dynamicBitrate", pluginConfig.dynamicBitrate);
+    bmp_cfg_db_set_bool(cfg, "musepack", "replaygain",     pluginConfig.replaygain);
+
+    bmp_cfg_db_close(cfg);
+
+    gtk_widget_destroy (widgets.configBox);
+}
+
+static int mpcIsOurFile(char* p_Filename)
+{
+   VFSFile *file;
+   gchar magic[3];
+   if ((file = vfs_fopen(p_Filename, "rb"))) {
+       vfs_fread(magic, 1, 3, file);
+       if (!strncmp(magic, "MP+", 3)) {
+            vfs_fclose(file);
+            return 1;
+       }
+       vfs_fclose(file);
+   }
+   return 0;
+}
+
+static void mpcPlay(char* p_Filename)
+{
+    mpcDecoder.offset   = -1;
+    mpcDecoder.isAlive  = true;
+    mpcDecoder.isOutput = false;
+    mpcDecoder.isPause  = false;
+    threadHandle = g_thread_create(GThreadFunc(decodeStream), (void *) g_strdup(p_Filename), TRUE, NULL);
+}
+
+static void mpcStop()
+{
+    setAlive(false);
+    if (threadHandle)
+    {
+        g_thread_join(threadHandle);
+        if (mpcDecoder.isOutput)
+        {
+            MpcPlugin.output->buffer_free();
+            MpcPlugin.output->close_audio();
+            mpcDecoder.isOutput = false;
+        }
+    }
+}
+
+static void mpcPause(short p_Pause)
+{
+    lockAcquire();
+    mpcDecoder.isPause = p_Pause;
+    MpcPlugin.output->pause(p_Pause);
+    lockRelease();
+}
+
+static void mpcSeek(int p_Offset)
+{
+    lockAcquire();
+    mpcDecoder.offset = static_cast<double> (p_Offset);
+    MpcPlugin.output->flush(1000 * p_Offset);
+    lockRelease();
+}
+
+static void mpcSetEq(int on, float preamp, float* eq)
+{
+    pluginConfig.isEq = static_cast<bool> (on);
+    init_iir(on, preamp, eq);
+}
+
+static int mpcGetTime()
+{
+    if(!isAlive())
+        return -1;
+    return MpcPlugin.output->output_time();
+}
+
+static TitleInput *mpcGetSongTuple(char* p_Filename)
+{
+    FILE* input = fopen(p_Filename, "rb");
+    TitleInput *tuple = NULL;
+
+    if(input)
+    {
+        tuple = bmp_title_input_new();
+        gchar *filename_proxy = g_strdup(p_Filename);
+
+        tuple->file_name = g_path_get_basename(filename_proxy);
+        tuple->file_path = g_path_get_dirname(filename_proxy);
+        tuple->file_ext = "mpc";		// XXX: I can't be assed. -nenolod
+
+        MpcInfo tags = getTags(p_Filename);
+
+        tuple->date         = g_strdup(tags.date);
+        tuple->track_name   = g_strdup(tags.title);
+        tuple->performer    = g_strdup(tags.artist);
+        tuple->album_name   = g_strdup(tags.album);
+        tuple->track_number = tags.track;
+        tuple->year         = tags.year;
+        tuple->genre        = g_strdup(tags.genre);
+        tuple->comment      = g_strdup(tags.comment);
+
+        freeTags(tags);
+
+        mpc_streaminfo info;
+        mpc_reader_file reader;
+        mpc_reader_setup_file_reader(&reader, input);
+        mpc_streaminfo_read(&info, &reader.reader);
+
+        tuple->length = static_cast<int> (1000 * mpc_streaminfo_get_length(&info));
+        fclose(input);
+    }
+    else
+    {
+        char* temp = g_strdup_printf("[xmms-musepack] mpcGetSongInfo is unable to open %s\n", p_Filename);
+        perror(temp);
+        free(temp);
+    }
+
+    return tuple;
+}
+
+static void mpcGetSongInfo(char* p_Filename, char** p_Title, int* p_Length)
+{
+    FILE* input = fopen(p_Filename, "rb");
+    if(input)
+    {
+        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
+    {
+        char* temp = g_strdup_printf("[xmms-musepack] mpcGetSongInfo is unable to open %s\n", p_Filename);
+        perror(temp);
+        free(temp);
+    }
+}
+
+static void freeTags(MpcInfo& tags)
+{
+    free(tags.title);
+    free(tags.artist);
+    free(tags.album);
+    free(tags.comment);
+    free(tags.genre);
+    free(tags.date);
+}
+
+static MpcInfo getTags(const char* p_Filename)
+{
+    File oFile(p_Filename, false);
+    Tag* poTag = oFile.tag();
+    MpcInfo tags = {0};
+    tags.title   = g_strdup(poTag->title().toCString(true));
+    REMOVE_NONEXISTANT_TAG(tags.title);
+    tags.artist  = g_strdup(poTag->artist().toCString(true));
+    REMOVE_NONEXISTANT_TAG(tags.artist);
+    tags.album   = g_strdup(poTag->album().toCString(true));
+    REMOVE_NONEXISTANT_TAG(tags.album);
+    tags.genre   = g_strdup(poTag->genre().toCString(true));
+    REMOVE_NONEXISTANT_TAG(tags.genre);
+    tags.comment = g_strdup(poTag->comment().toCString(true));
+    REMOVE_NONEXISTANT_TAG(tags.comment);
+    tags.year    = poTag->year();
+    tags.track   = poTag->track();
+    TagLib::APE::Tag* ape = oFile.APETag(false);
+    if(ape)
+    {
+        ItemListMap map = ape->itemListMap();
+        if(map.contains("YEAR"))
+        {
+            tags.date = g_strdup(map["YEAR"].toString().toCString(true));
+        }
+        else
+        {
+            tags.date = g_strdup_printf("%d", tags.year);
+        }
+    }
+    return tags;
+}
+
+static void mpcFileInfoBox(char* p_Filename)
+{
+    GtkWidget* infoBox = widgets.infoBox;
+
+    if(infoBox)
+        gdk_window_raise(infoBox->window);
+    else
+    {
+        infoBox = gtk_window_new(GTK_WINDOW_TOPLEVEL);
+        gtk_window_set_type_hint(GTK_WINDOW(infoBox), GDK_WINDOW_TYPE_HINT_DIALOG);
+        widgets.infoBox = infoBox;
+        gtk_window_set_policy(GTK_WINDOW(infoBox), FALSE, FALSE, FALSE);
+        g_signal_connect(G_OBJECT(infoBox), "destroy", G_CALLBACK(closeInfoBox), NULL);
+        gtk_container_set_border_width(GTK_CONTAINER(infoBox), 10);
+
+        GtkWidget* iVbox = gtk_vbox_new(FALSE, 10);
+        gtk_container_add(GTK_CONTAINER(infoBox), iVbox);
+
+        GtkWidget* filenameHbox = gtk_hbox_new(FALSE, 5);
+        gtk_box_pack_start(GTK_BOX(iVbox), filenameHbox, FALSE, TRUE, 0);
+
+        GtkWidget* fileLabel = gtk_label_new("Filename:");
+        gtk_box_pack_start(GTK_BOX(filenameHbox), fileLabel, FALSE, TRUE, 0);
+
+        GtkWidget* fileEntry = gtk_entry_new();
+        widgets.fileEntry = fileEntry;
+        gtk_editable_set_editable(GTK_EDITABLE(fileEntry), FALSE);
+        gtk_box_pack_start(GTK_BOX(filenameHbox), fileEntry, TRUE, TRUE, 0);
+
+        GtkWidget* iHbox = gtk_hbox_new(FALSE, 10);
+        gtk_box_pack_start(GTK_BOX(iVbox), iHbox, FALSE, TRUE, 0);
+
+        GtkWidget* leftBox = gtk_vbox_new(FALSE, 10);
+        gtk_box_pack_start(GTK_BOX(iHbox), leftBox, FALSE, FALSE, 0);
+
+        //Tag labels
+        GtkWidget* tagFrame = gtk_frame_new("Musepack Tag");
+        gtk_box_pack_start(GTK_BOX(leftBox), tagFrame, FALSE, FALSE, 0);
+        gtk_widget_set_sensitive(tagFrame, TRUE);
+
+        GtkWidget* iTable = gtk_table_new(5, 5, FALSE);
+        gtk_container_set_border_width(GTK_CONTAINER(iTable), 5);
+        gtk_container_add(GTK_CONTAINER(tagFrame), iTable);
+
+        mpcGtkTagLabel("Title:", 0, 1, 0, 1, iTable);
+        GtkWidget* titleEntry = mpcGtkTagEntry(1, 4, 0, 1, 0, iTable);
+        widgets.titleEntry = titleEntry;
+
+        mpcGtkTagLabel("Artist:", 0, 1, 1, 2, iTable);
+        GtkWidget* artistEntry = mpcGtkTagEntry(1, 4, 1, 2, 0, iTable);
+        widgets.artistEntry = artistEntry;
+
+        mpcGtkTagLabel("Album:", 0, 1, 2, 3, iTable);
+        GtkWidget* albumEntry = mpcGtkTagEntry(1, 4, 2, 3, 0, iTable);
+        widgets.albumEntry = albumEntry;
+
+        mpcGtkTagLabel("Comment:", 0, 1, 3, 4, iTable);
+        GtkWidget* commentEntry = mpcGtkTagEntry(1, 4, 3, 4, 0, iTable);
+        widgets.commentEntry = commentEntry;
+
+        mpcGtkTagLabel("Year:", 0, 1, 4, 5, iTable);
+        GtkWidget* yearEntry = mpcGtkTagEntry(1, 2, 4, 5, 4, iTable);
+        widgets.yearEntry = yearEntry;
+        gtk_widget_set_usize(yearEntry, 4, -1);
+
+        mpcGtkTagLabel("Track:", 2, 3, 4, 5, iTable);
+        GtkWidget* trackEntry = mpcGtkTagEntry(3, 4, 4, 5, 4, iTable);
+        widgets.trackEntry = trackEntry;
+        gtk_widget_set_usize(trackEntry, 3, -1);
+
+        mpcGtkTagLabel("Genre:", 0, 1, 5, 6, iTable);
+        GtkWidget* genreEntry = mpcGtkTagEntry(1, 4, 5, 6, 0, iTable);
+        widgets.genreEntry = genreEntry;
+        gtk_widget_set_usize(genreEntry, 20, -1);
+
+        //Buttons
+        GtkWidget* buttonBox = gtk_hbutton_box_new();
+        gtk_button_box_set_layout(GTK_BUTTON_BOX(buttonBox), GTK_BUTTONBOX_END);
+        gtk_button_box_set_spacing(GTK_BUTTON_BOX(buttonBox), 5);
+        gtk_box_pack_start(GTK_BOX(leftBox), buttonBox, FALSE, FALSE, 0);
+
+        GtkWidget* saveButton = mpcGtkButton("Save", buttonBox);
+        g_signal_connect(G_OBJECT(saveButton), "clicked", G_CALLBACK(saveTags), NULL);
+
+        GtkWidget* removeButton = mpcGtkButton("Remove Tag", buttonBox);
+        g_signal_connect_swapped(G_OBJECT(removeButton), "clicked", G_CALLBACK(removeTags), NULL);
+
+        GtkWidget* cancelButton = mpcGtkButton("Cancel", buttonBox);
+        g_signal_connect_swapped(G_OBJECT(cancelButton), "clicked", G_CALLBACK(closeInfoBox), NULL);
+        gtk_widget_grab_default(cancelButton);
+
+        //File information
+        GtkWidget* infoFrame = gtk_frame_new("Musepack Info");
+        gtk_box_pack_start(GTK_BOX(iHbox), infoFrame, FALSE, FALSE, 0);
+
+        GtkWidget* infoVbox = gtk_vbox_new(FALSE, 5);
+        gtk_container_add(GTK_CONTAINER(infoFrame), infoVbox);
+        gtk_container_set_border_width(GTK_CONTAINER(infoVbox), 10);
+        gtk_box_set_spacing(GTK_BOX(infoVbox), 0);
+
+        GtkWidget* streamLabel    = mpcGtkLabel(infoVbox);
+        GtkWidget* encoderLabel   = mpcGtkLabel(infoVbox);
+        GtkWidget* profileLabel   = mpcGtkLabel(infoVbox);
+        GtkWidget* bitrateLabel   = mpcGtkLabel(infoVbox);
+        GtkWidget* rateLabel      = mpcGtkLabel(infoVbox);
+        GtkWidget* channelsLabel  = mpcGtkLabel(infoVbox);
+        GtkWidget* lengthLabel    = mpcGtkLabel(infoVbox);
+        GtkWidget* fileSizeLabel  = mpcGtkLabel(infoVbox);
+        GtkWidget* trackPeakLabel = mpcGtkLabel(infoVbox);
+        GtkWidget* trackGainLabel = mpcGtkLabel(infoVbox);
+        GtkWidget* albumPeakLabel = mpcGtkLabel(infoVbox);
+        GtkWidget* albumGainLabel = mpcGtkLabel(infoVbox);
+
+        FILE* input = fopen(p_Filename, "rb");
+        if(input)
+        {
+            mpc_streaminfo info;
+            mpc_reader_file reader;
+            mpc_reader_setup_file_reader(&reader, input);
+            mpc_streaminfo_read(&info, &reader.reader);
+
+            int time = static_cast<int> (mpc_streaminfo_get_length(&info));
+            int minutes = time / 60;
+            int seconds = time % 60;
+
+            mpcGtkPrintLabel(streamLabel,    "Streamversion %d", info.stream_version);
+            mpcGtkPrintLabel(encoderLabel,   "Encoder: \%s", info.encoder);
+            mpcGtkPrintLabel(profileLabel,   "Profile: \%s", info.profile_name);
+            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(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);
+
+            MpcInfo tags = getTags(p_Filename);
+            gtk_entry_set_text(GTK_ENTRY(titleEntry),   tags.title);
+            gtk_entry_set_text(GTK_ENTRY(artistEntry),  tags.artist);
+            gtk_entry_set_text(GTK_ENTRY(albumEntry),   tags.album);
+            gtk_entry_set_text(GTK_ENTRY(commentEntry), tags.comment);
+            gtk_entry_set_text(GTK_ENTRY(genreEntry),   tags.genre);
+            char* entry = g_strdup_printf ("%d", tags.track);
+            gtk_entry_set_text(GTK_ENTRY(trackEntry), entry);
+            free(entry);
+            entry = g_strdup_printf ("%d", tags.year);
+            gtk_entry_set_text(GTK_ENTRY(yearEntry), entry);
+            free(entry);
+            entry = g_filename_display_name(p_Filename);
+            gtk_entry_set_text(GTK_ENTRY(fileEntry), entry);
+            free(entry);
+            freeTags(tags);
+            fclose(input);
+        }
+        else
+        {
+            char* temp = g_strdup_printf("[xmms-musepack] mpcFileInfoBox is unable to read tags from %s", p_Filename);
+            perror(temp);
+            free(temp);
+        }
+
+	char* name = g_filename_display_basename(p_Filename);
+        char* text = g_strdup_printf("File Info - %s", name);
+        free(name);
+        gtk_window_set_title(GTK_WINDOW(infoBox), text);
+        free(text);
+
+        gtk_widget_show_all(infoBox);
+    }
+}
+
+static void mpcGtkPrintLabel(GtkWidget* widget, char* format,...)
+{
+    va_list args;
+
+    va_start(args, format);
+    char* temp = g_strdup_vprintf(format, args);
+    va_end(args);
+
+    gtk_label_set_text(GTK_LABEL(widget), temp);
+    free(temp);
+}
+
+static GtkWidget* mpcGtkTagLabel(char* p_Text, int a, int b, int c, int d, GtkWidget* p_Box)
+{
+    GtkWidget* label = gtk_label_new(p_Text);
+    gtk_misc_set_alignment(GTK_MISC(label), 1, 0.5);
+    gtk_table_attach(GTK_TABLE(p_Box), label, a, b, c, d, GTK_FILL, GTK_FILL, 5, 5);
+    return label;
+}
+
+static GtkWidget* mpcGtkTagEntry(int a, int b, int c, int d, int p_Size, GtkWidget* p_Box)
+{
+    GtkWidget* entry;
+    if(p_Size == 0)
+        entry = gtk_entry_new();
+    else
+        entry = gtk_entry_new_with_max_length(p_Size);
+    gtk_table_attach(GTK_TABLE(p_Box), entry, a, b, c, d,
+                    (GtkAttachOptions) (GTK_FILL | GTK_EXPAND | GTK_SHRINK),
+                    (GtkAttachOptions) (GTK_FILL | GTK_EXPAND | GTK_SHRINK), 0, 5);
+    return entry;
+}
+
+static GtkWidget* mpcGtkLabel(GtkWidget* p_Box)
+{
+    GtkWidget* label = gtk_label_new("");
+    gtk_misc_set_alignment(GTK_MISC(label), 0, 0);
+    gtk_label_set_justify(GTK_LABEL(label), GTK_JUSTIFY_LEFT);
+    gtk_box_pack_start(GTK_BOX(p_Box), label, FALSE, FALSE, 0);
+    return label;
+}
+
+static GtkWidget* mpcGtkButton(char* p_Text, GtkWidget* p_Box)
+{
+    GtkWidget* button = gtk_button_new_with_label(p_Text);
+    GTK_WIDGET_SET_FLAGS(button, GTK_CAN_DEFAULT);
+    gtk_box_pack_start(GTK_BOX(p_Box), button, TRUE, TRUE, 0);
+    return button;
+}
+
+static void removeTags(GtkWidget * w, gpointer data)
+{
+    File oFile(gtk_entry_get_text(GTK_ENTRY(widgets.fileEntry)));
+    oFile.remove();
+    oFile.save();
+    closeInfoBox(NULL, NULL);
+}
+
+static void saveTags(GtkWidget* w, gpointer data)
+{
+    File oFile(gtk_entry_get_text(GTK_ENTRY(widgets.fileEntry)));
+    Tag* poTag = oFile.tag();
+
+    char* cAlbum   = g_strdup(gtk_entry_get_text(GTK_ENTRY(widgets.albumEntry)));
+    char* cArtist  = g_strdup(gtk_entry_get_text(GTK_ENTRY(widgets.artistEntry)));
+    char* cTitle   = g_strdup(gtk_entry_get_text(GTK_ENTRY(widgets.titleEntry)));
+    char* cGenre   = g_strdup(gtk_entry_get_text(GTK_ENTRY(widgets.genreEntry)));
+    char* cComment = g_strdup(gtk_entry_get_text(GTK_ENTRY(widgets.commentEntry)));
+
+    const String album   = String(cAlbum,   TagLib::String::UTF8);
+    const String artist  = String(cArtist,  TagLib::String::UTF8);
+    const String title   = String(cTitle,   TagLib::String::UTF8);
+    const String genre   = String(cGenre,   TagLib::String::UTF8);
+    const String comment = String(cComment, TagLib::String::UTF8);
+
+    poTag->setAlbum(album);
+    poTag->setArtist(artist);
+    poTag->setTitle(title);
+    poTag->setGenre(genre);
+    poTag->setComment(comment);
+    poTag->setYear(atoi(gtk_entry_get_text(GTK_ENTRY(widgets.yearEntry))));
+    poTag->setTrack(atoi(gtk_entry_get_text(GTK_ENTRY(widgets.trackEntry))));
+
+    free(cAlbum);
+    free(cArtist);
+    free(cTitle);
+    free(cGenre);
+    free(cComment);
+
+    oFile.save();
+    closeInfoBox(NULL, NULL);
+}
+
+static void closeInfoBox(GtkWidget* w, gpointer data)
+{
+    gtk_widget_destroy(widgets.infoBox);
+    widgets.infoBox = NULL;
+}
+
+static char* mpcGenerateTitle(const MpcInfo& p_Tags, char* p_Filename)
+{
+    TitleInput* tuple = mpcGetSongTuple(p_Filename);
+
+    char* title = xmms_get_titlestring (xmms_get_gentitle_format(), tuple);
+    if(!title)
+        title = g_strdup(tuple->file_name);
+    else if (!*title)
+        title = g_strdup(tuple->file_name);
+
+    bmp_title_input_free(tuple);
+    return title;
+}
+
+static void* endThread(char* p_FileName, FILE* p_FileHandle, bool release)
+{
+    free(p_FileName);
+    if(release)
+        lockRelease();
+    if(mpcDecoder.isError)
+    {
+        perror(mpcDecoder.isError);
+        free(mpcDecoder.isError);
+        mpcDecoder.isError = NULL;
+    }
+    setAlive(false);
+    if(p_FileHandle)
+        fclose(p_FileHandle);
+    if(track.display)
+    {
+        free(track.display);
+        track.display = NULL;
+    }
+    g_thread_exit(NULL);
+    return 0;
+}
+
+static void* decodeStream(void* data)
+{
+    lockAcquire();
+    char* filename = static_cast<char*> (data);
+    FILE* input = fopen(filename, "rb");
+    if (!input)
+    {
+        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;
+    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);
+
+    MPC_SAMPLE_FORMAT sampleBuffer[MPC_DECODER_BUFFER_LENGTH];
+    char xmmsBuffer[MPC_DECODER_BUFFER_LENGTH * 4];
+
+    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);
+    }
+    else
+    {
+        mpcDecoder.isOutput = true;
+    }
+
+    lockRelease();
+
+    int counter = 2 * track.sampleFreq / 3;
+    while (isAlive())
+    {
+        if (getOffset() != -1)
+        {
+            mpc_decoder_seek_seconds(&decoder, mpcDecoder.offset);
+            setOffset(-1);
+        }
+
+        lockAcquire();
+        short iPlaying = MpcPlugin.output->buffer_playing()? 1 : 0;
+        int iFree = MpcPlugin.output->buffer_free();
+        if (!mpcDecoder.isPause &&  iFree >= ((1152 * 4) << iPlaying))
+        {
+            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);
+            }
+            if (status == 0 && iPlaying == 0)
+                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;
+                }
+            }
+        }
+        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);
+
+    if (pluginConfig.dynamicBitrate)
+    {
+        track.bitrate = static_cast<int> (vbrUpd * track.sampleFreq / 1152);
+    }
+
+    produce_audio(MpcPlugin.output->written_time(), FMT_S16_LE, track.channels, status * 4, xmmsBuffer, NULL);
+    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);
+}
+
+inline static void lockAcquire()
+{
+    g_static_mutex_lock(&threadMutex);
+}
+
+inline static void lockRelease()
+{
+    g_static_mutex_unlock(&threadMutex);
+}
+
+inline static bool isAlive()
+{
+    lockAcquire();
+    bool isAlive = mpcDecoder.isAlive;
+    lockRelease();
+    return isAlive;
+}
+
+inline static bool isPause()
+{
+    lockAcquire();
+    bool isPause = mpcDecoder.isPause;
+    lockRelease();
+    return isPause;
+}
+
+inline static void setAlive(bool isAlive)
+{
+    lockAcquire();
+    mpcDecoder.isAlive = isAlive;
+    lockRelease();
+}
+
+inline static double getOffset()
+{
+    lockAcquire();
+    double offset = mpcDecoder.offset;
+    lockRelease();
+    return offset;
+}
+
+inline static void setOffset(double offset)
+{
+    lockAcquire();
+    mpcDecoder.offset = offset;
+    lockRelease();
+}
--- a/mk/init.mk	Thu Sep 14 14:06:45 2006 -0700
+++ b/mk/init.mk	Fri Sep 15 06:36:26 2006 -0700
@@ -18,6 +18,3 @@
 INCLUDEDIR = $(pkgincludedir)
 CFLAGS += -DHAVE_CONFIG_H -I/usr/pkg/include -I/usr/pkg/xorg/include
 CXXFLAGS += -DHAVE_CONFIG_H -I/usr/pkg/include -I/usr/pkg/xorg/include
-
-# some makes need this -nenolod
-.SUFFIXES: .cpp .cxx .cc
--- a/mk/objective.mk	Thu Sep 14 14:06:45 2006 -0700
+++ b/mk/objective.mk	Fri Sep 15 06:36:26 2006 -0700
@@ -1,6 +1,8 @@
 default: all
 all: build
 
+.SUFFIXES: .cxx .cc
+
 install: build
 	$(MAKE) install-prehook
 	@for i in $(BINDIR) $(LIBDIR) $(INCLUDEDIR); do \
@@ -162,7 +164,7 @@
 	fi;
 	$(CC) $(CFLAGS) -c $< -o $@
 
-.cc.o .cpp.o .cxx.o:
+.cc.o .cxx.o:
 	@if [ $(SHOW_CFLAGS) -eq 1 ]; then	\
 		printf "%10s     %-20s (%s)\n" CXX $< "${CXXFLAGS}";	\
 	else \