summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStéphane Doyon <s.doyon@videotron.ca>2008-05-04 13:47:58 +0000
committerStéphane Doyon <s.doyon@videotron.ca>2008-05-04 13:47:58 +0000
commitab0f7e17ef225f2db908276f903d1354b7777618 (patch)
treed9928efee4632f6c9a853fc83b9200f218c837e8
parent1ef5a836f8349b593945727a9905dbd9e1a3def0 (diff)
downloadrockbox-ab0f7e17ef225f2db908276f903d1354b7777618.zip
rockbox-ab0f7e17ef225f2db908276f903d1354b7777618.tar.gz
rockbox-ab0f7e17ef225f2db908276f903d1354b7777618.tar.bz2
rockbox-ab0f7e17ef225f2db908276f903d1354b7777618.tar.xz
Accept FS#6188: study mode.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@17355 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--apps/gui/gwps-common.c34
-rw-r--r--apps/gui/gwps-common.h1
-rw-r--r--apps/gui/gwps.c127
-rw-r--r--apps/lang/english.lang56
-rw-r--r--apps/menus/playback_menu.c6
-rw-r--r--apps/onplay.c36
-rw-r--r--apps/playback.h4
-rw-r--r--apps/settings.h2
-rw-r--r--apps/settings_list.c4
9 files changed, 222 insertions, 48 deletions
diff --git a/apps/gui/gwps-common.c b/apps/gui/gwps-common.c
index ed4ca17..bcb82df 100644
--- a/apps/gui/gwps-common.c
+++ b/apps/gui/gwps-common.c
@@ -78,6 +78,7 @@ static void gui_wps_statusbar_draw(struct gui_wps *wps, bool force)
#define gui_wps_statusbar_draw(wps, force) \
gui_statusbar_draw((wps)->statusbar, (force))
#endif
+#include "pcmbuf.h"
/* fades the volume */
void fade(bool fade_in)
@@ -143,6 +144,39 @@ bool update_onvol_change(struct gui_wps * gwps)
return false;
}
+void play_hop(int direction)
+{
+ if(!wps_state.id3 || !wps_state.id3->length
+ || global_settings.study_hop_step == 0)
+ return;
+#define STEP ((unsigned)global_settings.study_hop_step *1000)
+ if(direction == 1
+ && wps_state.id3->length - wps_state.id3->elapsed < STEP+1000) {
+#if CONFIG_CODEC == SWCODEC
+ if(global_settings.beep)
+ pcmbuf_beep(1000, 150, 1500*global_settings.beep);
+#endif
+ return;
+ }
+ if((direction == -1 && wps_state.id3->elapsed < STEP))
+ wps_state.id3->elapsed = 0;
+ else
+ wps_state.id3->elapsed += STEP *direction;
+ if((audio_status() & AUDIO_STATUS_PLAY) && !wps_state.paused) {
+#if (CONFIG_CODEC == SWCODEC)
+ audio_pre_ff_rewind();
+#else
+ audio_pause();
+#endif
+ }
+ audio_ff_rewind(wps_state.id3->elapsed);
+#if (CONFIG_CODEC != SWCODEC)
+ if (!wps_state.paused)
+ audio_resume();
+#endif
+#undef STEP
+}
+
bool ffwd_rew(int button)
{
unsigned int step = 0; /* current ff/rewind step */
diff --git a/apps/gui/gwps-common.h b/apps/gui/gwps-common.h
index 76555c1..2308025 100644
--- a/apps/gui/gwps-common.h
+++ b/apps/gui/gwps-common.h
@@ -27,6 +27,7 @@ void fade(bool fade_in);
bool gui_wps_display(void);
bool update_onvol_change(struct gui_wps * gwps);
bool update(struct gui_wps *gwps);
+void play_hop(int direction);
bool ffwd_rew(int button);
void display_keylock_text(bool locked);
diff --git a/apps/gui/gwps.c b/apps/gui/gwps.c
index 2e72813..28aea49 100644
--- a/apps/gui/gwps.c
+++ b/apps/gui/gwps.c
@@ -90,6 +90,51 @@ static void gui_wps_set_margin(struct gui_wps *gwps)
}
#endif
+static void prev_track(unsigned skip_thresh)
+{
+ if (!wps_state.id3 || (wps_state.id3->elapsed < skip_thresh*1000)) {
+ audio_prev();
+ }
+ else {
+ if (cuesheet_is_enabled() && wps_state.id3->cuesheet_type)
+ {
+ curr_cuesheet_skip(-1, wps_state.id3->elapsed);
+ return;
+ }
+
+ if (!wps_state.paused)
+#if (CONFIG_CODEC == SWCODEC)
+ audio_pre_ff_rewind();
+#else
+ audio_pause();
+#endif
+
+ audio_ff_rewind(0);
+
+#if (CONFIG_CODEC != SWCODEC)
+ if (!wps_state.paused)
+ audio_resume();
+#endif
+ }
+}
+
+void next_track(void)
+{
+ /* take care of if we're playing a cuesheet */
+ if (cuesheet_is_enabled() && wps_state.id3->cuesheet_type)
+ {
+ if (curr_cuesheet_skip(1, wps_state.id3->elapsed))
+ {
+ /* if the result was false, then we really want
+ to skip to the next track */
+ return;
+ }
+ }
+
+ audio_next();
+}
+
+
long gui_wps_show(void)
{
long button = 0;
@@ -335,11 +380,13 @@ long gui_wps_show(void)
}
break;
/* fast forward
- OR next dir if this is straight after ACTION_WPS_SKIPNEXT */
+ OR next dir if this is straight after ACTION_WPS_SKIPNEXT
+ OR in study mode, next track if straight after SKIPPREV. */
case ACTION_WPS_SEEKFWD:
if (global_settings.party_mode)
break;
- if (current_tick -last_right < HZ)
+ if (!global_settings.study_mode
+ && current_tick -last_right < HZ)
{
if (cuesheet_is_enabled() && wps_state.id3->cuesheet_type)
{
@@ -350,15 +397,23 @@ long gui_wps_show(void)
audio_next_dir();
}
}
+ else if(global_settings.study_mode
+ && current_tick -last_left < HZ) {
+ next_track();
+ update_track = true;
+ }
else ffwd_rew(ACTION_WPS_SEEKFWD);
- last_right = 0;
+ last_right = last_left = 0;
break;
/* fast rewind
- OR prev dir if this is straight after ACTION_WPS_SKIPPREV */
+ OR prev dir if this is straight after ACTION_WPS_SKIPPREV,
+ OR in study mode, beg of track or prev track if this is
+ straight after SKIPPREV */
case ACTION_WPS_SEEKBACK:
if (global_settings.party_mode)
break;
- if (current_tick -last_left < HZ)
+ if (!global_settings.study_mode
+ && current_tick -last_left < HZ)
{
if (cuesheet_is_enabled() && wps_state.id3->cuesheet_type)
{
@@ -375,8 +430,14 @@ long gui_wps_show(void)
audio_prev_dir();
}
}
+ else if(global_settings.study_mode
+ && current_tick -last_right < HZ)
+ {
+ prev_track(3+global_settings.study_hop_step);
+ update_track = true;
+ }
else ffwd_rew(ACTION_WPS_SEEKBACK);
- last_left = 0;
+ last_left = last_right = 0;
break;
/* prev / restart */
@@ -404,34 +465,13 @@ long gui_wps_show(void)
/* ...otherwise, do it normally */
#endif
- if (!wps_state.id3 || (wps_state.id3->elapsed < 3*1000)) {
- audio_prev();
- }
- else {
-
- if (cuesheet_is_enabled() && wps_state.id3->cuesheet_type)
- {
- curr_cuesheet_skip(-1, wps_state.id3->elapsed);
- break;
- }
-
- if (!wps_state.paused)
-#if (CONFIG_CODEC == SWCODEC)
- audio_pre_ff_rewind();
-#else
- audio_pause();
-#endif
-
- audio_ff_rewind(0);
-
-#if (CONFIG_CODEC != SWCODEC)
- if (!wps_state.paused)
- audio_resume();
-#endif
- }
+ if(global_settings.study_mode)
+ play_hop(-1);
+ else prev_track(3);
break;
- /* next */
+ /* next
+ OR in study mode, hop by predetermined amount. */
case ACTION_WPS_SKIPNEXT:
if (global_settings.party_mode)
break;
@@ -456,18 +496,9 @@ long gui_wps_show(void)
/* ...otherwise, do it normally */
#endif
- /* take care of if we're playing a cuesheet */
- if (cuesheet_is_enabled() && wps_state.id3->cuesheet_type)
- {
- if (curr_cuesheet_skip(1, wps_state.id3->elapsed))
- {
- /* if the result was false, then we really want
- to skip to the next track */
- break;
- }
- }
-
- audio_next();
+ if(global_settings.study_mode)
+ play_hop(1);
+ else next_track();
break;
/* next / prev directories */
/* and set A-B markers if in a-b mode */
@@ -484,7 +515,9 @@ long gui_wps_show(void)
else
#endif
{
- audio_next_dir();
+ if(global_settings.study_mode)
+ next_track();
+ else audio_next_dir();
}
break;
case ACTION_WPS_ABSETA_PREVDIR:
@@ -496,7 +529,9 @@ long gui_wps_show(void)
else
#endif
{
- audio_prev_dir();
+ if(global_settings.study_mode)
+ prev_track(3);
+ else audio_prev_dir();
}
break;
/* menu key functions */
diff --git a/apps/lang/english.lang b/apps/lang/english.lang
index eb19bce..dd1cfc3 100644
--- a/apps/lang/english.lang
+++ b/apps/lang/english.lang
@@ -11604,3 +11604,59 @@
*: "Unknown"
</voice>
</phrase>
+<phrase>
+ id: LANG_STUDY_MODE
+ desc: playback settings menu
+ user:
+ <source>
+ *: "Study Mode"
+ </source>
+ <dest>
+ *: "Study Mode"
+ </dest>
+ <voice>
+ *: "Study Mode"
+ </voice>
+</phrase>
+<phrase>
+ id: LANG_STUDY_HOP_STEP
+ desc: playback settings menu
+ user:
+ <source>
+ *: "Study Increment"
+ </source>
+ <dest>
+ *: "Study Increment"
+ </dest>
+ <voice>
+ *: "Study Increment"
+ </voice>
+</phrase>
+<phrase>
+ id: LANG_ENABLE_STUDY_MODE
+ desc: WPS context menu
+ user:
+ <source>
+ *: "Enable Study Mode"
+ </source>
+ <dest>
+ *: "Enable Study Mode"
+ </dest>
+ <voice>
+ *: "Enable Study Mode"
+ </voice>
+</phrase>
+<phrase>
+ id: LANG_DISABLE_STUDY_MODE
+ desc: WPS context menu
+ user:
+ <source>
+ *: "Disable Study Mode"
+ </source>
+ <dest>
+ *: "Disable Study Mode"
+ </dest>
+ <voice>
+ *: "Disable Study Mode"
+ </voice>
+</phrase>
diff --git a/apps/menus/playback_menu.c b/apps/menus/playback_menu.c
index 390d5cc..1dcb42b 100644
--- a/apps/menus/playback_menu.c
+++ b/apps/menus/playback_menu.c
@@ -174,6 +174,11 @@ MAKE_MENU(unplug_menu, ID2P(LANG_HEADPHONE_UNPLUG), 0, Icon_NOICON,
&unplug_mode, &unplug_rw, &unplug_autoresume);
#endif
+MENUITEM_SETTING(study_mode, &global_settings.study_mode, NULL);
+MENUITEM_SETTING(study_hop_step, &global_settings.study_hop_step, NULL);
+MAKE_MENU(study_mode_menu, ID2P(LANG_STUDY_MODE), 0, Icon_NOICON,
+ &study_mode, &study_hop_step);
+
MAKE_MENU(playback_menu_item,ID2P(LANG_PLAYBACK),0,
Icon_Playback_menu,
&shuffle_item, &repeat_mode, &play_selected,
@@ -194,6 +199,7 @@ MAKE_MENU(playback_menu_item,ID2P(LANG_PLAYBACK),0,
#ifdef HAVE_HEADPHONE_DETECTION
,&unplug_menu
#endif
+ ,&study_mode_menu
);
static int playback_callback(int action,const struct menu_item_ex *this_item)
diff --git a/apps/onplay.c b/apps/onplay.c
index 45b1860..b65d2fe 100644
--- a/apps/onplay.c
+++ b/apps/onplay.c
@@ -1011,6 +1011,41 @@ MENUITEM_FUNCTION(eq_browse_presets_item, 0, ID2P(LANG_EQUALIZER_BROWSE),
eq_browse_presets, NULL, NULL, Icon_Audio);
#endif
+/* study mode setting toggling */
+
+static char* study_mode_toggle_get_name(int selected_item, void * data,
+ char *buffer)
+{
+ (void)selected_item;
+ (void)data;
+ snprintf(buffer, MAX_PATH,
+ global_settings.study_mode ? str(LANG_DISABLE_STUDY_MODE)
+ : str(LANG_ENABLE_STUDY_MODE));
+ return buffer;
+}
+
+static int study_mode_toggle_speak_item(int selected_item, void * data)
+{
+ (void)selected_item;
+ (void)data;
+ talk_id(global_settings.study_mode ? LANG_DISABLE_STUDY_MODE
+ : LANG_ENABLE_STUDY_MODE, false);
+ return 0;
+}
+
+static int toggle_study_mode(void * param)
+{
+ (void)param;
+ global_settings.study_mode ^= 1;
+ return 0;
+}
+
+MENUITEM_FUNCTION_DYNTEXT(study_mode_toggle, 0,
+ toggle_study_mode, NULL,
+ study_mode_toggle_get_name,
+ study_mode_toggle_speak_item,
+ NULL, NULL, Icon_NOICON);
+
/* CONTEXT_[TREE|ID3DB] items */
static int clipboard_callback(int action,const struct menu_item_ex *this_item);
MENUITEM_FUNCTION(rename_file_item, 0, ID2P(LANG_RENAME),
@@ -1152,6 +1187,7 @@ MAKE_ONPLAYMENU( wps_onplay_menu, ID2P(LANG_ONPLAY_MENU_TITLE),
#if CONFIG_CODEC == SWCODEC
&eq_menu_graphical_item, &eq_browse_presets_item,
#endif
+ &study_mode_toggle,
);
/* used when onplay() is not called in the CONTEXT_WPS context */
MAKE_ONPLAYMENU( tree_onplay_menu, ID2P(LANG_ONPLAY_MENU_TITLE),
diff --git a/apps/playback.h b/apps/playback.h
index 103361c..5e1eb98 100644
--- a/apps/playback.h
+++ b/apps/playback.h
@@ -49,8 +49,8 @@ int audio_current_aa_hid(void);
extern void audio_next_dir(void);
extern void audio_prev_dir(void);
#else
-#define audio_next_dir()
-#define audio_prev_dir()
+#define audio_next_dir() ({ })
+#define audio_prev_dir() ({ })
#endif
#endif
diff --git a/apps/settings.h b/apps/settings.h
index 7c32ba2..b21b404 100644
--- a/apps/settings.h
+++ b/apps/settings.h
@@ -437,6 +437,8 @@ struct user_settings
bool play_selected; /* Plays selected file even in shuffle mode */
int ff_rewind_min_step; /* FF/Rewind minimum step size */
int ff_rewind_accel; /* FF/Rewind acceleration (in seconds per doubling) */
+ bool study_mode; /* study mode enabled */
+ int study_hop_step; /* hop step in study mode, in seconds */
#ifndef HAVE_FLASH_STORAGE
int disk_spindown; /* time until disk spindown, in seconds (0=off) */
diff --git a/apps/settings_list.c b/apps/settings_list.c
index 78b73af..94210ff 100644
--- a/apps/settings_list.c
+++ b/apps/settings_list.c
@@ -1163,6 +1163,10 @@ const struct settings_list settings[] = {
#endif
#endif
OFFON_SETTING(0,cuesheet,LANG_CUESHEET_ENABLE,false,"cuesheet support", NULL),
+ OFFON_SETTING(0,study_mode,LANG_ENABLE_STUDY_MODE,false,"Study mode",
+ NULL),
+ INT_SETTING(0, study_hop_step, LANG_STUDY_HOP_STEP, 5, "Study hop step",
+ UNIT_SEC, 0, 250, 1, NULL, NULL, NULL),
CHOICE_SETTING(0, start_in_screen, LANG_START_SCREEN, 1,
"start in screen", "previous,root,files,db,wps,menu,"
#ifdef HAVE_RECORDING