summaryrefslogtreecommitdiff
path: root/firmware/mp3data.c
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/mp3data.c')
-rw-r--r--firmware/mp3data.c96
1 files changed, 53 insertions, 43 deletions
diff --git a/firmware/mp3data.c b/firmware/mp3data.c
index c2d4cd2c37..519bc60b04 100644
--- a/firmware/mp3data.c
+++ b/firmware/mp3data.c
@@ -406,7 +406,7 @@ int get_mp3file_info(int fd, struct mp3info *info)
406 /* Is it a VBR file? */ 406 /* Is it a VBR file? */
407 info->is_vbr = info->is_xing_vbr = !memcmp(vbrheader, "Xing", 4); 407 info->is_vbr = info->is_xing_vbr = !memcmp(vbrheader, "Xing", 4);
408 408
409 if(vbrheader[7] & VBR_FRAMES_FLAG) /* Is the frame count there? */ 409 if (vbrheader[7] & VBR_FRAMES_FLAG) /* Is the frame count there? */
410 { 410 {
411 info->frame_count = BYTES2INT(vbrheader[i], vbrheader[i+1], 411 info->frame_count = BYTES2INT(vbrheader[i], vbrheader[i+1],
412 vbrheader[i+2], vbrheader[i+3]); 412 vbrheader[i+2], vbrheader[i+3]);
@@ -417,19 +417,24 @@ int get_mp3file_info(int fd, struct mp3info *info)
417 i += 4; 417 i += 4;
418 } 418 }
419 419
420 if(vbrheader[7] & VBR_BYTES_FLAG) /* Is byte count there? */ 420 if (vbrheader[7] & VBR_BYTES_FLAG) /* Is byte count there? */
421 { 421 {
422 info->byte_count = BYTES2INT(vbrheader[i], vbrheader[i+1], 422 info->byte_count = BYTES2INT(vbrheader[i], vbrheader[i+1],
423 vbrheader[i+2], vbrheader[i+3]); 423 vbrheader[i+2], vbrheader[i+3]);
424 i += 4; 424 i += 4;
425 } 425 }
426 426
427 if(info->file_time && info->byte_count) 427 if (info->file_time && info->byte_count)
428 info->bitrate = info->byte_count * 8 / info->file_time; 428 {
429 if (info->byte_count <= (ULONG_MAX/8))
430 info->bitrate = info->byte_count * 8 / info->file_time;
431 else
432 info->bitrate = info->byte_count / (info->file_time >> 3);
433 }
429 else 434 else
430 info->bitrate = 0; 435 info->bitrate = 0;
431 436
432 if(vbrheader[7] & VBR_TOC_FLAG) /* Is table-of-contents there? */ 437 if (vbrheader[7] & VBR_TOC_FLAG) /* Is table-of-contents there? */
433 { 438 {
434 memcpy( info->toc, vbrheader+i, 100 ); 439 memcpy( info->toc, vbrheader+i, 100 );
435 i += 100; 440 i += 100;
@@ -492,7 +497,11 @@ int get_mp3file_info(int fd, struct mp3info *info)
492 info->file_time = info->frame_count * info->ft_num / info->ft_den; 497 info->file_time = info->frame_count * info->ft_num / info->ft_den;
493 else 498 else
494 info->file_time = info->frame_count / info->ft_den * info->ft_num; 499 info->file_time = info->frame_count / info->ft_den * info->ft_num;
495 info->bitrate = info->byte_count * 8 / info->file_time; 500
501 if (info->byte_count <= (ULONG_MAX/8))
502 info->bitrate = info->byte_count * 8 / info->file_time;
503 else
504 info->bitrate = info->byte_count / (info->file_time >> 3);
496 505
497 /* We don't parse the TOC, since we don't yet know how to (FIXME) */ 506 /* We don't parse the TOC, since we don't yet know how to (FIXME) */
498 num_offsets = BYTES2INT(0, 0, vbrheader[18], vbrheader[19]); 507 num_offsets = BYTES2INT(0, 0, vbrheader[18], vbrheader[19]);
@@ -587,37 +596,35 @@ int count_mp3_frames(int fd, int startpos, int filesize,
587 596
588static const char cooltext[] = "Rockbox - rocks your box"; 597static const char cooltext[] = "Rockbox - rocks your box";
589 598
590int create_xing_header(int fd, int startpos, int filesize, 599/* buf needs to be the audio buffer with TOC generation enabled,
591 unsigned char *buf, /* must be at least 288 bytes */ 600 and at least MAX_XING_HEADER_SIZE bytes otherwise */
592 int num_frames, unsigned long header_template, 601int create_xing_header(int fd, long startpos, long filesize,
602 unsigned char *buf, unsigned long num_frames,
603 unsigned long rec_time, unsigned long header_template,
593 void (*progressfunc)(int), bool generate_toc) 604 void (*progressfunc)(int), bool generate_toc)
594{ 605{
595 unsigned long header = 0;
596 struct mp3info info; 606 struct mp3info info;
597 int pos, last_pos; 607 unsigned char toc[100];
598 int i, j; 608 unsigned long header = 0;
599 long bytes; 609 unsigned long xing_header_template = header_template;
600 unsigned long filepos; 610 unsigned long filepos;
601 int x; 611 long pos, last_pos;
612 long j;
613 long bytes;
614 int i;
602 int index; 615 int index;
603 unsigned char toc[100];
604 unsigned long xing_header_template = 0;
605 616
606 DEBUGF("create_xing_header()\n"); 617 DEBUGF("create_xing_header()\n");
607 618
608 if(header_template)
609 xing_header_template = header_template;
610
611 if(generate_toc) 619 if(generate_toc)
612 { 620 {
613 lseek(fd, startpos, SEEK_SET); 621 lseek(fd, startpos, SEEK_SET);
614 buf_init(); 622 buf_init();
615 623
616 /* Generate filepos table */ 624 /* Generate filepos table */
617 last_pos = 0; 625 last_pos = 0;
618 filepos = 0; 626 filepos = 0;
619 header = 0; 627 header = 0;
620 x = 0;
621 for(i = 0;i < 100;i++) { 628 for(i = 0;i < 100;i++) {
622 /* Calculate the absolute frame number for this seek point */ 629 /* Calculate the absolute frame number for this seek point */
623 pos = i * num_frames / 100; 630 pos = i * num_frames / 100;
@@ -654,7 +661,7 @@ int create_xing_header(int fd, int startpos, int filesize,
654 * the upper 8 bits of the file position are nonzero 661 * the upper 8 bits of the file position are nonzero
655 * (i.e. files over 16mb in size). 662 * (i.e. files over 16mb in size).
656 */ 663 */
657 if (filepos > 0xFFFFFF) 664 if (filepos > (ULONG_MAX/256))
658 { 665 {
659 /* instead of multiplying filepos by 256, we divide 666 /* instead of multiplying filepos by 256, we divide
660 * filesize by 256. 667 * filesize by 256.
@@ -673,46 +680,49 @@ int create_xing_header(int fd, int startpos, int filesize,
673 } 680 }
674 } 681 }
675 682
676 /* Check the template header for validity and get some preliminary info. */ 683 /* Use the template header and create a new one.
677 if (!mp3headerinfo(&info, xing_header_template)) 684 We ignore the Protection bit even if the rest of the stream is
685 protected. */
686 header = xing_header_template & ~(BITRATE_MASK|PROTECTION_MASK|PADDING_MASK);
687 header |= 8 << 12; /* This gives us plenty of space, 192..576 bytes */
688
689 if (!mp3headerinfo(&info, header))
678 return 0; /* invalid header */ 690 return 0; /* invalid header */
679 691
692 if (num_frames == 0 && rec_time) {
693 /* estimate the number of frames based on the recording time */
694 if (rec_time <= ULONG_MAX / info.ft_den)
695 num_frames = rec_time * info.ft_den / info.ft_num;
696 else
697 num_frames = rec_time / info.ft_num * info.ft_den;
698 }
699
680 /* Clear the frame */ 700 /* Clear the frame */
681 memset(buf, 0, MAX_XING_HEADER_SIZE); 701 memset(buf, 0, MAX_XING_HEADER_SIZE);
682 702
683 /* Use the template header and create a new one. */ 703 /* Write the header to the buffer */
684 header = xing_header_template & ~(BITRATE_MASK | PROTECTION_MASK); 704 long2bytes(buf, header);
685 705
686 /* Calculate position of VBR header and required frame bitrate */ 706 /* Calculate position of VBR header */
687 if (info.version == MPEG_VERSION1) { 707 if (info.version == MPEG_VERSION1) {
688 header |= 5 << 12;
689 if (info.channel_mode == 3) /* mono */ 708 if (info.channel_mode == 3) /* mono */
690 index = 21; 709 index = 21;
691 else 710 else
692 index = 36; 711 index = 36;
693 } 712 }
694 else { 713 else {
695 if (info.version == MPEG_VERSION2)
696 header |= 8 << 12;
697 else /* MPEG_VERSION2_5 */
698 header |= 4 << 12;
699 if (info.channel_mode == 3) /* mono */ 714 if (info.channel_mode == 3) /* mono */
700 index = 13; 715 index = 13;
701 else 716 else
702 index = 21; 717 index = 21;
703 } 718 }
704 mp3headerinfo(&info, header); /* Get final header info */
705 /* Size is now always one of 192, 208 or 288 bytes */
706
707 /* Write the header to the buffer */
708 long2bytes(buf, header);
709 719
710 /* Create the Xing data */ 720 /* Create the Xing data */
711 memcpy(&buf[index], "Xing", 4); 721 memcpy(&buf[index], "Xing", 4);
712 long2bytes(&buf[index+4], ((num_frames?VBR_FRAMES_FLAG:0) | 722 long2bytes(&buf[index+4], (num_frames ? VBR_FRAMES_FLAG : 0)
713 (filesize?VBR_BYTES_FLAG:0) | 723 | (filesize ? VBR_BYTES_FLAG : 0)
714 (generate_toc?VBR_TOC_FLAG:0))); 724 | (generate_toc ? VBR_TOC_FLAG : 0));
715 index = index+8; 725 index += 8;
716 if(num_frames) 726 if(num_frames)
717 { 727 {
718 long2bytes(&buf[index], num_frames); 728 long2bytes(&buf[index], num_frames);