Index: trunk/apps/gui/gwps-common.c =================================================================== --- trunk.orig/apps/gui/gwps-common.c +++ trunk/apps/gui/gwps-common.c @@ -56,6 +56,7 @@ #if (LCD_DEPTH > 1) || (defined(HAVE_LCD_REMOTE) && (LCD_REMOTE_DEPTH > 1)) #include "backdrop.h" #endif +#include "pcmbuf.h" #define FF_REWIND_MAX_PERCENT 3 /* cap ff/rewind step size at max % of file */ /* 3% of 30min file == 54s step size */ @@ -142,6 +143,36 @@ bool update_onvol_change(struct gui_wps 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) { + pcmbuf_beep(1000, 150, 1500*global_settings.beep); + 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) { static const uint16_t ff_rew_steps[] = { Index: trunk/apps/gui/gwps-common.h =================================================================== --- trunk.orig/apps/gui/gwps-common.h +++ trunk/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); Index: trunk/apps/gui/gwps.c =================================================================== --- trunk.orig/apps/gui/gwps.c +++ trunk/apps/gui/gwps.c @@ -92,6 +92,51 @@ static void gui_wps_set_margin(struct gu } #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; @@ -331,11 +376,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) { @@ -346,15 +393,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) { @@ -371,8 +426,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 */ @@ -400,34 +461,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; @@ -452,18 +492,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 */ Index: trunk/apps/menus/playback_menu.c =================================================================== --- trunk.orig/apps/menus/playback_menu.c +++ trunk/apps/menus/playback_menu.c @@ -60,8 +60,11 @@ MENUITEM_SETTING(play_selected, &global_ MENUITEM_SETTING(ff_rewind_accel, &global_settings.ff_rewind_accel, NULL); MENUITEM_SETTING(ff_rewind_min_step, &global_settings.ff_rewind_min_step, NULL); +MENUITEM_SETTING(study_mode, &global_settings.study_mode, NULL); +MENUITEM_SETTING(study_hop_step, &global_settings.study_hop_step, NULL); MAKE_MENU(ff_rewind_settings_menu, ID2P(LANG_WIND_MENU), 0, Icon_NOICON, - &ff_rewind_min_step, &ff_rewind_accel); + &ff_rewind_min_step, &ff_rewind_accel, + &study_mode, &study_hop_step); #ifndef HAVE_FLASH_STORAGE #if CONFIG_CODEC == SWCODEC int buffermargin_callback(int action,const struct menu_item_ex *this_item) Index: trunk/apps/settings.h =================================================================== --- trunk.orig/apps/settings.h +++ trunk/apps/settings.h @@ -453,6 +453,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) */ Index: trunk/apps/settings_list.c =================================================================== --- trunk.orig/apps/settings_list.c +++ trunk/apps/settings_list.c @@ -636,6 +636,9 @@ const struct settings_list settings[] = ff_rewind_min_step_getlang, NULL), INT_SETTING(0, ff_rewind_accel, LANG_FFRW_ACCEL, 3, "scan accel", UNIT_SEC, 16, 0, -1, scanaccel_formatter, scanaccel_getlang, NULL), + OFFON_SETTING(0,study_mode,LANG_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), #if (CONFIG_CODEC == SWCODEC) && !defined(HAVE_FLASH_STORAGE) STRINGCHOICE_SETTING(0, buffer_margin, LANG_MP3BUFFER_MARGIN, 0,"antiskip", "5s,15s,30s,1min,2min,3min,5min,10min",NULL, 8, Index: trunk/apps/lang/english.lang =================================================================== --- trunk.orig/apps/lang/english.lang +++ trunk/apps/lang/english.lang @@ -11516,12 +11516,40 @@ desc: onplay menu user: *: "Playing time" *: "Playing time" *: "Playing time" + + id: LANG_STUDY_MODE + desc: playback settings menu + user: + + *: "Study Mode" + + + *: "Study Mode" + + + *: "Study Mode" + + + + id: LANG_STUDY_HOP_STEP + desc: playback settings menu + user: + + *: "Study Increment" + + + *: "Study Increment" + + + *: "Study Increment" + +