diff options
Diffstat (limited to 'firmware/id3.c')
-rw-r--r-- | firmware/id3.c | 371 |
1 files changed, 75 insertions, 296 deletions
diff --git a/firmware/id3.c b/firmware/id3.c index 8e8a60eb71..6aeafc4749 100644 --- a/firmware/id3.c +++ b/firmware/id3.c | |||
@@ -22,9 +22,6 @@ | |||
22 | * by David Härdeman. It has since been extended and enhanced pretty much by | 22 | * by David Härdeman. It has since been extended and enhanced pretty much by |
23 | * all sorts of friendly Rockbox people. | 23 | * all sorts of friendly Rockbox people. |
24 | * | 24 | * |
25 | * A nice reference for MPEG header info: | ||
26 | * http://rockbox.haxx.se/docs/mpeghdr.html | ||
27 | * | ||
28 | */ | 25 | */ |
29 | 26 | ||
30 | #include <stdio.h> | 27 | #include <stdio.h> |
@@ -37,6 +34,7 @@ | |||
37 | #include "atoi.h" | 34 | #include "atoi.h" |
38 | 35 | ||
39 | #include "id3.h" | 36 | #include "id3.h" |
37 | #include "mp3data.h" | ||
40 | 38 | ||
41 | #define UNSYNC(b0,b1,b2,b3) (((b0 & 0x7F) << (3*7)) | \ | 39 | #define UNSYNC(b0,b1,b2,b3) (((b0 & 0x7F) << (3*7)) | \ |
42 | ((b1 & 0x7F) << (2*7)) | \ | 40 | ((b1 & 0x7F) << (2*7)) | \ |
@@ -48,38 +46,6 @@ | |||
48 | ((b2 & 0xFF) << (1*8)) | \ | 46 | ((b2 & 0xFF) << (1*8)) | \ |
49 | ((b3 & 0xFF) << (0*8))) | 47 | ((b3 & 0xFF) << (0*8))) |
50 | 48 | ||
51 | /* Table of bitrates for MP3 files, all values in kilo. | ||
52 | * Indexed by version, layer and value of bit 15-12 in header. | ||
53 | */ | ||
54 | const int bitrate_table[2][3][16] = | ||
55 | { | ||
56 | { | ||
57 | {0,32,64,96,128,160,192,224,256,288,320,352,384,416,448,0}, | ||
58 | {0,32,48,56, 64,80, 96, 112,128,160,192,224,256,320,384,0}, | ||
59 | {0,32,40,48, 56,64, 80, 96, 112,128,160,192,224,256,320,0} | ||
60 | }, | ||
61 | { | ||
62 | {0,32,48,56,64,80,96,112,128,144,160,176,192,224,256,0}, | ||
63 | {0, 8,16,24,32,40,48, 56, 64, 80, 96,112,128,144,160,0}, | ||
64 | {0, 8,16,24,32,40,48, 56, 64, 80, 96,112,128,144,160,0} | ||
65 | } | ||
66 | }; | ||
67 | |||
68 | /* Table of samples per frame for MP3 files. | ||
69 | * Indexed by layer. Multiplied with 1000. | ||
70 | */ | ||
71 | const int bs[4] = {0, 384000, 1152000, 1152000}; | ||
72 | |||
73 | /* Table of sample frequency for MP3 files. | ||
74 | * Indexed by version and layer. | ||
75 | */ | ||
76 | const int freqtab[][4] = | ||
77 | { | ||
78 | {11025, 12000, 8000, 0}, /* MPEG version 2.5 */ | ||
79 | {44100, 48000, 32000, 0}, /* MPEG Version 1 */ | ||
80 | {22050, 24000, 16000, 0}, /* MPEG version 2 */ | ||
81 | }; | ||
82 | |||
83 | /* Checks to see if the passed in string is a 16-bit wide Unicode v2 | 49 | /* Checks to see if the passed in string is a 16-bit wide Unicode v2 |
84 | string. If it is, we attempt to convert it to a 8-bit ASCII string | 50 | string. If it is, we attempt to convert it to a 8-bit ASCII string |
85 | (for valid 8-bit ASCII characters). If it's not unicode, we leave | 51 | (for valid 8-bit ASCII characters). If it's not unicode, we leave |
@@ -168,6 +134,7 @@ static bool setid3v1title(int fd, struct mp3entry *entry) | |||
168 | if (strncmp(buffer, "TAG", 3)) | 134 | if (strncmp(buffer, "TAG", 3)) |
169 | return false; | 135 | return false; |
170 | 136 | ||
137 | entry->id3v1len = 128; | ||
171 | entry->id3version = ID3_VER_1_0; | 138 | entry->id3version = ID3_VER_1_0; |
172 | 139 | ||
173 | for (i=0; i < (int)sizeof offsets; i++) { | 140 | for (i=0; i < (int)sizeof offsets; i++) { |
@@ -239,6 +206,8 @@ static void setid3v2title(int fd, struct mp3entry *entry) | |||
239 | char *tracknum = NULL; | 206 | char *tracknum = NULL; |
240 | int bytesread = 0; | 207 | int bytesread = 0; |
241 | int buffersize = sizeof(entry->id3v2buf); | 208 | int buffersize = sizeof(entry->id3v2buf); |
209 | int flags; | ||
210 | int skip; | ||
242 | 211 | ||
243 | /* Bail out if the tag is shorter than 10 bytes */ | 212 | /* Bail out if the tag is shorter than 10 bytes */ |
244 | if(entry->id3v2len < 10) | 213 | if(entry->id3v2len < 10) |
@@ -275,17 +244,34 @@ static void setid3v2title(int fd, struct mp3entry *entry) | |||
275 | } | 244 | } |
276 | entry->id3version = version; | 245 | entry->id3version = version; |
277 | 246 | ||
247 | /* Skip the extended header if it is present */ | ||
248 | if(version >= ID3_VER_2_4) { | ||
249 | if(header[5] & 0x40) { | ||
250 | if(4 != read(fd, header, 4)) | ||
251 | return; | ||
252 | |||
253 | framelen = UNSYNC(header[0], header[1], | ||
254 | header[2], header[3]); | ||
255 | |||
256 | lseek(fd, framelen - 4, SEEK_CUR); | ||
257 | } | ||
258 | } | ||
259 | |||
278 | /* | 260 | /* |
279 | * We must have at least minframesize bytes left for the | 261 | * We must have at least minframesize bytes left for the |
280 | * remaining frames to be interesting | 262 | * remaining frames to be interesting |
281 | */ | 263 | */ |
282 | while(size > minframesize) { | 264 | while(size > minframesize) { |
265 | flags = 0; | ||
266 | |||
283 | /* Read frame header and check length */ | 267 | /* Read frame header and check length */ |
284 | if(version >= ID3_VER_2_3) { | 268 | if(version >= ID3_VER_2_3) { |
285 | if(10 != read(fd, header, 10)) | 269 | if(10 != read(fd, header, 10)) |
286 | return; | 270 | return; |
287 | /* Adjust for the 10 bytes we read */ | 271 | /* Adjust for the 10 bytes we read */ |
288 | size -= 10; | 272 | size -= 10; |
273 | |||
274 | flags = BYTES2INT(0, 0, header[8], header[9]); | ||
289 | 275 | ||
290 | if (version >= ID3_VER_2_4) { | 276 | if (version >= ID3_VER_2_4) { |
291 | framelen = UNSYNC(header[4], header[5], | 277 | framelen = UNSYNC(header[4], header[5], |
@@ -311,6 +297,33 @@ static void setid3v2title(int fd, struct mp3entry *entry) | |||
311 | if(framelen == 0) | 297 | if(framelen == 0) |
312 | return; | 298 | return; |
313 | 299 | ||
300 | if(flags) | ||
301 | { | ||
302 | skip = 0; | ||
303 | |||
304 | if(flags & 0x0040) /* Grouping identity */ | ||
305 | skip++; | ||
306 | |||
307 | if(flags & 0x000e) /* Compression, encryption or | ||
308 | unsynchronization */ | ||
309 | { | ||
310 | /* Skip it using the total size in case | ||
311 | it was truncated */ | ||
312 | size -= totframelen; | ||
313 | lseek(fd, totframelen, SEEK_CUR); | ||
314 | continue; | ||
315 | } | ||
316 | |||
317 | if(flags & 0x0001) /* Data length indicator */ | ||
318 | skip += 4; | ||
319 | |||
320 | if(skip) | ||
321 | { | ||
322 | lseek(fd, skip, SEEK_CUR); | ||
323 | framelen -= skip; | ||
324 | } | ||
325 | } | ||
326 | |||
314 | /* If the frame is larger than the remaining buffer space we try | 327 | /* If the frame is larger than the remaining buffer space we try |
315 | to read as much as would fit in the buffer */ | 328 | to read as much as would fit in the buffer */ |
316 | if(framelen >= buffersize - bufferpos) | 329 | if(framelen >= buffersize - bufferpos) |
@@ -404,6 +417,7 @@ static int getid3v2len(int fd) | |||
404 | else | 417 | else |
405 | offset = UNSYNC(buf[0], buf[1], buf[2], buf[3]) + 10; | 418 | offset = UNSYNC(buf[0], buf[1], buf[2], buf[3]) + 10; |
406 | 419 | ||
420 | DEBUGF("ID3V2 Length: 0x%x\n", offset); | ||
407 | return offset; | 421 | return offset; |
408 | } | 422 | } |
409 | 423 | ||
@@ -419,29 +433,6 @@ static int getfilesize(int fd) | |||
419 | return size; | 433 | return size; |
420 | } | 434 | } |
421 | 435 | ||
422 | /* check if 'head' is a valid mp3 frame header */ | ||
423 | static bool mp3frameheader(unsigned long head) | ||
424 | { | ||
425 | if ((head & 0xffe00000) != 0xffe00000) /* bad sync? */ | ||
426 | return false; | ||
427 | if (!((head >> 17) & 3)) /* no layer? */ | ||
428 | return false; | ||
429 | if (((head >> 12) & 0xf) == 0xf) /* bad bitrate? */ | ||
430 | return false; | ||
431 | if (!((head >> 12) & 0xf)) /* no bitrate? */ | ||
432 | return false; | ||
433 | if (((head >> 10) & 0x3) == 0x3) /* bad sample rate? */ | ||
434 | return false; | ||
435 | if (((head >> 19) & 1) == 1 && | ||
436 | ((head >> 17) & 3) == 3 && | ||
437 | ((head >> 16) & 1) == 1) | ||
438 | return false; | ||
439 | if ((head & 0xffff0000) == 0xfffe0000) | ||
440 | return false; | ||
441 | |||
442 | return true; | ||
443 | } | ||
444 | |||
445 | /* | 436 | /* |
446 | * Calculates the length (in milliseconds) of an MP3 file. | 437 | * Calculates the length (in milliseconds) of an MP3 file. |
447 | * | 438 | * |
@@ -456,263 +447,48 @@ static bool mp3frameheader(unsigned long head) | |||
456 | static int getsonglength(int fd, struct mp3entry *entry) | 447 | static int getsonglength(int fd, struct mp3entry *entry) |
457 | { | 448 | { |
458 | unsigned int filetime = 0; | 449 | unsigned int filetime = 0; |
459 | unsigned long header=0; | 450 | struct mp3info info; |
460 | unsigned char tmp; | ||
461 | unsigned char frame[156]; | ||
462 | unsigned char* xing; | ||
463 | |||
464 | enum { | ||
465 | MPEG_VERSION2_5, | ||
466 | MPEG_VERSION1, | ||
467 | MPEG_VERSION2 | ||
468 | } version; | ||
469 | int layer; | ||
470 | int bitindex; | ||
471 | int bitrate; | ||
472 | int freqindex; | ||
473 | int frequency; | ||
474 | int chmode; | ||
475 | int bytecount; | 451 | int bytecount; |
476 | int bytelimit; | 452 | |
477 | int bittable; /* which bitrate table to use */ | ||
478 | bool header_found = false; | ||
479 | |||
480 | long bpf; | ||
481 | long tpf; | ||
482 | |||
483 | /* Start searching after ID3v2 header */ | 453 | /* Start searching after ID3v2 header */ |
484 | if(-1 == lseek(fd, entry->id3v2len, SEEK_SET)) | 454 | if(-1 == lseek(fd, entry->id3v2len, SEEK_SET)) |
485 | return 0; | 455 | return 0; |
486 | |||
487 | /* Fill up header with first 24 bits */ | ||
488 | for(version = 0; version < 3; version++) { | ||
489 | header <<= 8; | ||
490 | if(!read(fd, &tmp, 1)) | ||
491 | return 0; | ||
492 | header |= tmp; | ||
493 | } | ||
494 | |||
495 | /* Loop trough file until we find a frame header */ | ||
496 | bytecount = entry->id3v2len - 1; | ||
497 | bytelimit = entry->id3v2len + 0x20000; | ||
498 | restart: | ||
499 | do { | ||
500 | header <<= 8; | ||
501 | if(!read(fd, &tmp, 1)) | ||
502 | return 0; | ||
503 | header |= tmp; | ||
504 | 456 | ||
505 | /* Quit if we haven't found a valid header within 128K */ | 457 | bytecount = get_mp3file_info(fd, &info); |
506 | bytecount++; | ||
507 | if(bytecount > bytelimit) | ||
508 | return 0; | ||
509 | } while(!mp3frameheader(header)); | ||
510 | |||
511 | /* | ||
512 | * Some files are filled with garbage in the beginning, | ||
513 | * if the bitrate index of the header is binary 1111 | ||
514 | * that is a good indicator | ||
515 | */ | ||
516 | if((header & 0xF000) == 0xF000) | ||
517 | goto restart; | ||
518 | |||
519 | /* MPEG Audio Version */ | ||
520 | switch((header & 0x180000) >> 19) { | ||
521 | case 0: | ||
522 | /* MPEG version 2.5 is not an official standard */ | ||
523 | version = MPEG_VERSION2_5; | ||
524 | bittable = MPEG_VERSION2; /* use the V2 bit rate table */ | ||
525 | break; | ||
526 | 458 | ||
527 | case 2: | 459 | DEBUGF("Space between ID3V2 tag and first audio frame: 0x%x bytes\n", |
528 | /* MPEG version 2 (ISO/IEC 13818-3) */ | 460 | bytecount); |
529 | version = MPEG_VERSION2; | ||
530 | bittable = MPEG_VERSION2; | ||
531 | break; | ||
532 | 461 | ||
533 | case 3: | 462 | if(bytecount < 0) |
534 | /* MPEG version 1 (ISO/IEC 11172-3) */ | ||
535 | version = MPEG_VERSION1; | ||
536 | bittable = MPEG_VERSION1; | ||
537 | break; | ||
538 | default: | ||
539 | goto restart; | ||
540 | } | ||
541 | |||
542 | /* Layer */ | ||
543 | switch((header & 0x060000) >> 17) { | ||
544 | case 1: | ||
545 | layer = 3; | ||
546 | break; | ||
547 | case 2: | ||
548 | layer = 2; | ||
549 | break; | ||
550 | case 3: | ||
551 | layer = 1; | ||
552 | break; | ||
553 | default: | ||
554 | goto restart; | ||
555 | } | ||
556 | |||
557 | /* Bitrate */ | ||
558 | bitindex = (header & 0xF000) >> 12; | ||
559 | bitrate = bitrate_table[bittable-1][layer-1][bitindex]; | ||
560 | if(bitrate == 0) | ||
561 | goto restart; | ||
562 | |||
563 | /* Sampling frequency */ | ||
564 | freqindex = (header & 0x0C00) >> 10; | ||
565 | frequency = freqtab[version][freqindex]; | ||
566 | if(frequency == 0) | ||
567 | goto restart; | ||
568 | |||
569 | #ifdef DEBUG_VERBOSE | ||
570 | DEBUGF( "Version %i, lay %i, biti %i, bitr %i, freqi %i, freq %i, chmode %d\n", | ||
571 | version, layer, bitindex, bitrate, freqindex, frequency, chmode); | ||
572 | #endif | ||
573 | entry->version = version; | ||
574 | entry->layer = layer; | ||
575 | entry->frequency = frequency; | ||
576 | |||
577 | /* Calculate bytes per frame, calculation depends on layer */ | ||
578 | switch(layer) { | ||
579 | case 1: | ||
580 | bpf = bitrate_table[bittable - 1][layer - 1][bitindex]; | ||
581 | bpf *= 48000; | ||
582 | bpf /= freqtab[version][freqindex] << (bittable - 1); | ||
583 | break; | ||
584 | case 2: | ||
585 | case 3: | ||
586 | bpf = bitrate_table[bittable - 1][layer - 1][bitindex]; | ||
587 | bpf *= 144000; | ||
588 | bpf /= freqtab[version][freqindex] << (bittable - 1); | ||
589 | break; | ||
590 | default: | ||
591 | bpf = 1; | ||
592 | } | ||
593 | |||
594 | /* Calculate time per frame */ | ||
595 | tpf = bs[layer] / (freqtab[version][freqindex] << (bittable - 1)); | ||
596 | |||
597 | entry->bpf = bpf; | ||
598 | entry->tpf = tpf; | ||
599 | |||
600 | /* OK, we have found a frame. Let's see if it has a Xing header */ | ||
601 | if(read(fd, frame, sizeof frame) < 0) | ||
602 | return -1; | 463 | return -1; |
464 | |||
465 | bytecount += entry->id3v2len; | ||
603 | 466 | ||
604 | /* Channel mode (stereo/mono) */ | 467 | entry->bitrate = info.bitrate; |
605 | chmode = (header & 0xc0) >> 6; | ||
606 | |||
607 | /* calculate position of Xing VBR header */ | ||
608 | if ( version == 1 ) { | ||
609 | if ( chmode == 3 ) /* mono */ | ||
610 | xing = frame + 17; | ||
611 | else | ||
612 | xing = frame + 32; | ||
613 | } | ||
614 | else { | ||
615 | if ( chmode == 3 ) /* mono */ | ||
616 | xing = frame + 9; | ||
617 | else | ||
618 | xing = frame + 17; | ||
619 | } | ||
620 | |||
621 | if (xing[0] == 'X' && | ||
622 | xing[1] == 'i' && | ||
623 | xing[2] == 'n' && | ||
624 | xing[3] == 'g') | ||
625 | { | ||
626 | int i = 8; /* Where to start parsing info */ | ||
627 | |||
628 | /* Yes, it is a VBR file */ | ||
629 | entry->vbr = true; | ||
630 | entry->vbrflags = xing[7]; | ||
631 | |||
632 | if (entry->vbrflags & VBR_FRAMES_FLAG) /* Is the frame count there? */ | ||
633 | { | ||
634 | int framecount = (xing[i] << 24) | (xing[i+1] << 16) | | ||
635 | (xing[i+2] << 8) | xing[i+3]; | ||
636 | |||
637 | filetime = framecount * tpf; | ||
638 | i += 4; | ||
639 | } | ||
640 | |||
641 | if (entry->vbrflags & VBR_BYTES_FLAG) /* is byte count there? */ | ||
642 | { | ||
643 | int bytecount = (xing[i] << 24) | (xing[i+1] << 16) | | ||
644 | (xing[i+2] << 8) | xing[i+3]; | ||
645 | |||
646 | bitrate = bytecount * 8 / filetime; | ||
647 | i += 4; | ||
648 | } | ||
649 | |||
650 | if (entry->vbrflags & VBR_TOC_FLAG) /* is table-of-contents there? */ | ||
651 | { | ||
652 | memcpy( entry->toc, xing+i, 100 ); | ||
653 | } | ||
654 | |||
655 | /* Make sure we skip this frame in playback */ | ||
656 | bytecount += bpf; | ||
657 | |||
658 | header_found = true; | ||
659 | } | ||
660 | |||
661 | if (xing[0] == 'V' && | ||
662 | xing[1] == 'B' && | ||
663 | xing[2] == 'R' && | ||
664 | xing[3] == 'I') | ||
665 | { | ||
666 | int framecount; | ||
667 | int bytecount; | ||
668 | |||
669 | /* Yes, it is a FhG VBR file */ | ||
670 | entry->vbr = true; | ||
671 | entry->vbrflags = 0; | ||
672 | |||
673 | bytecount = (xing[10] << 24) | (xing[11] << 16) | | ||
674 | (xing[12] << 8) | xing[13]; | ||
675 | |||
676 | framecount = (xing[14] << 24) | (xing[15] << 16) | | ||
677 | (xing[16] << 8) | xing[17]; | ||
678 | |||
679 | filetime = framecount * tpf; | ||
680 | bitrate = bytecount * 8 / filetime; | ||
681 | |||
682 | /* We don't parse the TOC, since we don't yet know how to (FIXME) */ | ||
683 | |||
684 | /* Make sure we skip this frame in playback */ | ||
685 | bytecount += bpf; | ||
686 | |||
687 | header_found = true; | ||
688 | } | ||
689 | |||
690 | /* Is it a LAME Info frame? */ | ||
691 | if (xing[0] == 'I' && | ||
692 | xing[1] == 'n' && | ||
693 | xing[2] == 'f' && | ||
694 | xing[3] == 'o') | ||
695 | { | ||
696 | /* Make sure we skip this frame in playback */ | ||
697 | bytecount += bpf; | ||
698 | |||
699 | header_found = true; | ||
700 | } | ||
701 | |||
702 | |||
703 | entry->bitrate = bitrate; | ||
704 | 468 | ||
705 | /* If the file time hasn't been established, this may be a fixed | 469 | /* If the file time hasn't been established, this may be a fixed |
706 | rate MP3, so just use the default formula */ | 470 | rate MP3, so just use the default formula */ |
471 | |||
472 | filetime = info.file_time; | ||
473 | |||
707 | if(filetime == 0) | 474 | if(filetime == 0) |
708 | { | 475 | { |
709 | /* | 476 | /* |
710 | * Now song length is | 477 | * Now song length is |
711 | * ((filesize)/(bytes per frame))*(time per frame) | 478 | * ((filesize)/(bytes per frame))*(time per frame) |
712 | */ | 479 | */ |
713 | filetime = entry->filesize/bpf*tpf; | 480 | filetime = entry->filesize/info.frame_size*info.frame_time; |
714 | } | 481 | } |
715 | 482 | ||
483 | entry->tpf = info.frame_time; | ||
484 | entry->bpf = info.frame_size; | ||
485 | |||
486 | entry->vbr = info.is_vbr; | ||
487 | entry->has_toc = info.has_toc; | ||
488 | memcpy(entry->toc, info.toc, sizeof(info.toc)); | ||
489 | |||
490 | entry->xing_header_pos = info.xing_header_pos; | ||
491 | |||
716 | /* Update the seek point for the first playable frame */ | 492 | /* Update the seek point for the first playable frame */ |
717 | entry->first_frame_offset = bytecount; | 493 | entry->first_frame_offset = bytecount; |
718 | DEBUGF("First frame is at %x\n", entry->first_frame_offset); | 494 | DEBUGF("First frame is at %x\n", entry->first_frame_offset); |
@@ -720,7 +496,6 @@ static int getsonglength(int fd, struct mp3entry *entry) | |||
720 | return filetime; | 496 | return filetime; |
721 | } | 497 | } |
722 | 498 | ||
723 | |||
724 | /* | 499 | /* |
725 | * Checks all relevant information (such as ID3v1 tag, ID3v2 tag, length etc) | 500 | * Checks all relevant information (such as ID3v1 tag, ID3v2 tag, length etc) |
726 | * about an MP3 file and updates it's entry accordingly. | 501 | * about an MP3 file and updates it's entry accordingly. |
@@ -750,6 +525,10 @@ bool mp3info(struct mp3entry *entry, char *filename) | |||
750 | setid3v2title(fd, entry); | 525 | setid3v2title(fd, entry); |
751 | entry->length = getsonglength(fd, entry); | 526 | entry->length = getsonglength(fd, entry); |
752 | 527 | ||
528 | /* Subtract the meta information from the file size to get | ||
529 | the true size of the MP3 stream */ | ||
530 | entry->filesize -= entry->first_frame_offset; | ||
531 | |||
753 | /* only seek to end of file if no id3v2 tags were found */ | 532 | /* only seek to end of file if no id3v2 tags were found */ |
754 | if (!entry->id3v2len) { | 533 | if (!entry->id3v2len) { |
755 | if(!entry->title) | 534 | if(!entry->title) |