Changeset 456 for bmp-musepack


Ignore:
Timestamp:
11/07/09 23:31:32 (15 years ago)
Author:
r2d
Message:
  • update for audacious 2.1.0
  • changed build system to cmake
Location:
bmp-musepack/trunk
Files:
1 added
4 deleted
3 edited
2 copied

Legend:

Unmodified
Added
Removed
  • bmp-musepack/trunk/COPYING

    r34 r456  
    1 Copyright (c) 2005, The Musepack Development Team
     1Copyright (c) 2005-2009, The Musepack Development Team
    22All rights reserved.
    33
  • bmp-musepack/trunk/ChangeLog

    r34 r456  
     11.3
     2        Changes for libmpcdec 1.3.0 (sv8 support)
     3        Changes for Audacious 2.1.0
     4        Moved to cmake build system
     5
    161.2
    27        General code refactoring
     
    712        Safer multithreading
    813        Updated for libmpcdec-1.2
    9                                                
     14
    10151.1.2
    1116        port to new C libmusepack
    12        
     17
    13181.1
    1419        Autotools building process
    1520        %d now display full date tag
    1621
    17 1.1-alpha10 
     221.1-alpha10
    1823        Equalizer works now
    1924        Fixed a small Bug with skipping broken tracks
     
    4550        fixed tag reading
    4651
    47 1.1-alpha: 
     521.1-alpha:
    4853        rewrite from scratch using musepack lib
  • bmp-musepack/trunk/INSTALL

    r34 r456  
    1 Bmp-musepack plugin
     1Audacious-musepack plugin
    22Required:
    33        Taglib headers and libs >= 1.4
    44        GTK-2.0 headers and libs
    5         Bmp-0.9.7 headers and binaries
    6         libmpcdec >= 1.2
     5        Audacious-2.1.0 headers and binaries
     6        libmpcdec >= 1.3.0
    77To install:
    8 run "./configure && make" as user
    9 run "make install" as root
     8mkdir build
     9cd build
     10cmake ..
     11make
     12make install
  • bmp-musepack/trunk/libmpc.cpp

    r455 r456  
    11/*
    2  * Copyright (c) 2005, The Musepack Development Team
     2 * Copyright (c) 2005-2009, The Musepack Development Team
    33 * All rights reserved.
    44 *
     
    3333 */
    3434
     35
    3536#include "libmpc.h"
    3637
    37 #define FORCED_THREAD_STACKSIZE 1024 * 1000
    38 
     38#define REMOVE_NONEXISTANT_TAG(x)   if (!*x) { x = NULL; }
     39#define VERSION "1.3"
     40#define PACKAGE "aud_mpc"
    3941
    4042using TagLib::MPC::File;
     
    4345using TagLib::APE::ItemListMap;
    4446
    45 InputPlugin MpcPlugin = {
    46     NULL,           //File Handle               FILE* handle
    47     NULL,           //Filename                  char* filename
    48     NULL,           //Name of Plugin            char* filename
    49     mpcOpenPlugin,  //Open Plugin               [CALLBACK]
    50     mpcAboutBox,    //Show About box            [CALLBACK]
    51     mpcConfigBox,   //Show Configure box        [CALLBACK]
    52     mpcIsOurFile,   //Check if it's our file    [CALLBACK]
    53     NULL,           //Scan the directory        [UNUSED]
    54     mpcPlay,        //Play                      [CALLBACK]
    55     mpcStop,        //Stop                      [CALLBACK]
    56     mpcPause,       //Pause                     [CALLBACK]
    57     mpcSeek,        //Seek                      [CALLBACK]
    58     mpcSetEq,       //Set EQ                    [CALLBACK]
    59     mpcGetTime,     //Get Time                  [CALLBACK]
    60     NULL,           //Get Volume                [UNUSED]
    61     NULL,           //Set Volume                [UNUSED]
    62     mpcClosePlugin, //Close Plugin              [CALLBACK]
    63     NULL,           //Obsolete                  [UNUSED]
    64     NULL,           //Visual plugins            add_vis_pcm(int time, AFormat fmt, int nch, int length, void *ptr)
    65     NULL,           //Set Info Settings         set_info(char *title, int length, int rate, int freq, int nch)
    66     NULL,           //set Info Text             set_info_text(char* text)
    67     mpcGetSongInfo, //Get Title String callback [CALLBACK]
    68     mpcFileInfoBox, //Show File Info Box        [CALLBACK]
    69     NULL,           //Output Plugin Handle      OutputPlugin output
    70 };
    71 
    72 extern "C"
    73 InputPlugin* get_iplugin_info()
    74 {
    75     MpcPlugin.description = g_strdup_printf("Musepack Audio Plugin %s", VERSION);
    76     return &MpcPlugin;
    77 }
    78 
    7947static PluginConfig pluginConfig = {0};
    8048static Widgets      widgets      = {0};
     
    8250static TrackInfo    track        = {0};
    8351
    84 static pthread_t           threadHandle;
    85 static pthread_attr_t      threadAttr;
    86 static pthread_mutex_t     threadMutex;
    87 static pthread_mutexattr_t threadMutexAttr;
     52static GThread            *threadHandle;
     53static GStaticMutex threadMutex = G_STATIC_MUTEX_INIT;
     54
     55/*
     56 * VFS callback implementation, adapted from mpc_reader.c.
     57 * This _IS_ very sick, but it works. -nenolod
     58 */
     59static mpc_int32_t
     60aud_vfs_fread_impl(mpc_reader *d, void *ptr, mpc_int32_t size)
     61{
     62    VFSFile *file = (VFSFile *) d->data;
     63
     64    return (mpc_int32_t) aud_vfs_fread(ptr, 1, size, file);
     65}
     66
     67static mpc_bool_t
     68aud_vfs_fseek_impl(mpc_reader *d, mpc_int32_t offset)
     69{
     70    VFSFile *file = (VFSFile *) d->data;
     71
     72        return d->canseek(d) ? aud_vfs_fseek(file, offset, SEEK_SET) == 0 : FALSE;
     73}
     74
     75static mpc_int32_t
     76aud_vfs_ftell_impl(mpc_reader *d)
     77{
     78    VFSFile *file = (VFSFile *) d->data;
     79
     80    return aud_vfs_ftell(file);
     81}
     82
     83static mpc_int32_t
     84aud_vfs_getsize_impl(mpc_reader *d)
     85{
     86        int f_pos, f_size;
     87        VFSFile *file = (VFSFile *) d->data;
     88
     89        f_pos = aud_vfs_ftell(file);
     90        aud_vfs_fseek(file, 0, SEEK_END);
     91        f_size = aud_vfs_ftell(file);
     92        aud_vfs_fseek(file, f_pos, SEEK_SET);
     93
     94        return f_size;
     95}
     96
     97static mpc_bool_t
     98aud_vfs_canseek_impl(mpc_reader *d)
     99{
     100    return TRUE; // FIXME : can we really always seek ?
     101}
     102
     103/*
     104 * This sets up an mpc_reader object to read from VFS instead of libc.
     105 * Essentially, we use this instead of the normal constructor.
     106 *    - nenolod
     107 */
     108void
     109mpc_reader_setup_file_vfs(mpc_reader *p_reader, VFSFile *input)
     110{
     111    p_reader->seek = aud_vfs_fseek_impl;
     112    p_reader->read = aud_vfs_fread_impl;
     113    p_reader->tell = aud_vfs_ftell_impl;
     114    p_reader->get_size = aud_vfs_getsize_impl;
     115    p_reader->canseek = aud_vfs_canseek_impl;
     116        p_reader->data = input; // no worries, it gets cast back -nenolod
     117        aud_vfs_fseek(input, 0, SEEK_SET);
     118}
    88119
    89120static void mpcOpenPlugin()
    90121{
    91     pthread_mutexattr_init(&threadMutexAttr);
    92     pthread_mutex_init(&threadMutex, &threadMutexAttr);
    93     pthread_attr_init(&threadAttr);
    94     pthread_attr_setstacksize(&threadAttr, FORCED_THREAD_STACKSIZE);
    95 
    96     ConfigDb *cfg;
    97     cfg = bmp_cfg_db_open();
    98     bmp_cfg_db_get_bool(cfg, "musepack", "clipPrevention", &pluginConfig.clipPrevention);
    99     bmp_cfg_db_get_bool(cfg, "musepack", "albumGain",      &pluginConfig.albumGain);
    100     bmp_cfg_db_get_bool(cfg, "musepack", "dynamicBitrate", &pluginConfig.dynamicBitrate);
    101     bmp_cfg_db_get_bool(cfg, "musepack", "replaygain",     &pluginConfig.replaygain);
    102     bmp_cfg_db_close(cfg);
     122    mcs_handle_t *cfg;
     123    cfg = aud_cfg_db_open();
     124    aud_cfg_db_get_bool(cfg, "musepack", "clipPrevention", &pluginConfig.clipPrevention);
     125    aud_cfg_db_get_bool(cfg, "musepack", "albumGain",      &pluginConfig.albumGain);
     126    aud_cfg_db_get_bool(cfg, "musepack", "dynamicBitrate", &pluginConfig.dynamicBitrate);
     127    aud_cfg_db_get_bool(cfg, "musepack", "replaygain",     &pluginConfig.replaygain);
     128    aud_cfg_db_close(cfg);
    103129}
    104130
     
    110136    else
    111137    {
    112         char* titleText      = g_strdup_printf("Musepack Decoder Plugin %s", VERSION);
    113         const char* contentText = "Plugin code by\nBenoit Amiaux\nMartin Spuler\nKuniklo\n\nGet latest version at http://musepack.net\n";
    114             const char* buttonText  = "Nevermind";
    115         aboutBox = xmms_show_message(titleText, contentText, buttonText, FALSE, NULL, NULL);
     138        char* titleText      = g_strdup_printf(_("Musepack Decoder Plugin %s"), VERSION);
     139        const char* contentText = _("Plugin code by\nBenoit Amiaux\nMartin Spuler\nKuniklo\nNicolas Botti\n\nGet latest version at http://musepack.net\n");
     140        const char* buttonText  = _("Nevermind");
     141        aboutBox = audacious_info_dialog(titleText, contentText, buttonText, FALSE, NULL, NULL);
    116142        widgets.aboutBox = aboutBox;
    117         gtk_signal_connect(GTK_OBJECT(aboutBox), "destroy", GTK_SIGNAL_FUNC(gtk_widget_destroyed), &widgets.aboutBox);
    118     }
     143        g_signal_connect(G_OBJECT(aboutBox), "destroy", G_CALLBACK(gtk_widget_destroyed), &widgets.aboutBox);
     144    }
     145}
     146
     147static void toggleSwitch(GtkWidget* p_Widget, gpointer p_Data)
     148{
     149    gtk_widget_set_sensitive(GTK_WIDGET(p_Data), gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(p_Widget)));
    119150}
    120151
     
    129160        gtk_window_set_type_hint(GTK_WINDOW(configBox), GDK_WINDOW_TYPE_HINT_DIALOG);
    130161        widgets.configBox = configBox;
    131         gtk_signal_connect(GTK_OBJECT(configBox), "destroy", GTK_SIGNAL_FUNC(gtk_widget_destroyed), &widgets.configBox);
    132         gtk_window_set_title(GTK_WINDOW(configBox), "Musepack Decoder Configuration");
    133         gtk_window_set_policy(GTK_WINDOW(configBox), FALSE, FALSE, FALSE);
    134         gtk_container_border_width(GTK_CONTAINER(configBox), 10);
     162        g_signal_connect(G_OBJECT(configBox), "destroy", G_CALLBACK(gtk_widget_destroyed), &widgets.configBox);
     163        gtk_window_set_title(GTK_WINDOW(configBox), _("Musepack Decoder Configuration"));
     164        gtk_window_set_resizable(GTK_WINDOW(configBox), FALSE);
     165        gtk_container_set_border_width(GTK_CONTAINER(configBox), 10);
    135166
    136167        GtkWidget* notebook = gtk_notebook_new();
     
    140171
    141172        //General Settings Tab
    142         GtkWidget* generalSet = gtk_frame_new("General Settings");
    143         gtk_container_border_width(GTK_CONTAINER(generalSet), 5);
     173        GtkWidget* generalSet = gtk_frame_new(_("General Settings"));
     174        gtk_container_set_border_width(GTK_CONTAINER(generalSet), 5);
    144175
    145176        GtkWidget* gSvbox = gtk_vbox_new(FALSE, 10);
    146         gtk_container_border_width(GTK_CONTAINER(gSvbox), 5);
     177        gtk_container_set_border_width(GTK_CONTAINER(gSvbox), 5);
    147178        gtk_container_add(GTK_CONTAINER(generalSet), gSvbox);
    148179
    149         GtkWidget* bitrateCheck = gtk_check_button_new_with_label("Enable Dynamic Bitrate Display");
     180        GtkWidget* bitrateCheck = gtk_check_button_new_with_label(_("Enable Dynamic Bitrate Display"));
    150181        widgets.bitrateCheck = bitrateCheck;
    151182        gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(bitrateCheck), pluginConfig.dynamicBitrate);
    152183        gtk_box_pack_start(GTK_BOX(gSvbox), bitrateCheck, FALSE, FALSE, 0);
    153         gtk_notebook_append_page(GTK_NOTEBOOK(notebook), generalSet, gtk_label_new("Plugin"));
     184        gtk_notebook_append_page(GTK_NOTEBOOK(notebook), generalSet, gtk_label_new(_("Plugin")));
    154185
    155186        //ReplayGain Settings Tab
    156         GtkWidget* replaygainSet = gtk_frame_new("ReplayGain Settings");
    157         gtk_container_border_width(GTK_CONTAINER(replaygainSet), 5);
     187        GtkWidget* replaygainSet = gtk_frame_new(_("ReplayGain Settings"));
     188        gtk_container_set_border_width(GTK_CONTAINER(replaygainSet), 5);
    158189
    159190        GtkWidget* rSVbox = gtk_vbox_new(FALSE, 10);
    160         gtk_container_border_width(GTK_CONTAINER(rSVbox), 5);
     191        gtk_container_set_border_width(GTK_CONTAINER(rSVbox), 5);
    161192        gtk_container_add(GTK_CONTAINER(replaygainSet), rSVbox);
    162193
    163         GtkWidget* clippingCheck = gtk_check_button_new_with_label("Enable Clipping Prevention");
     194        GtkWidget* clippingCheck = gtk_check_button_new_with_label(_("Enable Clipping Prevention"));
    164195        widgets.clippingCheck = clippingCheck;
    165196        gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(clippingCheck), pluginConfig.clipPrevention);
    166197        gtk_box_pack_start(GTK_BOX(rSVbox), clippingCheck, FALSE, FALSE, 0);
    167198
    168         GtkWidget* replaygainCheck = gtk_check_button_new_with_label("Enable ReplayGain");
     199        GtkWidget* replaygainCheck = gtk_check_button_new_with_label(_("Enable ReplayGain"));
    169200        widgets.replaygainCheck = replaygainCheck;
    170201        gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(replaygainCheck), pluginConfig.replaygain);
    171202        gtk_box_pack_start(GTK_BOX(rSVbox), replaygainCheck, FALSE, FALSE, 0);
    172203
    173         GtkWidget* replaygainType = gtk_frame_new("ReplayGain Type");
     204        GtkWidget* replaygainType = gtk_frame_new(_("ReplayGain Type"));
    174205        gtk_box_pack_start(GTK_BOX(rSVbox), replaygainType, FALSE, FALSE, 0);
    175         gtk_signal_connect(GTK_OBJECT(replaygainCheck), "toggled", GTK_SIGNAL_FUNC(toggleSwitch), replaygainType);
     206        g_signal_connect(G_OBJECT(replaygainCheck), "toggled", G_CALLBACK(toggleSwitch), replaygainType);
    176207
    177208        GtkWidget* rgVbox = gtk_vbox_new(FALSE, 5);
     
    179210        gtk_container_add(GTK_CONTAINER(replaygainType), rgVbox);
    180211
    181         GtkWidget* trackCheck = gtk_radio_button_new_with_label(NULL, "Use Track Gain");
     212        GtkWidget* trackCheck = gtk_radio_button_new_with_label(NULL, _("Use Track Gain"));
    182213        gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(trackCheck), !pluginConfig.albumGain);
    183214        gtk_box_pack_start(GTK_BOX(rgVbox), trackCheck, FALSE, FALSE, 0);
    184215
    185         GtkWidget* albumCheck = gtk_radio_button_new_with_label(gtk_radio_button_group(GTK_RADIO_BUTTON(trackCheck)), "Use Album Gain");
     216        GtkWidget* albumCheck = gtk_radio_button_new_with_label(gtk_radio_button_get_group(GTK_RADIO_BUTTON(trackCheck)), _("Use Album Gain"));
    186217        widgets.albumCheck = albumCheck;
    187218        gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(albumCheck), pluginConfig.albumGain);
    188219        gtk_box_pack_start(GTK_BOX(rgVbox), albumCheck, FALSE, FALSE, 0);
    189220        gtk_widget_set_sensitive(replaygainType, pluginConfig.replaygain);
    190         gtk_notebook_append_page(GTK_NOTEBOOK(notebook), replaygainSet, gtk_label_new("ReplayGain"));
     221        gtk_notebook_append_page(GTK_NOTEBOOK(notebook), replaygainSet, gtk_label_new(_("ReplayGain")));
    191222
    192223        //Buttons
    193224        GtkWidget* buttonBox = gtk_hbutton_box_new();
    194225        gtk_button_box_set_layout(GTK_BUTTON_BOX(buttonBox), GTK_BUTTONBOX_END);
    195         gtk_button_box_set_spacing(GTK_BUTTON_BOX(buttonBox), 5);
     226        gtk_box_set_spacing(GTK_BOX(buttonBox), 5);
    196227        gtk_box_pack_start(GTK_BOX(vbox), buttonBox, FALSE, FALSE, 0);
    197228
    198         GtkWidget* okButton = gtk_button_new_with_label("Ok");
    199         gtk_signal_connect(GTK_OBJECT(okButton), "clicked", GTK_SIGNAL_FUNC(saveConfigBox), NULL);
     229        GtkWidget* okButton = gtk_button_new_with_label(_("Ok"));
     230        g_signal_connect(G_OBJECT(okButton), "clicked", G_CALLBACK(saveConfigBox), NULL);
    200231        GTK_WIDGET_SET_FLAGS(okButton, GTK_CAN_DEFAULT);
    201232        gtk_box_pack_start(GTK_BOX(buttonBox), okButton, TRUE, TRUE, 0);
    202233
    203         GtkWidget* cancelButton = gtk_button_new_with_label("Cancel");
    204         gtk_signal_connect_object(GTK_OBJECT(cancelButton), "clicked", GTK_SIGNAL_FUNC(gtk_widget_destroy), GTK_OBJECT(widgets.configBox));
     234        GtkWidget* cancelButton = gtk_button_new_with_label(_("Cancel"));
     235        g_signal_connect_swapped(G_OBJECT(cancelButton), "clicked", G_CALLBACK(gtk_widget_destroy), GTK_OBJECT(widgets.configBox));
    205236        GTK_WIDGET_SET_FLAGS(cancelButton, GTK_CAN_DEFAULT);
    206237        gtk_widget_grab_default(cancelButton);
     
    211242}
    212243
    213 static void toggleSwitch(GtkWidget* p_Widget, gpointer p_Data)
    214 {
    215     gtk_widget_set_sensitive(GTK_WIDGET(p_Data), gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(p_Widget)));
    216 }
    217 
    218244static void saveConfigBox(GtkWidget* p_Widget, gpointer p_Data)
    219245{
    220     ConfigDb* cfg;
     246    mcs_handle_t* cfg;
    221247    GtkToggleButton* tb;
    222248
     
    230256    pluginConfig.albumGain = gtk_toggle_button_get_active(tb);
    231257
    232     cfg = bmp_cfg_db_open();
    233 
    234     bmp_cfg_db_set_bool(cfg, "musepack", "clipPrevention", pluginConfig.clipPrevention);
    235     bmp_cfg_db_set_bool(cfg, "musepack", "albumGain",      pluginConfig.albumGain);
    236     bmp_cfg_db_set_bool(cfg, "musepack", "dynamicBitrate", pluginConfig.dynamicBitrate);
    237     bmp_cfg_db_set_bool(cfg, "musepack", "replaygain",     pluginConfig.replaygain);
    238 
    239     bmp_cfg_db_close(cfg);
     258    cfg = aud_cfg_db_open();
     259
     260    aud_cfg_db_set_bool(cfg, "musepack", "clipPrevention", pluginConfig.clipPrevention);
     261    aud_cfg_db_set_bool(cfg, "musepack", "albumGain",      pluginConfig.albumGain);
     262    aud_cfg_db_set_bool(cfg, "musepack", "dynamicBitrate", pluginConfig.dynamicBitrate);
     263    aud_cfg_db_set_bool(cfg, "musepack", "replaygain",     pluginConfig.replaygain);
     264
     265    aud_cfg_db_close(cfg);
    240266
    241267    gtk_widget_destroy (widgets.configBox);
    242268}
    243269
    244 static int mpcIsOurFile(char* p_Filename)
    245 {
    246     char* ext;
    247     ext = strrchr(p_Filename, '.');
    248     if(ext)
    249         return !(strcasecmp(ext, ".mpc") && strcasecmp(ext, ".mpp") && strcasecmp(ext, ".mp+"));
    250     return FALSE;
    251 }
    252 
    253 static void mpcPlay(char* p_Filename)
     270static gint mpcIsOurFD(gchar* p_Filename, VFSFile* file)
     271{
     272    gchar magic[4];
     273    aud_vfs_fread(magic, 1, 4, file);
     274    if (memcmp(magic, "MP+", 3) == 0)
     275        return 1;
     276        if (memcmp(magic, "MPCK", 4) == 0)
     277                return 1;
     278    return 0;
     279}
     280
     281static void mpcPlay(InputPlayback *data)
    254282{
    255283    mpcDecoder.offset   = -1;
     
    257285    mpcDecoder.isOutput = false;
    258286    mpcDecoder.isPause  = false;
    259     pthread_create(&threadHandle, &threadAttr, decodeStream, (void *) g_strdup(p_Filename));
    260 }
    261 
    262 static void mpcStop()
    263 {
    264     setAlive(false);
     287    threadHandle = g_thread_self();
     288    decodeStream(data);
     289}
     290
     291static void mpcStop(InputPlayback *data)
     292{
     293    mpcDecoder.isAlive = false;
    265294    if (threadHandle)
    266295    {
    267         pthread_join(threadHandle, NULL);
     296        g_thread_join(threadHandle);
    268297        if (mpcDecoder.isOutput)
    269298        {
    270             MpcPlugin.output->buffer_free();
    271             MpcPlugin.output->close_audio();
     299            data->output->buffer_free();
     300            data->output->close_audio();
    272301            mpcDecoder.isOutput = false;
    273302        }
     
    275304}
    276305
    277 static void mpcPause(short p_Pause)
     306inline static void lockAcquire()
     307{
     308    g_static_mutex_lock(&threadMutex);
     309}
     310
     311inline static void lockRelease()
     312{
     313    g_static_mutex_unlock(&threadMutex);
     314}
     315
     316static void mpcPause(InputPlayback *data, short p_Pause)
    278317{
    279318    lockAcquire();
    280319    mpcDecoder.isPause = p_Pause;
    281     MpcPlugin.output->pause(p_Pause);
     320    data->output->pause(p_Pause);
    282321    lockRelease();
    283322}
    284323
    285 static void mpcSeek(int p_Offset)
     324static void mpcSeekm(InputPlayback *data, gulong ms_offset)
    286325{
    287326    lockAcquire();
    288     mpcDecoder.offset = static_cast<double> (p_Offset);
    289     MpcPlugin.output->flush(1000 * p_Offset);
     327    mpcDecoder.offset = ms_offset;
    290328    lockRelease();
    291329}
    292330
    293 static void mpcSetEq(int on, float preamp, float* eq)
    294 {
    295     pluginConfig.isEq = static_cast<bool> (on);
    296     init_iir(on, preamp, eq);
    297 }
    298 
    299 static int mpcGetTime()
    300 {
    301     if(!isAlive())
    302         return -1;
    303     return MpcPlugin.output->output_time();
    304 }
    305 
    306 static void mpcClosePlugin()
    307 {
    308     pthread_mutex_destroy(&threadMutex);
    309     pthread_mutexattr_destroy(&threadMutexAttr);
    310     pthread_attr_destroy(&threadAttr);
    311 }
    312 
    313 static void mpcGetSongInfo(char* p_Filename, char** p_Title, int* p_Length)
    314 {
    315         mpc_reader reader;
    316         mpc_demux * demux;
    317         if (mpc_reader_init_stdio(&reader, p_Filename) == MPC_STATUS_OK && (demux = mpc_demux_init(&reader))) {
    318         MpcInfo tags = getTags(p_Filename);
    319         *p_Title = mpcGenerateTitle(tags, p_Filename);
    320         freeTags(tags);
    321                 mpc_streaminfo info;
    322                 mpc_demux_get_info(demux, &info);
    323                 *p_Length = static_cast<int> (1000 * mpc_streaminfo_get_length(&info));
    324                 mpc_demux_exit(demux);
    325                 mpc_reader_exit_stdio(&reader);
    326     } else {
    327         char* temp = g_strdup_printf("[xmms-musepack] mpcGetSongInfo is unable to open %s\n", p_Filename);
    328         perror(temp);
    329         free(temp);
    330     }
    331 }
    332 
    333 static void freeTags(MpcInfo& tags)
    334 {
    335     free(tags.title);
    336     free(tags.artist);
    337     free(tags.album);
    338     free(tags.comment);
    339     free(tags.genre);
    340     free(tags.date);
    341 }
    342 
    343 static MpcInfo getTags(const char* p_Filename)
    344 {
    345     File oFile(p_Filename, false);
     331static void mpcSeek(InputPlayback *data, int p_Offset)
     332{
     333        mpcSeekm(data, 1000 * p_Offset);
     334}
     335
     336static MpcInfo getTags(const gchar* p_Filename)
     337{
     338    gchar *pRealFilename = g_filename_from_uri(p_Filename, NULL, NULL);
     339    File oFile(pRealFilename ? pRealFilename : p_Filename, false);
     340    g_free(pRealFilename);
    346341    Tag* poTag = oFile.tag();
    347342    MpcInfo tags = {0};
    348343    tags.title   = g_strdup(poTag->title().toCString(true));
     344    REMOVE_NONEXISTANT_TAG(tags.title);
    349345    tags.artist  = g_strdup(poTag->artist().toCString(true));
     346    REMOVE_NONEXISTANT_TAG(tags.artist);
    350347    tags.album   = g_strdup(poTag->album().toCString(true));
     348    REMOVE_NONEXISTANT_TAG(tags.album);
    351349    tags.genre   = g_strdup(poTag->genre().toCString(true));
     350    REMOVE_NONEXISTANT_TAG(tags.genre);
    352351    tags.comment = g_strdup(poTag->comment().toCString(true));
     352    REMOVE_NONEXISTANT_TAG(tags.comment);
    353353    tags.year    = poTag->year();
    354354    tags.track   = poTag->track();
     355#if 0
    355356    TagLib::APE::Tag* ape = oFile.APETag(false);
    356357    if(ape)
     
    366367        }
    367368    }
     369#endif
    368370    return tags;
     371}
     372
     373static void removeTags(GtkWidget * w, gpointer data)
     374{
     375    File oFile(gtk_entry_get_text(GTK_ENTRY(widgets.fileEntry)));
     376    oFile.remove();
     377    oFile.save();
     378    closeInfoBox(NULL, NULL);
     379}
     380
     381static void saveTags(GtkWidget* w, gpointer data)
     382{
     383    File oFile(gtk_entry_get_text(GTK_ENTRY(widgets.fileEntry)));
     384    Tag* poTag = oFile.tag();
     385
     386    gchar* cAlbum   = g_strdup(gtk_entry_get_text(GTK_ENTRY(widgets.albumEntry)));
     387    gchar* cArtist  = g_strdup(gtk_entry_get_text(GTK_ENTRY(widgets.artistEntry)));
     388    gchar* cTitle   = g_strdup(gtk_entry_get_text(GTK_ENTRY(widgets.titleEntry)));
     389    gchar* cGenre   = g_strdup(gtk_entry_get_text(GTK_ENTRY(widgets.genreEntry)));
     390    gchar* cComment = g_strdup(gtk_entry_get_text(GTK_ENTRY(widgets.commentEntry)));
     391
     392    const String album   = String(cAlbum,   TagLib::String::UTF8);
     393    const String artist  = String(cArtist,  TagLib::String::UTF8);
     394    const String title   = String(cTitle,   TagLib::String::UTF8);
     395    const String genre   = String(cGenre,   TagLib::String::UTF8);
     396    const String comment = String(cComment, TagLib::String::UTF8);
     397
     398    poTag->setAlbum(album);
     399    poTag->setArtist(artist);
     400    poTag->setTitle(title);
     401    poTag->setGenre(genre);
     402    poTag->setComment(comment);
     403    poTag->setYear(atoi(gtk_entry_get_text(GTK_ENTRY(widgets.yearEntry))));
     404    poTag->setTrack(atoi(gtk_entry_get_text(GTK_ENTRY(widgets.trackEntry))));
     405
     406    g_free(cAlbum);
     407    g_free(cArtist);
     408    g_free(cTitle);
     409    g_free(cGenre);
     410    g_free(cComment);
     411
     412    oFile.save();
     413    closeInfoBox(NULL, NULL);
     414}
     415
     416static void freeTags(MpcInfo& tags)
     417{
     418    g_free(tags.title);
     419    g_free(tags.artist);
     420    g_free(tags.album);
     421    g_free(tags.comment);
     422    g_free(tags.genre);
     423    g_free(tags.date);
     424}
     425
     426static Tuple *mpcGetTuple(gchar* p_Filename, VFSFile *input)
     427{
     428        Tuple *tuple = 0;
     429        bool close_input = false;
     430
     431        if (input == 0) {
     432                input = aud_vfs_fopen(p_Filename, "rb");
     433                if (input == 0) {
     434                        gchar* temp = g_strdup_printf("[xmms-musepack] mpcGetTuple is unable to open %s\n", p_Filename);
     435                        perror(temp);
     436                        g_free(temp);
     437                        return 0;
     438                }
     439                close_input = true;
     440        }
     441
     442        tuple = aud_tuple_new_from_filename(p_Filename);
     443
     444        mpc_streaminfo info;
     445        mpc_reader reader;
     446        mpc_reader_setup_file_vfs(&reader, input);
     447        mpc_demux * demux = mpc_demux_init(&reader);
     448        mpc_demux_get_info(demux, &info);
     449        mpc_demux_exit(demux);
     450
     451        aud_tuple_associate_int(tuple, FIELD_LENGTH, NULL, static_cast<int> (1000 * mpc_streaminfo_get_length(&info)));
     452
     453//      gchar *scratch = g_strdup_printf("Musepack v%d (encoder %s)", info.stream_version, info.encoder);
     454//      aud_tuple_associate_string(tuple, FIELD_CODEC, NULL, scratch);
     455//      g_free(scratch);
     456
     457//      scratch = g_strdup_printf("lossy (%s)", info.profile_name);
     458//      aud_tuple_associate_string(tuple, FIELD_QUALITY, NULL, scratch);
     459//      g_free(scratch);
     460
     461        aud_tuple_associate_int(tuple, FIELD_BITRATE, NULL, static_cast<int> (info.average_bitrate / 1000));
     462
     463        MpcInfo tags = getTags(p_Filename);
     464
     465//      aud_tuple_associate_string(tuple, FIELD_DATE, NULL, tags.date);
     466//      aud_tuple_associate_string(tuple, FIELD_TITLE, NULL, tags.title);
     467//      aud_tuple_associate_string(tuple, FIELD_ARTIST, NULL, tags.artist);
     468//      aud_tuple_associate_string(tuple, FIELD_ALBUM, NULL, tags.album);
     469//      aud_tuple_associate_int(tuple, FIELD_TRACK_NUMBER, NULL, tags.track);
     470//      aud_tuple_associate_int(tuple, FIELD_YEAR, NULL, tags.year);
     471//      aud_tuple_associate_string(tuple, FIELD_GENRE, NULL, tags.genre);
     472//      aud_tuple_associate_string(tuple, FIELD_COMMENT, NULL, tags.comment);
     473
     474        freeTags(tags);
     475
     476        if (close_input)
     477                aud_vfs_fclose(input);
     478
     479        return tuple;
     480}
     481
     482static Tuple *mpcProbeForTuple(gchar* p_Filename, VFSFile *input)
     483{
     484    return mpcGetTuple(p_Filename, input);
     485}
     486
     487static Tuple *mpcGetSongTuple(gchar* p_Filename)
     488{
     489        return mpcGetTuple(p_Filename, 0);
     490}
     491
     492static char* mpcGenerateTitle(const MpcInfo& p_Tags, gchar* p_Filename)
     493{
     494    Tuple* tuple = mpcGetSongTuple(p_Filename);
     495
     496    gchar* title = aud_tuple_formatter_make_title_string(tuple, aud_get_gentitle_format());
     497
     498    aud_tuple_free((void *) tuple);
     499    return title;
     500}
     501
     502static void mpcGtkPrintLabel(GtkWidget* widget, const char* format,...)
     503{
     504    va_list args;
     505
     506    va_start(args, format);
     507    gchar* temp = g_strdup_vprintf(format, args);
     508    va_end(args);
     509
     510    gtk_label_set_text(GTK_LABEL(widget), temp);
     511    g_free(temp);
     512}
     513
     514static GtkWidget* mpcGtkTagLabel(const char* p_Text, int a, int b, int c, int d, GtkWidget* p_Box)
     515{
     516    GtkWidget* label = gtk_label_new(p_Text);
     517    gtk_misc_set_alignment(GTK_MISC(label), 1, 0.5);
     518    gtk_table_attach(GTK_TABLE(p_Box), label, a, b, c, d, GTK_FILL, GTK_FILL, 5, 5);
     519    return label;
     520}
     521
     522static GtkWidget* mpcGtkTagEntry(int a, int b, int c, int d, int p_Size, GtkWidget* p_Box)
     523{
     524    GtkWidget* entry;
     525    entry = gtk_entry_new();
     526    if(p_Size)
     527        gtk_entry_set_max_length(GTK_ENTRY(entry), p_Size);
     528
     529    gtk_table_attach(GTK_TABLE(p_Box), entry, a, b, c, d,
     530                    (GtkAttachOptions) (GTK_FILL | GTK_EXPAND | GTK_SHRINK),
     531                    (GtkAttachOptions) (GTK_FILL | GTK_EXPAND | GTK_SHRINK), 0, 5);
     532    return entry;
     533}
     534
     535static GtkWidget* mpcGtkLabel(GtkWidget* p_Box)
     536{
     537    GtkWidget* label = gtk_label_new("");
     538    gtk_misc_set_alignment(GTK_MISC(label), 0, 0);
     539    gtk_label_set_justify(GTK_LABEL(label), GTK_JUSTIFY_LEFT);
     540    gtk_box_pack_start(GTK_BOX(p_Box), label, FALSE, FALSE, 0);
     541    return label;
     542}
     543
     544static GtkWidget* mpcGtkButton(const char* p_Text, GtkWidget* p_Box)
     545{
     546    GtkWidget* button = gtk_button_new_with_label(p_Text);
     547    GTK_WIDGET_SET_FLAGS(button, GTK_CAN_DEFAULT);
     548    gtk_box_pack_start(GTK_BOX(p_Box), button, TRUE, TRUE, 0);
     549    return button;
    369550}
    370551
     
    380561        gtk_window_set_type_hint(GTK_WINDOW(infoBox), GDK_WINDOW_TYPE_HINT_DIALOG);
    381562        widgets.infoBox = infoBox;
    382         gtk_window_set_policy(GTK_WINDOW(infoBox), FALSE, FALSE, FALSE);
    383         gtk_signal_connect(GTK_OBJECT(infoBox), "destroy", GTK_SIGNAL_FUNC(closeInfoBox), NULL);
     563        gtk_window_set_resizable(GTK_WINDOW(infoBox), FALSE);
     564        g_signal_connect(G_OBJECT(infoBox), "destroy", G_CALLBACK(closeInfoBox), NULL);
    384565        gtk_container_set_border_width(GTK_CONTAINER(infoBox), 10);
    385566
     
    390571        gtk_box_pack_start(GTK_BOX(iVbox), filenameHbox, FALSE, TRUE, 0);
    391572
    392         GtkWidget* fileLabel = gtk_label_new("Filename:");
     573        GtkWidget* fileLabel = gtk_label_new(_("Filename:"));
    393574        gtk_box_pack_start(GTK_BOX(filenameHbox), fileLabel, FALSE, TRUE, 0);
    394575
     
    405586
    406587        //Tag labels
    407         GtkWidget* tagFrame = gtk_frame_new("Musepack Tag");
     588        GtkWidget* tagFrame = gtk_frame_new(_("Musepack Tag"));
    408589        gtk_box_pack_start(GTK_BOX(leftBox), tagFrame, FALSE, FALSE, 0);
    409590        gtk_widget_set_sensitive(tagFrame, TRUE);
     
    413594        gtk_container_add(GTK_CONTAINER(tagFrame), iTable);
    414595
    415         mpcGtkTagLabel("Title:", 0, 1, 0, 1, iTable);
     596        mpcGtkTagLabel(_("Title:"), 0, 1, 0, 1, iTable);
    416597        GtkWidget* titleEntry = mpcGtkTagEntry(1, 4, 0, 1, 0, iTable);
    417598        widgets.titleEntry = titleEntry;
    418599
    419         mpcGtkTagLabel("Artist:", 0, 1, 1, 2, iTable);
     600        mpcGtkTagLabel(_("Artist:"), 0, 1, 1, 2, iTable);
    420601        GtkWidget* artistEntry = mpcGtkTagEntry(1, 4, 1, 2, 0, iTable);
    421602        widgets.artistEntry = artistEntry;
    422603
    423         mpcGtkTagLabel("Album:", 0, 1, 2, 3, iTable);
     604        mpcGtkTagLabel(_("Album:"), 0, 1, 2, 3, iTable);
    424605        GtkWidget* albumEntry = mpcGtkTagEntry(1, 4, 2, 3, 0, iTable);
    425606        widgets.albumEntry = albumEntry;
    426607
    427         mpcGtkTagLabel("Comment:", 0, 1, 3, 4, iTable);
     608        mpcGtkTagLabel(_("Comment:"), 0, 1, 3, 4, iTable);
    428609        GtkWidget* commentEntry = mpcGtkTagEntry(1, 4, 3, 4, 0, iTable);
    429610        widgets.commentEntry = commentEntry;
    430611
    431         mpcGtkTagLabel("Year:", 0, 1, 4, 5, iTable);
     612        mpcGtkTagLabel(_("Year:"), 0, 1, 4, 5, iTable);
    432613        GtkWidget* yearEntry = mpcGtkTagEntry(1, 2, 4, 5, 4, iTable);
    433614        widgets.yearEntry = yearEntry;
    434         gtk_widget_set_usize(yearEntry, 4, -1);
    435 
    436         mpcGtkTagLabel("Track:", 2, 3, 4, 5, iTable);
     615        gtk_widget_set_size_request(yearEntry, 4, -1);
     616
     617        mpcGtkTagLabel(_("Track:"), 2, 3, 4, 5, iTable);
    437618        GtkWidget* trackEntry = mpcGtkTagEntry(3, 4, 4, 5, 4, iTable);
    438619        widgets.trackEntry = trackEntry;
    439         gtk_widget_set_usize(trackEntry, 3, -1);
    440 
    441         mpcGtkTagLabel("Genre:", 0, 1, 5, 6, iTable);
     620        gtk_widget_set_size_request(trackEntry, 3, -1);
     621
     622        mpcGtkTagLabel(_("Genre:"), 0, 1, 5, 6, iTable);
    442623        GtkWidget* genreEntry = mpcGtkTagEntry(1, 4, 5, 6, 0, iTable);
    443624        widgets.genreEntry = genreEntry;
    444         gtk_widget_set_usize(genreEntry, 20, -1);
     625        gtk_widget_set_size_request(genreEntry, 20, -1);
    445626
    446627        //Buttons
    447628        GtkWidget* buttonBox = gtk_hbutton_box_new();
    448629        gtk_button_box_set_layout(GTK_BUTTON_BOX(buttonBox), GTK_BUTTONBOX_END);
    449         gtk_button_box_set_spacing(GTK_BUTTON_BOX(buttonBox), 5);
     630        gtk_box_set_spacing(GTK_BOX(buttonBox), 5);
    450631        gtk_box_pack_start(GTK_BOX(leftBox), buttonBox, FALSE, FALSE, 0);
    451632
    452         GtkWidget* saveButton = mpcGtkButton("Save", buttonBox);
    453         gtk_signal_connect(GTK_OBJECT(saveButton), "clicked", GTK_SIGNAL_FUNC(saveTags), NULL);
    454 
    455         GtkWidget* removeButton = mpcGtkButton("Remove Tag", buttonBox);
    456         gtk_signal_connect_object(GTK_OBJECT(removeButton), "clicked", GTK_SIGNAL_FUNC(removeTags), NULL);
    457 
    458         GtkWidget* cancelButton = mpcGtkButton("Cancel", buttonBox);
    459         gtk_signal_connect_object(GTK_OBJECT(cancelButton), "clicked", GTK_SIGNAL_FUNC(closeInfoBox), NULL);
     633        GtkWidget* saveButton = mpcGtkButton(_("Save"), buttonBox);
     634        g_signal_connect(G_OBJECT(saveButton), "clicked", G_CALLBACK(saveTags), NULL);
     635
     636        GtkWidget* removeButton = mpcGtkButton(_("Remove Tag"), buttonBox);
     637        g_signal_connect_swapped(G_OBJECT(removeButton), "clicked", G_CALLBACK(removeTags), NULL);
     638
     639        GtkWidget* cancelButton = mpcGtkButton(_("Cancel"), buttonBox);
     640        g_signal_connect_swapped(G_OBJECT(cancelButton), "clicked", G_CALLBACK(closeInfoBox), NULL);
    460641        gtk_widget_grab_default(cancelButton);
    461642
    462643        //File information
    463         GtkWidget* infoFrame = gtk_frame_new("Musepack Info");
     644        GtkWidget* infoFrame = gtk_frame_new(_("Musepack Info"));
    464645        gtk_box_pack_start(GTK_BOX(iHbox), infoFrame, FALSE, FALSE, 0);
    465646
     
    471652        GtkWidget* streamLabel    = mpcGtkLabel(infoVbox);
    472653        GtkWidget* encoderLabel   = mpcGtkLabel(infoVbox);
    473                 GtkWidget* profileLabel   = mpcGtkLabel(infoVbox);
     654        GtkWidget* profileLabel   = mpcGtkLabel(infoVbox);
    474655                GtkWidget* pnsLabel       = mpcGtkLabel(infoVbox);
    475656                GtkWidget* gaplessLabel   = mpcGtkLabel(infoVbox);
     
    484665        GtkWidget* albumGainLabel = mpcGtkLabel(infoVbox);
    485666
    486                 mpc_reader reader;
    487                 mpc_demux * demux;
    488                 if (mpc_reader_init_stdio(&reader, p_Filename) == MPC_STATUS_OK && (demux = mpc_demux_init(&reader))) {
     667        VFSFile *input = aud_vfs_fopen(p_Filename, "rb");
     668        if(input)
     669        {
    489670            mpc_streaminfo info;
     671            mpc_reader reader;
     672            mpc_reader_setup_file_vfs(&reader, input);
     673                        mpc_demux * demux = mpc_demux_init(&reader);
    490674                        mpc_demux_get_info(demux, &info);
    491 
    492             int time = static_cast<int> (mpc_streaminfo_get_length(&info));
    493             int minutes = time / 60;
    494             int seconds = time % 60;
    495 
    496             mpcGtkPrintLabel(streamLabel,    "Streamversion %d", info.stream_version);
    497             mpcGtkPrintLabel(encoderLabel,   "Encoder: \%s", info.encoder);
    498                         mpcGtkPrintLabel(profileLabel,   "Profile: \%s (q=%0.2f)", info.profile_name, info.profile - 5);
    499                         mpcGtkPrintLabel(pnsLabel,       "PNS: \%s", info.pns == 0xFF ? "unknow" : info.pns ? "on" : "off");
    500                         mpcGtkPrintLabel(gaplessLabel,   "Gapless: \%s", info.is_true_gapless ? "on" : "off");
    501             mpcGtkPrintLabel(bitrateLabel,   "Average bitrate: \%6.1f kbps", info.average_bitrate * 1.e-3);
    502             mpcGtkPrintLabel(rateLabel,      "Samplerate: \%d Hz", info.sample_freq);
    503             mpcGtkPrintLabel(channelsLabel,  "Channels: \%d", info.channels);
    504                         mpcGtkPrintLabel(lengthLabel,    "Length: \%d:\%.2d (%u samples)", minutes, seconds, (mpc_uint32_t)mpc_streaminfo_get_length_samples(&info));
    505             mpcGtkPrintLabel(fileSizeLabel,  "File size: \%d Bytes", info.total_file_length);
    506                         mpcGtkPrintLabel(trackPeakLabel, "Track Peak: \%2.2f dB", info.peak_title / 256.);
    507                         mpcGtkPrintLabel(trackGainLabel, "Track Gain: \%2.2f dB", info.gain_title / 256.);
    508                         mpcGtkPrintLabel(albumPeakLabel, "Album Peak: \%2.2f dB", info.peak_album / 256.);
    509                         mpcGtkPrintLabel(albumGainLabel, "Album Gain: \%2.2f dB", info.gain_album / 256.);
     675                        mpc_demux_exit(demux);
     676
     677            gint time = static_cast<int> (mpc_streaminfo_get_length(&info));
     678            gint minutes = time / 60;
     679            gint seconds = time % 60;
     680
     681                        mpcGtkPrintLabel(streamLabel,    _("Streamversion %d"), info.stream_version);
     682                        mpcGtkPrintLabel(encoderLabel,   _("Encoder: \%s"), info.encoder);
     683                        mpcGtkPrintLabel(profileLabel,   _("Profile: \%s (q=%0.2f)"), info.profile_name, info.profile - 5);
     684                        mpcGtkPrintLabel(pnsLabel,       _("PNS: \%s"), info.pns == 0xFF ? _("unknow") : info.pns ? _("on") : _("off"));
     685                        mpcGtkPrintLabel(gaplessLabel,   _("Gapless: \%s"), info.is_true_gapless ? _("on") : _("off"));
     686                        mpcGtkPrintLabel(bitrateLabel,   _("Average bitrate: \%6.1f kbps"), info.average_bitrate * 1.e-3);
     687                        mpcGtkPrintLabel(rateLabel,      _("Samplerate: \%d Hz"), info.sample_freq);
     688                        mpcGtkPrintLabel(channelsLabel,  _("Channels: \%d"), info.channels);
     689                        mpcGtkPrintLabel(lengthLabel,    _("Length: \%d:\%.2d (%u samples)"), minutes, seconds, (mpc_uint32_t)mpc_streaminfo_get_length_samples(&info));
     690                        mpcGtkPrintLabel(fileSizeLabel,  _("File size: \%d Bytes"), info.total_file_length);
     691                        mpcGtkPrintLabel(trackPeakLabel, _("Track Peak: \%2.2f dB"), info.peak_title / 256.);
     692                        mpcGtkPrintLabel(trackGainLabel, _("Track Gain: \%2.2f dB"), info.gain_title / 256.);
     693                        mpcGtkPrintLabel(albumPeakLabel, _("Album Peak: \%2.2f dB"), info.peak_album / 256.);
     694                        mpcGtkPrintLabel(albumGainLabel, _("Album Gain: \%2.2f dB"), info.gain_album / 256.);
    510695
    511696            MpcInfo tags = getTags(p_Filename);
     
    515700            gtk_entry_set_text(GTK_ENTRY(commentEntry), tags.comment);
    516701            gtk_entry_set_text(GTK_ENTRY(genreEntry),   tags.genre);
    517             char* entry = g_strdup_printf ("%d", tags.track);
     702            gchar* entry = g_strdup_printf ("%d", tags.track);
    518703            gtk_entry_set_text(GTK_ENTRY(trackEntry), entry);
    519             free(entry);
     704            g_free(entry);
    520705            entry = g_strdup_printf ("%d", tags.year);
    521706            gtk_entry_set_text(GTK_ENTRY(yearEntry), entry);
    522             free(entry);
     707            g_free(entry);
    523708            entry = g_filename_display_name(p_Filename);
    524709            gtk_entry_set_text(GTK_ENTRY(fileEntry), entry);
    525             free(entry);
     710            g_free(entry);
    526711            freeTags(tags);
    527                         mpc_demux_exit(demux);
    528                         mpc_reader_exit_stdio(&reader);
     712            aud_vfs_fclose(input);
    529713        }
    530714        else
    531715        {
    532             char* temp = g_strdup_printf("[xmms-musepack] mpcFileInfoBox is unable to read tags from %s", p_Filename);
     716            gchar* temp = g_strdup_printf("[xmms-musepack] mpcFileInfoBox is unable to read tags from %s", p_Filename);
    533717            perror(temp);
    534             free(temp);
     718            g_free(temp);
    535719        }
    536720
    537         char* name = g_filename_display_basename(p_Filename);
    538         char* text = g_strdup_printf("File Info - %s", name);
    539         free(name);
     721        gchar* name = g_filename_display_basename(p_Filename);
     722        gchar* text = g_strdup_printf(_("File Info - %s"), name);
     723        g_free(name);
    540724        gtk_window_set_title(GTK_WINDOW(infoBox), text);
    541         free(text);
     725        g_free(text);
    542726
    543727        gtk_widget_show_all(infoBox);
    544728    }
    545 }
    546 
    547 static void mpcGtkPrintLabel(GtkWidget* widget, char* format,...)
    548 {
    549     va_list args;
    550 
    551     va_start(args, format);
    552     char* temp = g_strdup_vprintf(format, args);
    553     va_end(args);
    554 
    555     gtk_label_set_text(GTK_LABEL(widget), temp);
    556     free(temp);
    557 }
    558 
    559 static GtkWidget* mpcGtkTagLabel(char* p_Text, int a, int b, int c, int d, GtkWidget* p_Box)
    560 {
    561     GtkWidget* label = gtk_label_new(p_Text);
    562     gtk_misc_set_alignment(GTK_MISC(label), 1, 0.5);
    563     gtk_table_attach(GTK_TABLE(p_Box), label, a, b, c, d, GTK_FILL, GTK_FILL, 5, 5);
    564     return label;
    565 }
    566 
    567 static GtkWidget* mpcGtkTagEntry(int a, int b, int c, int d, int p_Size, GtkWidget* p_Box)
    568 {
    569     GtkWidget* entry;
    570     if(p_Size == 0)
    571         entry = gtk_entry_new();
    572     else
    573         entry = gtk_entry_new_with_max_length(p_Size);
    574     gtk_table_attach(GTK_TABLE(p_Box), entry, a, b, c, d,
    575                     (GtkAttachOptions) (GTK_FILL | GTK_EXPAND | GTK_SHRINK),
    576                     (GtkAttachOptions) (GTK_FILL | GTK_EXPAND | GTK_SHRINK), 0, 5);
    577     return entry;
    578 }
    579 
    580 static GtkWidget* mpcGtkLabel(GtkWidget* p_Box)
    581 {
    582     GtkWidget* label = gtk_label_new("");
    583     gtk_misc_set_alignment(GTK_MISC(label), 0, 0);
    584     gtk_label_set_justify(GTK_LABEL(label), GTK_JUSTIFY_LEFT);
    585     gtk_box_pack_start(GTK_BOX(p_Box), label, FALSE, FALSE, 0);
    586     return label;
    587 }
    588 
    589 static GtkWidget* mpcGtkButton(char* p_Text, GtkWidget* p_Box)
    590 {
    591     GtkWidget* button = gtk_button_new_with_label(p_Text);
    592     GTK_WIDGET_SET_FLAGS(button, GTK_CAN_DEFAULT);
    593     gtk_box_pack_start(GTK_BOX(p_Box), button, TRUE, TRUE, 0);
    594     return button;
    595 }
    596 
    597 static void removeTags(GtkWidget * w, gpointer data)
    598 {
    599     File oFile(gtk_entry_get_text(GTK_ENTRY(widgets.fileEntry)));
    600     oFile.remove();
    601     oFile.save();
    602     closeInfoBox(NULL, NULL);
    603 }
    604 
    605 static void saveTags(GtkWidget* w, gpointer data)
    606 {
    607     File oFile(gtk_entry_get_text(GTK_ENTRY(widgets.fileEntry)));
    608     Tag* poTag = oFile.tag();
    609 
    610     char* cAlbum   = g_strdup(gtk_entry_get_text(GTK_ENTRY(widgets.albumEntry)));
    611     char* cArtist  = g_strdup(gtk_entry_get_text(GTK_ENTRY(widgets.artistEntry)));
    612     char* cTitle   = g_strdup(gtk_entry_get_text(GTK_ENTRY(widgets.titleEntry)));
    613     char* cGenre   = g_strdup(gtk_entry_get_text(GTK_ENTRY(widgets.genreEntry)));
    614     char* cComment = g_strdup(gtk_entry_get_text(GTK_ENTRY(widgets.commentEntry)));
    615 
    616     const String album   = String(cAlbum,   TagLib::String::UTF8);
    617     const String artist  = String(cArtist,  TagLib::String::UTF8);
    618     const String title   = String(cTitle,   TagLib::String::UTF8);
    619     const String genre   = String(cGenre,   TagLib::String::UTF8);
    620     const String comment = String(cComment, TagLib::String::UTF8);
    621 
    622     poTag->setAlbum(album);
    623     poTag->setArtist(artist);
    624     poTag->setTitle(title);
    625     poTag->setGenre(genre);
    626     poTag->setComment(comment);
    627     poTag->setYear(atoi(gtk_entry_get_text(GTK_ENTRY(widgets.yearEntry))));
    628     poTag->setTrack(atoi(gtk_entry_get_text(GTK_ENTRY(widgets.trackEntry))));
    629 
    630     free(cAlbum);
    631     free(cArtist);
    632     free(cTitle);
    633     free(cGenre);
    634     free(cComment);
    635 
    636     oFile.save();
    637     closeInfoBox(NULL, NULL);
    638729}
    639730
     
    644735}
    645736
    646 static char* mpcGenerateTitle(const MpcInfo& p_Tags, const char* p_Filename)
    647 {
    648     TitleInput* input;
    649     //From titlestring.h
    650     input            = g_new0(TitleInput, 1);
    651     input->__size    = XMMS_TITLEINPUT_SIZE;
    652     input->__version = XMMS_TITLEINPUT_VERSION;
    653     //end
    654 
    655     input->file_name    = g_filename_display_basename(p_Filename);
    656     input->file_path    = g_path_get_dirname(p_Filename);
    657     input->file_ext     = "mpc";
    658     input->date         = g_strdup(p_Tags.date);
    659     input->track_name   = g_strdup(p_Tags.title);
    660     input->performer    = g_strdup(p_Tags.artist);
    661     input->album_name   = g_strdup(p_Tags.album);
    662     input->track_number = p_Tags.track;
    663     input->year         = p_Tags.year;
    664     input->genre        = g_strdup(p_Tags.genre);
    665     input->comment      = g_strdup(p_Tags.comment);
    666 
    667     char* title = xmms_get_titlestring (xmms_get_gentitle_format(), input);
    668     if(!title)
    669         title = g_strdup(input->file_name);
    670     else if (!*title)
    671         title = g_strdup(input->file_name);
    672 
    673     free(input->file_name);
    674     free(input->file_path);
    675     free(input->track_name);
    676     free(input->performer);
    677     free(input->album_name);
    678     free(input->genre);
    679     free(input->comment);
    680     free(input->date);
    681     g_free(input);
    682     return title;
    683 }
    684 
    685 static void* endThread(char* p_FileName, FILE* p_FileHandle, bool release)
    686 {
    687     free(p_FileName);
     737static void* endThread(gchar* p_FileName, VFSFile * p_FileHandle, bool release)
     738{
    688739    if(release)
    689740        lockRelease();
     
    691742    {
    692743        perror(mpcDecoder.isError);
    693         free(mpcDecoder.isError);
     744        g_free(mpcDecoder.isError);
    694745        mpcDecoder.isError = NULL;
    695746    }
    696     setAlive(false);
     747    mpcDecoder.isAlive = false;
    697748    if(p_FileHandle)
    698         fclose(p_FileHandle);
     749        aud_vfs_fclose(p_FileHandle);
    699750    if(track.display)
    700751    {
    701         free(track.display);
     752        g_free(track.display);
    702753        track.display = NULL;
    703754    }
    704     pthread_exit(NULL);
    705755    return 0;
    706756}
    707757
    708 static void* decodeStream(void* data)
     758static int processBuffer(InputPlayback *playback,
     759    MPC_SAMPLE_FORMAT* sampleBuffer, char* xmmsBuffer, mpc_demux* demux)
     760{
     761        mpc_frame_info info;
     762
     763        info.buffer = sampleBuffer;
     764        mpc_demux_decode(demux, &info);
     765
     766        if (info.bits == -1) return -1; // end of stream
     767
     768        copyBuffer(sampleBuffer, xmmsBuffer, info.samples * track.channels);
     769
     770    if (pluginConfig.dynamicBitrate)
     771    {
     772                track.bitrate = static_cast<int> (info.bits * track.sampleFreq / 1152);
     773    }
     774
     775        playback->pass_audio(playback, FMT_S16_LE, track.channels, info.samples * 2 * track.channels, xmmsBuffer, NULL);
     776        return info.samples;
     777}
     778
     779static void* decodeStream(InputPlayback *data)
    709780{
    710781    lockAcquire();
    711         const char* filename = static_cast<const char*> (data);
    712         mpc_reader reader;
    713         if (mpc_reader_init_stdio(&reader, filename) != MPC_STATUS_OK) {
     782    gchar* filename = data->filename;
     783    VFSFile *input = aud_vfs_fopen(filename, "rb");
     784    if (!input)
     785    {
    714786        mpcDecoder.isError = g_strdup_printf("[xmms-musepack] decodeStream is unable to open %s", filename);
    715         return endThread(filename, 0, true);
     787        return endThread(filename, input, true);
     788    }
     789
     790    mpc_reader reader;
     791    mpc_reader_setup_file_vfs(&reader, input);
     792
     793        mpc_demux * demux = mpc_demux_init(&reader);
     794        if (demux == 0)
     795        {
     796                mpcDecoder.isError = g_strdup_printf("[xmms-musepack] decodeStream is unable to initialize demuxer on %s", filename);
     797                return endThread(filename, input, true);
    716798        }
    717799
    718         mpc_demux * demux = 0;
    719         demux = mpc_demux_init(&reader);
    720 
    721         if ( demux == 0 ) {
    722                 mpcDecoder.isError = g_strdup_printf("[xmms-musepack] decodeStream is unable to initialize decoder on %s", filename);
    723                 mpc_reader_exit_stdio(&reader);
    724                 return endThread(filename, 0, true);
    725         }
    726 
    727         mpc_streaminfo info;
     800    mpc_streaminfo info;
    728801        mpc_demux_get_info(demux, &info);
    729         MpcInfo tags     = getTags(filename);
    730         track.display    = mpcGenerateTitle(tags, filename);
    731         track.length     = static_cast<int> (1000 * mpc_streaminfo_get_length(&info));
    732         track.bitrate    = static_cast<int> (info.average_bitrate);
    733         track.sampleFreq = info.sample_freq;
    734         track.channels   = info.channels;
     802
     803    MpcInfo tags     = getTags(filename);
     804    track.display    = mpcGenerateTitle(tags, filename);
     805    track.length     = static_cast<int> (1000 * mpc_streaminfo_get_length(&info));
     806    track.bitrate    = static_cast<int> (info.average_bitrate);
     807    track.sampleFreq = info.sample_freq;
     808    track.channels   = info.channels;
    735809    freeTags(tags);
    736810
    737     MpcPlugin.set_info(track.display, track.length, track.bitrate, track.sampleFreq, track.channels);
    738 
    739     setReplaygain(demux);
     811    data->set_params(data, track.display, track.length, track.bitrate, track.sampleFreq, track.channels);
     812
     813        mpc_set_replay_level(demux, MPC_OLD_GAIN_REF, pluginConfig.replaygain,
     814                                                 pluginConfig.albumGain, pluginConfig.clipPrevention);
    740815
    741816    MPC_SAMPLE_FORMAT sampleBuffer[MPC_DECODER_BUFFER_LENGTH];
    742817    char xmmsBuffer[MPC_DECODER_BUFFER_LENGTH * 4];
    743818
    744     if (!MpcPlugin.output->open_audio(FMT_S16_LE, track.sampleFreq, track.channels))
    745     {
    746                 mpcDecoder.isError = g_strdup_printf("[xmms-musepack] decodeStream is unable to open an audio output");
    747                 mpc_reader_exit_stdio(&reader);
    748         return endThread(filename, 0, true);
    749     }
    750     else
    751     {
    752         mpcDecoder.isOutput = true;
    753     }
    754 
     819    if (!data->output->open_audio(FMT_S16_LE, track.sampleFreq, track.channels))
     820    {
     821        mpcDecoder.isError = g_strdup_printf("[xmms-musepack] decodeStream is unable to open an audio output");
     822        return endThread(filename, input, true);
     823    }
     824
     825        mpcDecoder.isOutput = true;
    755826    lockRelease();
    756827
    757         int counter = 2 * track.sampleFreq / 3;
     828        data->set_pb_ready(data);
     829        data->playing = TRUE;
     830
     831    gint counter = 2 * track.sampleFreq / 3;
    758832        int status = 0;
    759     while (isAlive())
    760     {
    761         if (getOffset() != -1)
     833    while (mpcDecoder.isAlive)
     834    {
     835        lockAcquire();
     836
     837                if (mpcDecoder.offset != -1)
    762838        {
    763                         mpc_demux_seek_second(demux, mpcDecoder.offset);
    764             setOffset(-1);
    765                         status = 0;
     839                        mpc_demux_seek_sample(demux, mpcDecoder.offset * track.sampleFreq / 1000);
     840                        data->output->flush(mpcDecoder.offset);
     841            mpcDecoder.offset = -1;
    766842        }
    767843
    768         lockAcquire();
    769         short iPlaying = MpcPlugin.output->buffer_playing()? 1 : 0;
    770         int iFree = MpcPlugin.output->buffer_free();
    771         if (!mpcDecoder.isPause &&  iFree >= ((1152 * 4) << iPlaying) && status != -1)
     844        short iPlaying = data->output->buffer_playing()? 1 : 0;
     845        gint iFree = data->output->buffer_free();
     846        if (!mpcDecoder.isPause && iFree >= ((1152 * 4) << iPlaying) && status != -1)
    772847        {
    773                         status = processBuffer(sampleBuffer, xmmsBuffer, *demux);
    774                         lockRelease();
    775 
    776                         if(pluginConfig.dynamicBitrate) {
    777                                 counter -= status;
    778                                 if(counter < 0) {
    779                                         MpcPlugin.set_info(track.display, track.length, track.bitrate, track.sampleFreq, track.channels);
    780                                         counter = 2 * track.sampleFreq / 3;
    781                                 }
    782                         }
     848            status = processBuffer(data, sampleBuffer, xmmsBuffer, demux);
     849            lockRelease();
     850
     851            if(pluginConfig.dynamicBitrate)
     852            {
     853                counter -= status;
     854                if(counter < 0)
     855                {
     856                    data->set_params(data, track.display, track.length, track.bitrate, track.sampleFreq, track.channels);
     857                    counter = 2 * track.sampleFreq / 3;
     858                }
     859            }
    783860        }
    784861        else
    785862        {
    786                         lockRelease();
     863            lockRelease();
    787864                        if (mpcDecoder.isPause == FALSE && status == -1 &&
    788                                                  MpcPlugin.output->buffer_playing() == FALSE)
     865                                                 data->output->buffer_playing() == FALSE)
    789866                                break;
    790             xmms_usleep(100000);
    791                 }
    792         }
     867            g_usleep(60000);
     868        }
     869    }
    793870        mpc_demux_exit(demux);
    794         mpc_reader_exit_stdio(&reader);
    795     return endThread(filename, 0, false);
    796 }
    797 
    798 static int processBuffer(MPC_SAMPLE_FORMAT* sampleBuffer, char* xmmsBuffer, mpc_demux& demux)
    799 {
    800         mpc_frame_info info;
    801 
    802         info.buffer = sampleBuffer;
    803         mpc_demux_decode(&demux, &info);
    804 
    805         if (info.bits == -1) return -1; // end of stream
    806 
    807     copyBuffer(sampleBuffer, xmmsBuffer, info.samples * track.channels);
    808 
    809     if (pluginConfig.dynamicBitrate)
    810     {
    811         track.bitrate = static_cast<int> (info.bits * track.sampleFreq / 1152);
    812     }
    813 
    814     if (pluginConfig.isEq)
    815     {
    816                 iir(xmmsBuffer, 4 * info.samples);
    817     }
    818 
    819         MpcPlugin.add_vis_pcm(MpcPlugin.output->written_time(), FMT_S16_LE, track.channels, info.samples * 2 * track.channels, xmmsBuffer);
    820         MpcPlugin.output->write_audio(xmmsBuffer, info.samples * 2 * track.channels);
    821         return info.samples;
    822 }
    823 
    824 static void setReplaygain(mpc_demux * d)
    825 {
    826         mpc_set_replay_level(d, MPC_OLD_GAIN_REF, pluginConfig.replaygain,
    827                                                  !pluginConfig.albumGain, pluginConfig.clipPrevention);
    828 }
    829 
    830 inline static void lockAcquire()
    831 {
    832     pthread_mutex_lock(&threadMutex);
    833 }
    834 
    835 inline static void lockRelease()
    836 {
    837     pthread_mutex_unlock(&threadMutex);
    838 }
    839 
    840 inline static bool isAlive()
    841 {
    842     lockAcquire();
    843     bool isAlive = mpcDecoder.isAlive;
    844     lockRelease();
    845     return isAlive;
    846 }
    847 
    848 inline static bool isPause()
    849 {
    850     lockAcquire();
    851     bool isPause = mpcDecoder.isPause;
    852     lockRelease();
    853     return isPause;
    854 }
    855 
    856 inline static void setAlive(bool isAlive)
    857 {
    858     lockAcquire();
    859     mpcDecoder.isAlive = isAlive;
    860     lockRelease();
    861 }
    862 
    863 inline static double getOffset()
    864 {
    865     lockAcquire();
    866     double offset = mpcDecoder.offset;
    867     lockRelease();
    868     return offset;
    869 }
    870 
    871 inline static void setOffset(double offset)
    872 {
    873     lockAcquire();
    874     mpcDecoder.offset = offset;
    875     lockRelease();
    876 }
     871    return endThread(filename, input, false);
     872}
     873
     874const gchar *mpc_fmts[] = { "mpc", NULL };
     875
     876InputPlugin MpcPlugin = {
     877        0, // handle
     878        0, // filename
     879    (gchar *)"Musepack Audio Plugin", // description
     880    mpcOpenPlugin, // init
     881        0, // cleanup
     882    mpcAboutBox, // about : Show About box
     883    mpcConfigBox, // configure : Show Configure box
     884    TRUE, // enabled
     885        0, // is_our_file
     886        0, // scan_dir
     887    mpcPlay, // play_file
     888    mpcStop, // stop
     889    mpcPause, // pause
     890    mpcSeek, // seek
     891        0, // get_time
     892        0, // get_volume
     893        0, // set_volume
     894        0, // get_vis_type
     895        0, // add_vis_pcm
     896        0, // set_info
     897        0, // set_info_text
     898        0, // get_song_info : Get Title String callback
     899    mpcFileInfoBox, // file_info_box : Show File Info Box
     900    mpcGetSongTuple, // get_song_tuple : Acquire tuple for song
     901    mpcIsOurFD, // is_our_file_from_vfs
     902    (gchar **)mpc_fmts, // vfs_extensions
     903
     904    /* Added in Audacious 1.4.0 */
     905        mpcSeekm, // void (*mseek) (InputPlayback * playback, gulong millisecond);
     906        mpcProbeForTuple, // Tuple *(*probe_for_tuple)(gchar *uri, VFSFile *fd);
     907
     908    /* Added in Audacious 1.4.1 */
     909//     gboolean have_subtune;
     910
     911    /* Added in Audacious 1.5.0 */
     912//     gboolean (*update_song_tuple)(Tuple *tuple, VFSFile *fd);
     913};
     914
     915InputPlugin *mpc_iplist[] = { &MpcPlugin, NULL };
     916
     917DECLARE_PLUGIN(musepack, NULL, NULL, mpc_iplist, NULL, NULL, NULL, NULL,NULL);
  • bmp-musepack/trunk/libmpc.h

    r455 r456  
    1 /*
    2  * Copyright (c) 2005, The Musepack Development Team
    3  * All rights reserved.
    4  *
    5  * Redistribution and use in source and binary forms, with or without
    6  * modification, are permitted provided that the following conditions are
    7  * met:
    8  *
    9  *     * Redistributions of source code must retain the above copyright
    10  *       notice, this list of conditions and the following disclaimer.
    11  *
    12  *     * Redistributions in binary form must reproduce the above
    13  *       copyright notice, this list of conditions and the following
    14  *       disclaimer in the documentation and/or other materials provided
    15  *       with the distribution.
    16  *
    17  *     * Neither the name of the The Musepack Development Team nor the
    18  *       names of its contributors may be used to endorse or promote
    19  *       products derived from this software without specific prior
    20  *       written permission.
    21  *
    22  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    23  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
    24  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    25  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
    26  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    27  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
    28  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    29  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    30  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    31  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    32  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    33  */
    34 
    351#ifndef XMMS_MUSEPACK
    362#define XMMS_MUSEPACK
     
    406{
    417#include <audacious/plugin.h>
    42 #include <audacious/util.h>
    43 #include <audacious/configdb.h>
    44 #include <audacious/strings.h>
     8#include <audacious/output.h>
     9#include <audacious/i18n.h>
    4510}
    4611
     
    4914#include <stdio.h>
    5015#include <stdlib.h>
    51 #include <pthread.h>
    5216#include <unistd.h>
    5317#include <math.h>
     
    6529#include <taglib/mpcfile.h>
    6630
    67 #include "equalizer.h"
    68 
    69 #ifndef M_LN10
    70 #define M_LN10    2.3025850929940456840179914546843642
    71 #endif
    72 
    73 typedef struct PluginConfig
     31struct PluginConfig
    7432{
    7533    gboolean clipPrevention;
     
    7735    gboolean replaygain;
    7836    gboolean albumGain;
    79     gboolean isEq;
    8037};
    8138
    82 typedef struct Widgets
     39struct Widgets
    8340{
    8441    GtkWidget* aboutBox;
     
    9956};
    10057
    101 typedef struct MpcDecoder
     58struct MpcDecoder
    10259{
    103     char*      isError;
    104     double     offset;
     60    gchar*     isError;
     61    long long  offset;
    10562    bool       isOutput;
    10663    bool       isAlive;
     
    10865};
    10966
    110 typedef struct TrackInfo
     67struct TrackInfo
    11168{
    112     int   bitrate;
    113     char* display;
    114     int   length;
    115     int   sampleFreq;
    116     int   channels;
     69    gint   bitrate;
     70    gchar* display;
     71    gint   length;
     72    gint   sampleFreq;
     73    gint   channels;
    11774};
    11875
    119 typedef struct MpcInfo
     76struct MpcInfo
    12077{
    121     char*    title;
    122     char*    artist;
    123     char*    album;
    124     char*    comment;
    125     char*    genre;
    126     char*    date;
    127     unsigned track;
    128     unsigned year;
     78    gchar*    title;
     79    gchar*    artist;
     80    gchar*    album;
     81    gchar*    comment;
     82    gchar*    genre;
     83    gchar*    date;
     84    unsigned  track;
     85    unsigned  year;
    12986};
    13087
    131 extern "C" InputPlugin * get_iplugin_info(void);
    132 
    133 static void       mpcOpenPlugin();
    134 static void       mpcAboutBox();
    135 static void       mpcConfigBox();
    13688static void       toggleSwitch(GtkWidget*, gpointer);
    13789static void       saveConfigBox(GtkWidget*, gpointer);
    138 static int        mpcIsOurFile(char*);
    139 static void       mpcPlay(char*);
    140 static void       mpcStop();
    141 static void       mpcPause(short);
    142 static void       mpcSeek(int);
    143 static void       mpcSetEq(int, float, float*);
    144 static int        mpcGetTime();
    145 static void       mpcClosePlugin();
    146 static void       mpcGetSongInfo(char*, char**, int*);
    147 static void       freeTags(MpcInfo&);
    148 static MpcInfo    getTags(const char*);
    149 static void       mpcFileInfoBox(char*);
    150 static void       mpcGtkPrintLabel(GtkWidget*, char*, ...);
    151 static GtkWidget* mpcGtkTagLabel(char*, int, int, int, int, GtkWidget*);
    152 static GtkWidget* mpcGtkTagEntry(int, int, int, int, int, GtkWidget*);
    153 static GtkWidget* mpcGtkLabel(GtkWidget*);
    154 static GtkWidget* mpcGtkButton(char*, GtkWidget*);
    155 static void       removeTags(GtkWidget*, gpointer);
    156 static void       saveTags(GtkWidget*, gpointer);
    15790static void       closeInfoBox(GtkWidget*, gpointer);
    158 static char*      mpcGenerateTitle(const MpcInfo&, const char*);
    159 static void       lockAcquire();
    160 static void       lockRelease();
    161 static void*      decodeStream(void*);
    162 static int        processBuffer(MPC_SAMPLE_FORMAT*, char*, mpc_demux&);
    163 static void*      endThread(char*, FILE*, bool);
    164 static bool       isAlive();
    165 static void       setAlive(bool);
    166 static double     getOffset();
    167 static void       setOffset(double);
    168 static bool       isPause();
    169 static void       setReplaygain(mpc_demux *);
     91static void*      decodeStream(InputPlayback*);
    17092
    17193#ifdef MPC_FIXED_POINT
     
    186108    int clipMax    = (1 << (pSize - 1)) - 1;
    187109    int floatScale =  1 << (pSize - 1);
    188     for (unsigned n = 0; n < pLength; n++)
     110    for (unsigned n = 0; n < 2 * pLength; n++)
    189111    {
    190112        int val;
Note: See TracChangeset for help on using the changeset viewer.