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