diff options
-rw-r--r-- | firmware/id3.c | 46 |
1 files changed, 32 insertions, 14 deletions
diff --git a/firmware/id3.c b/firmware/id3.c index ebfa1d368f..c2ae42e46d 100644 --- a/firmware/id3.c +++ b/firmware/id3.c | |||
@@ -365,6 +365,7 @@ static int getsonglength(int fd, struct mp3entry *entry) | |||
365 | unsigned long header=0; | 365 | unsigned long header=0; |
366 | unsigned char tmp; | 366 | unsigned char tmp; |
367 | unsigned char frame[64]; | 367 | unsigned char frame[64]; |
368 | unsigned char* xing; | ||
368 | 369 | ||
369 | int version; | 370 | int version; |
370 | int layer; | 371 | int layer; |
@@ -372,6 +373,7 @@ static int getsonglength(int fd, struct mp3entry *entry) | |||
372 | int bitrate; | 373 | int bitrate; |
373 | int freqindex; | 374 | int freqindex; |
374 | int frequency; | 375 | int frequency; |
376 | int chmode; | ||
375 | 377 | ||
376 | long bpf; | 378 | long bpf; |
377 | long tpf; | 379 | long tpf; |
@@ -437,7 +439,7 @@ static int getsonglength(int fd, struct mp3entry *entry) | |||
437 | default: | 439 | default: |
438 | return -1; | 440 | return -1; |
439 | } | 441 | } |
440 | 442 | ||
441 | /* Bitrate */ | 443 | /* Bitrate */ |
442 | bitindex = (header & 0xF000) >> 12; | 444 | bitindex = (header & 0xF000) >> 12; |
443 | bitrate = bitrate_table[version-1][layer-1][bitindex]; | 445 | bitrate = bitrate_table[version-1][layer-1][bitindex]; |
@@ -451,9 +453,8 @@ static int getsonglength(int fd, struct mp3entry *entry) | |||
451 | return -1; | 453 | return -1; |
452 | 454 | ||
453 | #ifdef DEBUG_VERBOSE | 455 | #ifdef DEBUG_VERBOSE |
454 | fprintf(stderr, | 456 | DEBUGF( "Version %i, lay %i, biti %i, bitr %i, freqi %i, freq %i, chmode %d\n", |
455 | "Version %i, lay %i, biti %i, bitr %i, freqi %i, freq %i\n", | 457 | version, layer, bitindex, bitrate, freqindex, frequency, chmode); |
456 | version, layer, bitindex, bitrate, freqindex, frequency); | ||
457 | #endif | 458 | #endif |
458 | entry->version = version; | 459 | entry->version = version; |
459 | entry->layer = layer; | 460 | entry->layer = layer; |
@@ -483,25 +484,42 @@ static int getsonglength(int fd, struct mp3entry *entry) | |||
483 | if(read(fd, frame, sizeof frame) < 0) | 484 | if(read(fd, frame, sizeof frame) < 0) |
484 | return -1; | 485 | return -1; |
485 | 486 | ||
486 | if(frame[32] == 'X' && | 487 | /* Channel mode (stereo/mono) */ |
487 | frame[33] == 'i' && | 488 | chmode = (header & 0xc0) >> 6; |
488 | frame[34] == 'n' && | 489 | |
489 | frame[35] == 'g') | 490 | /* calculate position of Xing VBR header */ |
491 | if ( version == 1 ) { | ||
492 | if ( chmode == 3 ) /* mono */ | ||
493 | xing = frame + 17; | ||
494 | else | ||
495 | xing = frame + 32; | ||
496 | } | ||
497 | else { | ||
498 | if ( chmode == 3 ) /* mono */ | ||
499 | xing = frame + 9; | ||
500 | else | ||
501 | xing = frame + 17; | ||
502 | } | ||
503 | |||
504 | if (xing[0] == 'X' && | ||
505 | xing[1] == 'i' && | ||
506 | xing[2] == 'n' && | ||
507 | xing[3] == 'g') | ||
490 | { | 508 | { |
491 | /* Yes, it is a VBR file */ | 509 | /* Yes, it is a VBR file */ |
492 | entry->vbr = true; | 510 | entry->vbr = true; |
493 | 511 | ||
494 | if(frame[39] & 0x01) /* Is the frame count there? */ | 512 | if (xing[7] & 0x01) /* Is the frame count there? */ |
495 | { | 513 | { |
496 | int framecount = (frame[40] << 24) | (frame[41] << 16) | | 514 | int framecount = (xing[8] << 24) | (xing[9] << 16) | |
497 | (frame[42] << 8) | frame[43]; | 515 | (xing[10] << 8) | xing[11]; |
498 | 516 | ||
499 | filetime = framecount * tpf; | 517 | filetime = framecount * tpf; |
500 | } | 518 | } |
501 | if (frame[39] & 0x02) /* is byte count there? */ | 519 | if (xing[7] & 0x02) /* is byte count there? */ |
502 | { | 520 | { |
503 | int bytecount = (frame[44] << 24) | (frame[45] << 16) | | 521 | int bytecount = (xing[12] << 24) | (xing[13] << 16) | |
504 | (frame[46] << 8) | frame[47]; | 522 | (xing[14] << 8) | xing[15]; |
505 | 523 | ||
506 | bitrate = bytecount * 8 / filetime; | 524 | bitrate = bytecount * 8 / filetime; |
507 | } | 525 | } |