diff options
-rw-r--r-- | firmware/export/id3.h | 2 | ||||
-rw-r--r-- | firmware/id3.c | 51 |
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 */ | ||
359 | static 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 */ |
367 | static int parsegenre( struct mp3entry* entry, char* tag, int bufferpos ) | 359 | static 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) { | |||
564 | static bool setid3v1title(int fd, struct mp3entry *entry) | 556 | static 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) { |