Mercurial > audlegacy-plugins
annotate src/musepack/libmpc.cxx @ 2055:2f2ffbc2d04d
gentitle changes
| author | William Pitcock <nenolod@atheme.org> |
|---|---|
| date | Sat, 13 Oct 2007 20:43:07 -0500 |
| parents | 8f3188746b64 |
| children | ac599b9b0490 |
| rev | line source |
|---|---|
| 232 | 1 #include "libmpc.h" |
| 2 | |
| 3 #define FORCED_THREAD_STACKSIZE 1024 * 1000 | |
| 4 #define REMOVE_NONEXISTANT_TAG(x) if (!*x) { x = NULL; } | |
| 5 | |
| 6 using TagLib::MPC::File; | |
| 7 using TagLib::Tag; | |
| 8 using TagLib::String; | |
| 9 using TagLib::APE::ItemListMap; | |
| 10 | |
|
1044
b1128efde471
[svn] - get rid of all warnings gcc 4.2.0 emits with my build configuration.
yaz
parents:
659
diff
changeset
|
11 const gchar *mpc_fmts[] = { "mpc", NULL }; |
|
372
a157306caf03
[svn] - finalize the plugin-side of the extension-assist ABI
nenolod
parents:
368
diff
changeset
|
12 |
| 232 | 13 InputPlugin MpcPlugin = { |
| 14 NULL, //File Handle FILE* handle | |
| 15 NULL, //Filename char* filename | |
| 1185 | 16 (gchar *)"Musepack Audio Plugin", |
| 232 | 17 mpcOpenPlugin, //Open Plugin [CALLBACK] |
|
1621
031e91938009
musepack: C++ at it's worst.
William Pitcock <nenolod@atheme.org>
parents:
1510
diff
changeset
|
18 NULL, //Cleanup [UNUSED] |
| 232 | 19 mpcAboutBox, //Show About box [CALLBACK] |
| 20 mpcConfigBox, //Show Configure box [CALLBACK] | |
|
1621
031e91938009
musepack: C++ at it's worst.
William Pitcock <nenolod@atheme.org>
parents:
1510
diff
changeset
|
21 FALSE, //Enabled/Disabled [BOOLEAN] |
|
260
4f7b72c88319
[svn] So input.c wants to have the old-style function available...
chainsaw
parents:
254
diff
changeset
|
22 mpcIsOurFile, //Check if it's our file [CALLBACK] |
| 232 | 23 NULL, //Scan the directory [UNUSED] |
| 24 mpcPlay, //Play [CALLBACK] | |
| 25 mpcStop, //Stop [CALLBACK] | |
| 26 mpcPause, //Pause [CALLBACK] | |
| 27 mpcSeek, //Seek [CALLBACK] | |
| 28 NULL, //Set EQ [CALLBACK] | |
| 29 mpcGetTime, //Get Time [CALLBACK] | |
| 30 NULL, //Get Volume [UNUSED] | |
| 31 NULL, //Set Volume [UNUSED] | |
| 32 NULL, //Obsolete [UNUSED] | |
| 33 NULL, //Visual plugins add_vis_pcm(int time, AFormat fmt, int nch, int length, void *ptr) | |
| 34 NULL, //Set Info Settings set_info(char *title, int length, int rate, int freq, int nch) | |
| 35 NULL, //set Info Text set_info_text(char* text) | |
| 36 mpcGetSongInfo, //Get Title String callback [CALLBACK] | |
| 37 mpcFileInfoBox, //Show File Info Box [CALLBACK] | |
| 38 NULL, //Output Plugin Handle OutputPlugin output | |
| 254 | 39 mpcGetSongTuple,//Acquire tuple for song [CALLBACK] |
| 40 NULL, | |
| 41 NULL, | |
| 42 mpcIsOurFD, | |
|
1044
b1128efde471
[svn] - get rid of all warnings gcc 4.2.0 emits with my build configuration.
yaz
parents:
659
diff
changeset
|
43 (gchar **)mpc_fmts |
| 232 | 44 }; |
| 45 | |
| 1079 | 46 InputPlugin *mpc_iplist[] = { &MpcPlugin, NULL }; |
| 47 | |
|
1395
761e17b23e0c
added Discovery plugin type
Cristi Magherusan <majeru@atheme-project.org>
parents:
1357
diff
changeset
|
48 DECLARE_PLUGIN(musepack, NULL, NULL, mpc_iplist, NULL, NULL, NULL, NULL,NULL); |
| 232 | 49 |
| 50 static PluginConfig pluginConfig = {0}; | |
| 51 static Widgets widgets = {0}; | |
| 52 static MpcDecoder mpcDecoder = {0}; | |
| 53 static TrackInfo track = {0}; | |
| 54 | |
| 55 static GThread *threadHandle; | |
| 56 GStaticMutex threadMutex = G_STATIC_MUTEX_INIT; | |
| 57 | |
| 58 /* | |
| 59 * VFS callback implementation, adapted from mpc_reader.c. | |
| 60 * This _IS_ very sick, but it works. -nenolod | |
| 61 */ | |
| 62 static mpc_int32_t | |
| 1978 | 63 aud_vfs_fread_impl(void *data, void *ptr, mpc_int32_t size) |
| 232 | 64 { |
| 65 mpc_reader_file *d = (mpc_reader_file *) data; | |
| 66 VFSFile *file = (VFSFile *) d->file; | |
| 67 | |
| 1978 | 68 return (mpc_int32_t) aud_vfs_fread(ptr, 1, size, file); |
| 232 | 69 } |
| 70 | |
| 71 static mpc_bool_t | |
| 1978 | 72 aud_vfs_fseek_impl(void *data, mpc_int32_t offset) |
| 232 | 73 { |
| 74 mpc_reader_file *d = (mpc_reader_file *) data; | |
| 75 VFSFile *file = (VFSFile *) d->file; | |
| 76 | |
| 1978 | 77 return d->is_seekable ? aud_vfs_fseek(file, offset, SEEK_SET) == 0 : FALSE; |
| 232 | 78 } |
| 79 | |
| 80 static mpc_int32_t | |
| 1978 | 81 aud_vfs_ftell_impl(void *data) |
| 232 | 82 { |
| 83 mpc_reader_file *d = (mpc_reader_file *) data; | |
| 84 VFSFile *file = (VFSFile *) d->file; | |
| 85 | |
| 1978 | 86 return aud_vfs_ftell(file); |
| 232 | 87 } |
| 88 | |
| 89 static mpc_int32_t | |
| 1978 | 90 aud_vfs_getsize_impl(void *data) |
| 232 | 91 { |
| 92 mpc_reader_file *d = (mpc_reader_file *) data; | |
| 93 | |
| 94 return d->file_size; | |
| 95 } | |
| 96 | |
| 97 static mpc_bool_t | |
| 1978 | 98 aud_vfs_canseek_impl(void *data) |
| 232 | 99 { |
| 100 mpc_reader_file *d = (mpc_reader_file *) data; | |
| 101 | |
| 102 return d->is_seekable; | |
| 103 } | |
| 104 | |
| 105 /* | |
| 106 * This sets up an mpc_reader_file object to read from VFS instead of libc. | |
| 107 * Essentially, we use this instead of the normal constructor. | |
| 108 * - nenolod | |
| 109 */ | |
| 110 void | |
| 111 mpc_reader_setup_file_vfs(mpc_reader_file *p_reader, VFSFile *input) | |
| 112 { | |
| 1978 | 113 p_reader->reader.seek = aud_vfs_fseek_impl; |
| 114 p_reader->reader.read = aud_vfs_fread_impl; | |
| 115 p_reader->reader.tell = aud_vfs_ftell_impl; | |
| 116 p_reader->reader.get_size = aud_vfs_getsize_impl; | |
| 117 p_reader->reader.canseek = aud_vfs_canseek_impl; | |
| 232 | 118 p_reader->reader.data = p_reader; |
| 119 | |
| 120 p_reader->file = (FILE *) input; // no worries, it gets cast back -nenolod | |
| 121 p_reader->is_seekable = TRUE; // XXX streams | |
| 122 | |
| 1978 | 123 aud_vfs_fseek(input, 0, SEEK_END); |
| 124 p_reader->file_size = aud_vfs_ftell(input); | |
| 125 aud_vfs_fseek(input, 0, SEEK_SET); | |
| 232 | 126 } |
| 127 | |
| 128 static void mpcOpenPlugin() | |
| 129 { | |
| 130 ConfigDb *cfg; | |
| 131 cfg = bmp_cfg_db_open(); | |
| 132 bmp_cfg_db_get_bool(cfg, "musepack", "clipPrevention", &pluginConfig.clipPrevention); | |
| 133 bmp_cfg_db_get_bool(cfg, "musepack", "albumGain", &pluginConfig.albumGain); | |
| 134 bmp_cfg_db_get_bool(cfg, "musepack", "dynamicBitrate", &pluginConfig.dynamicBitrate); | |
| 135 bmp_cfg_db_get_bool(cfg, "musepack", "replaygain", &pluginConfig.replaygain); | |
| 136 bmp_cfg_db_close(cfg); | |
| 137 } | |
| 138 | |
| 139 static void mpcAboutBox() | |
| 140 { | |
| 141 GtkWidget* aboutBox = widgets.aboutBox; | |
| 142 if (aboutBox) | |
| 143 gdk_window_raise(aboutBox->window); | |
| 144 else | |
| 145 { | |
|
1304
f34112ab9101
As usual, "i18n" modifications.
Stany HENRY <StrassBoy@gmail.com>
parents:
1185
diff
changeset
|
146 char* titleText = g_strdup_printf(_("Musepack Decoder Plugin 1.2")); |
|
f34112ab9101
As usual, "i18n" modifications.
Stany HENRY <StrassBoy@gmail.com>
parents:
1185
diff
changeset
|
147 const char* contentText = _("Plugin code by\nBenoit Amiaux\nMartin Spuler\nKuniklo\n\nGet latest version at http://musepack.net\n"); |
|
f34112ab9101
As usual, "i18n" modifications.
Stany HENRY <StrassBoy@gmail.com>
parents:
1185
diff
changeset
|
148 const char* buttonText = _("Nevermind"); |
|
1677
f6f5603a0954
xmms_show_message() changed to audacious_info_dialog()
Matti Hamalainen <ccr@tnsp.org>
parents:
1676
diff
changeset
|
149 aboutBox = audacious_info_dialog(titleText, contentText, buttonText, FALSE, NULL, NULL); |
| 232 | 150 widgets.aboutBox = aboutBox; |
| 151 g_signal_connect(G_OBJECT(aboutBox), "destroy", G_CALLBACK(gtk_widget_destroyed), &widgets.aboutBox); | |
| 152 } | |
| 153 } | |
| 154 | |
| 155 static void mpcConfigBox() | |
| 156 { | |
| 157 GtkWidget* configBox = widgets.configBox; | |
| 158 if(configBox) | |
| 159 gdk_window_raise(configBox->window); | |
| 160 else | |
| 161 { | |
| 162 configBox = gtk_window_new(GTK_WINDOW_TOPLEVEL); | |
| 163 gtk_window_set_type_hint(GTK_WINDOW(configBox), GDK_WINDOW_TYPE_HINT_DIALOG); | |
| 164 widgets.configBox = configBox; | |
| 165 g_signal_connect(G_OBJECT(configBox), "destroy", G_CALLBACK(gtk_widget_destroyed), &widgets.configBox); | |
|
1304
f34112ab9101
As usual, "i18n" modifications.
Stany HENRY <StrassBoy@gmail.com>
parents:
1185
diff
changeset
|
166 gtk_window_set_title(GTK_WINDOW(configBox), _("Musepack Decoder Configuration")); |
| 232 | 167 gtk_window_set_policy(GTK_WINDOW(configBox), FALSE, FALSE, FALSE); |
| 168 gtk_container_border_width(GTK_CONTAINER(configBox), 10); | |
| 169 | |
| 170 GtkWidget* notebook = gtk_notebook_new(); | |
| 171 GtkWidget* vbox = gtk_vbox_new(FALSE, 10); | |
| 172 gtk_box_pack_start(GTK_BOX(vbox), notebook, TRUE, TRUE, 0); | |
| 173 gtk_container_add(GTK_CONTAINER(configBox), vbox); | |
| 174 | |
| 175 //General Settings Tab | |
|
1304
f34112ab9101
As usual, "i18n" modifications.
Stany HENRY <StrassBoy@gmail.com>
parents:
1185
diff
changeset
|
176 GtkWidget* generalSet = gtk_frame_new(_("General Settings")); |
| 232 | 177 gtk_container_border_width(GTK_CONTAINER(generalSet), 5); |
| 178 | |
| 179 GtkWidget* gSvbox = gtk_vbox_new(FALSE, 10); | |
| 180 gtk_container_border_width(GTK_CONTAINER(gSvbox), 5); | |
| 181 gtk_container_add(GTK_CONTAINER(generalSet), gSvbox); | |
| 182 | |
|
1304
f34112ab9101
As usual, "i18n" modifications.
Stany HENRY <StrassBoy@gmail.com>
parents:
1185
diff
changeset
|
183 GtkWidget* bitrateCheck = gtk_check_button_new_with_label(_("Enable Dynamic Bitrate Display")); |
| 232 | 184 widgets.bitrateCheck = bitrateCheck; |
| 185 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(bitrateCheck), pluginConfig.dynamicBitrate); | |
| 186 gtk_box_pack_start(GTK_BOX(gSvbox), bitrateCheck, FALSE, FALSE, 0); | |
|
1304
f34112ab9101
As usual, "i18n" modifications.
Stany HENRY <StrassBoy@gmail.com>
parents:
1185
diff
changeset
|
187 gtk_notebook_append_page(GTK_NOTEBOOK(notebook), generalSet, gtk_label_new(_("Plugin"))); |
| 232 | 188 |
| 189 //ReplayGain Settings Tab | |
|
1304
f34112ab9101
As usual, "i18n" modifications.
Stany HENRY <StrassBoy@gmail.com>
parents:
1185
diff
changeset
|
190 GtkWidget* replaygainSet = gtk_frame_new(_("ReplayGain Settings")); |
| 232 | 191 gtk_container_border_width(GTK_CONTAINER(replaygainSet), 5); |
| 192 | |
| 193 GtkWidget* rSVbox = gtk_vbox_new(FALSE, 10); | |
| 194 gtk_container_border_width(GTK_CONTAINER(rSVbox), 5); | |
| 195 gtk_container_add(GTK_CONTAINER(replaygainSet), rSVbox); | |
| 196 | |
|
1304
f34112ab9101
As usual, "i18n" modifications.
Stany HENRY <StrassBoy@gmail.com>
parents:
1185
diff
changeset
|
197 GtkWidget* clippingCheck = gtk_check_button_new_with_label(_("Enable Clipping Prevention")); |
| 232 | 198 widgets.clippingCheck = clippingCheck; |
| 199 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(clippingCheck), pluginConfig.clipPrevention); | |
| 200 gtk_box_pack_start(GTK_BOX(rSVbox), clippingCheck, FALSE, FALSE, 0); | |
| 201 | |
|
1304
f34112ab9101
As usual, "i18n" modifications.
Stany HENRY <StrassBoy@gmail.com>
parents:
1185
diff
changeset
|
202 GtkWidget* replaygainCheck = gtk_check_button_new_with_label(_("Enable ReplayGain")); |
| 232 | 203 widgets.replaygainCheck = replaygainCheck; |
| 204 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(replaygainCheck), pluginConfig.replaygain); | |
| 205 gtk_box_pack_start(GTK_BOX(rSVbox), replaygainCheck, FALSE, FALSE, 0); | |
| 206 | |
|
1304
f34112ab9101
As usual, "i18n" modifications.
Stany HENRY <StrassBoy@gmail.com>
parents:
1185
diff
changeset
|
207 GtkWidget* replaygainType = gtk_frame_new(_("ReplayGain Type")); |
| 232 | 208 gtk_box_pack_start(GTK_BOX(rSVbox), replaygainType, FALSE, FALSE, 0); |
| 209 g_signal_connect(G_OBJECT(replaygainCheck), "toggled", G_CALLBACK(toggleSwitch), replaygainType); | |
| 210 | |
| 211 GtkWidget* rgVbox = gtk_vbox_new(FALSE, 5); | |
| 212 gtk_container_set_border_width(GTK_CONTAINER(rgVbox), 5); | |
| 213 gtk_container_add(GTK_CONTAINER(replaygainType), rgVbox); | |
| 214 | |
|
1304
f34112ab9101
As usual, "i18n" modifications.
Stany HENRY <StrassBoy@gmail.com>
parents:
1185
diff
changeset
|
215 GtkWidget* trackCheck = gtk_radio_button_new_with_label(NULL, _("Use Track Gain")); |
| 232 | 216 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(trackCheck), !pluginConfig.albumGain); |
| 217 gtk_box_pack_start(GTK_BOX(rgVbox), trackCheck, FALSE, FALSE, 0); | |
| 218 | |
|
1304
f34112ab9101
As usual, "i18n" modifications.
Stany HENRY <StrassBoy@gmail.com>
parents:
1185
diff
changeset
|
219 GtkWidget* albumCheck = gtk_radio_button_new_with_label(gtk_radio_button_group(GTK_RADIO_BUTTON(trackCheck)), _("Use Album Gain")); |
| 232 | 220 widgets.albumCheck = albumCheck; |
| 221 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(albumCheck), pluginConfig.albumGain); | |
| 222 gtk_box_pack_start(GTK_BOX(rgVbox), albumCheck, FALSE, FALSE, 0); | |
| 223 gtk_widget_set_sensitive(replaygainType, pluginConfig.replaygain); | |
|
1304
f34112ab9101
As usual, "i18n" modifications.
Stany HENRY <StrassBoy@gmail.com>
parents:
1185
diff
changeset
|
224 gtk_notebook_append_page(GTK_NOTEBOOK(notebook), replaygainSet, gtk_label_new(_("ReplayGain"))); |
| 232 | 225 |
| 226 //Buttons | |
| 227 GtkWidget* buttonBox = gtk_hbutton_box_new(); | |
| 228 gtk_button_box_set_layout(GTK_BUTTON_BOX(buttonBox), GTK_BUTTONBOX_END); | |
| 229 gtk_button_box_set_spacing(GTK_BUTTON_BOX(buttonBox), 5); | |
| 230 gtk_box_pack_start(GTK_BOX(vbox), buttonBox, FALSE, FALSE, 0); | |
| 231 | |
|
1304
f34112ab9101
As usual, "i18n" modifications.
Stany HENRY <StrassBoy@gmail.com>
parents:
1185
diff
changeset
|
232 GtkWidget* okButton = gtk_button_new_with_label(_("Ok")); |
| 232 | 233 g_signal_connect(G_OBJECT(okButton), "clicked", G_CALLBACK(saveConfigBox), NULL); |
| 234 GTK_WIDGET_SET_FLAGS(okButton, GTK_CAN_DEFAULT); | |
| 235 gtk_box_pack_start(GTK_BOX(buttonBox), okButton, TRUE, TRUE, 0); | |
| 236 | |
|
1304
f34112ab9101
As usual, "i18n" modifications.
Stany HENRY <StrassBoy@gmail.com>
parents:
1185
diff
changeset
|
237 GtkWidget* cancelButton = gtk_button_new_with_label(_("Cancel")); |
| 232 | 238 g_signal_connect_swapped(G_OBJECT(cancelButton), "clicked", G_CALLBACK(gtk_widget_destroy), GTK_OBJECT(widgets.configBox)); |
| 239 GTK_WIDGET_SET_FLAGS(cancelButton, GTK_CAN_DEFAULT); | |
| 240 gtk_widget_grab_default(cancelButton); | |
| 241 gtk_box_pack_start(GTK_BOX(buttonBox), cancelButton, TRUE, TRUE, 0); | |
| 242 | |
| 243 gtk_widget_show_all(configBox); | |
| 244 } | |
| 245 } | |
| 246 | |
| 247 static void toggleSwitch(GtkWidget* p_Widget, gpointer p_Data) | |
| 248 { | |
| 249 gtk_widget_set_sensitive(GTK_WIDGET(p_Data), gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(p_Widget))); | |
| 250 } | |
| 251 | |
| 252 static void saveConfigBox(GtkWidget* p_Widget, gpointer p_Data) | |
| 253 { | |
| 254 ConfigDb* cfg; | |
| 255 GtkToggleButton* tb; | |
| 256 | |
| 257 tb = GTK_TOGGLE_BUTTON(widgets.replaygainCheck); | |
| 258 pluginConfig.replaygain = gtk_toggle_button_get_active(tb); | |
| 259 tb = GTK_TOGGLE_BUTTON(widgets.clippingCheck); | |
| 260 pluginConfig.clipPrevention = gtk_toggle_button_get_active(tb); | |
| 261 tb = GTK_TOGGLE_BUTTON(widgets.bitrateCheck); | |
| 262 pluginConfig.dynamicBitrate = gtk_toggle_button_get_active(tb); | |
| 263 tb = GTK_TOGGLE_BUTTON(widgets.albumCheck); | |
| 264 pluginConfig.albumGain = gtk_toggle_button_get_active(tb); | |
| 265 | |
| 266 cfg = bmp_cfg_db_open(); | |
| 267 | |
| 268 bmp_cfg_db_set_bool(cfg, "musepack", "clipPrevention", pluginConfig.clipPrevention); | |
| 269 bmp_cfg_db_set_bool(cfg, "musepack", "albumGain", pluginConfig.albumGain); | |
| 270 bmp_cfg_db_set_bool(cfg, "musepack", "dynamicBitrate", pluginConfig.dynamicBitrate); | |
| 271 bmp_cfg_db_set_bool(cfg, "musepack", "replaygain", pluginConfig.replaygain); | |
| 272 | |
| 273 bmp_cfg_db_close(cfg); | |
| 274 | |
| 275 gtk_widget_destroy (widgets.configBox); | |
| 276 } | |
| 277 | |
|
260
4f7b72c88319
[svn] So input.c wants to have the old-style function available...
chainsaw
parents:
254
diff
changeset
|
278 static int mpcIsOurFile(char* p_Filename) |
|
4f7b72c88319
[svn] So input.c wants to have the old-style function available...
chainsaw
parents:
254
diff
changeset
|
279 { |
|
4f7b72c88319
[svn] So input.c wants to have the old-style function available...
chainsaw
parents:
254
diff
changeset
|
280 VFSFile *file; |
|
4f7b72c88319
[svn] So input.c wants to have the old-style function available...
chainsaw
parents:
254
diff
changeset
|
281 gchar magic[3]; |
| 1978 | 282 if ((file = aud_vfs_fopen(p_Filename, "rb"))) { |
| 283 aud_vfs_fread(magic, 1, 3, file); | |
|
260
4f7b72c88319
[svn] So input.c wants to have the old-style function available...
chainsaw
parents:
254
diff
changeset
|
284 if (!memcmp(magic, "MP+", 3)) { |
| 1978 | 285 aud_vfs_fclose(file); |
|
260
4f7b72c88319
[svn] So input.c wants to have the old-style function available...
chainsaw
parents:
254
diff
changeset
|
286 return 1; |
|
4f7b72c88319
[svn] So input.c wants to have the old-style function available...
chainsaw
parents:
254
diff
changeset
|
287 } |
| 1978 | 288 aud_vfs_fclose(file); |
|
260
4f7b72c88319
[svn] So input.c wants to have the old-style function available...
chainsaw
parents:
254
diff
changeset
|
289 } |
|
4f7b72c88319
[svn] So input.c wants to have the old-style function available...
chainsaw
parents:
254
diff
changeset
|
290 return 0; |
|
4f7b72c88319
[svn] So input.c wants to have the old-style function available...
chainsaw
parents:
254
diff
changeset
|
291 } |
|
4f7b72c88319
[svn] So input.c wants to have the old-style function available...
chainsaw
parents:
254
diff
changeset
|
292 |
| 254 | 293 static int mpcIsOurFD(char* p_Filename, VFSFile* file) |
| 232 | 294 { |
| 254 | 295 gchar magic[3]; |
| 1978 | 296 aud_vfs_fread(magic, 1, 3, file); |
|
260
4f7b72c88319
[svn] So input.c wants to have the old-style function available...
chainsaw
parents:
254
diff
changeset
|
297 if (!memcmp(magic, "MP+", 3)) |
| 254 | 298 return 1; |
| 299 return 0; | |
| 232 | 300 } |
| 301 | |
| 567 | 302 static void mpcPlay(InputPlayback *data) |
| 232 | 303 { |
| 304 mpcDecoder.offset = -1; | |
| 305 mpcDecoder.isAlive = true; | |
| 306 mpcDecoder.isOutput = false; | |
| 307 mpcDecoder.isPause = false; | |
|
1357
cf46ed0ee590
musepack: new threading model
William Pitcock <nenolod@atheme-project.org>
parents:
1304
diff
changeset
|
308 threadHandle = g_thread_self(); |
|
1447
195b5657303e
updated input plugins to use set_pb_ready to signal to the core that they're ready for playback
Giacomo Lozito <james@develia.org>
parents:
1438
diff
changeset
|
309 data->set_pb_ready(data); |
| 1986 | 310 decodeStream(data); |
| 232 | 311 } |
| 312 | |
| 567 | 313 static void mpcStop(InputPlayback *data) |
| 232 | 314 { |
| 315 setAlive(false); | |
| 316 if (threadHandle) | |
| 317 { | |
| 318 g_thread_join(threadHandle); | |
| 319 if (mpcDecoder.isOutput) | |
| 320 { | |
| 567 | 321 data->output->buffer_free(); |
| 322 data->output->close_audio(); | |
| 232 | 323 mpcDecoder.isOutput = false; |
| 324 } | |
| 325 } | |
| 326 } | |
| 327 | |
| 567 | 328 static void mpcPause(InputPlayback *data, short p_Pause) |
| 232 | 329 { |
| 330 lockAcquire(); | |
| 331 mpcDecoder.isPause = p_Pause; | |
| 567 | 332 data->output->pause(p_Pause); |
| 232 | 333 lockRelease(); |
| 334 } | |
| 335 | |
| 567 | 336 static void mpcSeek(InputPlayback *data, int p_Offset) |
| 232 | 337 { |
| 338 lockAcquire(); | |
| 339 mpcDecoder.offset = static_cast<double> (p_Offset); | |
| 567 | 340 data->output->flush(1000 * p_Offset); |
| 232 | 341 lockRelease(); |
| 342 } | |
| 343 | |
| 567 | 344 static int mpcGetTime(InputPlayback *data) |
| 232 | 345 { |
| 346 if(!isAlive()) | |
| 347 return -1; | |
| 567 | 348 return data->output->output_time(); |
| 232 | 349 } |
| 350 | |
|
1438
dc3e28d3b92a
mpc: convert, wma: fixes
William Pitcock <nenolod@atheme-project.org>
parents:
1395
diff
changeset
|
351 static Tuple *mpcGetSongTuple(char* p_Filename) |
| 232 | 352 { |
| 1978 | 353 VFSFile *input = aud_vfs_fopen(p_Filename, "rb"); |
|
1438
dc3e28d3b92a
mpc: convert, wma: fixes
William Pitcock <nenolod@atheme-project.org>
parents:
1395
diff
changeset
|
354 Tuple *tuple = NULL; |
| 232 | 355 |
| 356 if(input) | |
| 357 { | |
|
1976
5fa26178eaef
s/tuple_/aud_tuple_/g
William Pitcock <nenolod@atheme.org>
parents:
1704
diff
changeset
|
358 tuple = aud_tuple_new_from_filename(p_Filename); |
| 232 | 359 |
| 360 MpcInfo tags = getTags(p_Filename); | |
| 361 | |
|
1976
5fa26178eaef
s/tuple_/aud_tuple_/g
William Pitcock <nenolod@atheme.org>
parents:
1704
diff
changeset
|
362 aud_tuple_associate_string(tuple, FIELD_DATE, NULL, tags.date); |
|
5fa26178eaef
s/tuple_/aud_tuple_/g
William Pitcock <nenolod@atheme.org>
parents:
1704
diff
changeset
|
363 aud_tuple_associate_string(tuple, FIELD_TITLE, NULL, tags.title); |
|
5fa26178eaef
s/tuple_/aud_tuple_/g
William Pitcock <nenolod@atheme.org>
parents:
1704
diff
changeset
|
364 aud_tuple_associate_string(tuple, FIELD_ARTIST, NULL, tags.artist); |
|
5fa26178eaef
s/tuple_/aud_tuple_/g
William Pitcock <nenolod@atheme.org>
parents:
1704
diff
changeset
|
365 aud_tuple_associate_string(tuple, FIELD_ALBUM, NULL, tags.album); |
|
5fa26178eaef
s/tuple_/aud_tuple_/g
William Pitcock <nenolod@atheme.org>
parents:
1704
diff
changeset
|
366 aud_tuple_associate_int(tuple, FIELD_TRACK_NUMBER, NULL, tags.track); |
|
5fa26178eaef
s/tuple_/aud_tuple_/g
William Pitcock <nenolod@atheme.org>
parents:
1704
diff
changeset
|
367 aud_tuple_associate_int(tuple, FIELD_YEAR, NULL, tags.year); |
|
5fa26178eaef
s/tuple_/aud_tuple_/g
William Pitcock <nenolod@atheme.org>
parents:
1704
diff
changeset
|
368 aud_tuple_associate_string(tuple, FIELD_GENRE, NULL, tags.genre); |
|
5fa26178eaef
s/tuple_/aud_tuple_/g
William Pitcock <nenolod@atheme.org>
parents:
1704
diff
changeset
|
369 aud_tuple_associate_string(tuple, FIELD_COMMENT, NULL, tags.comment); |
|
1438
dc3e28d3b92a
mpc: convert, wma: fixes
William Pitcock <nenolod@atheme-project.org>
parents:
1395
diff
changeset
|
370 |
| 232 | 371 freeTags(tags); |
| 372 | |
| 373 mpc_streaminfo info; | |
| 374 mpc_reader_file reader; | |
| 375 mpc_reader_setup_file_vfs(&reader, input); | |
| 376 mpc_streaminfo_read(&info, &reader.reader); | |
| 377 | |
|
1976
5fa26178eaef
s/tuple_/aud_tuple_/g
William Pitcock <nenolod@atheme.org>
parents:
1704
diff
changeset
|
378 aud_tuple_associate_int(tuple, FIELD_LENGTH, NULL, static_cast<int> (1000 * mpc_streaminfo_get_length(&info))); |
|
1478
dd05a74648a7
Improve ${codec} and ${quality} tuples.
William Pitcock <nenolod@atheme-project.org>
parents:
1477
diff
changeset
|
379 |
|
dd05a74648a7
Improve ${codec} and ${quality} tuples.
William Pitcock <nenolod@atheme-project.org>
parents:
1477
diff
changeset
|
380 gchar *scratch = g_strdup_printf("Musepack v%d (encoder %s)", info.stream_version, info.encoder); |
|
1976
5fa26178eaef
s/tuple_/aud_tuple_/g
William Pitcock <nenolod@atheme.org>
parents:
1704
diff
changeset
|
381 aud_tuple_associate_string(tuple, FIELD_CODEC, NULL, scratch); |
|
1478
dd05a74648a7
Improve ${codec} and ${quality} tuples.
William Pitcock <nenolod@atheme-project.org>
parents:
1477
diff
changeset
|
382 g_free(scratch); |
|
dd05a74648a7
Improve ${codec} and ${quality} tuples.
William Pitcock <nenolod@atheme-project.org>
parents:
1477
diff
changeset
|
383 |
|
dd05a74648a7
Improve ${codec} and ${quality} tuples.
William Pitcock <nenolod@atheme-project.org>
parents:
1477
diff
changeset
|
384 scratch = g_strdup_printf("lossy (%s)", info.profile_name); |
|
1976
5fa26178eaef
s/tuple_/aud_tuple_/g
William Pitcock <nenolod@atheme.org>
parents:
1704
diff
changeset
|
385 aud_tuple_associate_string(tuple, FIELD_QUALITY, NULL, scratch); |
|
1478
dd05a74648a7
Improve ${codec} and ${quality} tuples.
William Pitcock <nenolod@atheme-project.org>
parents:
1477
diff
changeset
|
386 g_free(scratch); |
|
dd05a74648a7
Improve ${codec} and ${quality} tuples.
William Pitcock <nenolod@atheme-project.org>
parents:
1477
diff
changeset
|
387 |
| 1978 | 388 aud_vfs_fclose(input); |
| 232 | 389 } |
| 390 else | |
| 391 { | |
| 392 char* temp = g_strdup_printf("[xmms-musepack] mpcGetSongInfo is unable to open %s\n", p_Filename); | |
| 393 perror(temp); | |
| 394 free(temp); | |
| 395 } | |
| 396 | |
| 397 return tuple; | |
| 398 } | |
| 399 | |
| 400 static void mpcGetSongInfo(char* p_Filename, char** p_Title, int* p_Length) | |
| 401 { | |
| 1978 | 402 VFSFile *input = aud_vfs_fopen(p_Filename, "rb"); |
| 232 | 403 if(input) |
| 404 { | |
| 405 MpcInfo tags = getTags(p_Filename); | |
| 406 *p_Title = mpcGenerateTitle(tags, p_Filename); | |
| 407 freeTags(tags); | |
| 408 mpc_streaminfo info; | |
| 409 mpc_reader_file reader; | |
| 410 mpc_reader_setup_file_vfs(&reader, input); | |
| 411 mpc_streaminfo_read(&info, &reader.reader); | |
| 412 *p_Length = static_cast<int> (1000 * mpc_streaminfo_get_length(&info)); | |
| 1978 | 413 aud_vfs_fclose(input); |
| 232 | 414 } |
| 415 else | |
| 416 { | |
| 417 char* temp = g_strdup_printf("[xmms-musepack] mpcGetSongInfo is unable to open %s\n", p_Filename); | |
| 418 perror(temp); | |
| 419 free(temp); | |
| 420 } | |
| 421 } | |
| 422 | |
| 423 static void freeTags(MpcInfo& tags) | |
| 424 { | |
| 425 free(tags.title); | |
| 426 free(tags.artist); | |
| 427 free(tags.album); | |
| 428 free(tags.comment); | |
| 429 free(tags.genre); | |
| 430 free(tags.date); | |
| 431 } | |
| 432 | |
| 433 static MpcInfo getTags(const char* p_Filename) | |
| 434 { | |
|
1477
04311d687e94
fix musepack tag retrieval
William Pitcock <nenolod@atheme-project.org>
parents:
1473
diff
changeset
|
435 gchar *pRealFilename = g_filename_from_uri(p_Filename, NULL, NULL); |
|
04311d687e94
fix musepack tag retrieval
William Pitcock <nenolod@atheme-project.org>
parents:
1473
diff
changeset
|
436 File oFile(pRealFilename ? pRealFilename : p_Filename, false); |
|
04311d687e94
fix musepack tag retrieval
William Pitcock <nenolod@atheme-project.org>
parents:
1473
diff
changeset
|
437 g_free(pRealFilename); |
| 232 | 438 Tag* poTag = oFile.tag(); |
| 439 MpcInfo tags = {0}; | |
| 440 tags.title = g_strdup(poTag->title().toCString(true)); | |
| 441 REMOVE_NONEXISTANT_TAG(tags.title); | |
| 442 tags.artist = g_strdup(poTag->artist().toCString(true)); | |
| 443 REMOVE_NONEXISTANT_TAG(tags.artist); | |
| 444 tags.album = g_strdup(poTag->album().toCString(true)); | |
| 445 REMOVE_NONEXISTANT_TAG(tags.album); | |
| 446 tags.genre = g_strdup(poTag->genre().toCString(true)); | |
| 447 REMOVE_NONEXISTANT_TAG(tags.genre); | |
| 448 tags.comment = g_strdup(poTag->comment().toCString(true)); | |
| 449 REMOVE_NONEXISTANT_TAG(tags.comment); | |
| 450 tags.year = poTag->year(); | |
| 451 tags.track = poTag->track(); | |
|
659
d1a03def0021
[svn] - disable broken APETag support for now, can cause crashes
nenolod
parents:
567
diff
changeset
|
452 #if 0 |
| 232 | 453 TagLib::APE::Tag* ape = oFile.APETag(false); |
| 454 if(ape) | |
| 455 { | |
| 456 ItemListMap map = ape->itemListMap(); | |
| 457 if(map.contains("YEAR")) | |
| 458 { | |
| 459 tags.date = g_strdup(map["YEAR"].toString().toCString(true)); | |
| 460 } | |
| 461 else | |
| 462 { | |
| 463 tags.date = g_strdup_printf("%d", tags.year); | |
| 464 } | |
| 465 } | |
|
659
d1a03def0021
[svn] - disable broken APETag support for now, can cause crashes
nenolod
parents:
567
diff
changeset
|
466 #endif |
| 232 | 467 return tags; |
| 468 } | |
| 469 | |
| 470 static void mpcFileInfoBox(char* p_Filename) | |
| 471 { | |
| 472 GtkWidget* infoBox = widgets.infoBox; | |
| 473 | |
| 474 if(infoBox) | |
| 475 gdk_window_raise(infoBox->window); | |
| 476 else | |
| 477 { | |
| 478 infoBox = gtk_window_new(GTK_WINDOW_TOPLEVEL); | |
| 479 gtk_window_set_type_hint(GTK_WINDOW(infoBox), GDK_WINDOW_TYPE_HINT_DIALOG); | |
| 480 widgets.infoBox = infoBox; | |
| 481 gtk_window_set_policy(GTK_WINDOW(infoBox), FALSE, FALSE, FALSE); | |
| 482 g_signal_connect(G_OBJECT(infoBox), "destroy", G_CALLBACK(closeInfoBox), NULL); | |
| 483 gtk_container_set_border_width(GTK_CONTAINER(infoBox), 10); | |
| 484 | |
| 485 GtkWidget* iVbox = gtk_vbox_new(FALSE, 10); | |
| 486 gtk_container_add(GTK_CONTAINER(infoBox), iVbox); | |
| 487 | |
| 488 GtkWidget* filenameHbox = gtk_hbox_new(FALSE, 5); | |
| 489 gtk_box_pack_start(GTK_BOX(iVbox), filenameHbox, FALSE, TRUE, 0); | |
| 490 | |
|
1304
f34112ab9101
As usual, "i18n" modifications.
Stany HENRY <StrassBoy@gmail.com>
parents:
1185
diff
changeset
|
491 GtkWidget* fileLabel = gtk_label_new(_("Filename:")); |
| 232 | 492 gtk_box_pack_start(GTK_BOX(filenameHbox), fileLabel, FALSE, TRUE, 0); |
| 493 | |
| 494 GtkWidget* fileEntry = gtk_entry_new(); | |
| 495 widgets.fileEntry = fileEntry; | |
| 496 gtk_editable_set_editable(GTK_EDITABLE(fileEntry), FALSE); | |
| 497 gtk_box_pack_start(GTK_BOX(filenameHbox), fileEntry, TRUE, TRUE, 0); | |
| 498 | |
| 499 GtkWidget* iHbox = gtk_hbox_new(FALSE, 10); | |
| 500 gtk_box_pack_start(GTK_BOX(iVbox), iHbox, FALSE, TRUE, 0); | |
| 501 | |
| 502 GtkWidget* leftBox = gtk_vbox_new(FALSE, 10); | |
| 503 gtk_box_pack_start(GTK_BOX(iHbox), leftBox, FALSE, FALSE, 0); | |
| 504 | |
| 505 //Tag labels | |
|
1304
f34112ab9101
As usual, "i18n" modifications.
Stany HENRY <StrassBoy@gmail.com>
parents:
1185
diff
changeset
|
506 GtkWidget* tagFrame = gtk_frame_new(_("Musepack Tag")); |
| 232 | 507 gtk_box_pack_start(GTK_BOX(leftBox), tagFrame, FALSE, FALSE, 0); |
| 508 gtk_widget_set_sensitive(tagFrame, TRUE); | |
| 509 | |
| 510 GtkWidget* iTable = gtk_table_new(5, 5, FALSE); | |
| 511 gtk_container_set_border_width(GTK_CONTAINER(iTable), 5); | |
| 512 gtk_container_add(GTK_CONTAINER(tagFrame), iTable); | |
| 513 | |
|
1304
f34112ab9101
As usual, "i18n" modifications.
Stany HENRY <StrassBoy@gmail.com>
parents:
1185
diff
changeset
|
514 mpcGtkTagLabel(_("Title:"), 0, 1, 0, 1, iTable); |
| 232 | 515 GtkWidget* titleEntry = mpcGtkTagEntry(1, 4, 0, 1, 0, iTable); |
| 516 widgets.titleEntry = titleEntry; | |
| 517 | |
|
1304
f34112ab9101
As usual, "i18n" modifications.
Stany HENRY <StrassBoy@gmail.com>
parents:
1185
diff
changeset
|
518 mpcGtkTagLabel(_("Artist:"), 0, 1, 1, 2, iTable); |
| 232 | 519 GtkWidget* artistEntry = mpcGtkTagEntry(1, 4, 1, 2, 0, iTable); |
| 520 widgets.artistEntry = artistEntry; | |
| 521 | |
|
1304
f34112ab9101
As usual, "i18n" modifications.
Stany HENRY <StrassBoy@gmail.com>
parents:
1185
diff
changeset
|
522 mpcGtkTagLabel(_("Album:"), 0, 1, 2, 3, iTable); |
| 232 | 523 GtkWidget* albumEntry = mpcGtkTagEntry(1, 4, 2, 3, 0, iTable); |
| 524 widgets.albumEntry = albumEntry; | |
| 525 | |
|
1304
f34112ab9101
As usual, "i18n" modifications.
Stany HENRY <StrassBoy@gmail.com>
parents:
1185
diff
changeset
|
526 mpcGtkTagLabel(_("Comment:"), 0, 1, 3, 4, iTable); |
| 232 | 527 GtkWidget* commentEntry = mpcGtkTagEntry(1, 4, 3, 4, 0, iTable); |
| 528 widgets.commentEntry = commentEntry; | |
| 529 | |
|
1304
f34112ab9101
As usual, "i18n" modifications.
Stany HENRY <StrassBoy@gmail.com>
parents:
1185
diff
changeset
|
530 mpcGtkTagLabel(_("Year:"), 0, 1, 4, 5, iTable); |
| 232 | 531 GtkWidget* yearEntry = mpcGtkTagEntry(1, 2, 4, 5, 4, iTable); |
| 532 widgets.yearEntry = yearEntry; | |
| 533 gtk_widget_set_usize(yearEntry, 4, -1); | |
| 534 | |
|
1304
f34112ab9101
As usual, "i18n" modifications.
Stany HENRY <StrassBoy@gmail.com>
parents:
1185
diff
changeset
|
535 mpcGtkTagLabel(_("Track:"), 2, 3, 4, 5, iTable); |
| 232 | 536 GtkWidget* trackEntry = mpcGtkTagEntry(3, 4, 4, 5, 4, iTable); |
| 537 widgets.trackEntry = trackEntry; | |
| 538 gtk_widget_set_usize(trackEntry, 3, -1); | |
| 539 | |
|
1304
f34112ab9101
As usual, "i18n" modifications.
Stany HENRY <StrassBoy@gmail.com>
parents:
1185
diff
changeset
|
540 mpcGtkTagLabel(_("Genre:"), 0, 1, 5, 6, iTable); |
| 232 | 541 GtkWidget* genreEntry = mpcGtkTagEntry(1, 4, 5, 6, 0, iTable); |
| 542 widgets.genreEntry = genreEntry; | |
| 543 gtk_widget_set_usize(genreEntry, 20, -1); | |
| 544 | |
| 545 //Buttons | |
| 546 GtkWidget* buttonBox = gtk_hbutton_box_new(); | |
| 547 gtk_button_box_set_layout(GTK_BUTTON_BOX(buttonBox), GTK_BUTTONBOX_END); | |
| 548 gtk_button_box_set_spacing(GTK_BUTTON_BOX(buttonBox), 5); | |
| 549 gtk_box_pack_start(GTK_BOX(leftBox), buttonBox, FALSE, FALSE, 0); | |
| 550 | |
|
1304
f34112ab9101
As usual, "i18n" modifications.
Stany HENRY <StrassBoy@gmail.com>
parents:
1185
diff
changeset
|
551 GtkWidget* saveButton = mpcGtkButton(_("Save"), buttonBox); |
| 232 | 552 g_signal_connect(G_OBJECT(saveButton), "clicked", G_CALLBACK(saveTags), NULL); |
| 553 | |
|
1304
f34112ab9101
As usual, "i18n" modifications.
Stany HENRY <StrassBoy@gmail.com>
parents:
1185
diff
changeset
|
554 GtkWidget* removeButton = mpcGtkButton(_("Remove Tag"), buttonBox); |
| 232 | 555 g_signal_connect_swapped(G_OBJECT(removeButton), "clicked", G_CALLBACK(removeTags), NULL); |
| 556 | |
|
1304
f34112ab9101
As usual, "i18n" modifications.
Stany HENRY <StrassBoy@gmail.com>
parents:
1185
diff
changeset
|
557 GtkWidget* cancelButton = mpcGtkButton(_("Cancel"), buttonBox); |
| 232 | 558 g_signal_connect_swapped(G_OBJECT(cancelButton), "clicked", G_CALLBACK(closeInfoBox), NULL); |
| 559 gtk_widget_grab_default(cancelButton); | |
| 560 | |
| 561 //File information | |
|
1304
f34112ab9101
As usual, "i18n" modifications.
Stany HENRY <StrassBoy@gmail.com>
parents:
1185
diff
changeset
|
562 GtkWidget* infoFrame = gtk_frame_new(_("Musepack Info")); |
| 232 | 563 gtk_box_pack_start(GTK_BOX(iHbox), infoFrame, FALSE, FALSE, 0); |
| 564 | |
| 565 GtkWidget* infoVbox = gtk_vbox_new(FALSE, 5); | |
| 566 gtk_container_add(GTK_CONTAINER(infoFrame), infoVbox); | |
| 567 gtk_container_set_border_width(GTK_CONTAINER(infoVbox), 10); | |
| 568 gtk_box_set_spacing(GTK_BOX(infoVbox), 0); | |
| 569 | |
| 570 GtkWidget* streamLabel = mpcGtkLabel(infoVbox); | |
| 571 GtkWidget* encoderLabel = mpcGtkLabel(infoVbox); | |
| 572 GtkWidget* profileLabel = mpcGtkLabel(infoVbox); | |
| 573 GtkWidget* bitrateLabel = mpcGtkLabel(infoVbox); | |
| 574 GtkWidget* rateLabel = mpcGtkLabel(infoVbox); | |
| 575 GtkWidget* channelsLabel = mpcGtkLabel(infoVbox); | |
| 576 GtkWidget* lengthLabel = mpcGtkLabel(infoVbox); | |
| 577 GtkWidget* fileSizeLabel = mpcGtkLabel(infoVbox); | |
| 578 GtkWidget* trackPeakLabel = mpcGtkLabel(infoVbox); | |
| 579 GtkWidget* trackGainLabel = mpcGtkLabel(infoVbox); | |
| 580 GtkWidget* albumPeakLabel = mpcGtkLabel(infoVbox); | |
| 581 GtkWidget* albumGainLabel = mpcGtkLabel(infoVbox); | |
| 582 | |
| 1978 | 583 VFSFile *input = aud_vfs_fopen(p_Filename, "rb"); |
| 232 | 584 if(input) |
| 585 { | |
| 586 mpc_streaminfo info; | |
| 587 mpc_reader_file reader; | |
| 588 mpc_reader_setup_file_vfs(&reader, input); | |
| 589 mpc_streaminfo_read(&info, &reader.reader); | |
| 590 | |
| 591 int time = static_cast<int> (mpc_streaminfo_get_length(&info)); | |
| 592 int minutes = time / 60; | |
| 593 int seconds = time % 60; | |
| 594 | |
|
1304
f34112ab9101
As usual, "i18n" modifications.
Stany HENRY <StrassBoy@gmail.com>
parents:
1185
diff
changeset
|
595 mpcGtkPrintLabel(streamLabel, _("Streamversion %d"), info.stream_version); |
|
f34112ab9101
As usual, "i18n" modifications.
Stany HENRY <StrassBoy@gmail.com>
parents:
1185
diff
changeset
|
596 mpcGtkPrintLabel(encoderLabel, _("Encoder: %s"), info.encoder); |
|
f34112ab9101
As usual, "i18n" modifications.
Stany HENRY <StrassBoy@gmail.com>
parents:
1185
diff
changeset
|
597 mpcGtkPrintLabel(profileLabel, _("Profile: %s"), info.profile_name); |
|
f34112ab9101
As usual, "i18n" modifications.
Stany HENRY <StrassBoy@gmail.com>
parents:
1185
diff
changeset
|
598 mpcGtkPrintLabel(bitrateLabel, _("Average bitrate: %6.1f kbps"), info.average_bitrate * 1.e-3); |
|
f34112ab9101
As usual, "i18n" modifications.
Stany HENRY <StrassBoy@gmail.com>
parents:
1185
diff
changeset
|
599 mpcGtkPrintLabel(rateLabel, _("Samplerate: %d Hz"), info.sample_freq); |
|
f34112ab9101
As usual, "i18n" modifications.
Stany HENRY <StrassBoy@gmail.com>
parents:
1185
diff
changeset
|
600 mpcGtkPrintLabel(channelsLabel, _("Channels: %d"), info.channels); |
|
f34112ab9101
As usual, "i18n" modifications.
Stany HENRY <StrassBoy@gmail.com>
parents:
1185
diff
changeset
|
601 mpcGtkPrintLabel(lengthLabel, _("Length: %d:\%.2d"), minutes, seconds); |
|
f34112ab9101
As usual, "i18n" modifications.
Stany HENRY <StrassBoy@gmail.com>
parents:
1185
diff
changeset
|
602 mpcGtkPrintLabel(fileSizeLabel, _("File size: %d Bytes"), info.total_file_length); |
|
f34112ab9101
As usual, "i18n" modifications.
Stany HENRY <StrassBoy@gmail.com>
parents:
1185
diff
changeset
|
603 mpcGtkPrintLabel(trackPeakLabel, _("Track Peak: %5u"), info.peak_title); |
|
f34112ab9101
As usual, "i18n" modifications.
Stany HENRY <StrassBoy@gmail.com>
parents:
1185
diff
changeset
|
604 mpcGtkPrintLabel(trackGainLabel, _("Track Gain: %-+2.2f dB"), 0.01 * info.gain_title); |
|
f34112ab9101
As usual, "i18n" modifications.
Stany HENRY <StrassBoy@gmail.com>
parents:
1185
diff
changeset
|
605 mpcGtkPrintLabel(albumPeakLabel, _("Album Peak: %5u"), info.peak_album); |
|
f34112ab9101
As usual, "i18n" modifications.
Stany HENRY <StrassBoy@gmail.com>
parents:
1185
diff
changeset
|
606 mpcGtkPrintLabel(albumGainLabel, _("Album Gain: %-+5.2f dB"), 0.01 * info.gain_album); |
| 232 | 607 |
| 608 MpcInfo tags = getTags(p_Filename); | |
| 609 gtk_entry_set_text(GTK_ENTRY(titleEntry), tags.title); | |
| 610 gtk_entry_set_text(GTK_ENTRY(artistEntry), tags.artist); | |
| 611 gtk_entry_set_text(GTK_ENTRY(albumEntry), tags.album); | |
| 612 gtk_entry_set_text(GTK_ENTRY(commentEntry), tags.comment); | |
| 613 gtk_entry_set_text(GTK_ENTRY(genreEntry), tags.genre); | |
| 614 char* entry = g_strdup_printf ("%d", tags.track); | |
| 615 gtk_entry_set_text(GTK_ENTRY(trackEntry), entry); | |
| 616 free(entry); | |
| 617 entry = g_strdup_printf ("%d", tags.year); | |
| 618 gtk_entry_set_text(GTK_ENTRY(yearEntry), entry); | |
| 619 free(entry); | |
| 620 entry = g_filename_display_name(p_Filename); | |
| 621 gtk_entry_set_text(GTK_ENTRY(fileEntry), entry); | |
| 622 free(entry); | |
| 623 freeTags(tags); | |
| 1978 | 624 aud_vfs_fclose(input); |
| 232 | 625 } |
| 626 else | |
| 627 { | |
| 628 char* temp = g_strdup_printf("[xmms-musepack] mpcFileInfoBox is unable to read tags from %s", p_Filename); | |
| 629 perror(temp); | |
| 630 free(temp); | |
| 631 } | |
| 632 | |
| 633 char* name = g_filename_display_basename(p_Filename); | |
|
1304
f34112ab9101
As usual, "i18n" modifications.
Stany HENRY <StrassBoy@gmail.com>
parents:
1185
diff
changeset
|
634 char* text = g_strdup_printf(_("File Info - %s"), name); |
| 232 | 635 free(name); |
| 636 gtk_window_set_title(GTK_WINDOW(infoBox), text); | |
| 637 free(text); | |
| 638 | |
| 639 gtk_widget_show_all(infoBox); | |
| 640 } | |
| 641 } | |
| 642 | |
|
1044
b1128efde471
[svn] - get rid of all warnings gcc 4.2.0 emits with my build configuration.
yaz
parents:
659
diff
changeset
|
643 static void mpcGtkPrintLabel(GtkWidget* widget, const char* format,...) |
| 232 | 644 { |
| 645 va_list args; | |
| 646 | |
| 647 va_start(args, format); | |
| 648 char* temp = g_strdup_vprintf(format, args); | |
| 649 va_end(args); | |
| 650 | |
| 651 gtk_label_set_text(GTK_LABEL(widget), temp); | |
| 652 free(temp); | |
| 653 } | |
| 654 | |
|
1044
b1128efde471
[svn] - get rid of all warnings gcc 4.2.0 emits with my build configuration.
yaz
parents:
659
diff
changeset
|
655 static GtkWidget* mpcGtkTagLabel(const char* p_Text, int a, int b, int c, int d, GtkWidget* p_Box) |
| 232 | 656 { |
| 657 GtkWidget* label = gtk_label_new(p_Text); | |
| 658 gtk_misc_set_alignment(GTK_MISC(label), 1, 0.5); | |
| 659 gtk_table_attach(GTK_TABLE(p_Box), label, a, b, c, d, GTK_FILL, GTK_FILL, 5, 5); | |
| 660 return label; | |
| 661 } | |
| 662 | |
| 663 static GtkWidget* mpcGtkTagEntry(int a, int b, int c, int d, int p_Size, GtkWidget* p_Box) | |
| 664 { | |
| 665 GtkWidget* entry; | |
| 666 if(p_Size == 0) | |
| 667 entry = gtk_entry_new(); | |
| 668 else | |
| 669 entry = gtk_entry_new_with_max_length(p_Size); | |
| 670 gtk_table_attach(GTK_TABLE(p_Box), entry, a, b, c, d, | |
| 671 (GtkAttachOptions) (GTK_FILL | GTK_EXPAND | GTK_SHRINK), | |
| 672 (GtkAttachOptions) (GTK_FILL | GTK_EXPAND | GTK_SHRINK), 0, 5); | |
| 673 return entry; | |
| 674 } | |
| 675 | |
| 676 static GtkWidget* mpcGtkLabel(GtkWidget* p_Box) | |
| 677 { | |
| 678 GtkWidget* label = gtk_label_new(""); | |
| 679 gtk_misc_set_alignment(GTK_MISC(label), 0, 0); | |
| 680 gtk_label_set_justify(GTK_LABEL(label), GTK_JUSTIFY_LEFT); | |
| 681 gtk_box_pack_start(GTK_BOX(p_Box), label, FALSE, FALSE, 0); | |
| 682 return label; | |
| 683 } | |
| 684 | |
|
1044
b1128efde471
[svn] - get rid of all warnings gcc 4.2.0 emits with my build configuration.
yaz
parents:
659
diff
changeset
|
685 static GtkWidget* mpcGtkButton(const char* p_Text, GtkWidget* p_Box) |
| 232 | 686 { |
| 687 GtkWidget* button = gtk_button_new_with_label(p_Text); | |
| 688 GTK_WIDGET_SET_FLAGS(button, GTK_CAN_DEFAULT); | |
| 689 gtk_box_pack_start(GTK_BOX(p_Box), button, TRUE, TRUE, 0); | |
| 690 return button; | |
| 691 } | |
| 692 | |
| 693 static void removeTags(GtkWidget * w, gpointer data) | |
| 694 { | |
| 695 File oFile(gtk_entry_get_text(GTK_ENTRY(widgets.fileEntry))); | |
| 696 oFile.remove(); | |
| 697 oFile.save(); | |
| 698 closeInfoBox(NULL, NULL); | |
| 699 } | |
| 700 | |
| 701 static void saveTags(GtkWidget* w, gpointer data) | |
| 702 { | |
| 703 File oFile(gtk_entry_get_text(GTK_ENTRY(widgets.fileEntry))); | |
| 704 Tag* poTag = oFile.tag(); | |
| 705 | |
| 706 char* cAlbum = g_strdup(gtk_entry_get_text(GTK_ENTRY(widgets.albumEntry))); | |
| 707 char* cArtist = g_strdup(gtk_entry_get_text(GTK_ENTRY(widgets.artistEntry))); | |
| 708 char* cTitle = g_strdup(gtk_entry_get_text(GTK_ENTRY(widgets.titleEntry))); | |
| 709 char* cGenre = g_strdup(gtk_entry_get_text(GTK_ENTRY(widgets.genreEntry))); | |
| 710 char* cComment = g_strdup(gtk_entry_get_text(GTK_ENTRY(widgets.commentEntry))); | |
| 711 | |
| 712 const String album = String(cAlbum, TagLib::String::UTF8); | |
| 713 const String artist = String(cArtist, TagLib::String::UTF8); | |
| 714 const String title = String(cTitle, TagLib::String::UTF8); | |
| 715 const String genre = String(cGenre, TagLib::String::UTF8); | |
| 716 const String comment = String(cComment, TagLib::String::UTF8); | |
| 717 | |
| 718 poTag->setAlbum(album); | |
| 719 poTag->setArtist(artist); | |
| 720 poTag->setTitle(title); | |
| 721 poTag->setGenre(genre); | |
| 722 poTag->setComment(comment); | |
| 723 poTag->setYear(atoi(gtk_entry_get_text(GTK_ENTRY(widgets.yearEntry)))); | |
| 724 poTag->setTrack(atoi(gtk_entry_get_text(GTK_ENTRY(widgets.trackEntry)))); | |
| 725 | |
| 726 free(cAlbum); | |
| 727 free(cArtist); | |
| 728 free(cTitle); | |
| 729 free(cGenre); | |
| 730 free(cComment); | |
| 731 | |
| 732 oFile.save(); | |
| 733 closeInfoBox(NULL, NULL); | |
| 734 } | |
| 735 | |
| 736 static void closeInfoBox(GtkWidget* w, gpointer data) | |
| 737 { | |
| 738 gtk_widget_destroy(widgets.infoBox); | |
| 739 widgets.infoBox = NULL; | |
| 740 } | |
| 741 | |
| 742 static char* mpcGenerateTitle(const MpcInfo& p_Tags, char* p_Filename) | |
| 743 { | |
|
1438
dc3e28d3b92a
mpc: convert, wma: fixes
William Pitcock <nenolod@atheme-project.org>
parents:
1395
diff
changeset
|
744 Tuple* tuple = mpcGetSongTuple(p_Filename); |
|
dc3e28d3b92a
mpc: convert, wma: fixes
William Pitcock <nenolod@atheme-project.org>
parents:
1395
diff
changeset
|
745 |
| 2055 | 746 char* title = aud_tuple_formatter_make_title_string(tuple, aud_get_gentitle_format()); |
| 232 | 747 |
|
1976
5fa26178eaef
s/tuple_/aud_tuple_/g
William Pitcock <nenolod@atheme.org>
parents:
1704
diff
changeset
|
748 aud_tuple_free((void *) tuple); |
| 232 | 749 return title; |
| 750 } | |
| 751 | |
| 752 static void* endThread(char* p_FileName, VFSFile * p_FileHandle, bool release) | |
| 753 { | |
| 754 free(p_FileName); | |
| 755 if(release) | |
| 756 lockRelease(); | |
| 757 if(mpcDecoder.isError) | |
| 758 { | |
| 759 perror(mpcDecoder.isError); | |
| 760 free(mpcDecoder.isError); | |
| 761 mpcDecoder.isError = NULL; | |
| 762 } | |
| 763 setAlive(false); | |
| 764 if(p_FileHandle) | |
| 1978 | 765 aud_vfs_fclose(p_FileHandle); |
| 232 | 766 if(track.display) |
| 767 { | |
| 768 free(track.display); | |
| 769 track.display = NULL; | |
| 770 } | |
| 771 return 0; | |
| 772 } | |
| 773 | |
| 1986 | 774 static void* decodeStream(InputPlayback *data) |
| 232 | 775 { |
| 776 lockAcquire(); | |
| 1986 | 777 char* filename = data->filename; |
| 1978 | 778 VFSFile *input = aud_vfs_fopen(filename, "rb"); |
| 232 | 779 if (!input) |
| 780 { | |
| 781 mpcDecoder.isError = g_strdup_printf("[xmms-musepack] decodeStream is unable to open %s", filename); | |
| 782 return endThread(filename, input, true); | |
| 783 } | |
| 784 | |
| 785 mpc_reader_file reader; | |
| 786 mpc_reader_setup_file_vfs(&reader, input); | |
| 787 | |
| 788 mpc_streaminfo info; | |
| 789 if (mpc_streaminfo_read(&info, &reader.reader) != ERROR_CODE_OK) | |
| 790 { | |
| 791 mpcDecoder.isError = g_strdup_printf("[xmms-musepack] decodeStream is unable to read %s", filename); | |
| 792 return endThread(filename, input, true); | |
| 793 } | |
| 794 | |
| 795 MpcInfo tags = getTags(filename); | |
| 796 track.display = mpcGenerateTitle(tags, filename); | |
| 797 track.length = static_cast<int> (1000 * mpc_streaminfo_get_length(&info)); | |
| 798 track.bitrate = static_cast<int> (info.average_bitrate); | |
| 799 track.sampleFreq = info.sample_freq; | |
| 800 track.channels = info.channels; | |
| 801 freeTags(tags); | |
| 802 | |
| 1986 | 803 data->set_params(data, track.display, track.length, track.bitrate, track.sampleFreq, track.channels); |
| 232 | 804 |
| 805 mpc_decoder decoder; | |
| 806 mpc_decoder_setup(&decoder, &reader.reader); | |
| 807 if (!mpc_decoder_initialize(&decoder, &info)) | |
| 808 { | |
| 809 mpcDecoder.isError = g_strdup_printf("[xmms-musepack] decodeStream is unable to initialize decoder on %s", filename); | |
| 810 return endThread(filename, input, true); | |
| 811 } | |
| 812 | |
| 813 setReplaygain(info, decoder); | |
| 814 | |
| 815 MPC_SAMPLE_FORMAT sampleBuffer[MPC_DECODER_BUFFER_LENGTH]; | |
| 816 char xmmsBuffer[MPC_DECODER_BUFFER_LENGTH * 4]; | |
| 817 | |
| 818 if (!MpcPlugin.output->open_audio(FMT_S16_LE, track.sampleFreq, track.channels)) | |
| 819 { | |
| 820 mpcDecoder.isError = g_strdup_printf("[xmms-musepack] decodeStream is unable to open an audio output"); | |
| 821 return endThread(filename, input, true); | |
| 822 } | |
| 823 else | |
| 824 { | |
| 825 mpcDecoder.isOutput = true; | |
| 826 } | |
| 827 | |
| 828 lockRelease(); | |
| 829 | |
| 830 int counter = 2 * track.sampleFreq / 3; | |
| 831 while (isAlive()) | |
| 832 { | |
| 833 if (getOffset() != -1) | |
| 834 { | |
| 835 mpc_decoder_seek_seconds(&decoder, mpcDecoder.offset); | |
| 836 setOffset(-1); | |
| 837 } | |
| 838 | |
| 839 lockAcquire(); | |
| 840 short iPlaying = MpcPlugin.output->buffer_playing()? 1 : 0; | |
| 841 int iFree = MpcPlugin.output->buffer_free(); | |
| 842 if (!mpcDecoder.isPause && iFree >= ((1152 * 4) << iPlaying)) | |
| 843 { | |
|
1998
8f3188746b64
chase last changeset in aud
William Pitcock <nenolod@atheme.org>
parents:
1986
diff
changeset
|
844 unsigned status = processBuffer(data, sampleBuffer, xmmsBuffer, decoder); |
| 232 | 845 if (status == (unsigned) (-1)) |
| 846 { | |
| 847 mpcDecoder.isError = g_strdup_printf("[xmms-musepack] error from internal decoder on %s", filename); | |
| 848 return endThread(filename, input, true); | |
| 849 } | |
| 850 if (status == 0 && iPlaying == 0) | |
| 851 return endThread(filename, input, true); | |
| 852 | |
| 853 lockRelease(); | |
| 854 | |
| 855 if(pluginConfig.dynamicBitrate) | |
| 856 { | |
| 857 counter -= status; | |
| 858 if(counter < 0) | |
| 859 { | |
| 1986 | 860 data->set_params(data, track.display, track.length, track.bitrate, track.sampleFreq, track.channels); |
| 232 | 861 counter = 2 * track.sampleFreq / 3; |
| 862 } | |
| 863 } | |
| 864 } | |
| 865 else | |
| 866 { | |
| 867 lockRelease(); | |
|
1676
aee4ebea943a
xmms_usleep() was removed, use g_usleep()
Matti Hamalainen <ccr@tnsp.org>
parents:
1621
diff
changeset
|
868 g_usleep(10000); |
| 232 | 869 } |
| 870 } | |
| 871 return endThread(filename, input, false); | |
| 872 } | |
| 873 | |
|
1998
8f3188746b64
chase last changeset in aud
William Pitcock <nenolod@atheme.org>
parents:
1986
diff
changeset
|
874 static int processBuffer(InputPlayback *playback, |
|
8f3188746b64
chase last changeset in aud
William Pitcock <nenolod@atheme.org>
parents:
1986
diff
changeset
|
875 MPC_SAMPLE_FORMAT* sampleBuffer, char* xmmsBuffer, mpc_decoder& decoder) |
| 232 | 876 { |
| 877 mpc_uint32_t vbrAcc = 0; | |
| 878 mpc_uint32_t vbrUpd = 0; | |
| 879 | |
| 880 unsigned status = mpc_decoder_decode(&decoder, sampleBuffer, &vbrAcc, &vbrUpd); | |
| 881 copyBuffer(sampleBuffer, xmmsBuffer, status); | |
| 882 | |
| 883 if (pluginConfig.dynamicBitrate) | |
| 884 { | |
| 885 track.bitrate = static_cast<int> (vbrUpd * track.sampleFreq / 1152); | |
| 886 } | |
| 887 | |
|
1998
8f3188746b64
chase last changeset in aud
William Pitcock <nenolod@atheme.org>
parents:
1986
diff
changeset
|
888 playback->pass_audio(playback, FMT_S16_LE, track.channels, status * 4, xmmsBuffer, NULL); |
| 232 | 889 return status; |
| 890 } | |
| 891 | |
| 892 static void setReplaygain(mpc_streaminfo& info, mpc_decoder& decoder) | |
| 893 { | |
| 894 if(!pluginConfig.replaygain && !pluginConfig.clipPrevention) | |
| 895 return; | |
| 896 | |
| 897 int peak = pluginConfig.albumGain ? info.peak_album : info.peak_title; | |
| 898 double gain = pluginConfig.albumGain ? info.gain_album : info.gain_title; | |
| 899 | |
| 900 if(!peak) | |
| 901 peak = 32767; | |
| 902 if(!gain) | |
| 903 gain = 1.; | |
| 904 | |
| 905 double clip = 32767. / peak; | |
| 906 gain = exp((M_LN10 / 2000.) * gain); | |
| 907 | |
| 908 if(pluginConfig.clipPrevention && !pluginConfig.replaygain) | |
| 909 gain = clip; | |
| 910 else if(pluginConfig.replaygain && pluginConfig.clipPrevention) | |
| 911 if(clip < gain) | |
| 912 gain = clip; | |
| 913 | |
| 914 mpc_decoder_scale_output(&decoder, gain); | |
| 915 } | |
| 916 | |
| 917 inline static void lockAcquire() | |
| 918 { | |
| 919 g_static_mutex_lock(&threadMutex); | |
| 920 } | |
| 921 | |
| 922 inline static void lockRelease() | |
| 923 { | |
| 924 g_static_mutex_unlock(&threadMutex); | |
| 925 } | |
| 926 | |
| 927 inline static bool isAlive() | |
| 928 { | |
| 929 lockAcquire(); | |
| 930 bool isAlive = mpcDecoder.isAlive; | |
| 931 lockRelease(); | |
| 932 return isAlive; | |
| 933 } | |
| 934 | |
| 935 inline static bool isPause() | |
| 936 { | |
| 937 lockAcquire(); | |
| 938 bool isPause = mpcDecoder.isPause; | |
| 939 lockRelease(); | |
| 940 return isPause; | |
| 941 } | |
| 942 | |
| 943 inline static void setAlive(bool isAlive) | |
| 944 { | |
| 945 lockAcquire(); | |
| 946 mpcDecoder.isAlive = isAlive; | |
| 947 lockRelease(); | |
| 948 } | |
| 949 | |
| 950 inline static double getOffset() | |
| 951 { | |
| 952 lockAcquire(); | |
| 953 double offset = mpcDecoder.offset; | |
| 954 lockRelease(); | |
| 955 return offset; | |
| 956 } | |
| 957 | |
| 958 inline static void setOffset(double offset) | |
| 959 { | |
| 960 lockAcquire(); | |
| 961 mpcDecoder.offset = offset; | |
| 962 lockRelease(); | |
| 963 } |
