From 7fdef57d572a5f81f5efec4fd6f73a4f797cc823 Mon Sep 17 00:00:00 2001 From: Linus Nielsen Feltzing Date: Sat, 19 Apr 2003 01:59:23 +0000 Subject: 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 --- firmware/export/mp3data.h | 1 + firmware/mp3data.c | 41 +++++++++++++++++++++++++++++++++++------ firmware/mpeg.c | 43 +++++++++++++++++-------------------------- 3 files changed, 53 insertions(+), 32 deletions(-) (limited to 'firmware') 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, void (*progressfunc)(int)); int create_xing_header(int fd, int startpos, int filesize, unsigned char *buf, int num_frames, + int mpeg_version, int sample_rate, void (*progressfunc)(int), bool generate_toc); #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 @@ #include "mp3data.h" #include "file.h" -#undef DEBUG_VERBOSE +#define DEBUG_VERBOSE #define BYTES2INT(b1,b2,b3,b4) (((b1 & 0xFF) << (3*8)) | \ ((b2 & 0xFF) << (2*8)) | \ @@ -530,9 +530,10 @@ int get_mp3file_info(int fd, struct mp3info *info) return bytecount; } -/* This is an MP3 header, 128kbit/s, 44.1kHz, with silence */ +/* This is an MP3 header, 128kbit/s, with silence + MPEG version and sample frequency are not set */ static const unsigned char xing_frame_header[] = { - 0xff, 0xfa, 0x90, 0x64, 0x86, 0x1f + 0xff, 0xe2, 0x90, 0x64, 0x86, 0x1f }; static const char cooltext[] = "Rockbox rocks"; @@ -601,11 +602,15 @@ int count_mp3_frames(int fd, int startpos, int filesize, } } +/* Note: mpeg_version and sample_rate are 2-bit values, as specified by the + MPEG frame standard. See the tables above. */ int create_xing_header(int fd, int startpos, int filesize, unsigned char *buf, int num_frames, + int mpeg_version, int sample_rate, void (*progressfunc)(int), bool generate_toc) { unsigned long header = 0; + unsigned long saved_header; struct mp3info info; int pos, last_pos; int i, j; @@ -618,9 +623,9 @@ int create_xing_header(int fd, int startpos, int filesize, DEBUGF("create_xing_header()\n"); /* Create the frame header */ - memset(buf, 0, 417); + memset(buf, 0, 1500); memcpy(buf, xing_frame_header, 6); - + lseek(fd, startpos, SEEK_SET); buf_init(); @@ -664,6 +669,10 @@ int create_xing_header(int fd, int startpos, int filesize, buf_seek(fd, info.frame_size-4); filepos += info.frame_size; } + + /* Save one header for later use */ + if(i == 1) + saved_header = header; if(progressfunc) { @@ -684,6 +693,26 @@ int create_xing_header(int fd, int startpos, int filesize, memcpy(buf + index + 100, cooltext, sizeof(cooltext)); + /* We must fill in the correct sample rate and mpeg version. If the TOC + should be generated, we take that data from the actual stream. If not, + we use the supplied parameters. */ + if(generate_toc) + { + saved_header &= (VERSION_MASK | SAMPLERATE_MASK); + + buf[1] |= (saved_header >> 16) & 0xff; + buf[2] |= (saved_header >> 8) & 0xff; + } + else + { + buf[1] |= mpeg_version << 3; + buf[2] |= sample_rate << 2; + } + + /* Now get the length of the newly created frame */ + header = BYTES2INT(buf[0], buf[1], buf[2], buf[3]); + mp3headerinfo(&info, header); + #ifdef DEBUG for(i = 0;i < 417;i++) { @@ -694,5 +723,5 @@ int create_xing_header(int fd, int startpos, int filesize, } #endif - return 0; + return info.frame_size; } 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 was started */ static bool saving; /* We are saving the buffer to disk */ static char recording_filename[MAX_PATH]; - +static int rec_frequency_index; /* For create_xing_header() calls */ +static int rec_version_index; /* For create_xing_header() calls */ #endif static int mpeg_file; @@ -1010,13 +1011,6 @@ void IRQ3(void) dma_tick(); else postpone_dma_tick(); - -#if 0 - if(mpeg_mode == MPEG_ENCODER) - /* Shut off if recording is stopped */ - if(!is_recording) - demand_irq_enable(false); -#endif } #endif @@ -1271,6 +1265,7 @@ static void mpeg_thread(void) #ifdef HAVE_MAS3587F int amount_to_save; int writelen; + int framelen; #endif is_playing = false; @@ -1734,15 +1729,6 @@ static void mpeg_thread(void) DEBUGF("R\n"); t1 = current_tick; len = read(mpeg_file, mp3buf+mp3buf_write, amount_to_read); -#if 0 - if(id3tags[tag_read_idx]->id3.vbr) - /* Average bitrate * 1.5 */ - recalculate_watermark( - (id3tags[tag_read_idx]->id3.bitrate * 3) / 2); - else - recalculate_watermark( - id3tags[tag_read_idx]->id3.bitrate); -#endif if(len > 0) { t2 = current_tick; @@ -1854,10 +1840,10 @@ static void mpeg_thread(void) DEBUGF("Recording...\n"); reset_mp3_buffer(); - /* Advance the write pointer 4096+417 bytes to make + /* Advance the write pointer 4096+1500 bytes to make room for an ID3 tag plus a VBR header */ - mp3buf_write = 4096+417; - memset(mp3buf, 0, 4096+417); + mp3buf_write = 4096+1500; + memset(mp3buf, 0, 4096+1500); /* Insert the ID3 header */ memcpy(mp3buf, empty_id3_header, sizeof(empty_id3_header)); @@ -1898,12 +1884,14 @@ static void mpeg_thread(void) if(num_recorded_frames == 0x7ffff) num_recorded_frames = 0; - create_xing_header(mpeg_file, 0, num_rec_bytes, - mp3buf, num_recorded_frames, NULL, - false); + framelen = create_xing_header(mpeg_file, 0, num_rec_bytes, + mp3buf, num_recorded_frames, + rec_version_index, + rec_frequency_index, + NULL, false); - lseek(mpeg_file, 4096, SEEK_SET); - write(mpeg_file, mp3buf, 417); + lseek(mpeg_file, 4096+1500-framelen, SEEK_SET); + write(mpeg_file, mp3buf, framelen); close(mpeg_file); mpeg_file = -1; @@ -2841,9 +2829,12 @@ void mpeg_set_recording_options(int frequency, int quality, unsigned long val; is_mpeg1 = (frequency < 3)?true:false; + + rec_version_index = is_mpeg1?3:2; + rec_frequency_index = frequency % 3; val = (quality << 17) | - ((frequency % 3) << 10) | + (rec_frequency_index << 10) | ((is_mpeg1?1:0) << 9) | (1 << 8) | /* CRC on */ (((channel_mode * 2 + 1) & 3) << 6) | -- cgit v1.2.3