summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMiika Pekkarinen <miipekk@ihme.org>2007-02-17 08:46:32 +0000
committerMiika Pekkarinen <miipekk@ihme.org>2007-02-17 08:46:32 +0000
commit6dbe772eb7af89e79d8da5122b3406b7da2b2c79 (patch)
tree8874a7cde8524a570defd6f615ab777e9e5d58da
parent92878d9ed464c21da8303d5b7434944332fcb79e (diff)
downloadrockbox-6dbe772eb7af89e79d8da5122b3406b7da2b2c79.tar.gz
rockbox-6dbe772eb7af89e79d8da5122b3406b7da2b2c79.zip
FS#6651 - Improved id3 comment extraction.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@12344 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--firmware/export/id3.h2
-rw-r--r--firmware/id3.c51
2 files changed, 34 insertions, 19 deletions
diff --git a/firmware/export/id3.h b/firmware/export/id3.h
index 721de9030c..367854fdd1 100644
--- a/firmware/export/id3.h
+++ b/firmware/export/id3.h
@@ -186,7 +186,7 @@ struct mp3entry {
186 186
187 /* these following two fields are used for local buffering */ 187 /* these following two fields are used for local buffering */
188 char id3v2buf[300]; 188 char id3v2buf[300];
189 char id3v1buf[3][92]; 189 char id3v1buf[4][92];
190 190
191 /* resume related */ 191 /* resume related */
192 unsigned long offset; /* bytes played */ 192 unsigned long offset; /* bytes played */
diff --git a/firmware/id3.c b/firmware/id3.c
index dd20926df2..29d45c5590 100644
--- a/firmware/id3.c
+++ b/firmware/id3.c
@@ -355,14 +355,6 @@ static int parseyearnum( struct mp3entry* entry, char* tag, int bufferpos )
355 return bufferpos; 355 return bufferpos;
356} 356}
357 357
358/* parse comment */
359static int parsecomment( struct mp3entry* entry, char* tag, int bufferpos )
360{
361
362 entry->comment = tag + 4; // simplistic
363 return bufferpos;
364}
365
366/* parse numeric genre from string, version 2.2 and 2.3 */ 358/* parse numeric genre from string, version 2.2 and 2.3 */
367static int parsegenre( struct mp3entry* entry, char* tag, int bufferpos ) 359static int parsegenre( struct mp3entry* entry, char* tag, int bufferpos )
368{ 360{
@@ -462,7 +454,7 @@ static const struct tag_resolver taglist[] = {
462 { "TCOM", 4, offsetof(struct mp3entry, composer), NULL, false }, 454 { "TCOM", 4, offsetof(struct mp3entry, composer), NULL, false },
463 { "TPE2", 4, offsetof(struct mp3entry, albumartist), NULL, false }, 455 { "TPE2", 4, offsetof(struct mp3entry, albumartist), NULL, false },
464 { "TP2", 3, offsetof(struct mp3entry, albumartist), NULL, false }, 456 { "TP2", 3, offsetof(struct mp3entry, albumartist), NULL, false },
465 { "COMM", 4, offsetof(struct mp3entry, comment), &parsecomment, false }, 457 { "COMM", 4, offsetof(struct mp3entry, comment), NULL, false },
466 { "TCON", 4, offsetof(struct mp3entry, genre_string), &parsegenre, false }, 458 { "TCON", 4, offsetof(struct mp3entry, genre_string), &parsegenre, false },
467 { "TCO", 3, offsetof(struct mp3entry, genre_string), &parsegenre, false }, 459 { "TCO", 3, offsetof(struct mp3entry, genre_string), &parsegenre, false },
468#if CONFIG_CODEC == SWCODEC 460#if CONFIG_CODEC == SWCODEC
@@ -564,7 +556,7 @@ static int unicode_munge(char* string, char* utf8buf, int *len) {
564static bool setid3v1title(int fd, struct mp3entry *entry) 556static bool setid3v1title(int fd, struct mp3entry *entry)
565{ 557{
566 unsigned char buffer[128]; 558 unsigned char buffer[128];
567 static const char offsets[] = {3, 33, 63, 93, 125, 127}; 559 static const char offsets[] = {3, 33, 63, 97, 93, 125, 127};
568 int i, j; 560 int i, j;
569 unsigned char* utf8; 561 unsigned char* utf8;
570 562
@@ -583,16 +575,13 @@ static bool setid3v1title(int fd, struct mp3entry *entry)
583 for (i=0; i < (int)sizeof offsets; i++) { 575 for (i=0; i < (int)sizeof offsets; i++) {
584 unsigned char* ptr = (unsigned char *)buffer + offsets[i]; 576 unsigned char* ptr = (unsigned char *)buffer + offsets[i];
585 577
586 if (i<3) {
587 /* kill trailing space in strings */
588 for (j=29; j && ptr[j]==' '; j--)
589 ptr[j] = 0;
590 }
591
592 switch(i) { 578 switch(i) {
593 case 0: 579 case 0:
594 case 1: 580 case 1:
595 case 2: 581 case 2:
582 /* kill trailing space in strings */
583 for (j=29; j && (ptr[j]==0 || ptr[j]==' '); j--)
584 ptr[j] = 0;
596 /* convert string to utf8 */ 585 /* convert string to utf8 */
597 utf8 = (unsigned char *)entry->id3v1buf[i]; 586 utf8 = (unsigned char *)entry->id3v1buf[i];
598 utf8 = iso_decode(ptr, utf8, -1, 30); 587 utf8 = iso_decode(ptr, utf8, -1, 30);
@@ -601,11 +590,22 @@ static bool setid3v1title(int fd, struct mp3entry *entry)
601 break; 590 break;
602 591
603 case 3: 592 case 3:
593 /* kill trailing space in strings */
594 for (j=27; j && (ptr[j]==0 || ptr[j]==' '); j--)
595 ptr[j] = 0;
596 /* convert string to utf8 */
597 utf8 = (unsigned char *)entry->id3v1buf[3];
598 utf8 = iso_decode(ptr, utf8, -1, 28);
599 /* make sure string is terminated */
600 *utf8 = 0;
601 break;
602
603 case 4:
604 ptr[4] = 0; 604 ptr[4] = 0;
605 entry->year = atoi((char *)ptr); 605 entry->year = atoi((char *)ptr);
606 break; 606 break;
607 607
608 case 4: 608 case 5:
609 /* id3v1.1 uses last two bytes of comment field for track 609 /* id3v1.1 uses last two bytes of comment field for track
610 number: first must be 0 and second is track num */ 610 number: first must be 0 and second is track num */
611 if (!ptr[0] && ptr[1]) { 611 if (!ptr[0] && ptr[1]) {
@@ -614,7 +614,7 @@ static bool setid3v1title(int fd, struct mp3entry *entry)
614 } 614 }
615 break; 615 break;
616 616
617 case 5: 617 case 6:
618 /* genre */ 618 /* genre */
619 entry->genre = ptr[0]; 619 entry->genre = ptr[0];
620 break; 620 break;
@@ -624,6 +624,7 @@ static bool setid3v1title(int fd, struct mp3entry *entry)
624 entry->title = entry->id3v1buf[0]; 624 entry->title = entry->id3v1buf[0];
625 entry->artist = entry->id3v1buf[1]; 625 entry->artist = entry->id3v1buf[1];
626 entry->album = entry->id3v1buf[2]; 626 entry->album = entry->id3v1buf[2];
627 entry->comment = entry->id3v1buf[3];
627 628
628 return true; 629 return true;
629} 630}
@@ -856,6 +857,7 @@ static void setid3v2title(int fd, struct mp3entry *entry)
856 char** ptag = tr->offset ? (char**) (((char*)entry) + tr->offset) 857 char** ptag = tr->offset ? (char**) (((char*)entry) + tr->offset)
857 : NULL; 858 : NULL;
858 char* tag; 859 char* tag;
860 int comm_offset=0;
859 861
860 /* Only ID3_VER_2_2 uses frames with three-character names. */ 862 /* Only ID3_VER_2_2 uses frames with three-character names. */
861 if (((version == ID3_VER_2_2) && (tr->tag_length != 3)) 863 if (((version == ID3_VER_2_2) && (tr->tag_length != 3))
@@ -887,6 +889,19 @@ static void setid3v2title(int fd, struct mp3entry *entry)
887 if(unsynch || (global_unsynch && version >= ID3_VER_2_4)) 889 if(unsynch || (global_unsynch && version >= ID3_VER_2_4))
888 bytesread = unsynchronize_frame(tag, bytesread); 890 bytesread = unsynchronize_frame(tag, bytesread);
889 891
892 /* the COMM frame has a 3 char field to hold an ISO-639-1
893 * language string and an optional short description;
894 * remove them so unicode_munge can work correctly
895 */
896
897 if(!memcmp( header, "COMM", 4 )) {
898 comm_offset = 3 + strlen(tag+4) + 1;
899 if(bytesread>comm_offset) {
900 bytesread-=comm_offset;
901 memmove(tag+1, tag+comm_offset+1, bytesread-1);
902 }
903 }
904
890 /* Attempt to parse Unicode string only if the tag contents 905 /* Attempt to parse Unicode string only if the tag contents
891 aren't binary */ 906 aren't binary */
892 if(!tr->binary) { 907 if(!tr->binary) {