summaryrefslogtreecommitdiffstats
path: root/apps
diff options
context:
space:
mode:
authorLinus Nielsen Feltzing <linus@haxx.se>2003-04-13 15:01:44 +0000
committerLinus Nielsen Feltzing <linus@haxx.se>2003-04-13 15:01:44 +0000
commit1793634a9bbb85b9c1997c65b66fe17f00b51695 (patch)
tree6629762b58cad47590eec8511a3dc3832e8a4549 /apps
parentb5401749cb413a644d7d787e804506b71e7898e1 (diff)
downloadrockbox-1793634a9bbb85b9c1997c65b66fe17f00b51695.tar.gz
rockbox-1793634a9bbb85b9c1997c65b66fe17f00b51695.zip
VBRFix should now work on all VBR files, with or without Xing headers and ID3 tags
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@3545 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'apps')
-rw-r--r--apps/onplay.c113
1 files changed, 68 insertions, 45 deletions
diff --git a/apps/onplay.c b/apps/onplay.c
index fb9d940bf3..ceaae2c238 100644
--- a/apps/onplay.c
+++ b/apps/onplay.c
@@ -117,7 +117,7 @@ static void xingupdate(int percent)
extern unsigned char mp3buf[];
extern unsigned char mp3end[];
-static int insert_space_in_file(char *fname, int fpos, int num_bytes)
+static int insert_data_in_file(char *fname, int fpos, char *buf, int num_bytes)
{
int readlen;
int rc;
@@ -154,23 +154,14 @@ static int insert_space_in_file(char *fname, int fpos, int num_bytes)
}
}
- /* Now insert some 0's in the file */
- memset(mp3buf, 0, num_bytes);
-
- rc = write(fd, mp3buf, num_bytes);
+ /* Now insert the data into the file */
+ rc = write(fd, buf, num_bytes);
if(rc < 0) {
close(orig_fd);
close(fd);
return 10*rc - 5;
}
- rc = lseek(orig_fd, 0, SEEK_SET);
- if(rc < 0) {
- close(orig_fd);
- close(fd);
- return 10*rc - 6;
- }
-
/* Copy the file */
do {
readlen = read(orig_fd, mp3buf, mp3end - mp3buf);
@@ -211,6 +202,12 @@ static void fileerror(int rc)
splash(HZ*2, 0, true, "File error: %d", rc);
}
+static const unsigned char empty_id3_header[] =
+{
+ 'I', 'D', '3', 0x04, 0x00, 0x00,
+ 0x00, 0x00, 0x1f, 0x76 /* Size is 4096 minus 10 bytes for the header */
+};
+
static bool vbr_fix(void)
{
unsigned char xingbuf[417];
@@ -264,55 +261,81 @@ static bool vbr_fix(void)
fpos = entry.vbr_header_pos;
DEBUGF("Reusing Xing header at %d\n", fpos);
+
+ rc = lseek(fd, entry.vbr_header_pos, SEEK_SET);
+ if(rc < 0) {
+ close(fd);
+ fileerror(rc);
+ return true;
+ }
+
+ rc = write(fd, xingbuf, 417);
+ if(rc < 0) {
+ close(fd);
+ fileerror(rc);
+ return true;
+ }
+
+ close(fd);
} else {
/* Any room between ID3 tag and first MP3 frame? */
if(entry.first_frame_offset - entry.id3v2len > 417) {
- fpos = entry.first_frame_offset - 417;
+ DEBUGF("Using existing space between ID3 and first frame\n");
+ rc = lseek(fd, entry.first_frame_offset - 417, SEEK_SET);
+ if(rc < 0) {
+ close(fd);
+ fileerror(rc);
+ return true;
+ }
+
+ rc = write(fd, xingbuf, 417);
+ if(rc < 0) {
+ close(fd);
+ fileerror(rc);
+ return true;
+ }
+
+ close(fd);
} else {
/* If not, insert some space. If there is an ID3 tag in the
file we only insert just enough to squeeze the Xing header
- in. If not, we insert 4K. */
+ in. If not, we insert an additional empty ID3 tag of 4K. */
+
close(fd);
- if(entry.first_frame_offset)
+
+ /* Nasty trick alert! The insert_data_in_file() function
+ uses the MP3 buffer when copying the data. We assume
+ that the ID3 tag isn't longer than 1MB so the xing
+ buffer won't be overwritten. */
+
+ if(entry.first_frame_offset) {
+ DEBUGF("Inserting 417 bytes\n");
numbytes = 417;
- else
- numbytes = 4096;
+ } else {
+ DEBUGF("Inserting 4096+417 bytes\n");
+ numbytes = 4096 + 417;
+
+ memset(mp3buf + 0x100000, 0, numbytes);
+
+ /* Insert the ID3 header */
+ memcpy(mp3buf + 0x100000, empty_id3_header,
+ sizeof(empty_id3_header));
+ }
+
+ /* Copy the Xing header */
+ memcpy(mp3buf + 0x100000 + numbytes - 417, xingbuf, 417);
- rc = insert_space_in_file(selected_file,
- entry.first_frame_offset, numbytes);
+ rc = insert_data_in_file(selected_file,
+ entry.first_frame_offset,
+ mp3buf + 0x100000, numbytes);
if(rc < 0) {
fileerror(rc);
return true;
}
-
- /* Reopen the file */
- fd = open(selected_file, O_RDWR);
- if(fd < 0) {
- splash(HZ*2, 0, true, "File reopen error: %d", fd);
- return true;
- }
-
- fpos = numbytes - 417;
}
}
- rc = lseek(fd, fpos, SEEK_SET);
- if(rc < 0) {
- close(fd);
- fileerror(rc);
- return true;
- }
-
- rc = write(fd, xingbuf, 417);
- if(rc < 0) {
- close(fd);
- fileerror(rc);
- return true;
- }
-
- close(fd);
-
xingupdate(100);
}
else
@@ -352,7 +375,7 @@ int onplay(char* file, int attr)
if (attr & TREE_ATTR_MPA)
{
- menu[i].desc = "VBRfix";
+ menu[i].desc = str(LANG_VBRFIX);
menu[i].function = vbr_fix;
i++;
}