comparison Plugins/Input/mpg123/mpg123.c @ 993:a9ac4beb4e15 trunk

[svn] Use taglib for length determination. Simpler code, might also deal better with some VBR MP3s if they have length info in their tags.
author chainsaw
date Sun, 30 Apr 2006 17:59:55 -0700
parents 773c485cf628
children 3d2984564cb8
comparison
equal deleted inserted replaced
992:90c87c7aee9c 993:a9ac4beb4e15
261 } 261 }
262 262
263 g_strfreev(mpg123_id3_encoding_list); 263 g_strfreev(mpg123_id3_encoding_list);
264 } 264 }
265 265
266 static guint32
267 convert_to_header(guint8 * buf)
268 {
269 return (buf[0] << 24) + (buf[1] << 16) + (buf[2] << 8) + buf[3];
270 }
271
272
273 #if 0 266 #if 0
274 #define DET_BUF_SIZE 1024 267 #define DET_BUF_SIZE 1024
275 268
276 static gboolean 269 static gboolean
277 mpg123_detect_by_content(char *filename) 270 mpg123_detect_by_content(char *filename)
368 else 361 else
369 skip_frames--; 362 skip_frames--;
370 } 363 }
371 } 364 }
372 365
373 static const char *
374 get_id3_genre(unsigned char genre_code)
375 {
376 if (genre_code < GENRE_MAX)
377 return gettext(mpg123_id3_genres[genre_code]);
378
379 return "";
380 }
381
382 guint 366 guint
383 mpg123_strip_spaces(char *src, size_t n) 367 mpg123_strip_spaces(char *src, size_t n)
384 { 368 {
385 gchar *space = NULL, /* last space in src */ 369 gchar *space = NULL, /* last space in src */
386 *start = src; 370 *start = src;
424 ++ext; 408 ++ext;
425 409
426 return ext; 410 return ext;
427 } 411 }
428 412
429 /*
430 * Function id3v1_to_id3v2 (v1, v2)
431 *
432 * Convert ID3v1 tag `v1' to ID3v2 tag `v2'.
433 *
434 */
435 void
436 mpg123_id3v1_to_id3v2(struct id3v1tag_t *v1, struct id3tag_t *v2)
437 {
438 memset(v2, 0, sizeof(struct id3tag_t));
439 strncpy(v2->title, v1->title, 30);
440 strncpy(v2->artist, v1->artist, 30);
441 strncpy(v2->album, v1->album, 30);
442 strncpy(v2->comment, v1->u.v1_0.comment, 30);
443 strncpy(v2->genre, get_id3_genre(v1->genre), sizeof(v2->genre));
444 g_strstrip(v2->title);
445 g_strstrip(v2->artist);
446 g_strstrip(v2->album);
447 g_strstrip(v2->comment);
448 g_strstrip(v2->genre);
449 {
450 char y[5];
451 memcpy(y, v1->year, 4); y[4]=0;
452 v2->year = atoi(y);
453 }
454
455 /* Check for v1.1 tags. */
456 if (v1->u.v1_1.__zero == 0)
457 v2->track_number = v1->u.v1_1.track_number;
458 else
459 v2->track_number = 0;
460 }
461
462 #define REMOVE_NONEXISTANT_TAG(x) if (!*x) { x = NULL; } 413 #define REMOVE_NONEXISTANT_TAG(x) if (!*x) { x = NULL; }
463 414
464 /* 415 /*
465 * Function mpg123_format_song_title (tag, filename) 416 * Function mpg123_format_song_title (tag, filename)
466 * 417 *
539 taglib_file_free(taglib_file); 490 taglib_file_free(taglib_file);
540 taglib_tag_free_strings(); 491 taglib_tag_free_strings();
541 return ret; 492 return ret;
542 } 493 }
543 494
544 static long 495 static guint
545 get_song_length(VFSFile * file) 496 get_song_time(char *filename)
546 { 497 {
547 int len; 498 int len;
548 char tmp[4]; 499
549 500 taglib_file = taglib_file_new(filename);
550 vfs_fseek(file, 0, SEEK_END); 501 if(taglib_file) {
551 len = vfs_ftell(file); 502 taglib_ap = taglib_file_audioproperties(taglib_file);
552 vfs_fseek(file, -128, SEEK_END); 503 }
553 vfs_fread(tmp, 1, 3, file); 504
554 if (!strncmp(tmp, "TAG", 3)) 505 len = taglib_audioproperties_length(taglib_ap);
555 len -= 128; 506
507 taglib_file_free(taglib_file);
508 taglib_tag_free_strings();
509
556 return len; 510 return len;
557 }
558
559
560 static guint
561 get_song_time(VFSFile * file)
562 {
563 guint32 head;
564 guchar tmp[4], *buf;
565 struct frame frm;
566 xing_header_t xing_header;
567 double tpf, bpf;
568 guint32 len;
569
570 if (!file)
571 return -1;
572
573 vfs_fseek(file, 0, SEEK_SET);
574 if (vfs_fread(tmp, 1, 4, file) != 4)
575 return 0;
576 head = convert_to_header(tmp);
577 while (!mpg123_head_check(head)) {
578 head <<= 8;
579 if (vfs_fread(tmp, 1, 1, file) != 1)
580 return 0;
581 head |= tmp[0];
582 }
583 if (mpg123_decode_header(&frm, head)) {
584 buf = g_malloc(frm.framesize + 4);
585 vfs_fseek(file, -4, SEEK_CUR);
586 vfs_fread(buf, 1, frm.framesize + 4, file);
587 tpf = mpg123_compute_tpf(&frm);
588 if (mpg123_get_xing_header(&xing_header, buf)) {
589 g_free(buf);
590 if (xing_header.bytes == 0)
591 xing_header.bytes = get_song_length(file);
592 return (tpf * xing_header.frames * 1000);
593 }
594 g_free(buf);
595 bpf = mpg123_compute_bpf(&frm);
596 len = get_song_length(file);
597 return ((guint) (len / bpf) * tpf * 1000);
598 }
599 return 0;
600 } 511 }
601 512
602 static void 513 static void
603 get_song_info(char *filename, char **title_real, int *len_real) 514 get_song_info(char *filename, char **title_real, int *len_real)
604 { 515 {
605 VFSFile *file;
606
607 (*len_real) = -1; 516 (*len_real) = -1;
608 (*title_real) = NULL; 517 (*title_real) = NULL;
609 518
610 /* 519 /*
611 * TODO: Getting song info from http streams. 520 * TODO: Getting song info from http streams.
612 */ 521 */
613 if (!strncasecmp(filename, "http://", 7)) 522 if (!strncasecmp(filename, "http://", 7))
614 return; 523 return;
615 524
616 if ((file = vfs_fopen(filename, "rb")) != NULL) { 525 (*len_real) = get_song_time(filename);
617 (*len_real) = get_song_time(file); 526 (*title_real) = get_song_title(filename);
618 (*title_real) = get_song_title(filename);
619 vfs_fclose(file);
620 }
621 } 527 }
622 528
623 static int 529 static int
624 open_output(void) 530 open_output(void)
625 { 531 {