summaryrefslogtreecommitdiff
path: root/firmware/mp3data.c
diff options
context:
space:
mode:
authorLinus Nielsen Feltzing <linus@haxx.se>2003-03-10 18:05:01 +0000
committerLinus Nielsen Feltzing <linus@haxx.se>2003-03-10 18:05:01 +0000
commit6475aa0c85fcca7a37a7aa4316173270fcb6d038 (patch)
treee6dbe18217113212a9b8e713d3325c5803b3f4a6 /firmware/mp3data.c
parent673937d65402b058b5b5bfa5a1bf990c2d218dba (diff)
downloadrockbox-6475aa0c85fcca7a37a7aa4316173270fcb6d038.tar.gz
rockbox-6475aa0c85fcca7a37a7aa4316173270fcb6d038.zip
Experimental Xing header generation added. Use with caution
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@3418 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'firmware/mp3data.c')
-rw-r--r--firmware/mp3data.c118
1 files changed, 69 insertions, 49 deletions
diff --git a/firmware/mp3data.c b/firmware/mp3data.c
index 8d925041ce..21f01ea19e 100644
--- a/firmware/mp3data.c
+++ b/firmware/mp3data.c
@@ -263,9 +263,7 @@ extern unsigned char mp3end[];
263static int fnf_read_index; 263static int fnf_read_index;
264static int fnf_buf_len; 264static int fnf_buf_len;
265 265
266static int fd; 266static int buf_getbyte(int fd, unsigned char *c)
267
268static int buf_getbyte(unsigned char *c)
269{ 267{
270 if(fnf_read_index < fnf_buf_len) 268 if(fnf_read_index < fnf_buf_len)
271 { 269 {
@@ -291,7 +289,7 @@ static int buf_getbyte(unsigned char *c)
291 return 0; 289 return 0;
292} 290}
293 291
294static int buf_seek(int len) 292static int buf_seek(int fd, int len)
295{ 293{
296 fnf_read_index += len; 294 fnf_read_index += len;
297 if(fnf_read_index > fnf_buf_len) 295 if(fnf_read_index > fnf_buf_len)
@@ -320,7 +318,7 @@ static void buf_init(void)
320 fnf_read_index = 0; 318 fnf_read_index = 0;
321} 319}
322 320
323unsigned long buf_find_next_frame(int *offset, int max_offset, 321unsigned long buf_find_next_frame(int fd, int *offset, int max_offset,
324 unsigned long last_header) 322 unsigned long last_header)
325{ 323{
326 unsigned long header=0; 324 unsigned long header=0;
@@ -336,7 +334,7 @@ unsigned long buf_find_next_frame(int *offset, int max_offset,
336 /* Fill up header with first 24 bits */ 334 /* Fill up header with first 24 bits */
337 for(i = 0; i < 3; i++) { 335 for(i = 0; i < 3; i++) {
338 header <<= 8; 336 header <<= 8;
339 if(!buf_getbyte(&tmp)) 337 if(!buf_getbyte(fd, &tmp))
340 return 0; 338 return 0;
341 header |= tmp; 339 header |= tmp;
342 pos++; 340 pos++;
@@ -344,7 +342,7 @@ unsigned long buf_find_next_frame(int *offset, int max_offset,
344 342
345 do { 343 do {
346 header <<= 8; 344 header <<= 8;
347 if(!buf_getbyte(&tmp)) 345 if(!buf_getbyte(fd, &tmp))
348 return 0; 346 return 0;
349 header |= tmp; 347 header |= tmp;
350 pos++; 348 pos++;
@@ -413,7 +411,7 @@ int get_mp3file_info(int fd, struct mp3info *info)
413 DEBUGF("Xing header\n"); 411 DEBUGF("Xing header\n");
414 412
415 /* Remember where in the file the Xing header is */ 413 /* Remember where in the file the Xing header is */
416 info->xing_header_pos = lseek(fd, 0, SEEK_CUR) - info->frame_size; 414 info->vbr_header_pos = lseek(fd, 0, SEEK_CUR) - info->frame_size;
417 415
418 /* We want to skip the Xing frame when playing the stream */ 416 /* We want to skip the Xing frame when playing the stream */
419 bytecount += info->frame_size; 417 bytecount += info->frame_size;
@@ -423,7 +421,7 @@ int get_mp3file_info(int fd, struct mp3info *info)
423 header = find_next_frame(fd, &tmp, 0x20000, 0); 421 header = find_next_frame(fd, &tmp, 0x20000, 0);
424 if(header == 0) 422 if(header == 0)
425 return -4; 423 return -4;
426 424
427 if(!mp3headerinfo(info, header)) 425 if(!mp3headerinfo(info, header))
428 return -5; 426 return -5;
429 427
@@ -443,10 +441,14 @@ int get_mp3file_info(int fd, struct mp3info *info)
443 { 441 {
444 info->byte_count = BYTES2INT(vbrheader[i], vbrheader[i+1], 442 info->byte_count = BYTES2INT(vbrheader[i], vbrheader[i+1],
445 vbrheader[i+2], vbrheader[i+3]); 443 vbrheader[i+2], vbrheader[i+3]);
446 info->bitrate = info->byte_count * 8 / info->file_time;
447 i += 4; 444 i += 4;
448 } 445 }
449 446
447 if(info->file_time && info->byte_count)
448 info->bitrate = info->byte_count * 8 / info->file_time;
449 else
450 info->bitrate = 0;
451
450 if(vbrheader[7] & VBR_TOC_FLAG) /* Is table-of-contents there? */ 452 if(vbrheader[7] & VBR_TOC_FLAG) /* Is table-of-contents there? */
451 { 453 {
452 memcpy( info->toc, vbrheader+i, 100 ); 454 memcpy( info->toc, vbrheader+i, 100 );
@@ -554,6 +556,8 @@ int count_mp3_frames(int fd, int startpos, int filesize,
554 int progress_chunk = filesize / 50; /* Max is 50%, in 1% increments */ 556 int progress_chunk = filesize / 50; /* Max is 50%, in 1% increments */
555 int progress_cnt = 0; 557 int progress_cnt = 0;
556 558
559 /* Nasty stuff to avoid passing the file handle around */
560
557 if(lseek(fd, startpos, SEEK_SET) < 0) 561 if(lseek(fd, startpos, SEEK_SET) < 0)
558 return -1; 562 return -1;
559 563
@@ -563,9 +567,9 @@ int count_mp3_frames(int fd, int startpos, int filesize,
563 num_frames = 0; 567 num_frames = 0;
564 cnt = 0; 568 cnt = 0;
565 569
566 while((header = buf_find_next_frame(&bytes, -1, header))) { 570 while((header = buf_find_next_frame(fd, &bytes, -1, header))) {
567 mp3headerinfo(&info, header); 571 mp3headerinfo(&info, header);
568 buf_seek(info.frame_size-4); 572 buf_seek(fd, info.frame_size-4);
569 num_frames++; 573 num_frames++;
570 if(progressfunc) 574 if(progressfunc)
571 { 575 {
@@ -585,7 +589,7 @@ int count_mp3_frames(int fd, int startpos, int filesize,
585 589
586int create_xing_header(int fd, int startpos, int filesize, 590int create_xing_header(int fd, int startpos, int filesize,
587 unsigned char *buf, int num_frames, 591 unsigned char *buf, int num_frames,
588 void (*progressfunc)(int)) 592 void (*progressfunc)(int), bool generate_toc)
589{ 593{
590 unsigned long header = 0; 594 unsigned long header = 0;
591 struct mp3info info; 595 struct mp3info info;
@@ -595,6 +599,7 @@ int create_xing_header(int fd, int startpos, int filesize,
595 int filepos; 599 int filepos;
596 int tocentry; 600 int tocentry;
597 int x; 601 int x;
602 int index;
598 603
599 DEBUGF("create_xing_header()\n"); 604 DEBUGF("create_xing_header()\n");
600 605
@@ -609,46 +614,61 @@ int create_xing_header(int fd, int startpos, int filesize,
609 buf[36+1] = 'i'; 614 buf[36+1] = 'i';
610 buf[36+2] = 'n'; 615 buf[36+2] = 'n';
611 buf[36+3] = 'g'; 616 buf[36+3] = 'g';
612 int2bytes(&buf[36+4], (VBR_FRAMES_FLAG | VBR_BYTES_FLAG | VBR_TOC_FLAG)); 617 int2bytes(&buf[36+4], (num_frames?VBR_FRAMES_FLAG:0 |
613 int2bytes(&buf[36+8], num_frames); 618 filesize?VBR_BYTES_FLAG:0 |
614 int2bytes(&buf[36+12], filesize - startpos); 619 generate_toc?VBR_TOC_FLAG:0));
615 620 index = 36+8;
616 /* Generate filepos table */ 621 if(num_frames)
617 last_pos = 0; 622 {
618 filepos = 0; 623 int2bytes(&buf[index], num_frames);
619 header = 0; 624 index += 4;
620 x = 0; 625 }
621 for(i = 0;i < 100;i++) {
622 /* Calculate the absolute frame number for this seek point */
623 pos = i * num_frames / 100;
624
625 /* Advance from the last seek point to this one */
626 for(j = 0;j < pos - last_pos;j++)
627 {
628 DEBUGF("fpos: %x frame no: %x ", filepos, x++);
629 header = buf_find_next_frame(&bytes, -1, header);
630 mp3headerinfo(&info, header);
631 buf_seek(info.frame_size-4);
632 filepos += info.frame_size;
633 }
634 626
635 if(progressfunc) 627 if(filesize)
636 { 628 {
637 progressfunc(50 + i/2); 629 int2bytes(&buf[index], filesize - startpos);
638 } 630 index += 4;
639 631 }
640 tocentry = filepos * 256 / filesize;
641
642 DEBUGF("Pos %d: %d relpos: %d filepos: %x tocentry: %x\n",
643 i, pos, pos-last_pos, filepos, tocentry);
644 632
645 /* Fill in the TOC entry */ 633 if(generate_toc)
646 buf[36+16+i] = tocentry; 634 {
647 635 /* Generate filepos table */
648 last_pos = pos; 636 last_pos = 0;
637 filepos = 0;
638 header = 0;
639 x = 0;
640 for(i = 0;i < 100;i++) {
641 /* Calculate the absolute frame number for this seek point */
642 pos = i * num_frames / 100;
643
644 /* Advance from the last seek point to this one */
645 for(j = 0;j < pos - last_pos;j++)
646 {
647 DEBUGF("fpos: %x frame no: %x ", filepos, x++);
648 header = buf_find_next_frame(fd, &bytes, -1, header);
649 mp3headerinfo(&info, header);
650 buf_seek(fd, info.frame_size-4);
651 filepos += info.frame_size;
652 }
653
654 if(progressfunc)
655 {
656 progressfunc(50 + i/2);
657 }
658
659 tocentry = filepos * 256 / filesize;
660
661 DEBUGF("Pos %d: %d relpos: %d filepos: %x tocentry: %x\n",
662 i, pos, pos-last_pos, filepos, tocentry);
663
664 /* Fill in the TOC entry */
665 buf[index + i] = tocentry;
666
667 last_pos = pos;
668 }
649 } 669 }
650 670
651 memcpy(buf+152, cooltext, sizeof(cooltext)); 671 memcpy(buf + index + 100, cooltext, sizeof(cooltext));
652 672
653#ifdef DEBUG 673#ifdef DEBUG
654 for(i = 0;i < 417;i++) 674 for(i = 0;i < 417;i++)