mirror of
https://github.com/Rockbox/rockbox.git
synced 2025-12-11 14:15:15 -05:00
Accept FS#6188: study mode.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@17355 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
parent
1ef5a836f8
commit
ab0f7e17ef
9 changed files with 222 additions and 48 deletions
|
|
@ -78,6 +78,7 @@ static void gui_wps_statusbar_draw(struct gui_wps *wps, bool force)
|
||||||
#define gui_wps_statusbar_draw(wps, force) \
|
#define gui_wps_statusbar_draw(wps, force) \
|
||||||
gui_statusbar_draw((wps)->statusbar, (force))
|
gui_statusbar_draw((wps)->statusbar, (force))
|
||||||
#endif
|
#endif
|
||||||
|
#include "pcmbuf.h"
|
||||||
|
|
||||||
/* fades the volume */
|
/* fades the volume */
|
||||||
void fade(bool fade_in)
|
void fade(bool fade_in)
|
||||||
|
|
@ -143,6 +144,39 @@ bool update_onvol_change(struct gui_wps * gwps)
|
||||||
return false;
|
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)
|
bool ffwd_rew(int button)
|
||||||
{
|
{
|
||||||
unsigned int step = 0; /* current ff/rewind step */
|
unsigned int step = 0; /* current ff/rewind step */
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,7 @@ void fade(bool fade_in);
|
||||||
bool gui_wps_display(void);
|
bool gui_wps_display(void);
|
||||||
bool update_onvol_change(struct gui_wps * gwps);
|
bool update_onvol_change(struct gui_wps * gwps);
|
||||||
bool update(struct gui_wps *gwps);
|
bool update(struct gui_wps *gwps);
|
||||||
|
void play_hop(int direction);
|
||||||
bool ffwd_rew(int button);
|
bool ffwd_rew(int button);
|
||||||
void display_keylock_text(bool locked);
|
void display_keylock_text(bool locked);
|
||||||
|
|
||||||
|
|
|
||||||
127
apps/gui/gwps.c
127
apps/gui/gwps.c
|
|
@ -90,6 +90,51 @@ static void gui_wps_set_margin(struct gui_wps *gwps)
|
||||||
}
|
}
|
||||||
#endif
|
#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 gui_wps_show(void)
|
||||||
{
|
{
|
||||||
long button = 0;
|
long button = 0;
|
||||||
|
|
@ -335,11 +380,13 @@ long gui_wps_show(void)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
/* fast forward
|
/* 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:
|
case ACTION_WPS_SEEKFWD:
|
||||||
if (global_settings.party_mode)
|
if (global_settings.party_mode)
|
||||||
break;
|
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)
|
if (cuesheet_is_enabled() && wps_state.id3->cuesheet_type)
|
||||||
{
|
{
|
||||||
|
|
@ -350,15 +397,23 @@ long gui_wps_show(void)
|
||||||
audio_next_dir();
|
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);
|
else ffwd_rew(ACTION_WPS_SEEKFWD);
|
||||||
last_right = 0;
|
last_right = last_left = 0;
|
||||||
break;
|
break;
|
||||||
/* fast rewind
|
/* 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:
|
case ACTION_WPS_SEEKBACK:
|
||||||
if (global_settings.party_mode)
|
if (global_settings.party_mode)
|
||||||
break;
|
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)
|
if (cuesheet_is_enabled() && wps_state.id3->cuesheet_type)
|
||||||
{
|
{
|
||||||
|
|
@ -375,8 +430,14 @@ long gui_wps_show(void)
|
||||||
audio_prev_dir();
|
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);
|
else ffwd_rew(ACTION_WPS_SEEKBACK);
|
||||||
last_left = 0;
|
last_left = last_right = 0;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* prev / restart */
|
/* prev / restart */
|
||||||
|
|
@ -404,34 +465,13 @@ long gui_wps_show(void)
|
||||||
/* ...otherwise, do it normally */
|
/* ...otherwise, do it normally */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (!wps_state.id3 || (wps_state.id3->elapsed < 3*1000)) {
|
if(global_settings.study_mode)
|
||||||
audio_prev();
|
play_hop(-1);
|
||||||
}
|
else prev_track(3);
|
||||||
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
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* next */
|
/* next
|
||||||
|
OR in study mode, hop by predetermined amount. */
|
||||||
case ACTION_WPS_SKIPNEXT:
|
case ACTION_WPS_SKIPNEXT:
|
||||||
if (global_settings.party_mode)
|
if (global_settings.party_mode)
|
||||||
break;
|
break;
|
||||||
|
|
@ -456,18 +496,9 @@ long gui_wps_show(void)
|
||||||
/* ...otherwise, do it normally */
|
/* ...otherwise, do it normally */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* take care of if we're playing a cuesheet */
|
if(global_settings.study_mode)
|
||||||
if (cuesheet_is_enabled() && wps_state.id3->cuesheet_type)
|
play_hop(1);
|
||||||
{
|
else next_track();
|
||||||
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();
|
|
||||||
break;
|
break;
|
||||||
/* next / prev directories */
|
/* next / prev directories */
|
||||||
/* and set A-B markers if in a-b mode */
|
/* and set A-B markers if in a-b mode */
|
||||||
|
|
@ -484,7 +515,9 @@ long gui_wps_show(void)
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
audio_next_dir();
|
if(global_settings.study_mode)
|
||||||
|
next_track();
|
||||||
|
else audio_next_dir();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ACTION_WPS_ABSETA_PREVDIR:
|
case ACTION_WPS_ABSETA_PREVDIR:
|
||||||
|
|
@ -496,7 +529,9 @@ long gui_wps_show(void)
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
audio_prev_dir();
|
if(global_settings.study_mode)
|
||||||
|
prev_track(3);
|
||||||
|
else audio_prev_dir();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
/* menu key functions */
|
/* menu key functions */
|
||||||
|
|
|
||||||
|
|
@ -11604,3 +11604,59 @@
|
||||||
*: "Unknown"
|
*: "Unknown"
|
||||||
</voice>
|
</voice>
|
||||||
</phrase>
|
</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>
|
||||||
|
|
|
||||||
|
|
@ -174,6 +174,11 @@ MAKE_MENU(unplug_menu, ID2P(LANG_HEADPHONE_UNPLUG), 0, Icon_NOICON,
|
||||||
&unplug_mode, &unplug_rw, &unplug_autoresume);
|
&unplug_mode, &unplug_rw, &unplug_autoresume);
|
||||||
#endif
|
#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,
|
MAKE_MENU(playback_menu_item,ID2P(LANG_PLAYBACK),0,
|
||||||
Icon_Playback_menu,
|
Icon_Playback_menu,
|
||||||
&shuffle_item, &repeat_mode, &play_selected,
|
&shuffle_item, &repeat_mode, &play_selected,
|
||||||
|
|
@ -194,6 +199,7 @@ MAKE_MENU(playback_menu_item,ID2P(LANG_PLAYBACK),0,
|
||||||
#ifdef HAVE_HEADPHONE_DETECTION
|
#ifdef HAVE_HEADPHONE_DETECTION
|
||||||
,&unplug_menu
|
,&unplug_menu
|
||||||
#endif
|
#endif
|
||||||
|
,&study_mode_menu
|
||||||
);
|
);
|
||||||
|
|
||||||
static int playback_callback(int action,const struct menu_item_ex *this_item)
|
static int playback_callback(int action,const struct menu_item_ex *this_item)
|
||||||
|
|
|
||||||
|
|
@ -1011,6 +1011,41 @@ MENUITEM_FUNCTION(eq_browse_presets_item, 0, ID2P(LANG_EQUALIZER_BROWSE),
|
||||||
eq_browse_presets, NULL, NULL, Icon_Audio);
|
eq_browse_presets, NULL, NULL, Icon_Audio);
|
||||||
#endif
|
#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 */
|
/* CONTEXT_[TREE|ID3DB] items */
|
||||||
static int clipboard_callback(int action,const struct menu_item_ex *this_item);
|
static int clipboard_callback(int action,const struct menu_item_ex *this_item);
|
||||||
MENUITEM_FUNCTION(rename_file_item, 0, ID2P(LANG_RENAME),
|
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
|
#if CONFIG_CODEC == SWCODEC
|
||||||
&eq_menu_graphical_item, &eq_browse_presets_item,
|
&eq_menu_graphical_item, &eq_browse_presets_item,
|
||||||
#endif
|
#endif
|
||||||
|
&study_mode_toggle,
|
||||||
);
|
);
|
||||||
/* used when onplay() is not called in the CONTEXT_WPS context */
|
/* used when onplay() is not called in the CONTEXT_WPS context */
|
||||||
MAKE_ONPLAYMENU( tree_onplay_menu, ID2P(LANG_ONPLAY_MENU_TITLE),
|
MAKE_ONPLAYMENU( tree_onplay_menu, ID2P(LANG_ONPLAY_MENU_TITLE),
|
||||||
|
|
|
||||||
|
|
@ -49,8 +49,8 @@ int audio_current_aa_hid(void);
|
||||||
extern void audio_next_dir(void);
|
extern void audio_next_dir(void);
|
||||||
extern void audio_prev_dir(void);
|
extern void audio_prev_dir(void);
|
||||||
#else
|
#else
|
||||||
#define audio_next_dir()
|
#define audio_next_dir() ({ })
|
||||||
#define audio_prev_dir()
|
#define audio_prev_dir() ({ })
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -437,6 +437,8 @@ struct user_settings
|
||||||
bool play_selected; /* Plays selected file even in shuffle mode */
|
bool play_selected; /* Plays selected file even in shuffle mode */
|
||||||
int ff_rewind_min_step; /* FF/Rewind minimum step size */
|
int ff_rewind_min_step; /* FF/Rewind minimum step size */
|
||||||
int ff_rewind_accel; /* FF/Rewind acceleration (in seconds per doubling) */
|
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
|
#ifndef HAVE_FLASH_STORAGE
|
||||||
int disk_spindown; /* time until disk spindown, in seconds (0=off) */
|
int disk_spindown; /* time until disk spindown, in seconds (0=off) */
|
||||||
|
|
|
||||||
|
|
@ -1163,6 +1163,10 @@ const struct settings_list settings[] = {
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
OFFON_SETTING(0,cuesheet,LANG_CUESHEET_ENABLE,false,"cuesheet support", NULL),
|
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,
|
CHOICE_SETTING(0, start_in_screen, LANG_START_SCREEN, 1,
|
||||||
"start in screen", "previous,root,files,db,wps,menu,"
|
"start in screen", "previous,root,files,db,wps,menu,"
|
||||||
#ifdef HAVE_RECORDING
|
#ifdef HAVE_RECORDING
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue