summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorroman.artiukhin <bahusdrive@gmail.com>2022-11-05 20:51:02 +0200
committerAidan MacDonald <amachronic@protonmail.com>2022-11-12 09:13:19 -0500
commitffe2df2e92cbdeb507a49279a85ac88cac2fbe4f (patch)
tree997ad849e34891f53ad55fa58fba437949e0aeaa
parent30ec10c790dd09f1eb681312093e945683ec643a (diff)
downloadrockbox-ffe2df2e92cbdeb507a49279a85ac88cac2fbe4f.tar.gz
rockbox-ffe2df2e92cbdeb507a49279a85ac88cac2fbe4f.zip
Implement Rewind across tracks functionality
Useful feature for audiobooks. To rewind from the end of the previous track - press rewind at the very beginning of the current track. So if you are in the middle of the track - first rewind till beginning then release and press rewind button again (Playback Settings -> Rewind Across Tracks option should be enabled) Fixes FS#13290 Change-Id: I5d7f06f64ad76d1e8f7827fe594ccca5f621769d
-rw-r--r--apps/gui/wps.c57
-rw-r--r--apps/lang/english.lang14
-rw-r--r--apps/menus/playback_menu.c2
-rw-r--r--apps/settings.h3
-rw-r--r--apps/settings_list.c2
-rw-r--r--docs/CREDITS1
-rw-r--r--manual/appendix/config_file_options.tex2
-rw-r--r--manual/configure_rockbox/playback_options.tex5
8 files changed, 66 insertions, 20 deletions
diff --git a/apps/gui/wps.c b/apps/gui/wps.c
index 9d7a4c96f3..05a64370ac 100644
--- a/apps/gui/wps.c
+++ b/apps/gui/wps.c
@@ -202,7 +202,7 @@ static int skintouch_to_wps(struct wps_data *data)
202} 202}
203#endif /* HAVE_TOUCHSCREEN */ 203#endif /* HAVE_TOUCHSCREEN */
204 204
205static bool ffwd_rew(int button) 205static bool ffwd_rew(int button, bool seek_from_end)
206{ 206{
207 unsigned int step = 0; /* current ff/rewind step */ 207 unsigned int step = 0; /* current ff/rewind step */
208 unsigned int max_step = 0; /* maximum ff/rewind step */ 208 unsigned int max_step = 0; /* maximum ff/rewind step */
@@ -213,6 +213,7 @@ static bool ffwd_rew(int button)
213 bool ff_rewind = false; 213 bool ff_rewind = false;
214 const long ff_rw_accel = (global_settings.ff_rewind_accel + 3); 214 const long ff_rw_accel = (global_settings.ff_rewind_accel + 3);
215 struct wps_state *gstate = get_wps_state(); 215 struct wps_state *gstate = get_wps_state();
216 struct mp3entry *old_id3 = gstate->id3;
216 217
217 if (button == ACTION_NONE) 218 if (button == ACTION_NONE)
218 { 219 {
@@ -221,6 +222,16 @@ static bool ffwd_rew(int button)
221 } 222 }
222 while (!exit) 223 while (!exit)
223 { 224 {
225 struct mp3entry *id3 = gstate->id3;
226 if (id3 != old_id3)
227 {
228 ff_rewind = false;
229 ff_rewind_count = 0;
230 old_id3 = id3;
231 }
232 if (id3 && seek_from_end)
233 id3->elapsed = id3->length;
234
224 switch ( button ) 235 switch ( button )
225 { 236 {
226 case ACTION_WPS_SEEKFWD: 237 case ACTION_WPS_SEEKFWD:
@@ -232,16 +243,16 @@ static bool ffwd_rew(int button)
232 if (direction == 1) 243 if (direction == 1)
233 { 244 {
234 /* fast forwarding, calc max step relative to end */ 245 /* fast forwarding, calc max step relative to end */
235 max_step = (gstate->id3->length - 246 max_step = (id3->length -
236 (gstate->id3->elapsed + 247 (id3->elapsed +
237 ff_rewind_count)) * 248 ff_rewind_count)) *
238 FF_REWIND_MAX_PERCENT / 100; 249 FF_REWIND_MAX_PERCENT / 100;
239 } 250 }
240 else 251 else
241 { 252 {
242 /* rewinding, calc max step relative to start */ 253 /* rewinding, calc max step relative to start */
243 max_step = (gstate->id3->elapsed + ff_rewind_count) * 254 max_step = (id3->elapsed + ff_rewind_count) *
244 FF_REWIND_MAX_PERCENT / 100; 255 FF_REWIND_MAX_PERCENT / 100;
245 } 256 }
246 257
247 max_step = MAX(max_step, MIN_FF_REWIND_STEP); 258 max_step = MAX(max_step, MIN_FF_REWIND_STEP);
@@ -256,8 +267,7 @@ static bool ffwd_rew(int button)
256 } 267 }
257 else 268 else
258 { 269 {
259 if ( (audio_status() & AUDIO_STATUS_PLAY) && 270 if ((audio_status() & AUDIO_STATUS_PLAY) && id3 && id3->length )
260 gstate->id3 && gstate->id3->length )
261 { 271 {
262 audio_pre_ff_rewind(); 272 audio_pre_ff_rewind();
263 if (direction > 0) 273 if (direction > 0)
@@ -274,12 +284,12 @@ static bool ffwd_rew(int button)
274 } 284 }
275 285
276 if (direction > 0) { 286 if (direction > 0) {
277 if ((gstate->id3->elapsed + ff_rewind_count) > gstate->id3->length) 287 if ((id3->elapsed + ff_rewind_count) > id3->length)
278 ff_rewind_count = gstate->id3->length - gstate->id3->elapsed; 288 ff_rewind_count = id3->length - id3->elapsed;
279 } 289 }
280 else { 290 else {
281 if ((int)(gstate->id3->elapsed + ff_rewind_count) < 0) 291 if ((int)(id3->elapsed + ff_rewind_count) < 0)
282 ff_rewind_count = -gstate->id3->elapsed; 292 ff_rewind_count = -id3->elapsed;
283 } 293 }
284 294
285 /* set the wps state ff_rewind_count so the progess info 295 /* set the wps state ff_rewind_count so the progess info
@@ -296,8 +306,8 @@ static bool ffwd_rew(int button)
296 break; 306 break;
297 307
298 case ACTION_WPS_STOPSEEK: 308 case ACTION_WPS_STOPSEEK:
299 gstate->id3->elapsed = gstate->id3->elapsed+ff_rewind_count; 309 id3->elapsed = id3->elapsed + ff_rewind_count;
300 audio_ff_rewind(gstate->id3->elapsed); 310 audio_ff_rewind(id3->elapsed);
301 gstate->ff_rewind_count = 0; 311 gstate->ff_rewind_count = 0;
302 ff_rewind = false; 312 ff_rewind = false;
303 status_set_ffmode(0); 313 status_set_ffmode(0);
@@ -319,8 +329,9 @@ static bool ffwd_rew(int button)
319 if (button == ACTION_TOUCHSCREEN) 329 if (button == ACTION_TOUCHSCREEN)
320 button = skintouch_to_wps(skin_get_gwps(WPS, SCREEN_MAIN)->data); 330 button = skintouch_to_wps(skin_get_gwps(WPS, SCREEN_MAIN)->data);
321#endif 331#endif
322 if (button != ACTION_WPS_SEEKFWD && 332 if (button != ACTION_WPS_SEEKFWD
323 button != ACTION_WPS_SEEKBACK) 333 && button != ACTION_WPS_SEEKBACK
334 && button != 0)
324 button = ACTION_WPS_STOPSEEK; 335 button = ACTION_WPS_STOPSEEK;
325 } 336 }
326 } 337 }
@@ -733,7 +744,7 @@ long gui_wps_show(void)
733 } 744 }
734 } 745 }
735 else 746 else
736 ffwd_rew(ACTION_WPS_SEEKFWD); 747 ffwd_rew(ACTION_WPS_SEEKFWD, false);
737 last_right = last_left = 0; 748 last_right = last_left = 0;
738 break; 749 break;
739 /* fast rewind 750 /* fast rewind
@@ -752,9 +763,19 @@ long gui_wps_show(void)
752 { 763 {
753 change_dir(-1); 764 change_dir(-1);
754 } 765 }
766 } else if (global_settings.rewind_across_tracks
767 && get_wps_state()->id3->elapsed < DEFAULT_SKIP_THRESH
768 && playlist_check(-1))
769 {
770 if (!audio_paused)
771 audio_pause();
772 audio_prev();
773 ffwd_rew(ACTION_WPS_SEEKBACK, true);
774 if (!audio_paused)
775 audio_resume();
755 } 776 }
756 else 777 else
757 ffwd_rew(ACTION_WPS_SEEKBACK); 778 ffwd_rew(ACTION_WPS_SEEKBACK, false);
758 last_left = last_right = 0; 779 last_left = last_right = 0;
759 break; 780 break;
760 781
@@ -926,7 +947,7 @@ long gui_wps_show(void)
926 break; 947 break;
927 case ACTION_NONE: /* Timeout, do a partial update */ 948 case ACTION_NONE: /* Timeout, do a partial update */
928 update = true; 949 update = true;
929 ffwd_rew(button); /* hopefully fix the ffw/rwd bug */ 950 ffwd_rew(button, false); /* hopefully fix the ffw/rwd bug */
930 break; 951 break;
931#ifdef HAVE_RECORDING 952#ifdef HAVE_RECORDING
932 case ACTION_WPS_REC: 953 case ACTION_WPS_REC:
diff --git a/apps/lang/english.lang b/apps/lang/english.lang
index 31090aa861..29a2527bec 100644
--- a/apps/lang/english.lang
+++ b/apps/lang/english.lang
@@ -16388,3 +16388,17 @@
16388 clear_settings_on_hold, iriverh10: "Clear settings when reset button is held during startup" 16388 clear_settings_on_hold, iriverh10: "Clear settings when reset button is held during startup"
16389 </voice> 16389 </voice>
16390</phrase> 16390</phrase>
16391<phrase>
16392 id: LANG_REWIND_ACROSS_TRACKS
16393 desc: in playback settings menu
16394 user: core
16395 <source>
16396 *: "Rewind Across Tracks"
16397 </source>
16398 <dest>
16399 *: "Rewind Across Tracks"
16400 </dest>
16401 <voice>
16402 *: "Rewind across tracks"
16403 </voice>
16404</phrase>
diff --git a/apps/menus/playback_menu.c b/apps/menus/playback_menu.c
index 881a4b5a99..e4945be0b5 100644
--- a/apps/menus/playback_menu.c
+++ b/apps/menus/playback_menu.c
@@ -174,6 +174,7 @@ MAKE_MENU(unplug_menu, ID2P(LANG_HEADPHONE_UNPLUG), 0, Icon_NOICON,
174 174
175MENUITEM_SETTING(skip_length, &global_settings.skip_length, NULL); 175MENUITEM_SETTING(skip_length, &global_settings.skip_length, NULL);
176MENUITEM_SETTING(prevent_skip, &global_settings.prevent_skip, NULL); 176MENUITEM_SETTING(prevent_skip, &global_settings.prevent_skip, NULL);
177MENUITEM_SETTING(rewind_across_tracks, &global_settings.rewind_across_tracks, NULL);
177MENUITEM_SETTING(resume_rewind, &global_settings.resume_rewind, NULL); 178MENUITEM_SETTING(resume_rewind, &global_settings.resume_rewind, NULL);
178MENUITEM_SETTING(pause_rewind, &global_settings.pause_rewind, NULL); 179MENUITEM_SETTING(pause_rewind, &global_settings.pause_rewind, NULL);
179#ifdef HAVE_PLAY_FREQ 180#ifdef HAVE_PLAY_FREQ
@@ -226,6 +227,7 @@ MAKE_MENU(playback_settings,ID2P(LANG_PLAYBACK),0,
226 ,&unplug_menu 227 ,&unplug_menu
227#endif 228#endif
228 ,&skip_length, &prevent_skip 229 ,&skip_length, &prevent_skip
230 ,&rewind_across_tracks
229 231
230 ,&resume_rewind 232 ,&resume_rewind
231 ,&pause_rewind 233 ,&pause_rewind
diff --git a/apps/settings.h b/apps/settings.h
index 092c04a76b..37e546f6fc 100644
--- a/apps/settings.h
+++ b/apps/settings.h
@@ -613,7 +613,8 @@ struct user_settings
613#ifdef HAVE_ALBUMART 613#ifdef HAVE_ALBUMART
614 int album_art; /* switch off album art display or choose preferred source */ 614 int album_art; /* switch off album art display or choose preferred source */
615#endif 615#endif
616 616 bool rewind_across_tracks;
617
617 /* playlist viewer settings */ 618 /* playlist viewer settings */
618 bool playlist_viewer_icons; /* display icons on viewer */ 619 bool playlist_viewer_icons; /* display icons on viewer */
619 bool playlist_viewer_indices; /* display playlist indices on viewer */ 620 bool playlist_viewer_indices; /* display playlist indices on viewer */
diff --git a/apps/settings_list.c b/apps/settings_list.c
index 6d01f5c6fc..f54738163a 100644
--- a/apps/settings_list.c
+++ b/apps/settings_list.c
@@ -2061,7 +2061,7 @@ const struct settings_list settings[] = {
2061 tsc_is_changed, tsc_set_default), 2061 tsc_is_changed, tsc_set_default),
2062#endif 2062#endif
2063 OFFON_SETTING(0, prevent_skip, LANG_PREVENT_SKIPPING, false, "prevent track skip", NULL), 2063 OFFON_SETTING(0, prevent_skip, LANG_PREVENT_SKIPPING, false, "prevent track skip", NULL),
2064 2064 OFFON_SETTING(0, rewind_across_tracks, LANG_REWIND_ACROSS_TRACKS, false, "rewind across tracks", NULL),
2065#ifdef HAVE_PITCHCONTROL 2065#ifdef HAVE_PITCHCONTROL
2066 OFFON_SETTING(0, pitch_mode_semitone, LANG_SEMITONE, false, 2066 OFFON_SETTING(0, pitch_mode_semitone, LANG_SEMITONE, false,
2067 "Semitone pitch change", NULL), 2067 "Semitone pitch change", NULL),
diff --git a/docs/CREDITS b/docs/CREDITS
index 86e009c8a8..c2422e2367 100644
--- a/docs/CREDITS
+++ b/docs/CREDITS
@@ -712,6 +712,7 @@ Selami Dinçer
712Matej Golian 712Matej Golian
713James Le Cuirot 713James Le Cuirot
714Michael Landherr 714Michael Landherr
715Roman Artiukhin
715 716
716The libmad team 717The libmad team
717The wavpack team 718The wavpack team
diff --git a/manual/appendix/config_file_options.tex b/manual/appendix/config_file_options.tex
index bf231de46c..dc186e2d26 100644
--- a/manual/appendix/config_file_options.tex
+++ b/manual/appendix/config_file_options.tex
@@ -174,6 +174,8 @@
174 90s, 2min, 3min, 5min, 10min, 15min & N/A\\ 174 90s, 2min, 3min, 5min, 10min, 15min & N/A\\
175 prevent track skip 175 prevent track skip
176 & on, off & N/A\\ 176 & on, off & N/A\\
177 rewind across tracks
178 & on, off & N/A\\
177 start in screen & previous, root, files, dB, wps, menu, 179 start in screen & previous, root, files, dB, wps, menu,
178 \opt{recording}{recording, } 180 \opt{recording}{recording, }
179 \opt{radio}{radio, } 181 \opt{radio}{radio, }
diff --git a/manual/configure_rockbox/playback_options.tex b/manual/configure_rockbox/playback_options.tex
index a2337439db..0c75315214 100644
--- a/manual/configure_rockbox/playback_options.tex
+++ b/manual/configure_rockbox/playback_options.tex
@@ -287,6 +287,11 @@ you to configure settings related to audio playback.
287 if a track ends, which can be achieved by combining this option with 287 if a track ends, which can be achieved by combining this option with
288 \setting{Repeat} set to \setting{One} 288 \setting{Repeat} set to \setting{One}
289 289
290\section{Rewind Across Tracks}\index{Rewind Across Tracks}
291 Enables rewinding to the end of the previous track. When enabled pressing rewind
292 at the very beginning of the current track (first 3 seconds) skips to the end of
293 the previous track.
294
290\section{Rewind Before Resume}\index{Rewind Before Resume} 295\section{Rewind Before Resume}\index{Rewind Before Resume}
291 When restarting a track or a bookmark, a short rewind can be done before the 296 When restarting a track or a bookmark, a short rewind can be done before the
292 playback is started. This can be useful when listening to speech material, 297 playback is started. This can be useful when listening to speech material,