diff options
Diffstat (limited to 'apps/onplay.c')
-rw-r--r-- | apps/onplay.c | 113 |
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) | |||
117 | extern unsigned char mp3buf[]; | 117 | extern unsigned char mp3buf[]; |
118 | extern unsigned char mp3end[]; | 118 | extern unsigned char mp3end[]; |
119 | 119 | ||
120 | static int insert_space_in_file(char *fname, int fpos, int num_bytes) | 120 | static int insert_data_in_file(char *fname, int fpos, char *buf, int num_bytes) |
121 | { | 121 | { |
122 | int readlen; | 122 | int readlen; |
123 | int rc; | 123 | int rc; |
@@ -154,23 +154,14 @@ static int insert_space_in_file(char *fname, int fpos, int num_bytes) | |||
154 | } | 154 | } |
155 | } | 155 | } |
156 | 156 | ||
157 | /* Now insert some 0's in the file */ | 157 | /* Now insert the data into the file */ |
158 | memset(mp3buf, 0, num_bytes); | 158 | rc = write(fd, buf, num_bytes); |
159 | |||
160 | rc = write(fd, mp3buf, num_bytes); | ||
161 | if(rc < 0) { | 159 | if(rc < 0) { |
162 | close(orig_fd); | 160 | close(orig_fd); |
163 | close(fd); | 161 | close(fd); |
164 | return 10*rc - 5; | 162 | return 10*rc - 5; |
165 | } | 163 | } |
166 | 164 | ||
167 | rc = lseek(orig_fd, 0, SEEK_SET); | ||
168 | if(rc < 0) { | ||
169 | close(orig_fd); | ||
170 | close(fd); | ||
171 | return 10*rc - 6; | ||
172 | } | ||
173 | |||
174 | /* Copy the file */ | 165 | /* Copy the file */ |
175 | do { | 166 | do { |
176 | readlen = read(orig_fd, mp3buf, mp3end - mp3buf); | 167 | readlen = read(orig_fd, mp3buf, mp3end - mp3buf); |
@@ -211,6 +202,12 @@ static void fileerror(int rc) | |||
211 | splash(HZ*2, 0, true, "File error: %d", rc); | 202 | splash(HZ*2, 0, true, "File error: %d", rc); |
212 | } | 203 | } |
213 | 204 | ||
205 | static const unsigned char empty_id3_header[] = | ||
206 | { | ||
207 | 'I', 'D', '3', 0x04, 0x00, 0x00, | ||
208 | 0x00, 0x00, 0x1f, 0x76 /* Size is 4096 minus 10 bytes for the header */ | ||
209 | }; | ||
210 | |||
214 | static bool vbr_fix(void) | 211 | static bool vbr_fix(void) |
215 | { | 212 | { |
216 | unsigned char xingbuf[417]; | 213 | unsigned char xingbuf[417]; |
@@ -264,55 +261,81 @@ static bool vbr_fix(void) | |||
264 | fpos = entry.vbr_header_pos; | 261 | fpos = entry.vbr_header_pos; |
265 | 262 | ||
266 | DEBUGF("Reusing Xing header at %d\n", fpos); | 263 | DEBUGF("Reusing Xing header at %d\n", fpos); |
264 | |||
265 | rc = lseek(fd, entry.vbr_header_pos, SEEK_SET); | ||
266 | if(rc < 0) { | ||
267 | close(fd); | ||
268 | fileerror(rc); | ||
269 | return true; | ||
270 | } | ||
271 | |||
272 | rc = write(fd, xingbuf, 417); | ||
273 | if(rc < 0) { | ||
274 | close(fd); | ||
275 | fileerror(rc); | ||
276 | return true; | ||
277 | } | ||
278 | |||
279 | close(fd); | ||
267 | } else { | 280 | } else { |
268 | /* Any room between ID3 tag and first MP3 frame? */ | 281 | /* Any room between ID3 tag and first MP3 frame? */ |
269 | if(entry.first_frame_offset - entry.id3v2len > 417) { | 282 | if(entry.first_frame_offset - entry.id3v2len > 417) { |
270 | fpos = entry.first_frame_offset - 417; | 283 | DEBUGF("Using existing space between ID3 and first frame\n"); |
284 | rc = lseek(fd, entry.first_frame_offset - 417, SEEK_SET); | ||
285 | if(rc < 0) { | ||
286 | close(fd); | ||
287 | fileerror(rc); | ||
288 | return true; | ||
289 | } | ||
290 | |||
291 | rc = write(fd, xingbuf, 417); | ||
292 | if(rc < 0) { | ||
293 | close(fd); | ||
294 | fileerror(rc); | ||
295 | return true; | ||
296 | } | ||
297 | |||
298 | close(fd); | ||
271 | } else { | 299 | } else { |
272 | /* If not, insert some space. If there is an ID3 tag in the | 300 | /* If not, insert some space. If there is an ID3 tag in the |
273 | file we only insert just enough to squeeze the Xing header | 301 | file we only insert just enough to squeeze the Xing header |
274 | in. If not, we insert 4K. */ | 302 | in. If not, we insert an additional empty ID3 tag of 4K. */ |
303 | |||
275 | close(fd); | 304 | close(fd); |
276 | if(entry.first_frame_offset) | 305 | |
306 | /* Nasty trick alert! The insert_data_in_file() function | ||
307 | uses the MP3 buffer when copying the data. We assume | ||
308 | that the ID3 tag isn't longer than 1MB so the xing | ||
309 | buffer won't be overwritten. */ | ||
310 | |||
311 | if(entry.first_frame_offset) { | ||
312 | DEBUGF("Inserting 417 bytes\n"); | ||
277 | numbytes = 417; | 313 | numbytes = 417; |
278 | else | 314 | } else { |
279 | numbytes = 4096; | 315 | DEBUGF("Inserting 4096+417 bytes\n"); |
316 | numbytes = 4096 + 417; | ||
317 | |||
318 | memset(mp3buf + 0x100000, 0, numbytes); | ||
319 | |||
320 | /* Insert the ID3 header */ | ||
321 | memcpy(mp3buf + 0x100000, empty_id3_header, | ||
322 | sizeof(empty_id3_header)); | ||
323 | } | ||
324 | |||
325 | /* Copy the Xing header */ | ||
326 | memcpy(mp3buf + 0x100000 + numbytes - 417, xingbuf, 417); | ||
280 | 327 | ||
281 | rc = insert_space_in_file(selected_file, | 328 | rc = insert_data_in_file(selected_file, |
282 | entry.first_frame_offset, numbytes); | 329 | entry.first_frame_offset, |
330 | mp3buf + 0x100000, numbytes); | ||
283 | 331 | ||
284 | if(rc < 0) { | 332 | if(rc < 0) { |
285 | fileerror(rc); | 333 | fileerror(rc); |
286 | return true; | 334 | return true; |
287 | } | 335 | } |
288 | |||
289 | /* Reopen the file */ | ||
290 | fd = open(selected_file, O_RDWR); | ||
291 | if(fd < 0) { | ||
292 | splash(HZ*2, 0, true, "File reopen error: %d", fd); | ||
293 | return true; | ||
294 | } | ||
295 | |||
296 | fpos = numbytes - 417; | ||
297 | } | 336 | } |
298 | } | 337 | } |
299 | 338 | ||
300 | rc = lseek(fd, fpos, SEEK_SET); | ||
301 | if(rc < 0) { | ||
302 | close(fd); | ||
303 | fileerror(rc); | ||
304 | return true; | ||
305 | } | ||
306 | |||
307 | rc = write(fd, xingbuf, 417); | ||
308 | if(rc < 0) { | ||
309 | close(fd); | ||
310 | fileerror(rc); | ||
311 | return true; | ||
312 | } | ||
313 | |||
314 | close(fd); | ||
315 | |||
316 | xingupdate(100); | 339 | xingupdate(100); |
317 | } | 340 | } |
318 | else | 341 | else |
@@ -352,7 +375,7 @@ int onplay(char* file, int attr) | |||
352 | 375 | ||
353 | if (attr & TREE_ATTR_MPA) | 376 | if (attr & TREE_ATTR_MPA) |
354 | { | 377 | { |
355 | menu[i].desc = "VBRfix"; | 378 | menu[i].desc = str(LANG_VBRFIX); |
356 | menu[i].function = vbr_fix; | 379 | menu[i].function = vbr_fix; |
357 | i++; | 380 | i++; |
358 | } | 381 | } |