Mercurial > audlegacy
annotate Plugins/Input/vorbis/vorbis.c @ 1622:55011fbbd8cb trunk
[svn] - detect what $(SHARED_SUFFIX) should be.
- detect if we are using Apple-GCC.
author | nenolod |
---|---|
date | Wed, 06 Sep 2006 12:57:50 -0700 |
parents | 705d4c089fce |
children |
rev | line source |
---|---|
61 | 1 /* |
2 * Copyright (C) Tony Arcieri <bascule@inferno.tusculum.edu> | |
3 * Copyright (C) 2001-2002 Haavard Kvaalen <havardk@xmms.org> | |
4 * | |
5 * ReplayGain processing Copyright (C) 2002 Gian-Carlo Pascutto <gcp@sjeng.org> | |
6 * | |
7 * This program is free software; you can redistribute it and/or | |
8 * modify it under the terms of the GNU General Public License | |
9 * as published by the Free Software Foundation; either version 2 | |
10 * of the License, or (at your option) any later version. | |
11 * | |
12 * This program is distributed in the hope that it will be useful, | |
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
15 * GNU General Public License for more details. | |
16 * | |
17 * You should have received a copy of the GNU General Public License | |
18 * along with this program; if not, write to the Free Software | |
1458
f12d7e208b43
[svn] Update FSF address in copyright notices. Update autotools templates.
chainsaw
parents:
1310
diff
changeset
|
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA |
1459 | 20 * 02110-1301, USA. |
61 | 21 * |
22 */ | |
23 | |
24 /* | |
25 * 2002-01-11 ReplayGain processing added by Gian-Carlo Pascutto <gcp@sjeng.org> | |
26 */ | |
27 | |
28 /* | |
29 * Note that this uses vorbisfile, which is not (currently) | |
30 * thread-safe. | |
31 */ | |
32 | |
33 #ifdef HAVE_CONFIG_H | |
34 # include "config.h" | |
35 #endif | |
36 | |
37 #include <glib.h> | |
38 #include <glib/gi18n.h> | |
39 #include <gtk/gtk.h> | |
40 | |
41 #include <stdlib.h> | |
42 #include <math.h> | |
43 #include <string.h> | |
44 | |
45 #include <fcntl.h> | |
46 | |
47 #include <ogg/ogg.h> | |
48 #include <vorbis/codec.h> | |
49 #include <vorbis/vorbisfile.h> | |
50 | |
51 #include "audacious/plugin.h" | |
52 #include "audacious/output.h" | |
53 #include "libaudacious/util.h" | |
54 #include "libaudacious/configdb.h" | |
55 #include "libaudacious/titlestring.h" | |
56 | |
57 #include "vorbis.h" | |
58 #include "http.h" | |
59 | |
60 extern vorbis_config_t vorbis_cfg; | |
61 | |
1234 | 62 static TitleInput *get_song_tuple(gchar *filename); |
61 | 63 static int vorbis_check_file(char *filename); |
64 static void vorbis_play(char *filename); | |
65 static void vorbis_stop(void); | |
66 static void vorbis_pause(short p); | |
67 static void vorbis_seek(int time); | |
68 static int vorbis_time(void); | |
69 static void vorbis_get_song_info(char *filename, char **title, int *length); | |
1310
ff98136a93d2
[svn] - title streaming works again, but we aren't pushing back to the playlist quite yet
nenolod
parents:
1240
diff
changeset
|
70 static gchar *vorbis_generate_title(OggVorbis_File * vorbisfile, gchar * fn); |
61 | 71 static void vorbis_aboutbox(void); |
72 static void vorbis_init(void); | |
73 static void vorbis_cleanup(void); | |
74 static long vorbis_process_replaygain(float **pcm, int samples, int ch, | |
75 char *pcmout, float rg_scale); | |
76 static gboolean vorbis_update_replaygain(float *scale); | |
77 | |
78 static size_t ovcb_read(void *ptr, size_t size, size_t nmemb, | |
79 void *datasource); | |
80 static int ovcb_seek(void *datasource, int64_t offset, int whence); | |
81 static int ovcb_close(void *datasource); | |
82 static long ovcb_tell(void *datasource); | |
83 | |
84 ov_callbacks vorbis_callbacks = { | |
85 ovcb_read, | |
86 ovcb_seek, | |
87 ovcb_close, | |
88 ovcb_tell | |
89 }; | |
90 | |
91 InputPlugin vorbis_ip = { | |
92 NULL, | |
93 NULL, | |
94 NULL, /* description */ | |
95 vorbis_init, /* init */ | |
96 vorbis_aboutbox, /* aboutbox */ | |
97 vorbis_configure, /* configure */ | |
98 vorbis_check_file, /* is_our_file */ | |
99 NULL, | |
100 vorbis_play, | |
101 vorbis_stop, | |
102 vorbis_pause, | |
103 vorbis_seek, | |
104 NULL, /* set eq */ | |
105 vorbis_time, | |
106 NULL, | |
107 NULL, | |
108 vorbis_cleanup, | |
109 NULL, | |
110 NULL, | |
111 NULL, | |
112 NULL, | |
113 vorbis_get_song_info, | |
114 vorbis_file_info_box, /* file info box, tag editing */ | |
115 NULL, | |
1234 | 116 get_song_tuple |
61 | 117 }; |
118 | |
119 static OggVorbis_File vf; | |
120 | |
121 static GThread *thread; | |
122 int vorbis_playing = 0; | |
123 static int vorbis_eos = 0; | |
124 static int vorbis_is_streaming = 0; | |
125 static int vorbis_bytes_streamed = 0; | |
126 static volatile int seekneeded = -1; | |
127 static int samplerate, channels; | |
128 GMutex *vf_mutex; | |
129 static gboolean output_error; | |
130 | |
281
e85198a7f34d
[svn] Vorbis UTF-8 tag conversion patch, via Takuo Kitame <kitame@debian.org>.
nenolod
parents:
61
diff
changeset
|
131 gchar **vorbis_tag_encoding_list = NULL; |
61 | 132 |
133 InputPlugin * | |
134 get_iplugin_info(void) | |
135 { | |
136 vorbis_ip.description = g_strdup_printf(_("Ogg Vorbis Audio Plugin")); | |
137 return &vorbis_ip; | |
138 } | |
139 | |
140 static int | |
141 vorbis_check_file(char *filename) | |
142 { | |
143 VFSFile *stream; | |
144 OggVorbis_File vfile; /* avoid thread interaction */ | |
145 char *ext; | |
146 gint result; | |
147 | |
148 /* is this our http resource? */ | |
149 if (strncasecmp(filename, "http://", 7) == 0) { | |
150 ext = strrchr(filename, '.'); | |
151 if (ext) { | |
152 if (!strncasecmp(ext, ".ogg", 4)) { | |
153 return TRUE; | |
154 } | |
155 } | |
156 return FALSE; | |
157 } | |
158 | |
159 if (!(stream = vfs_fopen(filename, "r"))) { | |
160 return FALSE; | |
161 } | |
162 /* | |
163 * The open function performs full stream detection and machine | |
164 * initialization. If it returns zero, the stream *is* Vorbis and | |
165 * we're fully ready to decode. | |
166 */ | |
167 | |
168 /* libvorbisfile isn't thread safe... */ | |
169 memset(&vfile, 0, sizeof(vfile)); | |
170 g_mutex_lock(vf_mutex); | |
171 | |
172 result = ov_test_callbacks(stream, &vfile, NULL, 0, vorbis_callbacks); | |
173 | |
174 switch (result) { | |
175 case OV_EREAD: | |
176 #ifdef DEBUG | |
177 g_message("** vorbis.c: Media read error: %s", filename); | |
178 #endif | |
179 g_mutex_unlock(vf_mutex); | |
180 vfs_fclose(stream); | |
181 return FALSE; | |
182 break; | |
183 case OV_ENOTVORBIS: | |
184 #ifdef DEBUG | |
185 g_message("** vorbis.c: Not Vorbis data: %s", filename); | |
186 #endif | |
187 g_mutex_unlock(vf_mutex); | |
188 vfs_fclose(stream); | |
189 return FALSE; | |
190 break; | |
191 case OV_EVERSION: | |
192 #ifdef DEBUG | |
193 g_message("** vorbis.c: Version mismatch: %s", filename); | |
194 #endif | |
195 g_mutex_unlock(vf_mutex); | |
196 vfs_fclose(stream); | |
197 return FALSE; | |
198 break; | |
199 case OV_EBADHEADER: | |
200 #ifdef DEBUG | |
201 g_message("** vorbis.c: Invalid Vorbis bistream header: %s", | |
202 filename); | |
203 #endif | |
204 g_mutex_unlock(vf_mutex); | |
205 vfs_fclose(stream); | |
206 return FALSE; | |
207 break; | |
208 case OV_EFAULT: | |
209 #ifdef DEBUG | |
210 g_message("** vorbis.c: Internal logic fault while reading %s", | |
211 filename); | |
212 #endif | |
213 g_mutex_unlock(vf_mutex); | |
214 vfs_fclose(stream); | |
215 return FALSE; | |
216 break; | |
217 case 0: | |
218 break; | |
219 default: | |
220 break; | |
221 } | |
222 | |
223 | |
224 ov_clear(&vfile); /* once the ov_open succeeds, the stream belongs to | |
225 vorbisfile.a. ov_clear will fclose it */ | |
226 g_mutex_unlock(vf_mutex); | |
227 return TRUE; | |
228 } | |
229 | |
230 static void | |
231 vorbis_jump_to_time(long time) | |
232 { | |
233 g_mutex_lock(vf_mutex); | |
234 | |
235 /* | |
236 * We need to guard against seeking to the end, or things | |
237 * don't work right. Instead, just seek to one second prior | |
238 * to this | |
239 */ | |
240 if (time == ov_time_total(&vf, -1)) | |
241 time--; | |
242 | |
243 vorbis_ip.output->flush(time * 1000); | |
244 ov_time_seek(&vf, time); | |
245 | |
246 g_mutex_unlock(vf_mutex); | |
247 } | |
248 | |
249 static void | |
250 do_seek(void) | |
251 { | |
252 if (seekneeded != -1 && !vorbis_is_streaming) { | |
253 vorbis_jump_to_time(seekneeded); | |
254 seekneeded = -1; | |
255 vorbis_eos = FALSE; | |
256 } | |
257 } | |
258 | |
259 static int | |
260 vorbis_process_data(int last_section, gboolean use_rg, float rg_scale) | |
261 { | |
262 char pcmout[4096]; | |
263 int bytes; | |
264 float **pcm; | |
265 | |
266 /* | |
267 * A vorbis physical bitstream may consist of many logical | |
268 * sections (information for each of which may be fetched from | |
269 * the vf structure). This value is filled in by ov_read to | |
270 * alert us what section we're currently decoding in case we | |
271 * need to change playback settings at a section boundary | |
272 */ | |
273 int current_section; | |
274 | |
275 g_mutex_lock(vf_mutex); | |
276 if (use_rg) { | |
277 bytes = | |
278 ov_read_float(&vf, &pcm, sizeof(pcmout) / 2 / channels, | |
279 ¤t_section); | |
280 if (bytes > 0) | |
281 bytes = vorbis_process_replaygain(pcm, bytes, channels, | |
282 pcmout, rg_scale); | |
283 } | |
284 else { | |
285 bytes = | |
286 ov_read(&vf, pcmout, sizeof(pcmout), | |
287 (int) (G_BYTE_ORDER == G_BIG_ENDIAN), | |
288 2, 1, ¤t_section); | |
289 } | |
290 | |
291 switch (bytes) { | |
292 case 0: | |
293 /* EOF */ | |
294 g_mutex_unlock(vf_mutex); | |
295 vorbis_ip.output->buffer_free(); | |
296 vorbis_ip.output->buffer_free(); | |
297 vorbis_eos = TRUE; | |
298 return last_section; | |
299 | |
300 case OV_HOLE: | |
301 case OV_EBADLINK: | |
302 /* | |
303 * error in the stream. Not a problem, just | |
304 * reporting it in case we (the app) cares. | |
305 * In this case, we don't. | |
306 */ | |
307 g_mutex_unlock(vf_mutex); | |
308 return last_section; | |
309 } | |
310 | |
311 if (current_section != last_section) { | |
312 /* | |
313 * The info struct is different in each section. vf | |
314 * holds them all for the given bitstream. This | |
315 * requests the current one | |
316 */ | |
317 vorbis_info *vi = ov_info(&vf, -1); | |
318 | |
319 if (vi->channels > 2) { | |
320 vorbis_eos = TRUE; | |
321 g_mutex_unlock(vf_mutex); | |
322 return current_section; | |
323 } | |
324 | |
325 | |
326 if (vi->rate != samplerate || vi->channels != channels) { | |
327 samplerate = vi->rate; | |
328 channels = vi->channels; | |
329 vorbis_ip.output->buffer_free(); | |
330 vorbis_ip.output->buffer_free(); | |
331 vorbis_ip.output->close_audio(); | |
332 if (!vorbis_ip.output-> | |
333 open_audio(FMT_S16_NE, vi->rate, vi->channels)) { | |
334 output_error = TRUE; | |
335 vorbis_eos = TRUE; | |
336 g_mutex_unlock(vf_mutex); | |
337 return current_section; | |
338 } | |
339 vorbis_ip.output->flush(ov_time_tell(&vf) * 1000); | |
340 } | |
341 } | |
342 | |
343 g_mutex_unlock(vf_mutex); | |
344 | |
345 if (!vorbis_playing) | |
346 return current_section; | |
347 | |
348 if (seekneeded != -1) | |
349 do_seek(); | |
350 | |
351 produce_audio(vorbis_ip.output->written_time(), | |
352 FMT_S16_NE, channels, bytes, pcmout, &vorbis_playing); | |
353 | |
354 return current_section; | |
355 } | |
356 | |
357 static gpointer | |
358 vorbis_play_loop(gpointer arg) | |
359 { | |
360 char *filename = (char *) arg; | |
361 gchar *title = NULL; | |
362 double time; | |
363 long timercount = 0; | |
364 vorbis_info *vi; | |
1007
a62f163c319a
[svn] - Make vorbisfile/vorbisinfo code threadsafe and reenterant by properly respecting vf_mutex. Patch by Johan Tavelin <d00jota -at- dtek.chalmers.se>.
nenolod
parents:
866
diff
changeset
|
365 long br; |
61 | 366 |
367 int last_section = -1; | |
368 | |
369 VFSFile *stream = NULL; | |
370 void *datasource = NULL; | |
371 | |
372 gboolean use_rg; | |
373 float rg_scale = 1.0; | |
374 | |
375 memset(&vf, 0, sizeof(vf)); | |
376 | |
377 if (strncasecmp("http://", filename, 7) != 0) { | |
378 /* file is a real file */ | |
379 if ((stream = vfs_fopen(filename, "r")) == NULL) { | |
380 vorbis_eos = TRUE; | |
381 goto play_cleanup; | |
382 } | |
383 datasource = (void *) stream; | |
384 } | |
385 else { | |
386 /* file is a stream */ | |
387 vorbis_is_streaming = 1; | |
388 vorbis_http_open(filename); | |
389 datasource = "NULL"; | |
390 } | |
391 | |
392 /* | |
393 * The open function performs full stream detection and | |
394 * machine initialization. None of the rest of ov_xx() works | |
395 * without it | |
396 */ | |
397 | |
398 g_mutex_lock(vf_mutex); | |
399 if (ov_open_callbacks(datasource, &vf, NULL, 0, vorbis_callbacks) < 0) { | |
400 vorbis_callbacks.close_func(datasource); | |
401 g_mutex_unlock(vf_mutex); | |
402 vorbis_eos = TRUE; | |
403 goto play_cleanup; | |
404 } | |
405 vi = ov_info(&vf, -1); | |
406 | |
407 if (vorbis_is_streaming) | |
408 time = -1; | |
409 else | |
410 time = ov_time_total(&vf, -1) * 1000; | |
411 | |
412 if (vi->channels > 2) { | |
413 vorbis_eos = TRUE; | |
414 g_mutex_unlock(vf_mutex); | |
415 goto play_cleanup; | |
416 } | |
417 | |
418 samplerate = vi->rate; | |
419 channels = vi->channels; | |
420 | |
1310
ff98136a93d2
[svn] - title streaming works again, but we aren't pushing back to the playlist quite yet
nenolod
parents:
1240
diff
changeset
|
421 title = vorbis_generate_title(&vf, filename); |
61 | 422 use_rg = vorbis_update_replaygain(&rg_scale); |
1007
a62f163c319a
[svn] - Make vorbisfile/vorbisinfo code threadsafe and reenterant by properly respecting vf_mutex. Patch by Johan Tavelin <d00jota -at- dtek.chalmers.se>.
nenolod
parents:
866
diff
changeset
|
423 br = ov_bitrate(&vf, -1); |
61 | 424 |
1007
a62f163c319a
[svn] - Make vorbisfile/vorbisinfo code threadsafe and reenterant by properly respecting vf_mutex. Patch by Johan Tavelin <d00jota -at- dtek.chalmers.se>.
nenolod
parents:
866
diff
changeset
|
425 g_mutex_unlock(vf_mutex); |
a62f163c319a
[svn] - Make vorbisfile/vorbisinfo code threadsafe and reenterant by properly respecting vf_mutex. Patch by Johan Tavelin <d00jota -at- dtek.chalmers.se>.
nenolod
parents:
866
diff
changeset
|
426 |
a62f163c319a
[svn] - Make vorbisfile/vorbisinfo code threadsafe and reenterant by properly respecting vf_mutex. Patch by Johan Tavelin <d00jota -at- dtek.chalmers.se>.
nenolod
parents:
866
diff
changeset
|
427 vorbis_ip.set_info(title, time, br, samplerate, channels); |
61 | 428 if (!vorbis_ip.output->open_audio(FMT_S16_NE, vi->rate, vi->channels)) { |
429 output_error = TRUE; | |
430 goto play_cleanup; | |
431 } | |
432 | |
433 seekneeded = -1; | |
434 | |
435 /* | |
436 * Note that chaining changes things here; A vorbis file may | |
437 * be a mix of different channels, bitrates and sample rates. | |
438 * You can fetch the information for any section of the file | |
439 * using the ov_ interface. | |
440 */ | |
441 | |
442 while (vorbis_playing) { | |
443 int current_section; | |
444 | |
445 if (seekneeded != -1) | |
446 do_seek(); | |
447 | |
448 if (vorbis_eos) { | |
449 xmms_usleep(20000); | |
450 continue; | |
451 } | |
452 | |
453 current_section = vorbis_process_data(last_section, use_rg, rg_scale); | |
454 | |
455 if (current_section != last_section) { | |
456 /* | |
457 * set total play time, bitrate, rate, and channels of | |
458 * current section | |
459 */ | |
460 if (title) | |
461 g_free(title); | |
462 g_mutex_lock(vf_mutex); | |
1310
ff98136a93d2
[svn] - title streaming works again, but we aren't pushing back to the playlist quite yet
nenolod
parents:
1240
diff
changeset
|
463 title = vorbis_generate_title(&vf, filename); |
61 | 464 use_rg = vorbis_update_replaygain(&rg_scale); |
465 | |
466 if (vorbis_is_streaming) | |
467 time = -1; | |
468 else | |
469 time = ov_time_total(&vf, -1) * 1000; | |
470 | |
1007
a62f163c319a
[svn] - Make vorbisfile/vorbisinfo code threadsafe and reenterant by properly respecting vf_mutex. Patch by Johan Tavelin <d00jota -at- dtek.chalmers.se>.
nenolod
parents:
866
diff
changeset
|
471 br = ov_bitrate(&vf, current_section); |
a62f163c319a
[svn] - Make vorbisfile/vorbisinfo code threadsafe and reenterant by properly respecting vf_mutex. Patch by Johan Tavelin <d00jota -at- dtek.chalmers.se>.
nenolod
parents:
866
diff
changeset
|
472 |
61 | 473 g_mutex_unlock(vf_mutex); |
1007
a62f163c319a
[svn] - Make vorbisfile/vorbisinfo code threadsafe and reenterant by properly respecting vf_mutex. Patch by Johan Tavelin <d00jota -at- dtek.chalmers.se>.
nenolod
parents:
866
diff
changeset
|
474 |
a62f163c319a
[svn] - Make vorbisfile/vorbisinfo code threadsafe and reenterant by properly respecting vf_mutex. Patch by Johan Tavelin <d00jota -at- dtek.chalmers.se>.
nenolod
parents:
866
diff
changeset
|
475 vorbis_ip.set_info(title, time, br, samplerate, channels); |
61 | 476 timercount = vorbis_ip.output->output_time(); |
477 | |
478 last_section = current_section; | |
479 } | |
480 | |
701
d539e5c5f730
[svn] Fixes of the remaining GCC 4.1 warnings from external contributor Diego "Flameeyes" Petteno (Gentoo).
chainsaw
parents:
281
diff
changeset
|
481 if (!(vi->bitrate_upper == vi->bitrate_lower && vi->bitrate_upper == vi->bitrate_nominal) |
61 | 482 && (vorbis_ip.output->output_time() > timercount + 1000 |
483 || vorbis_ip.output->output_time() < timercount)) { | |
484 /* | |
485 * simple hack to avoid updating too | |
486 * often | |
487 */ | |
488 g_mutex_lock(vf_mutex); | |
489 br = ov_bitrate_instant(&vf); | |
490 g_mutex_unlock(vf_mutex); | |
491 if (br > 0) | |
492 vorbis_ip.set_info(title, time, br, samplerate, channels); | |
493 timercount = vorbis_ip.output->output_time(); | |
494 } | |
495 } | |
496 if (!output_error) | |
497 vorbis_ip.output->close_audio(); | |
498 /* fall through intentional */ | |
499 | |
500 play_cleanup: | |
501 g_free(title); | |
502 g_free(filename); | |
503 | |
504 /* | |
505 * ov_clear closes the stream if its open. Safe to call on an | |
506 * uninitialized structure as long as we've zeroed it | |
507 */ | |
508 g_mutex_lock(vf_mutex); | |
509 ov_clear(&vf); | |
510 g_mutex_unlock(vf_mutex); | |
511 vorbis_is_streaming = 0; | |
512 return NULL; | |
513 } | |
514 | |
515 static void | |
516 vorbis_play(char *filename) | |
517 { | |
518 vorbis_playing = 1; | |
519 vorbis_bytes_streamed = 0; | |
520 vorbis_eos = 0; | |
521 output_error = FALSE; | |
522 | |
523 thread = g_thread_create(vorbis_play_loop, g_strdup(filename), TRUE, | |
524 NULL); | |
525 } | |
526 | |
527 static void | |
528 vorbis_stop(void) | |
529 { | |
530 if (vorbis_playing) { | |
531 vorbis_playing = 0; | |
532 g_thread_join(thread); | |
533 } | |
534 } | |
535 | |
536 static void | |
537 vorbis_pause(short p) | |
538 { | |
539 vorbis_ip.output->pause(p); | |
540 } | |
541 | |
542 static int | |
543 vorbis_time(void) | |
544 { | |
545 if (output_error) | |
546 return -2; | |
547 if (vorbis_eos && !vorbis_ip.output->buffer_playing()) | |
548 return -1; | |
549 return vorbis_ip.output->output_time(); | |
550 } | |
551 | |
552 static void | |
553 vorbis_seek(int time) | |
554 { | |
555 if (vorbis_is_streaming) | |
556 return; | |
557 | |
558 seekneeded = time; | |
559 | |
560 while (seekneeded != -1) | |
561 xmms_usleep(20000); | |
562 } | |
563 | |
564 static void | |
565 vorbis_get_song_info(char *filename, char **title, int *length) | |
566 { | |
1240 | 567 TitleInput *tuple = get_song_tuple(filename); |
61 | 568 |
1240 | 569 *length = tuple->length; |
570 *title = xmms_get_titlestring(vorbis_cfg.tag_override ? | |
571 vorbis_cfg.tag_format : | |
572 xmms_get_gentitle_format(), | |
573 tuple); | |
61 | 574 |
1240 | 575 bmp_title_input_free(tuple); |
61 | 576 } |
577 | |
578 static const gchar * | |
579 get_extension(const gchar * filename) | |
580 { | |
581 const gchar *ext; | |
582 if ((ext = strrchr(filename, '.'))) | |
583 ++ext; | |
584 return ext; | |
585 } | |
586 | |
587 /* Make sure you've locked vf_mutex */ | |
588 static gboolean | |
589 vorbis_update_replaygain(float *scale) | |
590 { | |
591 vorbis_comment *comment; | |
592 char *rg_gain = NULL, *rg_peak_str = NULL; | |
593 float rg_peak; | |
594 | |
595 if (!vorbis_cfg.use_replaygain && !vorbis_cfg.use_anticlip) | |
596 return FALSE; | |
597 if ((comment = ov_comment(&vf, -1)) == NULL) | |
598 return FALSE; | |
599 | |
600 *scale = 1.0; | |
601 | |
602 if (vorbis_cfg.use_replaygain) { | |
603 if (vorbis_cfg.replaygain_mode == REPLAYGAIN_MODE_ALBUM) { | |
604 rg_gain = | |
605 vorbis_comment_query(comment, "replaygain_album_gain", 0); | |
606 if (!rg_gain) | |
607 rg_gain = vorbis_comment_query(comment, "rg_audiophile", 0); /* Old */ | |
608 } | |
609 | |
610 if (!rg_gain) | |
611 rg_gain = | |
612 vorbis_comment_query(comment, "replaygain_track_gain", 0); | |
613 if (!rg_gain) | |
614 rg_gain = vorbis_comment_query(comment, "rg_radio", 0); /* Old */ | |
615 | |
616 /* FIXME: Make sure this string is the correct format first? */ | |
617 if (rg_gain) | |
618 *scale = pow(10., atof(rg_gain) / 20); | |
619 } | |
620 | |
621 if (vorbis_cfg.use_anticlip) { | |
622 if (vorbis_cfg.replaygain_mode == REPLAYGAIN_MODE_ALBUM) | |
623 rg_peak_str = | |
624 vorbis_comment_query(comment, "replaygain_album_peak", 0); | |
625 | |
626 if (!rg_peak_str) | |
627 rg_peak_str = | |
628 vorbis_comment_query(comment, "replaygain_track_peak", 0); | |
629 if (!rg_peak_str) | |
630 rg_peak_str = vorbis_comment_query(comment, "rg_peak", 0); /* Old */ | |
631 | |
632 if (rg_peak_str) | |
633 rg_peak = atof(rg_peak_str); | |
634 else | |
635 rg_peak = 1; | |
636 | |
637 if (*scale * rg_peak > 1.0) | |
638 *scale = 1.0 / rg_peak; | |
639 } | |
640 | |
641 if (*scale != 1.0 || vorbis_cfg.use_booster) { | |
642 /* safety */ | |
643 if (*scale > 15.0) | |
644 *scale = 15.0; | |
645 | |
646 return TRUE; | |
647 } | |
648 | |
649 return FALSE; | |
650 } | |
651 | |
652 #if (G_BYTE_ORDER == G_BIG_ENDIAN) | |
653 # define GET_BYTE1(val) ((val) >> 8) | |
654 # define GET_BYTE2(val) ((val) & 0xff) | |
655 #else | |
656 # define GET_BYTE1(val) ((val) & 0xff) | |
657 # define GET_BYTE2(val) ((val) >> 8) | |
658 #endif | |
659 | |
660 static long | |
661 vorbis_process_replaygain(float **pcm, int samples, int ch, | |
662 char *pcmout, float rg_scale) | |
663 { | |
664 int i, j; | |
665 /* ReplayGain processing */ | |
666 for (i = 0; i < samples; i++) | |
667 for (j = 0; j < ch; j++) { | |
668 float sample = pcm[j][i] * rg_scale; | |
669 int value; | |
670 | |
671 if (vorbis_cfg.use_booster) { | |
672 sample *= 2; | |
673 | |
674 /* hard 6dB limiting */ | |
675 if (sample < -0.5) | |
676 sample = tanh((sample + 0.5) / 0.5) * 0.5 - 0.5; | |
677 else if (sample > 0.5) | |
678 sample = tanh((sample - 0.5) / 0.5) * 0.5 + 0.5; | |
679 } | |
680 | |
681 value = sample * 32767; | |
682 if (value > 32767) | |
683 value = 32767; | |
684 else if (value < -32767) | |
685 value = -32767; | |
686 | |
687 *pcmout++ = GET_BYTE1(value); | |
688 *pcmout++ = GET_BYTE2(value); | |
689 } | |
690 | |
691 return 2 * ch * samples; | |
692 } | |
693 | |
1310
ff98136a93d2
[svn] - title streaming works again, but we aren't pushing back to the playlist quite yet
nenolod
parents:
1240
diff
changeset
|
694 /* |
ff98136a93d2
[svn] - title streaming works again, but we aren't pushing back to the playlist quite yet
nenolod
parents:
1240
diff
changeset
|
695 * Ok, nhjm449! Are you *happy* now?! -nenolod |
ff98136a93d2
[svn] - title streaming works again, but we aren't pushing back to the playlist quite yet
nenolod
parents:
1240
diff
changeset
|
696 */ |
1234 | 697 static TitleInput * |
1310
ff98136a93d2
[svn] - title streaming works again, but we aren't pushing back to the playlist quite yet
nenolod
parents:
1240
diff
changeset
|
698 get_tuple_for_vorbisfile(OggVorbis_File * vorbisfile, gchar *filename, gboolean is_stream) |
1234 | 699 { |
700 TitleInput *tuple = NULL; | |
701 vorbis_comment *comment; | |
702 | |
1310
ff98136a93d2
[svn] - title streaming works again, but we aren't pushing back to the playlist quite yet
nenolod
parents:
1240
diff
changeset
|
703 tuple = bmp_title_input_new(); |
ff98136a93d2
[svn] - title streaming works again, but we aren't pushing back to the playlist quite yet
nenolod
parents:
1240
diff
changeset
|
704 |
ff98136a93d2
[svn] - title streaming works again, but we aren't pushing back to the playlist quite yet
nenolod
parents:
1240
diff
changeset
|
705 tuple->file_name = g_path_get_basename(filename); |
ff98136a93d2
[svn] - title streaming works again, but we aren't pushing back to the playlist quite yet
nenolod
parents:
1240
diff
changeset
|
706 tuple->file_ext = get_extension(filename); |
ff98136a93d2
[svn] - title streaming works again, but we aren't pushing back to the playlist quite yet
nenolod
parents:
1240
diff
changeset
|
707 tuple->file_path = g_path_get_dirname(filename); |
1234 | 708 |
1310
ff98136a93d2
[svn] - title streaming works again, but we aren't pushing back to the playlist quite yet
nenolod
parents:
1240
diff
changeset
|
709 /* Retrieve the length */ |
ff98136a93d2
[svn] - title streaming works again, but we aren't pushing back to the playlist quite yet
nenolod
parents:
1240
diff
changeset
|
710 if (is_stream == FALSE) |
ff98136a93d2
[svn] - title streaming works again, but we aren't pushing back to the playlist quite yet
nenolod
parents:
1240
diff
changeset
|
711 tuple->length = ov_time_total(vorbisfile, -1) * 1000; |
ff98136a93d2
[svn] - title streaming works again, but we aren't pushing back to the playlist quite yet
nenolod
parents:
1240
diff
changeset
|
712 else |
ff98136a93d2
[svn] - title streaming works again, but we aren't pushing back to the playlist quite yet
nenolod
parents:
1240
diff
changeset
|
713 tuple->length = -1; |
1234 | 714 |
1310
ff98136a93d2
[svn] - title streaming works again, but we aren't pushing back to the playlist quite yet
nenolod
parents:
1240
diff
changeset
|
715 if ((comment = ov_comment(vorbisfile, -1))) { |
ff98136a93d2
[svn] - title streaming works again, but we aren't pushing back to the playlist quite yet
nenolod
parents:
1240
diff
changeset
|
716 tuple->track_name = |
ff98136a93d2
[svn] - title streaming works again, but we aren't pushing back to the playlist quite yet
nenolod
parents:
1240
diff
changeset
|
717 g_strdup(vorbis_comment_query(comment, "title", 0)); |
ff98136a93d2
[svn] - title streaming works again, but we aren't pushing back to the playlist quite yet
nenolod
parents:
1240
diff
changeset
|
718 tuple->performer = |
ff98136a93d2
[svn] - title streaming works again, but we aren't pushing back to the playlist quite yet
nenolod
parents:
1240
diff
changeset
|
719 g_strdup(vorbis_comment_query(comment, "artist", 0)); |
ff98136a93d2
[svn] - title streaming works again, but we aren't pushing back to the playlist quite yet
nenolod
parents:
1240
diff
changeset
|
720 tuple->album_name = |
ff98136a93d2
[svn] - title streaming works again, but we aren't pushing back to the playlist quite yet
nenolod
parents:
1240
diff
changeset
|
721 g_strdup(vorbis_comment_query(comment, "album", 0)); |
1234 | 722 |
1310
ff98136a93d2
[svn] - title streaming works again, but we aren't pushing back to the playlist quite yet
nenolod
parents:
1240
diff
changeset
|
723 if (vorbis_comment_query(comment, "tracknumber", 0) != NULL) |
ff98136a93d2
[svn] - title streaming works again, but we aren't pushing back to the playlist quite yet
nenolod
parents:
1240
diff
changeset
|
724 tuple->track_number = |
ff98136a93d2
[svn] - title streaming works again, but we aren't pushing back to the playlist quite yet
nenolod
parents:
1240
diff
changeset
|
725 atoi(vorbis_comment_query(comment, "tracknumber", 0)); |
1234 | 726 |
1310
ff98136a93d2
[svn] - title streaming works again, but we aren't pushing back to the playlist quite yet
nenolod
parents:
1240
diff
changeset
|
727 tuple->date = g_strdup(vorbis_comment_query(comment, "date", 0)); |
ff98136a93d2
[svn] - title streaming works again, but we aren't pushing back to the playlist quite yet
nenolod
parents:
1240
diff
changeset
|
728 tuple->genre = g_strdup(vorbis_comment_query(comment, "genre", 0)); |
ff98136a93d2
[svn] - title streaming works again, but we aren't pushing back to the playlist quite yet
nenolod
parents:
1240
diff
changeset
|
729 tuple->comment = |
ff98136a93d2
[svn] - title streaming works again, but we aren't pushing back to the playlist quite yet
nenolod
parents:
1240
diff
changeset
|
730 g_strdup(vorbis_comment_query(comment, "comment", 0)); |
1234 | 731 } |
732 | |
733 return tuple; | |
734 } | |
61 | 735 |
1310
ff98136a93d2
[svn] - title streaming works again, but we aren't pushing back to the playlist quite yet
nenolod
parents:
1240
diff
changeset
|
736 static TitleInput * |
ff98136a93d2
[svn] - title streaming works again, but we aren't pushing back to the playlist quite yet
nenolod
parents:
1240
diff
changeset
|
737 get_song_tuple(gchar *filename) |
ff98136a93d2
[svn] - title streaming works again, but we aren't pushing back to the playlist quite yet
nenolod
parents:
1240
diff
changeset
|
738 { |
ff98136a93d2
[svn] - title streaming works again, but we aren't pushing back to the playlist quite yet
nenolod
parents:
1240
diff
changeset
|
739 VFSFile *stream = NULL; |
ff98136a93d2
[svn] - title streaming works again, but we aren't pushing back to the playlist quite yet
nenolod
parents:
1240
diff
changeset
|
740 OggVorbis_File vfile; /* avoid thread interaction */ |
ff98136a93d2
[svn] - title streaming works again, but we aren't pushing back to the playlist quite yet
nenolod
parents:
1240
diff
changeset
|
741 TitleInput *tuple = NULL; |
ff98136a93d2
[svn] - title streaming works again, but we aren't pushing back to the playlist quite yet
nenolod
parents:
1240
diff
changeset
|
742 gboolean is_stream = FALSE; |
ff98136a93d2
[svn] - title streaming works again, but we aren't pushing back to the playlist quite yet
nenolod
parents:
1240
diff
changeset
|
743 |
ff98136a93d2
[svn] - title streaming works again, but we aren't pushing back to the playlist quite yet
nenolod
parents:
1240
diff
changeset
|
744 if (strncasecmp(filename, "http://", 7)) { |
ff98136a93d2
[svn] - title streaming works again, but we aren't pushing back to the playlist quite yet
nenolod
parents:
1240
diff
changeset
|
745 if ((stream = vfs_fopen(filename, "r")) == NULL) |
ff98136a93d2
[svn] - title streaming works again, but we aren't pushing back to the playlist quite yet
nenolod
parents:
1240
diff
changeset
|
746 return NULL; |
ff98136a93d2
[svn] - title streaming works again, but we aren't pushing back to the playlist quite yet
nenolod
parents:
1240
diff
changeset
|
747 } |
ff98136a93d2
[svn] - title streaming works again, but we aren't pushing back to the playlist quite yet
nenolod
parents:
1240
diff
changeset
|
748 else |
ff98136a93d2
[svn] - title streaming works again, but we aren't pushing back to the playlist quite yet
nenolod
parents:
1240
diff
changeset
|
749 is_stream = TRUE; |
ff98136a93d2
[svn] - title streaming works again, but we aren't pushing back to the playlist quite yet
nenolod
parents:
1240
diff
changeset
|
750 |
ff98136a93d2
[svn] - title streaming works again, but we aren't pushing back to the playlist quite yet
nenolod
parents:
1240
diff
changeset
|
751 /* |
ff98136a93d2
[svn] - title streaming works again, but we aren't pushing back to the playlist quite yet
nenolod
parents:
1240
diff
changeset
|
752 * The open function performs full stream detection and |
ff98136a93d2
[svn] - title streaming works again, but we aren't pushing back to the playlist quite yet
nenolod
parents:
1240
diff
changeset
|
753 * machine initialization. If it returns zero, the stream |
ff98136a93d2
[svn] - title streaming works again, but we aren't pushing back to the playlist quite yet
nenolod
parents:
1240
diff
changeset
|
754 * *is* Vorbis and we're fully ready to decode. |
ff98136a93d2
[svn] - title streaming works again, but we aren't pushing back to the playlist quite yet
nenolod
parents:
1240
diff
changeset
|
755 */ |
ff98136a93d2
[svn] - title streaming works again, but we aren't pushing back to the playlist quite yet
nenolod
parents:
1240
diff
changeset
|
756 if (ov_open_callbacks(stream, &vfile, NULL, 0, vorbis_callbacks) < 0) { |
ff98136a93d2
[svn] - title streaming works again, but we aren't pushing back to the playlist quite yet
nenolod
parents:
1240
diff
changeset
|
757 if (is_stream == FALSE) |
ff98136a93d2
[svn] - title streaming works again, but we aren't pushing back to the playlist quite yet
nenolod
parents:
1240
diff
changeset
|
758 vfs_fclose(stream); |
ff98136a93d2
[svn] - title streaming works again, but we aren't pushing back to the playlist quite yet
nenolod
parents:
1240
diff
changeset
|
759 return NULL; |
ff98136a93d2
[svn] - title streaming works again, but we aren't pushing back to the playlist quite yet
nenolod
parents:
1240
diff
changeset
|
760 } |
ff98136a93d2
[svn] - title streaming works again, but we aren't pushing back to the playlist quite yet
nenolod
parents:
1240
diff
changeset
|
761 |
ff98136a93d2
[svn] - title streaming works again, but we aren't pushing back to the playlist quite yet
nenolod
parents:
1240
diff
changeset
|
762 tuple = get_tuple_for_vorbisfile(&vfile, filename, is_stream); |
ff98136a93d2
[svn] - title streaming works again, but we aren't pushing back to the playlist quite yet
nenolod
parents:
1240
diff
changeset
|
763 |
ff98136a93d2
[svn] - title streaming works again, but we aren't pushing back to the playlist quite yet
nenolod
parents:
1240
diff
changeset
|
764 /* |
ff98136a93d2
[svn] - title streaming works again, but we aren't pushing back to the playlist quite yet
nenolod
parents:
1240
diff
changeset
|
765 * once the ov_open succeeds, the stream belongs to |
ff98136a93d2
[svn] - title streaming works again, but we aren't pushing back to the playlist quite yet
nenolod
parents:
1240
diff
changeset
|
766 * vorbisfile.a. ov_clear will fclose it |
ff98136a93d2
[svn] - title streaming works again, but we aren't pushing back to the playlist quite yet
nenolod
parents:
1240
diff
changeset
|
767 */ |
ff98136a93d2
[svn] - title streaming works again, but we aren't pushing back to the playlist quite yet
nenolod
parents:
1240
diff
changeset
|
768 ov_clear(&vfile); |
ff98136a93d2
[svn] - title streaming works again, but we aren't pushing back to the playlist quite yet
nenolod
parents:
1240
diff
changeset
|
769 |
ff98136a93d2
[svn] - title streaming works again, but we aren't pushing back to the playlist quite yet
nenolod
parents:
1240
diff
changeset
|
770 return tuple; |
ff98136a93d2
[svn] - title streaming works again, but we aren't pushing back to the playlist quite yet
nenolod
parents:
1240
diff
changeset
|
771 } |
ff98136a93d2
[svn] - title streaming works again, but we aren't pushing back to the playlist quite yet
nenolod
parents:
1240
diff
changeset
|
772 |
61 | 773 static gchar * |
1310
ff98136a93d2
[svn] - title streaming works again, but we aren't pushing back to the playlist quite yet
nenolod
parents:
1240
diff
changeset
|
774 vorbis_generate_title(OggVorbis_File * vorbisfile, gchar * filename) |
61 | 775 { |
776 /* Caller should hold vf_mutex */ | |
777 gchar *displaytitle = NULL; | |
778 TitleInput *input; | |
779 | |
1310
ff98136a93d2
[svn] - title streaming works again, but we aren't pushing back to the playlist quite yet
nenolod
parents:
1240
diff
changeset
|
780 input = get_tuple_for_vorbisfile(vorbisfile, filename, vorbis_is_streaming); |
61 | 781 |
782 if (!(displaytitle = xmms_get_titlestring(vorbis_cfg.tag_override ? | |
783 vorbis_cfg.tag_format : | |
784 xmms_get_gentitle_format(), | |
785 input))) { | |
786 if (!vorbis_is_streaming) | |
787 displaytitle = g_strdup(input->file_name); | |
788 else | |
789 displaytitle = vorbis_http_get_title(filename); | |
790 } | |
791 | |
1234 | 792 bmp_title_input_free(input); |
61 | 793 |
794 return displaytitle; | |
795 } | |
796 | |
797 static void | |
798 vorbis_aboutbox() | |
799 { | |
800 static GtkWidget *about_window; | |
801 | |
802 if (about_window) | |
803 gdk_window_raise(about_window->window); | |
866 | 804 else |
805 { | |
806 about_window = xmms_show_message(_("About Ogg Vorbis Audio Plugin"), | |
807 /* | |
808 * I18N: UTF-8 Translation: "Haavard Kvaalen" -> | |
809 * "H\303\245vard Kv\303\245len" | |
810 */ | |
811 _ | |
812 ("Ogg Vorbis Plugin by the Xiph.org Foundation\n\n" | |
813 "Original code by\n" | |
814 "Tony Arcieri <bascule@inferno.tusculum.edu>\n" | |
815 "Contributions from\n" | |
816 "Chris Montgomery <monty@xiph.org>\n" | |
817 "Peter Alm <peter@xmms.org>\n" | |
818 "Michael Smith <msmith@labyrinth.edu.au>\n" | |
819 "Jack Moffitt <jack@icecast.org>\n" | |
820 "Jorn Baayen <jorn@nl.linux.org>\n" | |
821 "Haavard Kvaalen <havardk@xmms.org>\n" | |
822 "Gian-Carlo Pascutto <gcp@sjeng.org>\n\n" | |
823 "Visit the Xiph.org Foundation at http://www.xiph.org/\n"), | |
824 _("Ok"), FALSE, NULL, NULL); | |
825 g_signal_connect(G_OBJECT(about_window), "destroy", | |
826 G_CALLBACK(gtk_widget_destroyed), &about_window); | |
827 } | |
61 | 828 } |
829 | |
830 | |
831 static void | |
832 vorbis_init(void) | |
833 { | |
834 ConfigDb *db; | |
1133 | 835 gchar *tmp = NULL; |
61 | 836 |
837 memset(&vorbis_cfg, 0, sizeof(vorbis_config_t)); | |
838 vorbis_cfg.http_buffer_size = 128; | |
839 vorbis_cfg.http_prebuffer = 25; | |
840 vorbis_cfg.proxy_port = 8080; | |
841 vorbis_cfg.proxy_use_auth = FALSE; | |
842 vorbis_cfg.proxy_user = NULL; | |
843 vorbis_cfg.proxy_pass = NULL; | |
844 vorbis_cfg.tag_override = FALSE; | |
845 vorbis_cfg.tag_format = NULL; | |
846 vorbis_cfg.use_anticlip = FALSE; | |
847 vorbis_cfg.use_replaygain = FALSE; | |
848 vorbis_cfg.replaygain_mode = REPLAYGAIN_MODE_TRACK; | |
849 vorbis_cfg.use_booster = FALSE; | |
850 | |
851 db = bmp_cfg_db_open(); | |
852 bmp_cfg_db_get_int(db, "vorbis", "http_buffer_size", | |
853 &vorbis_cfg.http_buffer_size); | |
854 bmp_cfg_db_get_int(db, "vorbis", "http_prebuffer", | |
855 &vorbis_cfg.http_prebuffer); | |
856 bmp_cfg_db_get_bool(db, "vorbis", "save_http_stream", | |
857 &vorbis_cfg.save_http_stream); | |
858 if (!bmp_cfg_db_get_string(db, "vorbis", "save_http_path", | |
859 &vorbis_cfg.save_http_path)) | |
860 vorbis_cfg.save_http_path = g_strdup(g_get_home_dir()); | |
861 | |
862 bmp_cfg_db_get_bool(db, "vorbis", "tag_override", | |
863 &vorbis_cfg.tag_override); | |
864 if (!bmp_cfg_db_get_string(db, "vorbis", "tag_format", | |
865 &vorbis_cfg.tag_format)) | |
866 vorbis_cfg.tag_format = g_strdup("%p - %t"); | |
867 bmp_cfg_db_get_bool(db, "vorbis", "use_anticlip", | |
868 &vorbis_cfg.use_anticlip); | |
869 bmp_cfg_db_get_bool(db, "vorbis", "use_replaygain", | |
870 &vorbis_cfg.use_replaygain); | |
871 bmp_cfg_db_get_int(db, "vorbis", "replaygain_mode", | |
872 &vorbis_cfg.replaygain_mode); | |
873 bmp_cfg_db_get_bool(db, "vorbis", "use_booster", &vorbis_cfg.use_booster); | |
1071
592ef16386aa
[svn] - use global proxy configuration instead of individual configurations (chainsaw)
nenolod
parents:
1007
diff
changeset
|
874 |
592ef16386aa
[svn] - use global proxy configuration instead of individual configurations (chainsaw)
nenolod
parents:
1007
diff
changeset
|
875 bmp_cfg_db_get_bool(db, NULL, "use_proxy", &vorbis_cfg.use_proxy); |
592ef16386aa
[svn] - use global proxy configuration instead of individual configurations (chainsaw)
nenolod
parents:
1007
diff
changeset
|
876 bmp_cfg_db_get_string(db, NULL, "proxy_host", &vorbis_cfg.proxy_host); |
1133 | 877 bmp_cfg_db_get_string(db, NULL, "proxy_port", &tmp); |
1138 | 878 |
879 if (tmp != NULL) | |
880 vorbis_cfg.proxy_port = atoi(tmp); | |
881 | |
1071
592ef16386aa
[svn] - use global proxy configuration instead of individual configurations (chainsaw)
nenolod
parents:
1007
diff
changeset
|
882 bmp_cfg_db_get_bool(db, NULL, "proxy_use_auth", &vorbis_cfg.proxy_use_auth); |
592ef16386aa
[svn] - use global proxy configuration instead of individual configurations (chainsaw)
nenolod
parents:
1007
diff
changeset
|
883 bmp_cfg_db_get_string(db, NULL, "proxy_user", &vorbis_cfg.proxy_user); |
592ef16386aa
[svn] - use global proxy configuration instead of individual configurations (chainsaw)
nenolod
parents:
1007
diff
changeset
|
884 bmp_cfg_db_get_string(db, NULL, "proxy_pass", &vorbis_cfg.proxy_pass); |
592ef16386aa
[svn] - use global proxy configuration instead of individual configurations (chainsaw)
nenolod
parents:
1007
diff
changeset
|
885 |
61 | 886 bmp_cfg_db_close(db); |
887 | |
888 vf_mutex = g_mutex_new(); | |
889 } | |
890 | |
891 static void | |
892 vorbis_cleanup(void) | |
893 { | |
813
c8cf439179b8
[svn] - Fix a ton and a half of memory leaks, via the wonderful Leonardo Boshell <leonardop -at- gentoo.org>.
nenolod
parents:
701
diff
changeset
|
894 g_free(vorbis_ip.description); |
c8cf439179b8
[svn] - Fix a ton and a half of memory leaks, via the wonderful Leonardo Boshell <leonardop -at- gentoo.org>.
nenolod
parents:
701
diff
changeset
|
895 vorbis_ip.description = NULL; |
c8cf439179b8
[svn] - Fix a ton and a half of memory leaks, via the wonderful Leonardo Boshell <leonardop -at- gentoo.org>.
nenolod
parents:
701
diff
changeset
|
896 |
c8cf439179b8
[svn] - Fix a ton and a half of memory leaks, via the wonderful Leonardo Boshell <leonardop -at- gentoo.org>.
nenolod
parents:
701
diff
changeset
|
897 if (vorbis_cfg.save_http_path) { |
c8cf439179b8
[svn] - Fix a ton and a half of memory leaks, via the wonderful Leonardo Boshell <leonardop -at- gentoo.org>.
nenolod
parents:
701
diff
changeset
|
898 free(vorbis_cfg.save_http_path); |
c8cf439179b8
[svn] - Fix a ton and a half of memory leaks, via the wonderful Leonardo Boshell <leonardop -at- gentoo.org>.
nenolod
parents:
701
diff
changeset
|
899 vorbis_cfg.save_http_path = NULL; |
c8cf439179b8
[svn] - Fix a ton and a half of memory leaks, via the wonderful Leonardo Boshell <leonardop -at- gentoo.org>.
nenolod
parents:
701
diff
changeset
|
900 } |
c8cf439179b8
[svn] - Fix a ton and a half of memory leaks, via the wonderful Leonardo Boshell <leonardop -at- gentoo.org>.
nenolod
parents:
701
diff
changeset
|
901 |
c8cf439179b8
[svn] - Fix a ton and a half of memory leaks, via the wonderful Leonardo Boshell <leonardop -at- gentoo.org>.
nenolod
parents:
701
diff
changeset
|
902 if (vorbis_cfg.proxy_host) { |
c8cf439179b8
[svn] - Fix a ton and a half of memory leaks, via the wonderful Leonardo Boshell <leonardop -at- gentoo.org>.
nenolod
parents:
701
diff
changeset
|
903 free(vorbis_cfg.proxy_host); |
c8cf439179b8
[svn] - Fix a ton and a half of memory leaks, via the wonderful Leonardo Boshell <leonardop -at- gentoo.org>.
nenolod
parents:
701
diff
changeset
|
904 vorbis_cfg.proxy_host = NULL; |
c8cf439179b8
[svn] - Fix a ton and a half of memory leaks, via the wonderful Leonardo Boshell <leonardop -at- gentoo.org>.
nenolod
parents:
701
diff
changeset
|
905 } |
c8cf439179b8
[svn] - Fix a ton and a half of memory leaks, via the wonderful Leonardo Boshell <leonardop -at- gentoo.org>.
nenolod
parents:
701
diff
changeset
|
906 |
c8cf439179b8
[svn] - Fix a ton and a half of memory leaks, via the wonderful Leonardo Boshell <leonardop -at- gentoo.org>.
nenolod
parents:
701
diff
changeset
|
907 if (vorbis_cfg.proxy_user) { |
c8cf439179b8
[svn] - Fix a ton and a half of memory leaks, via the wonderful Leonardo Boshell <leonardop -at- gentoo.org>.
nenolod
parents:
701
diff
changeset
|
908 free(vorbis_cfg.proxy_user); |
c8cf439179b8
[svn] - Fix a ton and a half of memory leaks, via the wonderful Leonardo Boshell <leonardop -at- gentoo.org>.
nenolod
parents:
701
diff
changeset
|
909 vorbis_cfg.proxy_user = NULL; |
c8cf439179b8
[svn] - Fix a ton and a half of memory leaks, via the wonderful Leonardo Boshell <leonardop -at- gentoo.org>.
nenolod
parents:
701
diff
changeset
|
910 } |
c8cf439179b8
[svn] - Fix a ton and a half of memory leaks, via the wonderful Leonardo Boshell <leonardop -at- gentoo.org>.
nenolod
parents:
701
diff
changeset
|
911 |
c8cf439179b8
[svn] - Fix a ton and a half of memory leaks, via the wonderful Leonardo Boshell <leonardop -at- gentoo.org>.
nenolod
parents:
701
diff
changeset
|
912 if (vorbis_cfg.proxy_pass) { |
c8cf439179b8
[svn] - Fix a ton and a half of memory leaks, via the wonderful Leonardo Boshell <leonardop -at- gentoo.org>.
nenolod
parents:
701
diff
changeset
|
913 free(vorbis_cfg.proxy_pass); |
c8cf439179b8
[svn] - Fix a ton and a half of memory leaks, via the wonderful Leonardo Boshell <leonardop -at- gentoo.org>.
nenolod
parents:
701
diff
changeset
|
914 vorbis_cfg.proxy_pass = NULL; |
c8cf439179b8
[svn] - Fix a ton and a half of memory leaks, via the wonderful Leonardo Boshell <leonardop -at- gentoo.org>.
nenolod
parents:
701
diff
changeset
|
915 } |
c8cf439179b8
[svn] - Fix a ton and a half of memory leaks, via the wonderful Leonardo Boshell <leonardop -at- gentoo.org>.
nenolod
parents:
701
diff
changeset
|
916 |
c8cf439179b8
[svn] - Fix a ton and a half of memory leaks, via the wonderful Leonardo Boshell <leonardop -at- gentoo.org>.
nenolod
parents:
701
diff
changeset
|
917 if (vorbis_cfg.tag_format) { |
c8cf439179b8
[svn] - Fix a ton and a half of memory leaks, via the wonderful Leonardo Boshell <leonardop -at- gentoo.org>.
nenolod
parents:
701
diff
changeset
|
918 free(vorbis_cfg.tag_format); |
c8cf439179b8
[svn] - Fix a ton and a half of memory leaks, via the wonderful Leonardo Boshell <leonardop -at- gentoo.org>.
nenolod
parents:
701
diff
changeset
|
919 vorbis_cfg.tag_format = NULL; |
c8cf439179b8
[svn] - Fix a ton and a half of memory leaks, via the wonderful Leonardo Boshell <leonardop -at- gentoo.org>.
nenolod
parents:
701
diff
changeset
|
920 } |
c8cf439179b8
[svn] - Fix a ton and a half of memory leaks, via the wonderful Leonardo Boshell <leonardop -at- gentoo.org>.
nenolod
parents:
701
diff
changeset
|
921 |
c8cf439179b8
[svn] - Fix a ton and a half of memory leaks, via the wonderful Leonardo Boshell <leonardop -at- gentoo.org>.
nenolod
parents:
701
diff
changeset
|
922 if (vorbis_cfg.title_encoding) { |
c8cf439179b8
[svn] - Fix a ton and a half of memory leaks, via the wonderful Leonardo Boshell <leonardop -at- gentoo.org>.
nenolod
parents:
701
diff
changeset
|
923 free(vorbis_cfg.title_encoding); |
c8cf439179b8
[svn] - Fix a ton and a half of memory leaks, via the wonderful Leonardo Boshell <leonardop -at- gentoo.org>.
nenolod
parents:
701
diff
changeset
|
924 vorbis_cfg.title_encoding = NULL; |
c8cf439179b8
[svn] - Fix a ton and a half of memory leaks, via the wonderful Leonardo Boshell <leonardop -at- gentoo.org>.
nenolod
parents:
701
diff
changeset
|
925 } |
c8cf439179b8
[svn] - Fix a ton and a half of memory leaks, via the wonderful Leonardo Boshell <leonardop -at- gentoo.org>.
nenolod
parents:
701
diff
changeset
|
926 |
281
e85198a7f34d
[svn] Vorbis UTF-8 tag conversion patch, via Takuo Kitame <kitame@debian.org>.
nenolod
parents:
61
diff
changeset
|
927 g_strfreev(vorbis_tag_encoding_list); |
61 | 928 g_mutex_free(vf_mutex); |
929 } | |
930 | |
931 static size_t | |
932 ovcb_read(void *ptr, size_t size, size_t nmemb, void *datasource) | |
933 { | |
934 size_t tmp; | |
935 | |
936 | |
937 if (vorbis_is_streaming) { | |
938 /* this is a stream */ | |
939 tmp = vorbis_http_read(ptr, size * nmemb); | |
940 vorbis_bytes_streamed += tmp; | |
941 return tmp; | |
942 } | |
943 | |
944 return vfs_fread(ptr, size, nmemb, (VFSFile *) datasource); | |
945 } | |
946 | |
947 static int | |
948 ovcb_seek(void *datasource, int64_t offset, int whence) | |
949 { | |
950 if (vorbis_is_streaming) { | |
951 /* this is a stream */ | |
952 /* streams aren't seekable */ | |
953 return -1; | |
954 } | |
955 | |
956 return vfs_fseek((VFSFile *) datasource, offset, whence); | |
957 } | |
958 | |
959 static int | |
960 ovcb_close(void *datasource) | |
961 { | |
962 if (vorbis_is_streaming) { | |
963 /* this is a stream */ | |
964 vorbis_http_close(); | |
965 return 0; | |
966 } | |
967 | |
968 return vfs_fclose((VFSFile *) datasource); | |
969 } | |
970 | |
971 static long | |
972 ovcb_tell(void *datasource) | |
973 { | |
974 if (vorbis_is_streaming) { | |
975 /* this is a stream */ | |
976 /* return bytes read */ | |
977 return vorbis_bytes_streamed; | |
978 } | |
979 | |
980 return vfs_ftell((VFSFile *) datasource); | |
981 } |