summaryrefslogtreecommitdiff
path: root/firmware
diff options
context:
space:
mode:
authorLinus Nielsen Feltzing <linus@haxx.se>2003-04-20 22:00:30 +0000
committerLinus Nielsen Feltzing <linus@haxx.se>2003-04-20 22:00:30 +0000
commit478da628f0eb5fb3b5163dab459927ada52badfc (patch)
tree04e27d8bd6122a23c0fe483c4d35e149d1953179 /firmware
parentc6fb565dd98d2da0cd5ba0e29b73c49617edcb9c (diff)
downloadrockbox-478da628f0eb5fb3b5163dab459927ada52badfc.zip
rockbox-478da628f0eb5fb3b5163dab459927ada52badfc.tar.gz
rockbox-478da628f0eb5fb3b5163dab459927ada52badfc.tar.bz2
rockbox-478da628f0eb5fb3b5163dab459927ada52badfc.tar.xz
Xing headers now support mono better, added the 'editable files' option
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@3572 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'firmware')
-rw-r--r--firmware/export/mp3data.h2
-rw-r--r--firmware/export/mpeg.h6
-rw-r--r--firmware/mp3data.c133
-rw-r--r--firmware/mpeg.c26
4 files changed, 95 insertions, 72 deletions
diff --git a/firmware/export/mp3data.h b/firmware/export/mp3data.h
index d180935..6b3ff83 100644
--- a/firmware/export/mp3data.h
+++ b/firmware/export/mp3data.h
@@ -61,7 +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,
+ unsigned long header_template,
void (*progressfunc)(int), bool generate_toc);
#endif
diff --git a/firmware/export/mpeg.h b/firmware/export/mpeg.h
index e971aaa..d939567 100644
--- a/firmware/export/mpeg.h
+++ b/firmware/export/mpeg.h
@@ -32,6 +32,9 @@
#define MPEG_PLAY_PENDING_THRESHOLD 0x10000
#define MPEG_PLAY_PENDING_SWAPSIZE 0x10000
+/* For ID3 info and VBR header */
+#define MPEG_RESERVED_HEADER_SPACE (4096 + 1500)
+
struct mpeg_debug
{
int mp3buflen;
@@ -84,7 +87,8 @@ void mpeg_init_recording(void);
void mpeg_init_playback(void);
void mpeg_record(char *filename);
void mpeg_set_recording_options(int frequency, int quality,
- int source, int channel_mode);
+ int source, int channel_mode,
+ bool editable);
void mpeg_set_recording_gain(int left, int right, int mic);
unsigned long mpeg_recorded_time(void);
unsigned long mpeg_num_recorded_bytes(void);
diff --git a/firmware/mp3data.c b/firmware/mp3data.c
index 415d3bf..1cbf8e5 100644
--- a/firmware/mp3data.c
+++ b/firmware/mp3data.c
@@ -530,14 +530,6 @@ int get_mp3file_info(int fd, struct mp3info *info)
return bytecount;
}
-/* 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, 0xe2, 0x90, 0x64, 0x86, 0x1f
-};
-
-static const char cooltext[] = "Rockbox rocks";
-
static void int2bytes(unsigned char *buf, int val)
{
buf[0] = (val >> 24) & 0xff;
@@ -602,55 +594,30 @@ 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. */
+static const char cooltext[] = "Rockbox - rocks your box";
+
int create_xing_header(int fd, int startpos, int filesize,
unsigned char *buf, int num_frames,
- int mpeg_version, int sample_rate,
+ unsigned long header_template,
void (*progressfunc)(int), bool generate_toc)
{
unsigned long header = 0;
- unsigned long saved_header = 0;
struct mp3info info;
int pos, last_pos;
int i, j;
int bytes;
int filepos;
- int tocentry;
int x;
int index;
+ unsigned char toc[100];
DEBUGF("create_xing_header()\n");
- /* Create the frame header */
- memset(buf, 0, 1500);
- memcpy(buf, xing_frame_header, 6);
-
- lseek(fd, startpos, SEEK_SET);
- buf_init();
-
- buf[36] = 'X';
- buf[36+1] = 'i';
- buf[36+2] = 'n';
- buf[36+3] = 'g';
- int2bytes(&buf[36+4], ((num_frames?VBR_FRAMES_FLAG:0) |
- (filesize?VBR_BYTES_FLAG:0) |
- (generate_toc?VBR_TOC_FLAG:0)));
- index = 36+8;
- if(num_frames)
- {
- int2bytes(&buf[index], num_frames);
- index += 4;
- }
-
- if(filesize)
- {
- int2bytes(&buf[index], filesize - startpos);
- index += 4;
- }
-
if(generate_toc)
{
+ lseek(fd, startpos, SEEK_SET);
+ buf_init();
+
/* Generate filepos table */
last_pos = 0;
filepos = 0;
@@ -670,48 +637,90 @@ int create_xing_header(int fd, int startpos, int filesize,
filepos += info.frame_size;
}
- /* Save one header for later use */
+ /* Save a header for later use. Yes, we may be passed a header
+ template in the header_template argument, but since we are
+ reading headers from the stream anyway, we might as well
+ use the ones we find. However, we only save one header, and
+ we want to save one in te middle of the stream, just in case
+ the first and the last headers are corrupt. */
if(i == 1)
- saved_header = header;
+ header_template = header;
if(progressfunc)
{
progressfunc(50 + i/2);
}
- tocentry = filepos * 256 / filesize;
+ /* Fill in the TOC entry */
+ toc[i] = filepos * 256 / filesize;
DEBUGF("Pos %d: %d relpos: %d filepos: %x tocentry: %x\n",
- i, pos, pos-last_pos, filepos, tocentry);
-
- /* Fill in the TOC entry */
- buf[index + i] = tocentry;
+ i, pos, pos-last_pos, filepos, toc[i]);
last_pos = pos;
}
+ }
+
+ /* Clear the frame */
+ memset(buf, 0, 1500);
- /* Copy the MPEG version and sample rate from the mpeg stream into
- the Xing header */
- saved_header &= (VERSION_MASK | SAMPLERATE_MASK);
+ /* Use the template header and create a new one */
+ mp3headerinfo(&info, header_template);
+
+ /* calculate position of VBR header */
+ if ( info.version == MPEG_VERSION1 ) {
+ if (info.channel_mode == 3) /* mono */
+ index = 21;
+ else
+ index = 36;
+ }
+ else {
+ if (info.channel_mode == 3) /* mono */
+ index = 13;
+ else
+ index = 21;
+ }
+
+ /* We ignore the Protection bit even if the rest of the stream is
+ protected. (fixme?) */
+ header = header_template & ~(BITRATE_MASK | PROTECTION_MASK);
+ header |= 8 << 12; /* This gives us plenty of space, at least 192 bytes */
+
+ /* Write the header to the buffer */
+ int2bytes(buf, header);
- buf[1] |= (saved_header >> 16) & 0xff;
- buf[2] |= (saved_header >> 8) & 0xff;
+ /* Now get the length of the newly created frame */
+ mp3headerinfo(&info, header);
+
+ /* Create the Xing data */
+ buf[index] = 'X';
+ buf[index+1] = 'i';
+ buf[index+2] = 'n';
+ buf[index+3] = 'g';
+ int2bytes(&buf[index+4], ((num_frames?VBR_FRAMES_FLAG:0) |
+ (filesize?VBR_BYTES_FLAG:0) |
+ (generate_toc?VBR_TOC_FLAG:0)));
+ index = index+8;
+ if(num_frames)
+ {
+ int2bytes(&buf[index], num_frames);
+ index += 4;
}
- else
+
+ if(filesize)
{
- /* Fill in the MPEG version and sample rate into the Xing header */
- buf[1] |= mpeg_version << 3;
- buf[2] |= sample_rate << 2;
+ int2bytes(&buf[index], filesize - startpos);
+ index += 4;
}
-
+
+ /* Copy the TOC */
+ memcpy(buf + index, toc, 100);
+
+ /* And some extra cool info */
memcpy(buf + index + 100, cooltext, sizeof(cooltext));
- /* 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++)
+ for(i = 0;i < info.framesize;i++)
{
if(i && !(i % 16))
DEBUGF("\n");
diff --git a/firmware/mpeg.c b/firmware/mpeg.c
index 7e48040..11837d6 100644
--- a/firmware/mpeg.c
+++ b/firmware/mpeg.c
@@ -1266,6 +1266,7 @@ static void mpeg_thread(void)
int amount_to_save;
int writelen;
int framelen;
+ unsigned long saved_header;
#endif
is_playing = false;
@@ -1840,10 +1841,10 @@ static void mpeg_thread(void)
DEBUGF("Recording...\n");
reset_mp3_buffer();
- /* Advance the write pointer 4096+1500 bytes to make
+ /* Advance the write pointer to make
room for an ID3 tag plus a VBR header */
- mp3buf_write = 4096+1500;
- memset(mp3buf, 0, 4096+1500);
+ mp3buf_write = MPEG_RESERVED_HEADER_SPACE;
+ memset(mp3buf, 0, MPEG_RESERVED_HEADER_SPACE);
/* Insert the ID3 header */
memcpy(mp3buf, empty_id3_header, sizeof(empty_id3_header));
@@ -1883,14 +1884,17 @@ static void mpeg_thread(void)
we can no longer trust it */
if(num_recorded_frames == 0x7ffff)
num_recorded_frames = 0;
+
+ /* Read the first MP3 frame from the recorded stream */
+ lseek(mpeg_file, MPEG_RESERVED_HEADER_SPACE, SEEK_SET);
+ read(mpeg_file, &saved_header, 4);
framelen = create_xing_header(mpeg_file, 0, num_rec_bytes,
mp3buf, num_recorded_frames,
- rec_version_index,
- rec_frequency_index,
- NULL, false);
+ saved_header, NULL, false);
- lseek(mpeg_file, 4096+1500-framelen, SEEK_SET);
+ lseek(mpeg_file, MPEG_RESERVED_HEADER_SPACE-framelen,
+ SEEK_SET);
write(mpeg_file, mp3buf, framelen);
close(mpeg_file);
@@ -2823,7 +2827,8 @@ void mpeg_set_pitch(int pitch)
#ifdef HAVE_MAS3587F
void mpeg_set_recording_options(int frequency, int quality,
- int source, int channel_mode)
+ int source, int channel_mode,
+ bool editable)
{
bool is_mpeg1;
unsigned long val;
@@ -2844,6 +2849,11 @@ void mpeg_set_recording_options(int frequency, int quality,
DEBUGF("mas_writemem(MAS_BANK_D0, 0x7f0, %x)\n", val);
+ val = editable?4:0;
+ mas_writemem(MAS_BANK_D0, 0x7f9, &val,1);
+
+ DEBUGF("mas_writemem(MAS_BANK_D0, 0x7f9, %x)\n", val);
+
val = ((!is_recording << 10) | /* Monitoring */
((source < 2)?1:2) << 8) | /* Input select */
(1 << 5) | /* SDO strobe invert */