summaryrefslogtreecommitdiff
path: root/firmware
diff options
context:
space:
mode:
Diffstat (limited to 'firmware')
-rw-r--r--firmware/id3.c2
-rw-r--r--firmware/mp3data.c22
-rw-r--r--firmware/mpeg.c67
3 files changed, 56 insertions, 35 deletions
diff --git a/firmware/id3.c b/firmware/id3.c
index ab638807c3..96b660658d 100644
--- a/firmware/id3.c
+++ b/firmware/id3.c
@@ -497,7 +497,7 @@ static int getsonglength(int fd, struct mp3entry *entry)
497 entry->has_toc = info.has_toc; 497 entry->has_toc = info.has_toc;
498 memcpy(entry->toc, info.toc, sizeof(info.toc)); 498 memcpy(entry->toc, info.toc, sizeof(info.toc));
499 499
500 entry->xing_header_pos = info.xing_header_pos; 500 entry->vbr_header_pos = info.vbr_header_pos;
501 501
502 /* Update the seek point for the first playable frame */ 502 /* Update the seek point for the first playable frame */
503 entry->first_frame_offset = bytecount; 503 entry->first_frame_offset = bytecount;
diff --git a/firmware/mp3data.c b/firmware/mp3data.c
index 21f01ea19e..f38b51c8f4 100644
--- a/firmware/mp3data.c
+++ b/firmware/mp3data.c
@@ -555,9 +555,9 @@ int count_mp3_frames(int fd, int startpos, int filesize,
555 int cnt; 555 int cnt;
556 int progress_chunk = filesize / 50; /* Max is 50%, in 1% increments */ 556 int progress_chunk = filesize / 50; /* Max is 50%, in 1% increments */
557 int progress_cnt = 0; 557 int progress_cnt = 0;
558 bool is_vbr = false;
559 int last_bitrate = 0;
558 560
559 /* Nasty stuff to avoid passing the file handle around */
560
561 if(lseek(fd, startpos, SEEK_SET) < 0) 561 if(lseek(fd, startpos, SEEK_SET) < 0)
562 return -1; 562 return -1;
563 563
@@ -569,6 +569,14 @@ int count_mp3_frames(int fd, int startpos, int filesize,
569 569
570 while((header = buf_find_next_frame(fd, &bytes, -1, header))) { 570 while((header = buf_find_next_frame(fd, &bytes, -1, header))) {
571 mp3headerinfo(&info, header); 571 mp3headerinfo(&info, header);
572
573 /* See if this really is a VBR file */
574 if(last_bitrate && info.bitrate != last_bitrate)
575 {
576 is_vbr = true;
577 }
578 last_bitrate = info.bitrate;
579
572 buf_seek(fd, info.frame_size-4); 580 buf_seek(fd, info.frame_size-4);
573 num_frames++; 581 num_frames++;
574 if(progressfunc) 582 if(progressfunc)
@@ -583,8 +591,14 @@ int count_mp3_frames(int fd, int startpos, int filesize,
583 } 591 }
584 } 592 }
585 DEBUGF("Total number of frames: %d\n", num_frames); 593 DEBUGF("Total number of frames: %d\n", num_frames);
586 594
587 return num_frames; 595 if(is_vbr)
596 return num_frames;
597 else
598 {
599 DEBUGF("Not a VBR file\n");
600 return 0;
601 }
588} 602}
589 603
590int create_xing_header(int fd, int startpos, int filesize, 604int create_xing_header(int fd, int startpos, int filesize,
diff --git a/firmware/mpeg.c b/firmware/mpeg.c
index 13c4b01b8a..9528ede0ec 100644
--- a/firmware/mpeg.c
+++ b/firmware/mpeg.c
@@ -3030,42 +3030,49 @@ int mpeg_create_xing_header(char *filename, void (*progressfunc)(int))
3030 progressfunc(0); 3030 progressfunc(0);
3031 3031
3032 num_frames = count_mp3_frames(fd, entry.first_frame_offset, 3032 num_frames = count_mp3_frames(fd, entry.first_frame_offset,
3033 flen, 3033 flen, progressfunc);
3034 progressfunc);
3035 3034
3036 create_xing_header(fd, entry.first_frame_offset, 3035 if(num_frames)
3037 flen, xingbuf, num_frames, progressfunc, true);
3038
3039 /* Try to fit the Xing header first in the stream. Replace the existing
3040 Xing header if there is one, else see if there is room between the
3041 ID3 tag and the first MP3 frame. */
3042 if(entry.vbr_header_pos)
3043 {
3044 /* Reuse existing Xing header */
3045 fpos = entry.vbr_header_pos;
3046
3047 DEBUGF("Reusing Xing header at %d\n", fpos);
3048 }
3049 else
3050 { 3036 {
3051 /* Any room between ID3 tag and first MP3 frame? */ 3037 create_xing_header(fd, entry.first_frame_offset,
3052 if(entry.first_frame_offset - entry.id3v2len > 417) 3038 flen, xingbuf, num_frames, progressfunc, true);
3039
3040 /* Try to fit the Xing header first in the stream. Replace the existing
3041 Xing header if there is one, else see if there is room between the
3042 ID3 tag and the first MP3 frame. */
3043 if(entry.vbr_header_pos)
3053 { 3044 {
3054 fpos = entry.first_frame_offset - 417; 3045 /* Reuse existing Xing header */
3046 fpos = entry.vbr_header_pos;
3047
3048 DEBUGF("Reusing Xing header at %d\n", fpos);
3055 } 3049 }
3056 else 3050 else
3057 { 3051 {
3058 close(fd); 3052 /* Any room between ID3 tag and first MP3 frame? */
3059 return -3; 3053 if(entry.first_frame_offset - entry.id3v2len > 417)
3054 {
3055 fpos = entry.first_frame_offset - 417;
3056 }
3057 else
3058 {
3059 close(fd);
3060 return -3;
3061 }
3060 } 3062 }
3063
3064 lseek(fd, fpos, SEEK_SET);
3065 write(fd, xingbuf, 417);
3066 close(fd);
3067
3068 if(progressfunc)
3069 progressfunc(100);
3070 return 0;
3071 }
3072 else
3073 {
3074 /* Not a VBR file */
3075 DEBUGF("Not a VBR file\n");
3076 return -9;
3061 } 3077 }
3062
3063 lseek(fd, fpos, SEEK_SET);
3064 write(fd, xingbuf, 417);
3065 close(fd);
3066
3067 if(progressfunc)
3068 progressfunc(100);
3069
3070 return 0;
3071} 3078}