summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--firmware/id3.c46
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 }