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.zip
rockbox-6475aa0c85fcca7a37a7aa4316173270fcb6d038.tar.gz
rockbox-6475aa0c85fcca7a37a7aa4316173270fcb6d038.tar.bz2
rockbox-6475aa0c85fcca7a37a7aa4316173270fcb6d038.tar.xz
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 8d92504..21f01ea 100644
--- a/firmware/mp3data.c
+++ b/firmware/mp3data.c
@@ -263,9 +263,7 @@ extern unsigned char mp3end[];
static int fnf_read_index;
static int fnf_buf_len;
-static int fd;
-
-static int buf_getbyte(unsigned char *c)
+static int buf_getbyte(int fd, unsigned char *c)
{
if(fnf_read_index < fnf_buf_len)
{
@@ -291,7 +289,7 @@ static int buf_getbyte(unsigned char *c)
return 0;
}
-static int buf_seek(int len)
+static int buf_seek(int fd, int len)
{
fnf_read_index += len;
if(fnf_read_index > fnf_buf_len)
@@ -320,7 +318,7 @@ static void buf_init(void)
fnf_read_index = 0;
}
-unsigned long buf_find_next_frame(int *offset, int max_offset,
+unsigned long buf_find_next_frame(int fd, int *offset, int max_offset,
unsigned long last_header)
{
unsigned long header=0;
@@ -336,7 +334,7 @@ unsigned long buf_find_next_frame(int *offset, int max_offset,
/* Fill up header with first 24 bits */
for(i = 0; i < 3; i++) {
header <<= 8;
- if(!buf_getbyte(&tmp))
+ if(!buf_getbyte(fd, &tmp))
return 0;
header |= tmp;
pos++;
@@ -344,7 +342,7 @@ unsigned long buf_find_next_frame(int *offset, int max_offset,
do {
header <<= 8;
- if(!buf_getbyte(&tmp))
+ if(!buf_getbyte(fd, &tmp))
return 0;
header |= tmp;
pos++;
@@ -413,7 +411,7 @@ int get_mp3file_info(int fd, struct mp3info *info)
DEBUGF("Xing header\n");
/* Remember where in the file the Xing header is */
- info->xing_header_pos = lseek(fd, 0, SEEK_CUR) - info->frame_size;
+ info->vbr_header_pos = lseek(fd, 0, SEEK_CUR) - info->frame_size;
/* We want to skip the Xing frame when playing the stream */
bytecount += info->frame_size;
@@ -423,7 +421,7 @@ int get_mp3file_info(int fd, struct mp3info *info)
header = find_next_frame(fd, &tmp, 0x20000, 0);
if(header == 0)
return -4;
-
+
if(!mp3headerinfo(info, header))
return -5;
@@ -443,10 +441,14 @@ int get_mp3file_info(int fd, struct mp3info *info)
{
info->byte_count = BYTES2INT(vbrheader[i], vbrheader[i+1],
vbrheader[i+2], vbrheader[i+3]);
- info->bitrate = info->byte_count * 8 / info->file_time;
i += 4;
}
+ if(info->file_time && info->byte_count)
+ info->bitrate = info->byte_count * 8 / info->file_time;
+ else
+ info->bitrate = 0;
+
if(vbrheader[7] & VBR_TOC_FLAG) /* Is table-of-contents there? */
{
memcpy( info->toc, vbrheader+i, 100 );
@@ -554,6 +556,8 @@ int count_mp3_frames(int fd, int startpos, int filesize,
int progress_chunk = filesize / 50; /* Max is 50%, in 1% increments */
int progress_cnt = 0;
+ /* Nasty stuff to avoid passing the file handle around */
+
if(lseek(fd, startpos, SEEK_SET) < 0)
return -1;
@@ -563,9 +567,9 @@ int count_mp3_frames(int fd, int startpos, int filesize,
num_frames = 0;
cnt = 0;
- while((header = buf_find_next_frame(&bytes, -1, header))) {
+ while((header = buf_find_next_frame(fd, &bytes, -1, header))) {
mp3headerinfo(&info, header);
- buf_seek(info.frame_size-4);
+ buf_seek(fd, info.frame_size-4);
num_frames++;
if(progressfunc)
{
@@ -585,7 +589,7 @@ int count_mp3_frames(int fd, int startpos, int filesize,
int create_xing_header(int fd, int startpos, int filesize,
unsigned char *buf, int num_frames,
- void (*progressfunc)(int))
+ void (*progressfunc)(int), bool generate_toc)
{
unsigned long header = 0;
struct mp3info info;
@@ -595,6 +599,7 @@ int create_xing_header(int fd, int startpos, int filesize,
int filepos;
int tocentry;
int x;
+ int index;
DEBUGF("create_xing_header()\n");
@@ -609,46 +614,61 @@ int create_xing_header(int fd, int startpos, int filesize,
buf[36+1] = 'i';
buf[36+2] = 'n';
buf[36+3] = 'g';
- int2bytes(&buf[36+4], (VBR_FRAMES_FLAG | VBR_BYTES_FLAG | VBR_TOC_FLAG));
- int2bytes(&buf[36+8], num_frames);
- int2bytes(&buf[36+12], filesize - startpos);
-
- /* Generate filepos table */
- last_pos = 0;
- filepos = 0;
- header = 0;
- x = 0;
- for(i = 0;i < 100;i++) {
- /* Calculate the absolute frame number for this seek point */
- pos = i * num_frames / 100;
-
- /* Advance from the last seek point to this one */
- for(j = 0;j < pos - last_pos;j++)
- {
- DEBUGF("fpos: %x frame no: %x ", filepos, x++);
- header = buf_find_next_frame(&bytes, -1, header);
- mp3headerinfo(&info, header);
- buf_seek(info.frame_size-4);
- filepos += info.frame_size;
- }
+ 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(progressfunc)
- {
- progressfunc(50 + i/2);
- }
-
- tocentry = filepos * 256 / filesize;
-
- DEBUGF("Pos %d: %d relpos: %d filepos: %x tocentry: %x\n",
- i, pos, pos-last_pos, filepos, tocentry);
+ if(filesize)
+ {
+ int2bytes(&buf[index], filesize - startpos);
+ index += 4;
+ }
- /* Fill in the TOC entry */
- buf[36+16+i] = tocentry;
-
- last_pos = pos;
+ if(generate_toc)
+ {
+ /* Generate filepos table */
+ last_pos = 0;
+ filepos = 0;
+ header = 0;
+ x = 0;
+ for(i = 0;i < 100;i++) {
+ /* Calculate the absolute frame number for this seek point */
+ pos = i * num_frames / 100;
+
+ /* Advance from the last seek point to this one */
+ for(j = 0;j < pos - last_pos;j++)
+ {
+ DEBUGF("fpos: %x frame no: %x ", filepos, x++);
+ header = buf_find_next_frame(fd, &bytes, -1, header);
+ mp3headerinfo(&info, header);
+ buf_seek(fd, info.frame_size-4);
+ filepos += info.frame_size;
+ }
+
+ if(progressfunc)
+ {
+ progressfunc(50 + i/2);
+ }
+
+ tocentry = 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;
+
+ last_pos = pos;
+ }
}
- memcpy(buf+152, cooltext, sizeof(cooltext));
+ memcpy(buf + index + 100, cooltext, sizeof(cooltext));
#ifdef DEBUG
for(i = 0;i < 417;i++)