summaryrefslogtreecommitdiff
path: root/apps/onplay.c
diff options
context:
space:
mode:
Diffstat (limited to 'apps/onplay.c')
-rw-r--r--apps/onplay.c253
1 files changed, 0 insertions, 253 deletions
diff --git a/apps/onplay.c b/apps/onplay.c
index d864b3b2a9..7873941af6 100644
--- a/apps/onplay.c
+++ b/apps/onplay.c
@@ -374,251 +374,6 @@ static bool rename_file(void)
374 return false; 374 return false;
375} 375}
376 376
377static void xingupdate(int percent)
378{
379 char buf[32];
380
381 snprintf(buf, 32, "%d%%", percent);
382 lcd_puts(0, 1, buf);
383 lcd_update();
384}
385
386
387static int insert_data_in_file(char *fname, int fpos, char *buf, int num_bytes)
388{
389 int readlen;
390 int rc;
391 int orig_fd, fd;
392 char tmpname[MAX_PATH];
393
394 talk_buffer_steal(); /* we use the mp3 buffer, need to tell */
395
396 snprintf(tmpname, MAX_PATH, "%s.tmp", fname);
397
398 orig_fd = open(fname, O_RDONLY);
399 if(orig_fd < 0) {
400 return 10*orig_fd - 1;
401 }
402
403 fd = creat(tmpname, O_WRONLY);
404 if(fd < 0) {
405 close(orig_fd);
406 return 10*fd - 2;
407 }
408
409 /* First, copy the initial portion (the ID3 tag) */
410 if(fpos) {
411 readlen = read(orig_fd, mp3buf, fpos);
412 if(readlen < 0) {
413 close(fd);
414 close(orig_fd);
415 return 10*readlen - 3;
416 }
417
418 rc = write(fd, mp3buf, readlen);
419 if(rc < 0) {
420 close(fd);
421 close(orig_fd);
422 return 10*rc - 4;
423 }
424 }
425
426 /* Now insert the data into the file */
427 rc = write(fd, buf, num_bytes);
428 if(rc < 0) {
429 close(orig_fd);
430 close(fd);
431 return 10*rc - 5;
432 }
433
434 /* Copy the file */
435 do {
436 readlen = read(orig_fd, mp3buf, mp3end - mp3buf);
437 if(readlen < 0) {
438 close(fd);
439 close(orig_fd);
440 return 10*readlen - 7;
441 }
442
443 rc = write(fd, mp3buf, readlen);
444 if(rc < 0) {
445 close(fd);
446 close(orig_fd);
447 return 10*rc - 8;
448 }
449 } while(readlen > 0);
450
451 close(fd);
452 close(orig_fd);
453
454 /* Remove the old file */
455 rc = remove(fname);
456 if(rc < 0) {
457 return 10*rc - 9;
458 }
459
460 /* Replace the old file with the new */
461 rc = rename(tmpname, fname);
462 if(rc < 0) {
463 return 10*rc - 9;
464 }
465
466 return 0;
467}
468
469static void fileerror(int rc)
470{
471 splash(HZ*2, true, "File error: %d", rc);
472}
473
474static const unsigned char empty_id3_header[] =
475{
476 'I', 'D', '3', 0x04, 0x00, 0x00,
477 0x00, 0x00, 0x1f, 0x76 /* Size is 4096 minus 10 bytes for the header */
478};
479
480static bool vbr_fix(void)
481{
482 unsigned char xingbuf[1500];
483 struct mp3entry entry;
484 int fd;
485 int rc;
486 int flen;
487 int num_frames;
488 int numbytes;
489 int framelen;
490 int unused_space;
491
492 if(mpeg_status()) {
493 splash(HZ*2, true, str(LANG_VBRFIX_STOP_PLAY));
494 return onplay_result;
495 }
496
497 talk_buffer_steal(); /* we use the mp3 buffer, need to tell */
498
499 lcd_clear_display();
500 lcd_puts_scroll(0, 0, selected_file);
501 lcd_update();
502
503 xingupdate(0);
504
505 rc = mp3info(&entry, selected_file);
506 if(rc < 0) {
507 fileerror(rc);
508 return true;
509 }
510
511 fd = open(selected_file, O_RDWR);
512 if(fd < 0) {
513 fileerror(fd);
514 return true;
515 }
516
517 flen = lseek(fd, 0, SEEK_END);
518
519 xingupdate(0);
520
521 num_frames = count_mp3_frames(fd, entry.first_frame_offset,
522 flen, xingupdate);
523
524 if(num_frames) {
525 /* Note: We don't need to pass a template header because it will be
526 taken from the mpeg stream */
527 framelen = create_xing_header(fd, entry.first_frame_offset,
528 flen, xingbuf, num_frames,
529 0, xingupdate, true);
530
531 /* Try to fit the Xing header first in the stream. Replace the existing
532 VBR header if there is one, else see if there is room between the
533 ID3 tag and the first MP3 frame. */
534 if(entry.first_frame_offset - entry.id3v2len >=
535 (unsigned int)framelen) {
536 DEBUGF("Using existing space between ID3 and first frame\n");
537
538 /* Seek to the beginning of the unused space */
539 rc = lseek(fd, entry.id3v2len, SEEK_SET);
540 if(rc < 0) {
541 close(fd);
542 fileerror(rc);
543 return true;
544 }
545
546 unused_space =
547 entry.first_frame_offset - entry.id3v2len - framelen;
548
549 /* Fill the unused space with 0's (using the MP3 buffer)
550 and write it to the file */
551 if(unused_space)
552 {
553 memset(mp3buf, 0, unused_space);
554 rc = write(fd, mp3buf, unused_space);
555 if(rc < 0) {
556 close(fd);
557 fileerror(rc);
558 return true;
559 }
560 }
561
562 /* Then write the Xing header */
563 rc = write(fd, xingbuf, framelen);
564 if(rc < 0) {
565 close(fd);
566 fileerror(rc);
567 return true;
568 }
569
570 close(fd);
571 } else {
572 /* If not, insert some space. If there is an ID3 tag in the
573 file we only insert just enough to squeeze the Xing header
574 in. If not, we insert an additional empty ID3 tag of 4K. */
575
576 close(fd);
577
578 /* Nasty trick alert! The insert_data_in_file() function
579 uses the MP3 buffer when copying the data. We assume
580 that the ID3 tag isn't longer than 1MB so the xing
581 buffer won't be overwritten. */
582
583 if(entry.first_frame_offset) {
584 DEBUGF("Inserting %d bytes\n", framelen);
585 numbytes = framelen;
586 } else {
587 DEBUGF("Inserting 4096+%d bytes\n", framelen);
588 numbytes = 4096 + framelen;
589
590 memset(mp3buf + 0x100000, 0, numbytes);
591
592 /* Insert the ID3 header */
593 memcpy(mp3buf + 0x100000, empty_id3_header,
594 sizeof(empty_id3_header));
595 }
596
597 /* Copy the Xing header */
598 memcpy(mp3buf + 0x100000 + numbytes - framelen, xingbuf, framelen);
599
600 rc = insert_data_in_file(selected_file,
601 entry.first_frame_offset,
602 mp3buf + 0x100000, numbytes);
603
604 if(rc < 0) {
605 fileerror(rc);
606 return true;
607 }
608 }
609
610 xingupdate(100);
611 }
612 else
613 {
614 /* Not a VBR file */
615 DEBUGF("Not a VBR file\n");
616 splash(HZ*2, true, str(LANG_VBRFIX_NOT_VBR));
617 }
618
619 return false;
620}
621
622bool create_dir(void) 377bool create_dir(void)
623{ 378{
624 char dirname[MAX_PATH]; 379 char dirname[MAX_PATH];
@@ -696,14 +451,6 @@ int onplay(char* file, int attr)
696 items[i].function = delete_dir; 451 items[i].function = delete_dir;
697 i++; 452 i++;
698 } 453 }
699
700 if ((attr & TREE_ATTR_MASK) == TREE_ATTR_MPA)
701 {
702 items[i].desc = str(LANG_VBRFIX);
703 items[i].voice_id = LANG_VBRFIX;
704 items[i].function = vbr_fix;
705 i++;
706 }
707 } 454 }
708 455
709 items[i].desc = str(LANG_CREATE_DIR); 456 items[i].desc = str(LANG_CREATE_DIR);