diff options
author | roman.artiukhin <bahusdrive@gmail.com> | 2022-11-05 20:51:02 +0200 |
---|---|---|
committer | Aidan MacDonald <amachronic@protonmail.com> | 2022-11-12 09:13:19 -0500 |
commit | ffe2df2e92cbdeb507a49279a85ac88cac2fbe4f (patch) | |
tree | 997ad849e34891f53ad55fa58fba437949e0aeaa /apps/gui/wps.c | |
parent | 30ec10c790dd09f1eb681312093e945683ec643a (diff) | |
download | rockbox-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
Diffstat (limited to 'apps/gui/wps.c')
-rw-r--r-- | apps/gui/wps.c | 57 |
1 files changed, 39 insertions, 18 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 | ||
205 | static bool ffwd_rew(int button) | 205 | static 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: |