summaryrefslogtreecommitdiffstats
path: root/apps/plugins/splitedit.c
diff options
context:
space:
mode:
Diffstat (limited to 'apps/plugins/splitedit.c')
-rw-r--r--apps/plugins/splitedit.c1231
1 files changed, 0 insertions, 1231 deletions
diff --git a/apps/plugins/splitedit.c b/apps/plugins/splitedit.c
deleted file mode 100644
index b698e2e18a..0000000000
--- a/apps/plugins/splitedit.c
+++ /dev/null
@@ -1,1231 +0,0 @@
-/***************************************************************************
- * __________ __ ___.
- * Open \______ \ ____ ____ | | _\_ |__ _______ ___
- * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
- * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
- * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
- * \/ \/ \/ \/ \/
- * $Id$
- *
- * Copyright (C) 2002 Philipp Pertermann
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- * KIND, either express or implied.
- *
- ****************************************************************************/
-
-#include "plugin.h"
-
-
-
-/* variable button definitions */
-#if CONFIG_KEYPAD == IRIVER_H100_PAD
-#define SPLITEDIT_QUIT BUTTON_OFF
-#define SPLITEDIT_PLAY BUTTON_ON
-#define SPLITEDIT_SAVE BUTTON_SELECT
-#define SPLITEDIT_LOOP_MODE BUTTON_MODE
-#define SPLITEDIT_SCALE (BUTTON_REC | BUTTON_UP)
-#define SPLITEDIT_SPEED50 (BUTTON_REC | BUTTON_LEFT)
-#define SPLITEDIT_SPEED100 (BUTTON_REC | BUTTON_DOWN)
-#define SPLITEDIT_SPEED150 (BUTTON_REC | BUTTON_RIGHT)
-#define SPLITEDIT_MENU_RUN BUTTON_RIGHT
-
-#elif (CONFIG_KEYPAD == SAMSUNG_YH820_PAD) || \
- (CONFIG_KEYPAD == SAMSUNG_YH92X_PAD)
-#define SPLITEDIT_QUIT (BUTTON_REC | BUTTON_REW)
-#define SPLITEDIT_PLAY (BUTTON_REC | BUTTON_FFWD)
-#define SPLITEDIT_SAVE BUTTON_FFWD
-#define SPLITEDIT_LOOP_MODE BUTTON_REW
-#define SPLITEDIT_SCALE BUTTON_UP
-#define SPLITEDIT_SPEED50 BUTTON_LEFT
-#define SPLITEDIT_SPEED100 BUTTON_DOWN
-#define SPLITEDIT_SPEED150 BUTTON_RIGHT
-#define SPLITEDIT_MENU_RUN BUTTON_PLAY
-
-#define SPLITEDIT_RC_QUIT BUTTON_RC_STOP
-#endif
-
-#define BMPHEIGHT 7
-#define BMPWIDTH 13
-unsigned char LOOP_BMP[][13] =
-{
- {0xfc,0x00,0x10,0x11,0x93,0x7f,0x13,0x11,0x7c,0x38,0x10,0x00,0x7c}, /*ALL */
- {0x81,0x03,0x7f,0x03,0x91,0x10,0x10,0x10,0x7c,0x38,0x10,0x00,0x7c}, /*FROM*/
- {0xfc,0x00,0x10,0x10,0x90,0x10,0x7c,0x38,0x11,0x03,0x7f,0x03,0x01}, /*TO */
- {0x80,0x10,0x10,0x11,0x93,0x7f,0x13,0x11,0x10,0x7c,0x38,0x10,0x00}, /*FREE*/
-};
-
-unsigned char CUT_BMP[] =
-{
- 0xc1,0x63,0x63,0x36,0xb6,0x1c,0x1c,0x36,0x77,0x55,0x55,0x55,0x32,
-};
-
-unsigned char SCALE_BMP[][13] =
-{
- {0x80,0x06,0x49,0x66,0xb0,0x18,0x0c,0x06,0x33,0x49,0x30,0x00,0x00}, /*lin*/
- {0x80,0x30,0x78,0x48,0xff,0x7f,0x00,0x7f,0x7f,0x48,0x78,0x30,0x00}, /*db*/
-};
-
-#define TIMEBAR_Y 9
-#define TIMEBAR_HEIGHT 4
-
-#define OSCI_X 0
-#define OSCI_Y (TIMEBAR_Y + TIMEBAR_HEIGHT + 1)
-#define OSCI_WIDTH LCD_WIDTH
-#define OSCI_HEIGHT (LCD_HEIGHT - BMPHEIGHT - OSCI_Y - 1)
-
-/* Indices of the menu items in the save editor, see save_editor */
-#define SE_PART1_SAVE 0
-#define SE_PART1_NAME 1
-#define SE_PART2_SAVE 2
-#define SE_PART2_NAME 3
-#define SE_SAVE 4
-#define SE_COUNT 5
-
-/* contains the file name of the song that is to be split */
-static char path_mp3[MAX_PATH];
-
-/* Exit code of this plugin */
-static enum plugin_status splitedit_exit_code = PLUGIN_OK;
-
-/* The range in time that the displayed aerea comprises */
-static unsigned int range_start = 0;
-static unsigned int range_end = 0;
-
-/* The range in time that is being looped */
-static unsigned int play_start = 0;
-static unsigned int play_end = 0;
-
-/* Point in time (pixel) at which the split mark is set */
-static int split_x = OSCI_X + (OSCI_WIDTH / 2);
-
-/* Contains the peak values */
-static unsigned char osci_buffer[OSCI_WIDTH];
-
-/* if true peak values from a previous loop are only overwritten
- if the new value is greater than the old value */
-static bool osci_valid = false;
-
-/**
- * point in time from which on the osci_buffer is invalid
- * if set to ~(unsigned int)0 the entire osci_buffer is invalid
- */
-static unsigned int validation_start = ~(unsigned int)0;
-
-/* all the visible aerea is looped */
-#define LOOP_MODE_ALL 0
-
-/* loop starts at split point, ends at right visible border */
-#define LOOP_MODE_FROM 1
-
-/* loop start at left visible border, ends at split point */
-#define LOOP_MODE_TO 2
-
-/* let the song play without looping */
-#define LOOP_MODE_FREE 3
-
-/* see LOOP_MODE_XXX constants vor valid values */
-static int loop_mode = LOOP_MODE_FREE;
-
-/* minimal allowed timespan (ms) of the visible (and looped) aerea*/
-#define MIN_RANGE_SIZE 1000
-
-/* Format time into buf.
- *
- * buf - buffer to format to.
- * buf_size - size of buffer.
- * time - time to format, in milliseconds.
- */
-static void format_time_ms(char* buf, int buf_size, int time)
-{
- rb->snprintf(buf, buf_size, "%d:%02d:%03d", time / 60000,
- time % 60000 / 1000, (time % 60000) % 1000);
-}
-
-/**
- * converts screen coordinate (pixel) to time (ms)
- */
-static int xpos_to_time(int xpos)
-{
- int retval = 0;
- int range = range_end - range_start;
- retval = range_start + (((xpos - OSCI_X) * range) / OSCI_WIDTH);
- return retval;
-}
-
-/**
- * Converts time (ms) to screen coordinates (pixel).
- */
-static int time_to_xpos(unsigned int time)
-{
- int retval = OSCI_X;
-
- /* clip the range */
- if (time < range_start)
- {
- retval = OSCI_X;
- }
- else
- if (time >= range_end)
- {
- retval = OSCI_X + OSCI_WIDTH;
- }
-
- /* do the calculation */
- else
- {
- int range = range_end - range_start;
- retval = OSCI_X + ((time - range_start) * OSCI_WIDTH) / range ;
- }
- return retval;
-}
-
-/**
- * Updates the display of the textual data only.
- */
-static void update_data(void)
-{
- char buf[20];
- char timebuf[10];
- int w, h;
-
- /* split point */
- format_time_ms(timebuf, sizeof timebuf, xpos_to_time(split_x));
- rb->snprintf(buf, sizeof buf, "Split at: %s", timebuf);
-
- rb->lcd_getstringsize(buf, &w, &h);
-
- rb->lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID);
- rb->lcd_fillrect(0, 0, LCD_WIDTH, h);
- rb->lcd_set_drawmode(DRMODE_SOLID);
- rb->lcd_puts(0, 0, buf);
- rb->lcd_update_rect(0, 0, LCD_WIDTH, h);
-}
-
-/**
- * Displays which part of the song is visible
- * in the osci.
- */
-static void update_timebar(struct mp3entry *mp3)
-{
- rb->gui_scrollbar_draw
- (
- rb->screens[SCREEN_MAIN],0, TIMEBAR_Y, LCD_WIDTH, TIMEBAR_HEIGHT,
- mp3->length, range_start, range_end,
- HORIZONTAL
- );
- rb->lcd_update_rect(0, TIMEBAR_Y, LCD_WIDTH, TIMEBAR_HEIGHT);
-}
-
-/**
- * Marks the entire area of the osci buffer invalid.
- * It will be drawn with new values in the next loop.
- */
-static void splitedit_invalidate_osci(void)
-{
- osci_valid = false;
- validation_start = ~(unsigned int)0;
-}
-
-/**
- * Returns the loop mode. See the LOOP_MODE_XXX constants above.
- */
-static int splitedit_get_loop_mode(void)
-{
- return loop_mode;
-}
-
-/**
- * Updates the icons that display the Fn key hints.
- */
-static void update_icons(void)
-{
- rb->lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID);
- rb->lcd_fillrect(0, LCD_HEIGHT - BMPHEIGHT, LCD_WIDTH, BMPHEIGHT);
- rb->lcd_set_drawmode(DRMODE_SOLID);
-
- /* The CUT icon */
- rb->lcd_mono_bitmap(CUT_BMP,
- LCD_WIDTH / 3 / 2 - BMPWIDTH / 2, LCD_HEIGHT - BMPHEIGHT,
- BMPWIDTH, BMPHEIGHT);
-
- /* The loop mode icon */
- rb->lcd_mono_bitmap(LOOP_BMP[splitedit_get_loop_mode()],
- LCD_WIDTH/3 + LCD_WIDTH/3 / 2 - BMPWIDTH/2, LCD_HEIGHT - BMPHEIGHT,
- BMPWIDTH, BMPHEIGHT);
-
- {
- static int idx;
- if (idx < 0 || idx > 1) idx = 0;
- idx = 1 - idx;
- rb->lcd_mono_bitmap(SCALE_BMP[idx],
- 2 *LCD_WIDTH/3 + LCD_WIDTH/3 / 2 - BMPWIDTH/2, LCD_HEIGHT - BMPHEIGHT,
- BMPWIDTH, BMPHEIGHT);
- }
-
- rb->lcd_update_rect(0, LCD_HEIGHT - BMPHEIGHT, LCD_WIDTH, BMPHEIGHT);
-}
-
-/**
- * Sets the loop mode. See the LOOP_MODE_XXX constants above.
- */
-static void splitedit_set_loop_mode(int mode)
-{
- int old_loop_mode = loop_mode;
- /* range restriction */
- loop_mode = mode % (LOOP_MODE_FREE + 1);
- switch (loop_mode)
- {
- case LOOP_MODE_ALL:
- play_start = range_start;
- play_end = range_end;
- break;
-
- case LOOP_MODE_FROM:
- play_start = xpos_to_time(split_x);
- play_end = range_end;
- break;
-
- case LOOP_MODE_TO:
- play_start = range_start;
- play_end = xpos_to_time(split_x);
- break;
-
- case LOOP_MODE_FREE:
- /* play_start is used when the song plays beyond its end */
- play_start = range_start;
- play_end = range_end;
- break;
- }
-
- if (loop_mode != old_loop_mode)
- {
- update_icons();
- }
-}
-
-/**
- * Readraws the osci without clear.
- */
-static void redraw_osci(void)
-{
- int x;
- for (x = 0; x < OSCI_WIDTH; x++)
- {
- if (osci_buffer[x] > 0)
- {
- rb->lcd_vline
- (
- OSCI_X + x, OSCI_Y + OSCI_HEIGHT - 1,
- OSCI_Y + OSCI_HEIGHT - osci_buffer[x] - 1
- );
- }
- }
-}
-
-/**
- * Sets the range of time in which the user can finetune the split
- * point. The split point is the center of the time range.
- */
-static void set_range_by_time(
- struct mp3entry *mp3,
- unsigned int split_time,
- unsigned int range)
-{
- if (mp3 != NULL)
- {
- if (range < MIN_RANGE_SIZE)
- {
- range = MIN_RANGE_SIZE;
- }
- range_start = (split_time > range / 2) ? (split_time - range / 2) : 0;
- range_end = MIN(range_start + range, mp3->length);
- split_x = time_to_xpos(split_time);
-
- splitedit_invalidate_osci();
-
- /* this sets the play_start / play_end */
- splitedit_set_loop_mode(splitedit_get_loop_mode());
-
- update_data();
- update_timebar(mp3);
- }
-}
-
-/**
- * Set the split point in screen coordinates
- */
-static void splitedit_set_split_x(int newx)
-{
- int minx = split_x - 2 > 0 ? split_x - 2: 0;
-
- /* remove old split point from screen, only if moved */
- if (split_x != newx)
- {
- rb->lcd_set_drawmode(DRMODE_COMPLEMENT);
- rb->lcd_fillrect(minx, OSCI_Y, 5, 1);
- rb->lcd_fillrect(split_x-1 > 0 ? split_x - 1: 0, OSCI_Y + 1, 3, 1);
- rb->lcd_fillrect(split_x, OSCI_Y + 2, 1, OSCI_HEIGHT - 2);
- rb->lcd_set_drawmode(DRMODE_SOLID);
- rb->lcd_update_rect(minx, OSCI_Y, 5, OSCI_HEIGHT);
- }
-
- if (newx >= OSCI_X && newx < OSCI_X + OSCI_WIDTH)
- {
- split_x = newx;
- /* in LOOP_FROM / LOOP_TO modes play_start /play_end must be updated */
- splitedit_set_loop_mode(splitedit_get_loop_mode());
-
- /* display new split time */
- update_data();
- }
-
- /* display new split point */
- minx = split_x - 2 > 0 ? split_x - 2: 0;
- rb->lcd_set_drawmode(DRMODE_COMPLEMENT);
- rb->lcd_fillrect(minx, OSCI_Y, 5, 1);
- rb->lcd_fillrect(split_x - 1 > 0 ? split_x - 1: 0, OSCI_Y + 1, 3, 1);
- rb->lcd_fillrect(split_x, OSCI_Y + 2, 1, OSCI_HEIGHT - 2);
- rb->lcd_set_drawmode(DRMODE_SOLID);
- rb->lcd_update_rect(minx, OSCI_Y, 5, OSCI_HEIGHT);
-}
-
-/**
- * returns the split point in screen coordinates
- */
-static int splitedit_get_split_x(void)
-{
- return split_x;
-}
-
-/**
- * Clears the osci area and redraws it
- */
-static void update_osci(void)
-{
- rb->lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID);
- rb->lcd_fillrect(OSCI_X, OSCI_Y, OSCI_WIDTH, OSCI_HEIGHT);
- rb->lcd_set_drawmode(DRMODE_SOLID);
- redraw_osci();
- splitedit_set_split_x(splitedit_get_split_x());
- rb->lcd_update_rect(OSCI_X, OSCI_Y, OSCI_WIDTH, OSCI_HEIGHT);
-}
-
-/**
- * Zooms the visable and loopable range by the factor
- * (counter / denominator). The split point is used as
- * center point of the new selected range.
- */
-static void zoom(struct mp3entry *mp3, int counter, int denominator)
-{
- unsigned char oldbuf[OSCI_WIDTH];
- int oldrange = range_end - range_start;
- int range = oldrange * counter / denominator;
- int i;
- int oldindex;
- int oldsplitx;
- int splitx;
- int split;
-
- /* for stretching / shrinking a second buffer is needed */
- rb->memcpy(&oldbuf, &osci_buffer, sizeof osci_buffer);
-
- /* recalculate the new range and split point */
- oldsplitx = split_x;
- split = xpos_to_time(split_x);
-
- set_range_by_time(mp3, split, range);
- range = range_end - range_start;
-
- splitx = time_to_xpos(split);
-
- /* strech / shrink the existing osci buffer */
- for (i = 0; i < OSCI_WIDTH; i++)
- {
- /* oldindex = (i + OSCI_X - splitx) * range / oldrange + oldsplitx ;*/
- oldindex = (i*range / oldrange) + oldsplitx - (splitx*range /oldrange);
- if (oldindex >= 0 && oldindex < OSCI_WIDTH)
- {
- osci_buffer[i] = oldbuf[oldindex];
- }
- else
- {
- osci_buffer[i] = 0;
- }
- }
-
- splitx = time_to_xpos(split);
- splitedit_set_split_x(splitx);
- splitedit_invalidate_osci();
-
-}
-
-static void scroll(struct mp3entry *mp3)
-{
- zoom(mp3, 1, 1);
- rb->lcd_update_rect(OSCI_X, OSCI_Y, LCD_WIDTH, OSCI_HEIGHT);
- update_osci();
- update_data();
-}
-
-/**
- * Zooms in by 3/4
- */
-static void splitedit_zoom_in(struct mp3entry *mp3)
-{
- rb->lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID);
- rb->lcd_fillrect(OSCI_X, OSCI_Y, OSCI_WIDTH, OSCI_HEIGHT);
- rb->lcd_set_drawmode(DRMODE_SOLID);
- zoom(mp3, 3, 4);
- rb->lcd_update_rect(OSCI_X, OSCI_Y, LCD_WIDTH, OSCI_HEIGHT);
- update_osci();
- update_data();
-}
-
-/**
- * Zooms out by 4/3
- */
-static void splitedit_zoom_out(struct mp3entry *mp3)
-{
- rb->lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID);
- rb->lcd_fillrect(OSCI_X, OSCI_Y, LCD_WIDTH, OSCI_HEIGHT);
- rb->lcd_set_drawmode(DRMODE_SOLID);
- zoom(mp3, 4, 3);
- rb->lcd_update_rect(OSCI_X, OSCI_Y, LCD_WIDTH, OSCI_HEIGHT);
- update_osci();
- update_data();
-}
-
-/**
- * Append part_no to the file name.
- */
-static void generateFileName(char* file_name, int part_no)
-{
- if (rb->strlen(file_name) <MAX_PATH)
- {
- int len = rb->strlen(file_name);
- int ext_len = rb->strlen(".mp3");
- if (rb->strcasecmp(
- &file_name[len - ext_len],
- ".mp3") == 0)
- {
- int i = 0;
- /* shift the extension one position to the right*/
- for (i = len; i > len - ext_len; i--)
- {
- file_name[i] = file_name[i - 1];
- }
- file_name[len - ext_len] = '0' + part_no;
- }
- else
- {
- rb->splash(0, "wrong extension");
- rb->button_get(true);
- rb->button_get(true);
- }
- }
- else
- {
- rb->splash(0, "name too long");
- rb->button_get(true);
- rb->button_get(true);
-
- }
-
-}
-
-/**
- * Copy bytes from src to dest while displaying a progressbar.
- * The files must be already open.
- */
-static int copy_file(
- int dest,
- int src,
- unsigned int bytes,
- int prg_y,
- int prg_h)
-{
- long button;
- unsigned char *buffer;
- unsigned int i = 0;
- ssize_t bytes_read = 1; /* ensure the for loop is executed */
- size_t buffer_size;
- buffer = rb->plugin_get_buffer(&buffer_size);
-
- for (i = 0; i < bytes && bytes_read > 0; i += bytes_read)
- {
- ssize_t bytes_written;
- unsigned int bytes_to_read =
- bytes - i > buffer_size ? buffer_size : bytes - i;
- bytes_read = rb->read(src, buffer, bytes_to_read);
- bytes_written = rb->write(dest, buffer, bytes_read);
-
- if (bytes_written < 0) {
- rb->splash(0, "Write failed in copy.");
- rb->button_get(true);
- rb->button_get(true);
- return -1;
- }
-
- button = rb->button_get(false);
-
- if (button == SPLITEDIT_QUIT
-#ifdef SPLITEDIT_RC_QUIT
- || button == SPLITEDIT_RC_QUIT:
-#endif
- ) {
- rb->splash(0, "Aborting copy.");
- rb->button_get(true);
- rb->button_get(true);
- return -1;
- }
-
- rb->gui_scrollbar_draw(rb->screens[SCREEN_MAIN],0, prg_y, LCD_WIDTH,
- prg_h, bytes, 0, i, HORIZONTAL);
- rb->lcd_update_rect(0, prg_y, LCD_WIDTH, prg_h);
- }
-
- return 0;
-}
-
-/**
- * Save the files, if the file_name is not NULL
- */
-static int save(
- struct mp3entry *mp3,
- char *file_name1,
- char *file_name2,
- int splittime)
-{
- int file1, file2, src_file;
- unsigned int end = 0;
- int retval = 0;
-
- /* Verify that file 1 doesn't exit yet */
- if (file_name1 != NULL)
- {
- file1 = rb->open(file_name1, O_RDONLY);
- if (file1 >= 0)
- {
- rb->close(file1);
- rb->splash(0, "File 1 exists. Please rename.");
- rb->button_get(true);
- rb->button_get(true);
- return -1;
- }
- }
-
- /* Verify that file 2 doesn't exit yet */
- if (file_name2 != NULL)
- {
- file2 = rb->open(file_name2, O_RDONLY);
- if (file2 >= 0)
- {
- rb->close(file2);
- rb->splash(0, "File 2 exists. Please rename.");
- rb->button_get(true);
- rb->button_get(true);
- return -2;
- }
- }
-
- /* find the file position of the split point */
- rb->audio_pause();
- rb->audio_ff_rewind(splittime);
- rb->yield();
- rb->yield();
- end = rb->audio_get_file_pos();
-
- /* open the source file */
- src_file = rb->open(mp3->path, O_RDONLY);
- if (src_file >= 0)
- {
- int close_stat = 0;
- int x, y;
- long offset;
- unsigned long last_header = rb->mpeg_get_last_header();
-
- rb->lcd_getstringsize("M", &x, &y);
-
- /* Find the next frame boundary */
- rb->lseek(src_file, end, SEEK_SET);
- rb->find_next_frame(src_file, &offset, 8000, last_header);
- rb->lseek(src_file, 0, SEEK_SET);
- end += offset;
-
- /* write the file 1 */
- if (file_name1 != NULL)
- {
- file1 = rb->open (file_name1, O_WRONLY | O_CREAT, 0666);
- if (file1 >= 0)
- {
- int rc = copy_file(file1, src_file, end, y*2 + 1, y -1);
- close_stat = rb->close(file1);
-
- if (close_stat != 0)
- {
- rb->splashf(0, "failed closing file1: error %d", close_stat);
- rb->button_get(true);
- rb->button_get(true);
- } else {
- /* If there was an error, cleanup */
- if (rc) {
- rb->remove(file_name1);
- }
- }
- }
- else
- {
- rb->splashf(0, "Can't write File1: error %d", file1);
- rb->button_get(true);
- rb->button_get(true);
- retval = -1;
- }
- }
- /* if file1 hasn't been written we're not at the split point yet */
- else
- {
- if (rb->lseek(src_file, end, SEEK_SET) < (off_t)end)
- {
- rb->splashf(0, "Src file to short: error %d", src_file);
- rb->button_get(true);
- rb->button_get(true);
- }
- }
-
- if (file_name2 != NULL)
- {
- /* write file 2 */
- file2 = rb->open (file_name2, O_WRONLY | O_CREAT, 0666);
- if (file2 >= 0)
- {
- end = mp3->filesize - end;
- int rc = copy_file(file2, src_file, end, y * 5 + 1, y -1);
- close_stat = rb->close(file2);
-
- if (close_stat != 0)
- {
- rb->splashf(0, "failed: closing file2: error %d",
- close_stat);
- rb->button_get(true);
- rb->button_get(true);
- } else {
- /* If there was an error, cleanup */
- if (rc) {
- rb->remove(file_name2);
- }
- }
- }
- else
- {
- rb->splashf(0, "Can't write File2: error %d", file2);
- rb->button_get(true);
- rb->button_get(true);
- retval = -2;
- }
- }
-
- close_stat = rb->close(src_file);
- if (close_stat != 0)
- {
- rb->splashf(0, "failed: closing src: error %d", close_stat);
- rb->button_get(true);
- rb->button_get(true);
- }
- }
- else
- {
- rb->splash(0, "Source file not found");
- rb->button_get(true);
- rb->button_get(true);
- retval = -3;
- }
-
- rb->audio_resume();
-
- return retval;
-}
-
-static void puts_wrapper(int x, int y, const char *str, bool scroll, bool selected)
-{
- struct line_desc line = LINE_DESC_DEFINIT;
- struct screen *lcd = rb->screens[SCREEN_MAIN];
- int w = lcd->getcharwidth();
- int h = lcd->getcharheight();
-
- line.scroll = scroll;
- line.style = selected ? STYLE_INVERT : STYLE_DEFAULT;
-
- rb->screens[0]->put_line(x * w, y * h, &line, str);
-}
-
-/**
- * Let the user choose which file to save with which name
- */
-static void save_editor(struct mp3entry *mp3, int splittime)
-{
- bool exit_request = false;
- int choice = 0;
- int button = BUTTON_NONE;
- char part1_name [MAX_PATH];
- char part2_name [MAX_PATH];
- bool part1_save = true;
- bool part2_save = true;
-
- /* file name for left part */
- rb->strlcpy(part1_name, mp3->path, MAX_PATH);
- generateFileName(part1_name, 1);
-
- /* file name for right part */
- rb->strlcpy(part2_name, mp3->path, MAX_PATH);
- generateFileName(part2_name, 2);
-
- while (!exit_request)
- {
- int pos;
- rb->lcd_clear_display();
-
- /* Save file1? */
- puts_wrapper(0, 0, "Save part 1?", false, choice == SE_PART1_SAVE);
- puts_wrapper(7, 0, part1_save?"yes":"no", false, false);
-
- /* trim to display the filename without path */
- for (pos = rb->strlen(part1_name); pos > 0; pos--)
- {
- if (part1_name[pos] == '/')
- break;
- }
- pos++;
-
- /* File name 1 */
- puts_wrapper(0, 1, &part1_name[pos], true, choice == SE_PART1_NAME);
-
- /* Save file2? */
- puts_wrapper(0, 3, "Save part 2?", false, choice == SE_PART2_SAVE);
- puts_wrapper(7, 3, part2_save?"yes":"no", false, false);
-
- /* trim to display the filename without path */
- for (pos = rb->strlen(part2_name); pos > 0; pos --)
- {
- if (part2_name[pos] == '/')
- break;
- }
- pos++;
-
- /* File name 2 */
- puts_wrapper(0, 4, &part2_name[pos], true, choice == SE_PART2_NAME);
-
- /* Save */
- puts_wrapper(0, 6, "Save", false, choice == SE_SAVE);
-
- rb->lcd_update();
-
-
- button = rb->button_get(true);
- switch (button)
- {
- case BUTTON_UP:
- choice = (choice + SE_COUNT - 1) % SE_COUNT;
- break;
-
- case BUTTON_DOWN:
- choice = (choice + 1) % SE_COUNT;
- break;
-
- case SPLITEDIT_MENU_RUN:
- switch (choice)
- {
- int saved;
-
- case SE_PART1_SAVE:
- part1_save = !part1_save;
- break;
-
- case SE_PART1_NAME:
- rb->kbd_input(part1_name, MAX_PATH, NULL);
- break;
-
- case SE_PART2_SAVE:
- part2_save = !part2_save;
- break;
-
- case SE_PART2_NAME:
- rb->kbd_input(part2_name, MAX_PATH, NULL);
- break;
-
- case SE_SAVE:
- rb->lcd_scroll_stop();
- rb->lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID);
- rb->lcd_fillrect(0, 6*8, LCD_WIDTH, LCD_HEIGHT);
- rb->lcd_set_drawmode(DRMODE_SOLID);
- saved = save
- (
- mp3,
- part1_save?part1_name:NULL,
- part2_save?part2_name:NULL,
- splittime
- );
-
- /* if something failed the user may go on choosing */
- if (saved >= 0)
- {
- exit_request = true;
- }
- break;
- }
- break;
-#ifdef SPLITEDIT_RC_QUIT
- case SPLITEDIT_RC_QUIT:
-#endif
- case SPLITEDIT_QUIT:
- exit_request = true;
- break;
-
- default:
- if (rb->default_event_handler(button) == SYS_USB_CONNECTED)
- {
- splitedit_exit_code = PLUGIN_USB_CONNECTED;
- exit_request = true;
- }
- break;
- }
- }
-}
-
-/**
- * The main loop of the editor
- */
-static unsigned long splitedit_editor(struct mp3entry * mp3_to_split,
- unsigned int split_time,
- unsigned int range)
-{
- int button = BUTTON_NONE;
- int lastbutton = BUTTON_NONE;
- struct mp3entry *mp3 = mp3_to_split;
- unsigned int last_elapsed = 0;
- int lastx = OSCI_X + (OSCI_WIDTH / 2);
- int retval = -1;
-
- if (mp3 != NULL)
- {
- /*unsigned short scheme = SCHEME_SPLIT_EDITOR;*/
- bool exit_request = false;
- set_range_by_time(mp3, split_time, range);
- splitedit_set_loop_mode(LOOP_MODE_ALL);
- update_icons();
-
- /*while (scheme != SCHEME_RETURN) {*/
- while (!exit_request)
- {
- unsigned int elapsed ;
- int x ;
-
- /* get position */
- elapsed = mp3->elapsed;
- x = time_to_xpos(elapsed);
-
- /* are we still in the zoomed range? */
- if (elapsed > play_start && elapsed < play_end)
- {
- /* read volume info */
- unsigned short volume;
- volume = OSCI_HEIGHT / 2;
-
- /* update osci_buffer */
- if (osci_valid || lastx == x)
- {
- int index = x - OSCI_X;
- osci_buffer[index] = MAX(osci_buffer[index], volume);
- }
- else
- {
- int i;
- osci_buffer[x - OSCI_X] = volume;
- for (i = lastx + 1; i < x; i++)
- {
- osci_buffer[i - OSCI_X] = 0;
- }
- }
-
- /* make room */
- rb->lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID);
- rb->lcd_fillrect(lastx + 1, OSCI_Y, x - lastx, OSCI_HEIGHT);
- rb->lcd_set_drawmode(DRMODE_SOLID);
- /* draw a value */
- if (osci_buffer[x - OSCI_X] > 0)
- {
- int i;
- for (i = lastx +1; i <= x; i++)
- {
- rb->lcd_vline
- (
- i, OSCI_Y + OSCI_HEIGHT - 1,
- OSCI_Y + OSCI_HEIGHT - osci_buffer[i - OSCI_X]-1
- );
- }
- }
-
- /* mark the current position */
- if (lastx != x)
- {
- rb->lcd_set_drawmode(DRMODE_COMPLEMENT);
- rb->lcd_fillrect(lastx, OSCI_Y, 1, OSCI_HEIGHT);
- rb->lcd_fillrect(x, OSCI_Y, 1, OSCI_HEIGHT);
- rb->lcd_set_drawmode(DRMODE_SOLID);
- }
-
- /* mark the split point */
- if ((x > split_x - 2) && (lastx < split_x + 3))
- {
- if ((lastx < split_x) && (x >= split_x))
- {
- rb->lcd_set_drawmode(DRMODE_COMPLEMENT);
- rb->lcd_fillrect
- (
- split_x, OSCI_Y + 2,
- 1, OSCI_HEIGHT - 2
- );
- rb->lcd_set_drawmode(DRMODE_SOLID);
- }
- rb->lcd_hline(split_x -2, split_x + 2, OSCI_Y);
- rb->lcd_hline(split_x-1, split_x +1,OSCI_Y+1);
- }
-
- /* make visible */
- if (lastx <= x)
- {
- rb->lcd_update_rect(lastx, OSCI_Y, x-lastx+1, OSCI_HEIGHT);
- }
- else
- {
- rb->lcd_update_rect
- (
- lastx, OSCI_Y,
- OSCI_X + OSCI_WIDTH - lastx, OSCI_HEIGHT
- );
- rb->lcd_update_rect(0, OSCI_Y, x + 1, OSCI_HEIGHT);
- }
-
- lastx = x;
- }
-
- /* we're not in the zoom range -> rewind */
- else
- {
- if (elapsed >= play_end)
- {
- switch (splitedit_get_loop_mode())
- {
- unsigned int range_width;
-
- case LOOP_MODE_ALL:
- case LOOP_MODE_TO:
- rb->audio_pause();
- rb->audio_ff_rewind(range_start);
-#if (CONFIG_STORAGE & STORAGE_MMC)
-/* MMC is slow - wait some time to allow track reload to finish */
- rb->sleep(HZ/20);
- if (mp3->elapsed > play_end) /* reload in progress */
- rb->splash(10*HZ, "Wait - reloading");
-#endif
- rb->audio_resume();
- break;
-
- case LOOP_MODE_FROM:
- rb->audio_pause();
- rb->audio_ff_rewind(xpos_to_time(split_x));
-#if (CONFIG_STORAGE & STORAGE_MMC)
-/* MMC is slow - wait some time to allow track reload to finish */
- rb->sleep(HZ/20);
- if (mp3->elapsed > play_end) /* reload in progress */
- rb->splash(10*HZ, "Wait - reloading");
-#endif
- rb->audio_resume();
- break;
-
- case LOOP_MODE_FREE:
- range_width = range_end - range_start;
- set_range_by_time(mp3,
- range_end + range_width / 2, range_width);
-
- /* play_end und play_start anpassen */
- splitedit_set_loop_mode(LOOP_MODE_FREE);
- rb->memset(osci_buffer, 0, sizeof osci_buffer);
- update_osci();
- rb->lcd_update();
- break;
- }
- }
- }
-
- button = rb->button_get(false);
- rb->yield();
-
- /* here the evaluation of the key scheme starts.
- All functions the user triggers are called from
- within execute_scheme */
- /* key_scheme_execute(button, &scheme); */
- switch (button)
- {
- case SPLITEDIT_PLAY:
-#ifdef SPLITEDIT_PLAY_PRE
- if (lastbutton != SPLITEDIT_PLAY_PRE)
- break;
-#endif
- rb->audio_pause();
- rb->audio_ff_rewind(xpos_to_time(split_x));
- rb->audio_resume();
- break;
-
- case BUTTON_UP:
- splitedit_zoom_in(mp3);
- lastx = time_to_xpos(mp3->elapsed);
- break;
-
- case BUTTON_DOWN:
- splitedit_zoom_out(mp3);
- lastx = time_to_xpos(mp3->elapsed);
- break;
-
- case BUTTON_LEFT:
- case BUTTON_LEFT | BUTTON_REPEAT:
- if (splitedit_get_split_x() > OSCI_X + 2)
- {
- splitedit_set_split_x(splitedit_get_split_x() - 1);
- }
- else
- {
- scroll(mp3);
- lastx = time_to_xpos(mp3->elapsed);
- }
- break;
-
- case BUTTON_RIGHT:
- case BUTTON_RIGHT | BUTTON_REPEAT:
- if (splitedit_get_split_x() < OSCI_X + OSCI_WIDTH-3)
- {
- splitedit_set_split_x(splitedit_get_split_x() + 1);
- }
- else
- {
- scroll(mp3);
- lastx = time_to_xpos(mp3->elapsed);
- }
- break;
-
- case SPLITEDIT_SAVE:
- save_editor(mp3, xpos_to_time(split_x));
- rb->lcd_clear_display();
- update_osci();
- update_timebar(mp3);
- update_icons();
- break;
-
- case SPLITEDIT_LOOP_MODE:
- splitedit_set_loop_mode(splitedit_get_loop_mode() + 1);
- update_icons();
- break;
-
- case SPLITEDIT_SCALE:
- splitedit_invalidate_osci();
- update_icons();
- break;
-
-#ifdef SPLITEDIT_RC_QUIT
- case SPLITEDIT_RC_QUIT:
-#endif
- case SPLITEDIT_QUIT:
- exit_request = true;
- break;
-
- default:
- if (rb->default_event_handler(button) == SYS_USB_CONNECTED)
- {
- splitedit_exit_code = PLUGIN_USB_CONNECTED;
- exit_request = true;
- }
- break;
-
- }
- if (button != BUTTON_NONE)
- lastbutton = button;
-
- if (validation_start == ~(unsigned int)0)
- {
- if (elapsed < range_end && elapsed > range_start)
- {
- validation_start = elapsed;
- }
- else
- {
- int endx = time_to_xpos(range_end);
- validation_start = xpos_to_time(endx - 2);
- }
- last_elapsed = elapsed + 1;
- }
- else
- {
- if ((last_elapsed <= validation_start) &&
- (elapsed > validation_start))
- {
- osci_valid = true;
- }
-
- last_elapsed = elapsed;
- }
- update_data();
-
- if (mp3 != rb->audio_current_track())
- {
- struct mp3entry *new_mp3 = rb->audio_current_track();
- if (rb->strncasecmp(path_mp3, new_mp3->path,
- sizeof (path_mp3)))
- {
- rb->splash(0, "Abort due to file change");
- rb->button_get(true);
- rb->button_get(true);
- exit_request = true;
- }
- else
- {
- mp3 = new_mp3;
- rb->audio_pause();
- rb->audio_flush_and_reload_tracks();
- rb->audio_ff_rewind(range_start);
- rb->audio_resume();
- }
- }
- }
- }
- return retval;
-}
-
-enum plugin_status plugin_start(const void* parameter)
-{
- struct mp3entry* mp3;
-
- (void)parameter;
- rb->lcd_clear_display();
- rb->lcd_update();
- mp3 = rb->audio_current_track();
- if (mp3 != NULL)
- {
- if (rb->audio_status() & AUDIO_STATUS_PAUSE)
- {
- rb->audio_resume();
- }
- splitedit_editor(mp3, mp3->elapsed, MIN_RANGE_SIZE * 8);
- }
- else
- {
- rb->splash(0, "Play or pause a mp3 file first.");
- rb->button_get(true);
- rb->button_get(true);
- }
- return splitedit_exit_code;
-}