diff options
-rw-r--r-- | apps/tagcache.c | 13 | ||||
-rw-r--r-- | apps/tagcache.h | 1 | ||||
-rw-r--r-- | firmware/export/mp3data.h | 5 | ||||
-rw-r--r-- | firmware/id3.c | 43 | ||||
-rw-r--r-- | firmware/mp3data.c | 36 |
5 files changed, 51 insertions, 47 deletions
diff --git a/apps/tagcache.c b/apps/tagcache.c index 6ef0755809..43b4ad6e3b 100644 --- a/apps/tagcache.c +++ b/apps/tagcache.c | |||
@@ -226,19 +226,6 @@ static int processed_dir_count; | |||
226 | static volatile int write_lock; | 226 | static volatile int write_lock; |
227 | static volatile int read_lock; | 227 | static volatile int read_lock; |
228 | 228 | ||
229 | int tagcache_str_to_tag(const char *str) | ||
230 | { | ||
231 | int i; | ||
232 | |||
233 | for (i = 0; i < (long)(sizeof(tags_str)/sizeof(tags_str[0])); i++) | ||
234 | { | ||
235 | if (!strcasecmp(tags_str[i], str)) | ||
236 | return i; | ||
237 | } | ||
238 | |||
239 | return -1; | ||
240 | } | ||
241 | |||
242 | const char* tagcache_tag_to_str(int tag) | 229 | const char* tagcache_tag_to_str(int tag) |
243 | { | 230 | { |
244 | return tags_str[tag]; | 231 | return tags_str[tag]; |
diff --git a/apps/tagcache.h b/apps/tagcache.h index 5140aa1989..771629f6f2 100644 --- a/apps/tagcache.h +++ b/apps/tagcache.h | |||
@@ -142,7 +142,6 @@ void build_tagcache(const char *path); | |||
142 | void tagcache_reverse_scan(void); | 142 | void tagcache_reverse_scan(void); |
143 | #endif | 143 | #endif |
144 | 144 | ||
145 | int tagcache_str_to_tag(const char *str); | ||
146 | const char* tagcache_tag_to_str(int tag); | 145 | const char* tagcache_tag_to_str(int tag); |
147 | 146 | ||
148 | bool tagcache_is_numeric_tag(int type); | 147 | bool tagcache_is_numeric_tag(int type); |
diff --git a/firmware/export/mp3data.h b/firmware/export/mp3data.h index f36120a4e5..6ae97376c8 100644 --- a/firmware/export/mp3data.h +++ b/firmware/export/mp3data.h | |||
@@ -73,4 +73,9 @@ int create_xing_header(int fd, long startpos, long filesize, | |||
73 | unsigned long rec_time, unsigned long header_template, | 73 | unsigned long rec_time, unsigned long header_template, |
74 | void (*progressfunc)(int), bool generate_toc); | 74 | void (*progressfunc)(int), bool generate_toc); |
75 | 75 | ||
76 | extern unsigned long bytes2int(unsigned long b0, | ||
77 | unsigned long b1, | ||
78 | unsigned long b2, | ||
79 | unsigned long b3); | ||
80 | |||
76 | #endif | 81 | #endif |
diff --git a/firmware/id3.c b/firmware/id3.c index 0547bed3af..dd20926df2 100644 --- a/firmware/id3.c +++ b/firmware/id3.c | |||
@@ -137,15 +137,16 @@ const int afmt_rec_format[AFMT_NUM_CODECS] = | |||
137 | #endif /* CONFIG_CODEC == SWCODEC && defined (HAVE_RECORDING) */ | 137 | #endif /* CONFIG_CODEC == SWCODEC && defined (HAVE_RECORDING) */ |
138 | /****/ | 138 | /****/ |
139 | 139 | ||
140 | #define UNSYNC(b0,b1,b2,b3) (((long)(b0 & 0x7F) << (3*7)) | \ | 140 | unsigned long unsync(unsigned long b0, |
141 | ((long)(b1 & 0x7F) << (2*7)) | \ | 141 | unsigned long b1, |
142 | ((long)(b2 & 0x7F) << (1*7)) | \ | 142 | unsigned long b2, |
143 | ((long)(b3 & 0x7F) << (0*7))) | 143 | unsigned long b3) |
144 | 144 | { | |
145 | #define BYTES2INT(b0,b1,b2,b3) (((long)(b0 & 0xFF) << (3*8)) | \ | 145 | return (((long)(b0 & 0x7F) << (3*7)) | |
146 | ((long)(b1 & 0xFF) << (2*8)) | \ | 146 | ((long)(b1 & 0x7F) << (2*7)) | |
147 | ((long)(b2 & 0xFF) << (1*8)) | \ | 147 | ((long)(b2 & 0x7F) << (1*7)) | |
148 | ((long)(b3 & 0xFF) << (0*8))) | 148 | ((long)(b3 & 0x7F) << (0*7))); |
149 | } | ||
149 | 150 | ||
150 | static const char* const genres[] = { | 151 | static const char* const genres[] = { |
151 | "Blues", "Classic Rock", "Country", "Dance", "Disco", "Funk", "Grunge", | 152 | "Blues", "Classic Rock", "Country", "Dance", "Disco", "Funk", "Grunge", |
@@ -500,7 +501,7 @@ static int unicode_munge(char* string, char* utf8buf, int *len) { | |||
500 | /* Handle frames with more than one string | 501 | /* Handle frames with more than one string |
501 | (needed for TXXX frames).*/ | 502 | (needed for TXXX frames).*/ |
502 | do { | 503 | do { |
503 | tmp = BYTES2INT(0, 0, str[0], str[1]); | 504 | tmp = bytes2int(0, 0, str[0], str[1]); |
504 | 505 | ||
505 | /* Now check if there is a BOM | 506 | /* Now check if there is a BOM |
506 | (zero-width non-breaking space, 0xfeff) | 507 | (zero-width non-breaking space, 0xfeff) |
@@ -706,9 +707,9 @@ static void setid3v2title(int fd, struct mp3entry *entry) | |||
706 | /* The 2.3 extended header size doesn't include the following | 707 | /* The 2.3 extended header size doesn't include the following |
707 | data, so we have to find out the size by checking the flags. | 708 | data, so we have to find out the size by checking the flags. |
708 | Also, it is not unsynched. */ | 709 | Also, it is not unsynched. */ |
709 | framelen = BYTES2INT(header[0], header[1], header[2], header[3]) + | 710 | framelen = bytes2int(header[0], header[1], header[2], header[3]) + |
710 | BYTES2INT(header[6], header[7], header[8], header[9]); | 711 | bytes2int(header[6], header[7], header[8], header[9]); |
711 | flags = BYTES2INT(0, 0, header[4], header[5]); | 712 | flags = bytes2int(0, 0, header[4], header[5]); |
712 | if(flags & 0x8000) | 713 | if(flags & 0x8000) |
713 | framelen += 4; /* CRC */ | 714 | framelen += 4; /* CRC */ |
714 | 715 | ||
@@ -721,7 +722,7 @@ static void setid3v2title(int fd, struct mp3entry *entry) | |||
721 | 722 | ||
722 | /* The 2.4 extended header size does include the entire header, | 723 | /* The 2.4 extended header size does include the entire header, |
723 | so here we can just skip it. This header is unsynched. */ | 724 | so here we can just skip it. This header is unsynched. */ |
724 | framelen = UNSYNC(header[0], header[1], | 725 | framelen = unsync(header[0], header[1], |
725 | header[2], header[3]); | 726 | header[2], header[3]); |
726 | 727 | ||
727 | lseek(fd, framelen - 4, SEEK_CUR); | 728 | lseek(fd, framelen - 4, SEEK_CUR); |
@@ -751,15 +752,15 @@ static void setid3v2title(int fd, struct mp3entry *entry) | |||
751 | /* Adjust for the 10 bytes we read */ | 752 | /* Adjust for the 10 bytes we read */ |
752 | size -= 10; | 753 | size -= 10; |
753 | 754 | ||
754 | flags = BYTES2INT(0, 0, header[8], header[9]); | 755 | flags = bytes2int(0, 0, header[8], header[9]); |
755 | 756 | ||
756 | if (version >= ID3_VER_2_4) { | 757 | if (version >= ID3_VER_2_4) { |
757 | framelen = UNSYNC(header[4], header[5], | 758 | framelen = unsync(header[4], header[5], |
758 | header[6], header[7]); | 759 | header[6], header[7]); |
759 | } else { | 760 | } else { |
760 | /* version .3 files don't use synchsafe ints for | 761 | /* version .3 files don't use synchsafe ints for |
761 | * size */ | 762 | * size */ |
762 | framelen = BYTES2INT(header[4], header[5], | 763 | framelen = bytes2int(header[4], header[5], |
763 | header[6], header[7]); | 764 | header[6], header[7]); |
764 | } | 765 | } |
765 | } else { | 766 | } else { |
@@ -768,7 +769,7 @@ static void setid3v2title(int fd, struct mp3entry *entry) | |||
768 | /* Adjust for the 6 bytes we read */ | 769 | /* Adjust for the 6 bytes we read */ |
769 | size -= 6; | 770 | size -= 6; |
770 | 771 | ||
771 | framelen = BYTES2INT(0, header[3], header[4], header[5]); | 772 | framelen = bytes2int(0, header[3], header[4], header[5]); |
772 | } | 773 | } |
773 | 774 | ||
774 | /* Keep track of the total size */ | 775 | /* Keep track of the total size */ |
@@ -818,7 +819,7 @@ static void setid3v2title(int fd, struct mp3entry *entry) | |||
818 | if(4 != read(fd, tmp, 4)) | 819 | if(4 != read(fd, tmp, 4)) |
819 | return; | 820 | return; |
820 | 821 | ||
821 | data_length_ind = UNSYNC(tmp[0], tmp[1], tmp[2], tmp[3]); | 822 | data_length_ind = unsync(tmp[0], tmp[1], tmp[2], tmp[3]); |
822 | framelen -= 4; | 823 | framelen -= 4; |
823 | } | 824 | } |
824 | } | 825 | } |
@@ -963,7 +964,7 @@ int getid3v2len(int fd) | |||
963 | if(read(fd, buf, 4) != 4) | 964 | if(read(fd, buf, 4) != 4) |
964 | offset = 0; | 965 | offset = 0; |
965 | else | 966 | else |
966 | offset = UNSYNC(buf[0], buf[1], buf[2], buf[3]) + 10; | 967 | offset = unsync(buf[0], buf[1], buf[2], buf[3]) + 10; |
967 | 968 | ||
968 | DEBUGF("ID3V2 Length: 0x%x\n", offset); | 969 | DEBUGF("ID3V2 Length: 0x%x\n", offset); |
969 | return offset; | 970 | return offset; |
@@ -1066,8 +1067,10 @@ static int getsonglength(int fd, struct mp3entry *entry) | |||
1066 | entry->vbr = info.is_vbr; | 1067 | entry->vbr = info.is_vbr; |
1067 | entry->has_toc = info.has_toc; | 1068 | entry->has_toc = info.has_toc; |
1068 | 1069 | ||
1070 | #if CONFIC_CODEC==SWCODEC | ||
1069 | entry->lead_trim = info.enc_delay; | 1071 | entry->lead_trim = info.enc_delay; |
1070 | entry->tail_trim = info.enc_padding; | 1072 | entry->tail_trim = info.enc_padding; |
1073 | #endif | ||
1071 | 1074 | ||
1072 | memcpy(entry->toc, info.toc, sizeof(info.toc)); | 1075 | memcpy(entry->toc, info.toc, sizeof(info.toc)); |
1073 | 1076 | ||
diff --git a/firmware/mp3data.c b/firmware/mp3data.c index 49b95f2d9e..2ebb620ed6 100644 --- a/firmware/mp3data.c +++ b/firmware/mp3data.c | |||
@@ -40,11 +40,6 @@ | |||
40 | 40 | ||
41 | #define DEBUG_VERBOSE | 41 | #define DEBUG_VERBOSE |
42 | 42 | ||
43 | #define BYTES2INT(b1,b2,b3,b4) (((long)(b1 & 0xFF) << (3*8)) | \ | ||
44 | ((long)(b2 & 0xFF) << (2*8)) | \ | ||
45 | ((long)(b3 & 0xFF) << (1*8)) | \ | ||
46 | ((long)(b4 & 0xFF) << (0*8))) | ||
47 | |||
48 | #define SYNC_MASK (0x7ffL << 21) | 43 | #define SYNC_MASK (0x7ffL << 21) |
49 | #define VERSION_MASK (3L << 19) | 44 | #define VERSION_MASK (3L << 19) |
50 | #define LAYER_MASK (3L << 17) | 45 | #define LAYER_MASK (3L << 17) |
@@ -82,13 +77,24 @@ static const short *bitrate_table[3][3] = | |||
82 | }; | 77 | }; |
83 | 78 | ||
84 | /* Sampling frequency table, indexed by version and frequency index */ | 79 | /* Sampling frequency table, indexed by version and frequency index */ |
85 | static const long freq_table[3][3] = | 80 | static const unsigned short freq_table[3][3] = |
86 | { | 81 | { |
87 | {44100, 48000, 32000}, /* MPEG Version 1 */ | 82 | {44100, 48000, 32000}, /* MPEG Version 1 */ |
88 | {22050, 24000, 16000}, /* MPEG version 2 */ | 83 | {22050, 24000, 16000}, /* MPEG version 2 */ |
89 | {11025, 12000, 8000}, /* MPEG version 2.5 */ | 84 | {11025, 12000, 8000}, /* MPEG version 2.5 */ |
90 | }; | 85 | }; |
91 | 86 | ||
87 | unsigned long bytes2int(unsigned long b0, | ||
88 | unsigned long b1, | ||
89 | unsigned long b2, | ||
90 | unsigned long b3) | ||
91 | { | ||
92 | return (((long)(b0 & 0xFF) << (3*8)) | | ||
93 | ((long)(b1 & 0xFF) << (2*8)) | | ||
94 | ((long)(b2 & 0xFF) << (1*8)) | | ||
95 | ((long)(b3 & 0xFF) << (0*8))); | ||
96 | } | ||
97 | |||
92 | /* check if 'head' is a valid mp3 frame header */ | 98 | /* check if 'head' is a valid mp3 frame header */ |
93 | static bool is_mp3frameheader(unsigned long head) | 99 | static bool is_mp3frameheader(unsigned long head) |
94 | { | 100 | { |
@@ -357,9 +363,11 @@ int get_mp3file_info(int fd, struct mp3info *info) | |||
357 | return -1; | 363 | return -1; |
358 | 364 | ||
359 | memset(info, 0, sizeof(struct mp3info)); | 365 | memset(info, 0, sizeof(struct mp3info)); |
366 | #if CONFIG_CODEC==SWCODEC | ||
360 | /* These two are needed for proper LAME gapless MP3 playback */ | 367 | /* These two are needed for proper LAME gapless MP3 playback */ |
361 | info->enc_delay = -1; | 368 | info->enc_delay = -1; |
362 | info->enc_padding = -1; | 369 | info->enc_padding = -1; |
370 | #endif | ||
363 | if(!mp3headerinfo(info, header)) | 371 | if(!mp3headerinfo(info, header)) |
364 | return -2; | 372 | return -2; |
365 | 373 | ||
@@ -416,7 +424,7 @@ int get_mp3file_info(int fd, struct mp3info *info) | |||
416 | 424 | ||
417 | if (vbrheader[7] & VBR_FRAMES_FLAG) /* Is the frame count there? */ | 425 | if (vbrheader[7] & VBR_FRAMES_FLAG) /* Is the frame count there? */ |
418 | { | 426 | { |
419 | info->frame_count = BYTES2INT(vbrheader[i], vbrheader[i+1], | 427 | info->frame_count = bytes2int(vbrheader[i], vbrheader[i+1], |
420 | vbrheader[i+2], vbrheader[i+3]); | 428 | vbrheader[i+2], vbrheader[i+3]); |
421 | if (info->frame_count <= ULONG_MAX / info->ft_num) | 429 | if (info->frame_count <= ULONG_MAX / info->ft_num) |
422 | info->file_time = info->frame_count * info->ft_num / info->ft_den; | 430 | info->file_time = info->frame_count * info->ft_num / info->ft_den; |
@@ -427,7 +435,7 @@ int get_mp3file_info(int fd, struct mp3info *info) | |||
427 | 435 | ||
428 | if (vbrheader[7] & VBR_BYTES_FLAG) /* Is byte count there? */ | 436 | if (vbrheader[7] & VBR_BYTES_FLAG) /* Is byte count there? */ |
429 | { | 437 | { |
430 | info->byte_count = BYTES2INT(vbrheader[i], vbrheader[i+1], | 438 | info->byte_count = bytes2int(vbrheader[i], vbrheader[i+1], |
431 | vbrheader[i+2], vbrheader[i+3]); | 439 | vbrheader[i+2], vbrheader[i+3]); |
432 | i += 4; | 440 | i += 4; |
433 | } | 441 | } |
@@ -453,6 +461,7 @@ int get_mp3file_info(int fd, struct mp3info *info) | |||
453 | /* We don't care about this, but need to skip it */ | 461 | /* We don't care about this, but need to skip it */ |
454 | i += 4; | 462 | i += 4; |
455 | } | 463 | } |
464 | #if CONFIG_CODEC==SWCODEC | ||
456 | i += 21; | 465 | i += 21; |
457 | info->enc_delay = (vbrheader[i] << 4) | (vbrheader[i + 1] >> 4); | 466 | info->enc_delay = (vbrheader[i] << 4) | (vbrheader[i + 1] >> 4); |
458 | info->enc_padding = ((vbrheader[i + 1] & 0x0f) << 8) | vbrheader[i + 2]; | 467 | info->enc_padding = ((vbrheader[i + 1] & 0x0f) << 8) | vbrheader[i + 2]; |
@@ -465,6 +474,7 @@ int get_mp3file_info(int fd, struct mp3info *info) | |||
465 | info->enc_delay = -1; | 474 | info->enc_delay = -1; |
466 | info->enc_padding = -1; | 475 | info->enc_padding = -1; |
467 | } | 476 | } |
477 | #endif | ||
468 | } | 478 | } |
469 | 479 | ||
470 | if (!memcmp(vbrheader, "VBRI", 4)) | 480 | if (!memcmp(vbrheader, "VBRI", 4)) |
@@ -500,9 +510,9 @@ int get_mp3file_info(int fd, struct mp3info *info) | |||
500 | info->is_vbri_vbr = true; | 510 | info->is_vbri_vbr = true; |
501 | info->has_toc = false; /* We don't parse the TOC (yet) */ | 511 | info->has_toc = false; /* We don't parse the TOC (yet) */ |
502 | 512 | ||
503 | info->byte_count = BYTES2INT(vbrheader[10], vbrheader[11], | 513 | info->byte_count = bytes2int(vbrheader[10], vbrheader[11], |
504 | vbrheader[12], vbrheader[13]); | 514 | vbrheader[12], vbrheader[13]); |
505 | info->frame_count = BYTES2INT(vbrheader[14], vbrheader[15], | 515 | info->frame_count = bytes2int(vbrheader[14], vbrheader[15], |
506 | vbrheader[16], vbrheader[17]); | 516 | vbrheader[16], vbrheader[17]); |
507 | if (info->frame_count <= ULONG_MAX / info->ft_num) | 517 | if (info->frame_count <= ULONG_MAX / info->ft_num) |
508 | info->file_time = info->frame_count * info->ft_num / info->ft_den; | 518 | info->file_time = info->frame_count * info->ft_num / info->ft_den; |
@@ -515,8 +525,8 @@ int get_mp3file_info(int fd, struct mp3info *info) | |||
515 | info->bitrate = info->byte_count / (info->file_time >> 3); | 525 | info->bitrate = info->byte_count / (info->file_time >> 3); |
516 | 526 | ||
517 | /* We don't parse the TOC, since we don't yet know how to (FIXME) */ | 527 | /* We don't parse the TOC, since we don't yet know how to (FIXME) */ |
518 | num_offsets = BYTES2INT(0, 0, vbrheader[18], vbrheader[19]); | 528 | num_offsets = bytes2int(0, 0, vbrheader[18], vbrheader[19]); |
519 | frames_per_entry = BYTES2INT(0, 0, vbrheader[24], vbrheader[25]); | 529 | frames_per_entry = bytes2int(0, 0, vbrheader[24], vbrheader[25]); |
520 | DEBUGF("Frame size (%dkpbs): %d bytes (0x%x)\n", | 530 | DEBUGF("Frame size (%dkpbs): %d bytes (0x%x)\n", |
521 | info->bitrate, info->frame_size, info->frame_size); | 531 | info->bitrate, info->frame_size, info->frame_size); |
522 | DEBUGF("Frame count: %x\n", info->frame_count); | 532 | DEBUGF("Frame count: %x\n", info->frame_count); |
@@ -528,7 +538,7 @@ int get_mp3file_info(int fd, struct mp3info *info) | |||
528 | 538 | ||
529 | for(i = 0;i < num_offsets;i++) | 539 | for(i = 0;i < num_offsets;i++) |
530 | { | 540 | { |
531 | j = BYTES2INT(0, 0, vbrheader[26+i*2], vbrheader[27+i*2]); | 541 | j = bytes2int(0, 0, vbrheader[26+i*2], vbrheader[27+i*2]); |
532 | offset += j; | 542 | offset += j; |
533 | DEBUGF("%03d: %x (%x)\n", i, offset - bytecount, j); | 543 | DEBUGF("%03d: %x (%x)\n", i, offset - bytecount, j); |
534 | } | 544 | } |