diff options
author | Linus Nielsen Feltzing <linus@haxx.se> | 2003-03-10 18:05:01 +0000 |
---|---|---|
committer | Linus Nielsen Feltzing <linus@haxx.se> | 2003-03-10 18:05:01 +0000 |
commit | 6475aa0c85fcca7a37a7aa4316173270fcb6d038 (patch) | |
tree | e6dbe18217113212a9b8e713d3325c5803b3f4a6 /firmware/mp3data.c | |
parent | 673937d65402b058b5b5bfa5a1bf990c2d218dba (diff) | |
download | rockbox-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.c | 118 |
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[]; | |||
263 | static int fnf_read_index; | 263 | static int fnf_read_index; |
264 | static int fnf_buf_len; | 264 | static int fnf_buf_len; |
265 | 265 | ||
266 | static int fd; | 266 | static int buf_getbyte(int fd, unsigned char *c) |
267 | |||
268 | static 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 | ||
294 | static int buf_seek(int len) | 292 | static 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 | ||
323 | unsigned long buf_find_next_frame(int *offset, int max_offset, | 321 | unsigned 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 | ||
586 | int create_xing_header(int fd, int startpos, int filesize, | 590 | int 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++) |