diff options
Diffstat (limited to 'firmware/id3.c')
-rw-r--r-- | firmware/id3.c | 55 |
1 files changed, 37 insertions, 18 deletions
diff --git a/firmware/id3.c b/firmware/id3.c index 35b983cbee..b373c9b77c 100644 --- a/firmware/id3.c +++ b/firmware/id3.c | |||
@@ -19,7 +19,12 @@ | |||
19 | 19 | ||
20 | /* | 20 | /* |
21 | * Parts of this code has been stolen from the Ample project and was written | 21 | * Parts of this code has been stolen from the Ample project and was written |
22 | * by David Härdeman. | 22 | * by David Härdeman. It has since been extended and enhanced pretty much by |
23 | * all sorts of friendly Rockbox people. | ||
24 | * | ||
25 | * A nice reference for MPEG header info: | ||
26 | * http://rockbox.haxx.se/docs/mpeghdr.html | ||
27 | * | ||
23 | */ | 28 | */ |
24 | 29 | ||
25 | #include <stdio.h> | 30 | #include <stdio.h> |
@@ -69,10 +74,11 @@ const int bs[4] = {0, 384000, 1152000, 1152000}; | |||
69 | /* Table of sample frequency for MP3 files. | 74 | /* Table of sample frequency for MP3 files. |
70 | * Indexed by version and layer. | 75 | * Indexed by version and layer. |
71 | */ | 76 | */ |
72 | const int freqtab[2][4] = | 77 | const int freqtab[][4] = |
73 | { | 78 | { |
74 | {44100, 48000, 32000, 0}, | 79 | {11025, 12000, 8000, 0}, /* MPEG version 2.5 */ |
75 | {22050, 24000, 16000, 0}, | 80 | {44100, 48000, 32000, 0}, /* MPEG Version 1 */ |
81 | {22050, 24000, 16000, 0}, /* MPEG version 2 */ | ||
76 | }; | 82 | }; |
77 | 83 | ||
78 | /* | 84 | /* |
@@ -365,10 +371,7 @@ static bool mp3frameheader(unsigned long head) | |||
365 | } | 371 | } |
366 | 372 | ||
367 | /* | 373 | /* |
368 | * Calculates the length (in milliseconds) of an MP3 file. Currently this code | 374 | * Calculates the length (in milliseconds) of an MP3 file. |
369 | * doesn't care about VBR (Variable BitRate) files since it would have to scan | ||
370 | * through the entire file but this should become a config option in the | ||
371 | * future. | ||
372 | * | 375 | * |
373 | * Modified to only use integers. | 376 | * Modified to only use integers. |
374 | * | 377 | * |
@@ -386,7 +389,11 @@ static int getsonglength(int fd, struct mp3entry *entry) | |||
386 | unsigned char frame[156]; | 389 | unsigned char frame[156]; |
387 | unsigned char* xing; | 390 | unsigned char* xing; |
388 | 391 | ||
389 | int version; | 392 | enum { |
393 | MPEG_VERSION2_5, | ||
394 | MPEG_VERSION1, | ||
395 | MPEG_VERSION2 | ||
396 | } version; | ||
390 | int layer; | 397 | int layer; |
391 | int bitindex; | 398 | int bitindex; |
392 | int bitrate; | 399 | int bitrate; |
@@ -394,6 +401,7 @@ static int getsonglength(int fd, struct mp3entry *entry) | |||
394 | int frequency; | 401 | int frequency; |
395 | int chmode; | 402 | int chmode; |
396 | int bytecount; | 403 | int bytecount; |
404 | int bittable; /* which bitrate table to use */ | ||
397 | 405 | ||
398 | long bpf; | 406 | long bpf; |
399 | long tpf; | 407 | long tpf; |
@@ -441,11 +449,22 @@ static int getsonglength(int fd, struct mp3entry *entry) | |||
441 | #endif | 449 | #endif |
442 | /* MPEG Audio Version */ | 450 | /* MPEG Audio Version */ |
443 | switch((header & 0x180000) >> 19) { | 451 | switch((header & 0x180000) >> 19) { |
452 | case 0: | ||
453 | /* MPEG version 2.5 is not an official standard */ | ||
454 | version = MPEG_VERSION2_5; | ||
455 | bittable = MPEG_VERSION2; /* use the V2 bit rate table */ | ||
456 | break; | ||
457 | |||
444 | case 2: | 458 | case 2: |
445 | version = 2; | 459 | /* MPEG version 2 (ISO/IEC 13818-3) */ |
460 | version = MPEG_VERSION2; | ||
461 | bittable = MPEG_VERSION2; | ||
446 | break; | 462 | break; |
463 | |||
447 | case 3: | 464 | case 3: |
448 | version = 1; | 465 | /* MPEG version 1 (ISO/IEC 11172-3) */ |
466 | version = MPEG_VERSION1; | ||
467 | bittable = MPEG_VERSION1; | ||
449 | break; | 468 | break; |
450 | default: | 469 | default: |
451 | goto restart; | 470 | goto restart; |
@@ -468,13 +487,13 @@ static int getsonglength(int fd, struct mp3entry *entry) | |||
468 | 487 | ||
469 | /* Bitrate */ | 488 | /* Bitrate */ |
470 | bitindex = (header & 0xF000) >> 12; | 489 | bitindex = (header & 0xF000) >> 12; |
471 | bitrate = bitrate_table[version-1][layer-1][bitindex]; | 490 | bitrate = bitrate_table[bittable-1][layer-1][bitindex]; |
472 | if(bitrate == 0) | 491 | if(bitrate == 0) |
473 | goto restart; | 492 | goto restart; |
474 | 493 | ||
475 | /* Sampling frequency */ | 494 | /* Sampling frequency */ |
476 | freqindex = (header & 0x0C00) >> 10; | 495 | freqindex = (header & 0x0C00) >> 10; |
477 | frequency = freqtab[version-1][freqindex]; | 496 | frequency = freqtab[version][freqindex]; |
478 | if(frequency == 0) | 497 | if(frequency == 0) |
479 | goto restart; | 498 | goto restart; |
480 | 499 | ||
@@ -489,22 +508,22 @@ static int getsonglength(int fd, struct mp3entry *entry) | |||
489 | /* Calculate bytes per frame, calculation depends on layer */ | 508 | /* Calculate bytes per frame, calculation depends on layer */ |
490 | switch(layer) { | 509 | switch(layer) { |
491 | case 1: | 510 | case 1: |
492 | bpf = bitrate_table[version - 1][layer - 1][bitindex]; | 511 | bpf = bitrate_table[bittable - 1][layer - 1][bitindex]; |
493 | bpf *= 48000; | 512 | bpf *= 48000; |
494 | bpf /= freqtab[version-1][freqindex] << (version - 1); | 513 | bpf /= freqtab[version][freqindex] << (bittable - 1); |
495 | break; | 514 | break; |
496 | case 2: | 515 | case 2: |
497 | case 3: | 516 | case 3: |
498 | bpf = bitrate_table[version - 1][layer - 1][bitindex]; | 517 | bpf = bitrate_table[bittable - 1][layer - 1][bitindex]; |
499 | bpf *= 144000; | 518 | bpf *= 144000; |
500 | bpf /= freqtab[version-1][freqindex] << (version - 1); | 519 | bpf /= freqtab[version][freqindex] << (bittable - 1); |
501 | break; | 520 | break; |
502 | default: | 521 | default: |
503 | bpf = 1; | 522 | bpf = 1; |
504 | } | 523 | } |
505 | 524 | ||
506 | /* Calculate time per frame */ | 525 | /* Calculate time per frame */ |
507 | tpf = bs[layer] / (freqtab[version-1][freqindex] << (version - 1)); | 526 | tpf = bs[layer] / (freqtab[version][freqindex] << (bittable - 1)); |
508 | 527 | ||
509 | entry->bpf = bpf; | 528 | entry->bpf = bpf; |
510 | entry->tpf = tpf; | 529 | entry->tpf = tpf; |