summaryrefslogtreecommitdiff
path: root/firmware
diff options
context:
space:
mode:
authorLinus Nielsen Feltzing <linus@haxx.se>2003-04-19 01:59:23 +0000
committerLinus Nielsen Feltzing <linus@haxx.se>2003-04-19 01:59:23 +0000
commit7fdef57d572a5f81f5efec4fd6f73a4f797cc823 (patch)
treef686ce671a0b1d1bce0418a7bbb3400789fb6094 /firmware
parent1c32bd0f48605b9ee4623418812c30bc9ca4ba1b (diff)
downloadrockbox-7fdef57d572a5f81f5efec4fd6f73a4f797cc823.tar.gz
rockbox-7fdef57d572a5f81f5efec4fd6f73a4f797cc823.zip
Better generation of Xing headers, now they contain the correct MPEG version and sample rate info.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@3567 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'firmware')
-rw-r--r--firmware/export/mp3data.h1
-rw-r--r--firmware/mp3data.c41
-rw-r--r--firmware/mpeg.c43
3 files changed, 53 insertions, 32 deletions
diff --git a/firmware/export/mp3data.h b/firmware/export/mp3data.h
index 54a6899a78..d180935aa4 100644
--- a/firmware/export/mp3data.h
+++ b/firmware/export/mp3data.h
@@ -61,6 +61,7 @@ int count_mp3_frames(int fd, int startpos, int filesize,
61 void (*progressfunc)(int)); 61 void (*progressfunc)(int));
62int create_xing_header(int fd, int startpos, int filesize, 62int create_xing_header(int fd, int startpos, int filesize,
63 unsigned char *buf, int num_frames, 63 unsigned char *buf, int num_frames,
64 int mpeg_version, int sample_rate,
64 void (*progressfunc)(int), bool generate_toc); 65 void (*progressfunc)(int), bool generate_toc);
65 66
66#endif 67#endif
diff --git a/firmware/mp3data.c b/firmware/mp3data.c
index 28f2cb27f3..98dff50442 100644
--- a/firmware/mp3data.c
+++ b/firmware/mp3data.c
@@ -35,7 +35,7 @@
35#include "mp3data.h" 35#include "mp3data.h"
36#include "file.h" 36#include "file.h"
37 37
38#undef DEBUG_VERBOSE 38#define DEBUG_VERBOSE
39 39
40#define BYTES2INT(b1,b2,b3,b4) (((b1 & 0xFF) << (3*8)) | \ 40#define BYTES2INT(b1,b2,b3,b4) (((b1 & 0xFF) << (3*8)) | \
41 ((b2 & 0xFF) << (2*8)) | \ 41 ((b2 & 0xFF) << (2*8)) | \
@@ -530,9 +530,10 @@ int get_mp3file_info(int fd, struct mp3info *info)
530 return bytecount; 530 return bytecount;
531} 531}
532 532
533/* This is an MP3 header, 128kbit/s, 44.1kHz, with silence */ 533/* This is an MP3 header, 128kbit/s, with silence
534 MPEG version and sample frequency are not set */
534static const unsigned char xing_frame_header[] = { 535static const unsigned char xing_frame_header[] = {
535 0xff, 0xfa, 0x90, 0x64, 0x86, 0x1f 536 0xff, 0xe2, 0x90, 0x64, 0x86, 0x1f
536}; 537};
537 538
538static const char cooltext[] = "Rockbox rocks"; 539static const char cooltext[] = "Rockbox rocks";
@@ -601,11 +602,15 @@ int count_mp3_frames(int fd, int startpos, int filesize,
601 } 602 }
602} 603}
603 604
605/* Note: mpeg_version and sample_rate are 2-bit values, as specified by the
606 MPEG frame standard. See the tables above. */
604int create_xing_header(int fd, int startpos, int filesize, 607int create_xing_header(int fd, int startpos, int filesize,
605 unsigned char *buf, int num_frames, 608 unsigned char *buf, int num_frames,
609 int mpeg_version, int sample_rate,
606 void (*progressfunc)(int), bool generate_toc) 610 void (*progressfunc)(int), bool generate_toc)
607{ 611{
608 unsigned long header = 0; 612 unsigned long header = 0;
613 unsigned long saved_header;
609 struct mp3info info; 614 struct mp3info info;
610 int pos, last_pos; 615 int pos, last_pos;
611 int i, j; 616 int i, j;
@@ -618,9 +623,9 @@ int create_xing_header(int fd, int startpos, int filesize,
618 DEBUGF("create_xing_header()\n"); 623 DEBUGF("create_xing_header()\n");
619 624
620 /* Create the frame header */ 625 /* Create the frame header */
621 memset(buf, 0, 417); 626 memset(buf, 0, 1500);
622 memcpy(buf, xing_frame_header, 6); 627 memcpy(buf, xing_frame_header, 6);
623 628
624 lseek(fd, startpos, SEEK_SET); 629 lseek(fd, startpos, SEEK_SET);
625 buf_init(); 630 buf_init();
626 631
@@ -664,6 +669,10 @@ int create_xing_header(int fd, int startpos, int filesize,
664 buf_seek(fd, info.frame_size-4); 669 buf_seek(fd, info.frame_size-4);
665 filepos += info.frame_size; 670 filepos += info.frame_size;
666 } 671 }
672
673 /* Save one header for later use */
674 if(i == 1)
675 saved_header = header;
667 676
668 if(progressfunc) 677 if(progressfunc)
669 { 678 {
@@ -684,6 +693,26 @@ int create_xing_header(int fd, int startpos, int filesize,
684 693
685 memcpy(buf + index + 100, cooltext, sizeof(cooltext)); 694 memcpy(buf + index + 100, cooltext, sizeof(cooltext));
686 695
696 /* We must fill in the correct sample rate and mpeg version. If the TOC
697 should be generated, we take that data from the actual stream. If not,
698 we use the supplied parameters. */
699 if(generate_toc)
700 {
701 saved_header &= (VERSION_MASK | SAMPLERATE_MASK);
702
703 buf[1] |= (saved_header >> 16) & 0xff;
704 buf[2] |= (saved_header >> 8) & 0xff;
705 }
706 else
707 {
708 buf[1] |= mpeg_version << 3;
709 buf[2] |= sample_rate << 2;
710 }
711
712 /* Now get the length of the newly created frame */
713 header = BYTES2INT(buf[0], buf[1], buf[2], buf[3]);
714 mp3headerinfo(&info, header);
715
687#ifdef DEBUG 716#ifdef DEBUG
688 for(i = 0;i < 417;i++) 717 for(i = 0;i < 417;i++)
689 { 718 {
@@ -694,5 +723,5 @@ int create_xing_header(int fd, int startpos, int filesize,
694 } 723 }
695#endif 724#endif
696 725
697 return 0; 726 return info.frame_size;
698} 727}
diff --git a/firmware/mpeg.c b/firmware/mpeg.c
index 85f9c72a25..7e48040da2 100644
--- a/firmware/mpeg.c
+++ b/firmware/mpeg.c
@@ -489,7 +489,8 @@ unsigned long record_start_time; /* Value of current_tick when recording
489 was started */ 489 was started */
490static bool saving; /* We are saving the buffer to disk */ 490static bool saving; /* We are saving the buffer to disk */
491static char recording_filename[MAX_PATH]; 491static char recording_filename[MAX_PATH];
492 492static int rec_frequency_index; /* For create_xing_header() calls */
493static int rec_version_index; /* For create_xing_header() calls */
493#endif 494#endif
494 495
495static int mpeg_file; 496static int mpeg_file;
@@ -1010,13 +1011,6 @@ void IRQ3(void)
1010 dma_tick(); 1011 dma_tick();
1011 else 1012 else
1012 postpone_dma_tick(); 1013 postpone_dma_tick();
1013
1014#if 0
1015 if(mpeg_mode == MPEG_ENCODER)
1016 /* Shut off if recording is stopped */
1017 if(!is_recording)
1018 demand_irq_enable(false);
1019#endif
1020} 1014}
1021#endif 1015#endif
1022 1016
@@ -1271,6 +1265,7 @@ static void mpeg_thread(void)
1271#ifdef HAVE_MAS3587F 1265#ifdef HAVE_MAS3587F
1272 int amount_to_save; 1266 int amount_to_save;
1273 int writelen; 1267 int writelen;
1268 int framelen;
1274#endif 1269#endif
1275 1270
1276 is_playing = false; 1271 is_playing = false;
@@ -1734,15 +1729,6 @@ static void mpeg_thread(void)
1734 DEBUGF("R\n"); 1729 DEBUGF("R\n");
1735 t1 = current_tick; 1730 t1 = current_tick;
1736 len = read(mpeg_file, mp3buf+mp3buf_write, amount_to_read); 1731 len = read(mpeg_file, mp3buf+mp3buf_write, amount_to_read);
1737#if 0
1738 if(id3tags[tag_read_idx]->id3.vbr)
1739 /* Average bitrate * 1.5 */
1740 recalculate_watermark(
1741 (id3tags[tag_read_idx]->id3.bitrate * 3) / 2);
1742 else
1743 recalculate_watermark(
1744 id3tags[tag_read_idx]->id3.bitrate);
1745#endif
1746 if(len > 0) 1732 if(len > 0)
1747 { 1733 {
1748 t2 = current_tick; 1734 t2 = current_tick;
@@ -1854,10 +1840,10 @@ static void mpeg_thread(void)
1854 DEBUGF("Recording...\n"); 1840 DEBUGF("Recording...\n");
1855 reset_mp3_buffer(); 1841 reset_mp3_buffer();
1856 1842
1857 /* Advance the write pointer 4096+417 bytes to make 1843 /* Advance the write pointer 4096+1500 bytes to make
1858 room for an ID3 tag plus a VBR header */ 1844 room for an ID3 tag plus a VBR header */
1859 mp3buf_write = 4096+417; 1845 mp3buf_write = 4096+1500;
1860 memset(mp3buf, 0, 4096+417); 1846 memset(mp3buf, 0, 4096+1500);
1861 1847
1862 /* Insert the ID3 header */ 1848 /* Insert the ID3 header */
1863 memcpy(mp3buf, empty_id3_header, sizeof(empty_id3_header)); 1849 memcpy(mp3buf, empty_id3_header, sizeof(empty_id3_header));
@@ -1898,12 +1884,14 @@ static void mpeg_thread(void)
1898 if(num_recorded_frames == 0x7ffff) 1884 if(num_recorded_frames == 0x7ffff)
1899 num_recorded_frames = 0; 1885 num_recorded_frames = 0;
1900 1886
1901 create_xing_header(mpeg_file, 0, num_rec_bytes, 1887 framelen = create_xing_header(mpeg_file, 0, num_rec_bytes,
1902 mp3buf, num_recorded_frames, NULL, 1888 mp3buf, num_recorded_frames,
1903 false); 1889 rec_version_index,
1890 rec_frequency_index,
1891 NULL, false);
1904 1892
1905 lseek(mpeg_file, 4096, SEEK_SET); 1893 lseek(mpeg_file, 4096+1500-framelen, SEEK_SET);
1906 write(mpeg_file, mp3buf, 417); 1894 write(mpeg_file, mp3buf, framelen);
1907 close(mpeg_file); 1895 close(mpeg_file);
1908 1896
1909 mpeg_file = -1; 1897 mpeg_file = -1;
@@ -2841,9 +2829,12 @@ void mpeg_set_recording_options(int frequency, int quality,
2841 unsigned long val; 2829 unsigned long val;
2842 2830
2843 is_mpeg1 = (frequency < 3)?true:false; 2831 is_mpeg1 = (frequency < 3)?true:false;
2832
2833 rec_version_index = is_mpeg1?3:2;
2834 rec_frequency_index = frequency % 3;
2844 2835
2845 val = (quality << 17) | 2836 val = (quality << 17) |
2846 ((frequency % 3) << 10) | 2837 (rec_frequency_index << 10) |
2847 ((is_mpeg1?1:0) << 9) | 2838 ((is_mpeg1?1:0) << 9) |
2848 (1 << 8) | /* CRC on */ 2839 (1 << 8) | /* CRC on */
2849 (((channel_mode * 2 + 1) & 3) << 6) | 2840 (((channel_mode * 2 + 1) & 3) << 6) |