summaryrefslogtreecommitdiff
path: root/firmware/mp3data.c
diff options
context:
space:
mode:
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 8d925041ce..21f01ea19e 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++)