summaryrefslogtreecommitdiff
path: root/apps
diff options
context:
space:
mode:
authorMichael Hohmuth <sideral@rockbox.org>2011-02-08 20:31:35 +0000
committerMichael Hohmuth <sideral@rockbox.org>2011-02-08 20:31:35 +0000
commit7141ff45133c9c669e9a0769a6c13e05cbe0595c (patch)
tree329e47007c157841d61bc604431223fce3d34ab7 /apps
parent4844142e161f24102bbe45f1f6207f3468649e78 (diff)
downloadrockbox-7141ff45133c9c669e9a0769a6c13e05cbe0595c.tar.gz
rockbox-7141ff45133c9c669e9a0769a6c13e05cbe0595c.zip
Add option to resume next track on automatic track change
Move autoresume setting into its own menu. Add option to customize which tracks should be resumed on automatic track change. Tracks can be selected based on their their file location or genre tag (comma-separated list of filename / genre substrings). git-svn-id: svn://svn.rockbox.org/rockbox/trunk@29251 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'apps')
-rw-r--r--apps/lang/english.lang28
-rw-r--r--apps/menus/settings_menu.c86
-rw-r--r--apps/metadata.c47
-rw-r--r--apps/metadata.h7
-rw-r--r--apps/playback.c9
-rw-r--r--apps/settings.h7
-rw-r--r--apps/settings_list.c9
7 files changed, 165 insertions, 28 deletions
diff --git a/apps/lang/english.lang b/apps/lang/english.lang
index dd8ed84caf..7da2cc2959 100644
--- a/apps/lang/english.lang
+++ b/apps/lang/english.lang
@@ -12716,3 +12716,31 @@
12716 *: "Automatic resume" 12716 *: "Automatic resume"
12717 </voice> 12717 </voice>
12718</phrase> 12718</phrase>
12719<phrase>
12720 id: LANG_AUTORESUME_AUTOMATIC
12721 desc: resume on automatic track change
12722 user: core
12723 <source>
12724 *: "Resume on automatic track change"
12725 </source>
12726 <dest>
12727 *: "Resume on automatic track change"
12728 </dest>
12729 <voice>
12730 *: "Resume on automatic track change"
12731 </voice>
12732</phrase>
12733<phrase>
12734 id: LANG_AUTORESUME_CUSTOM
12735 desc: enable customization of resume on automatic track change
12736 user: core
12737 <source>
12738 *: "Custom path/genre substrings (comma-separated)"
12739 </source>
12740 <dest>
12741 *: "Custom path/genre substrings (comma-separated)"
12742 </dest>
12743 <voice>
12744 *: "Custom path/genre substrings (comma-separated)"
12745 </voice>
12746</phrase>
diff --git a/apps/menus/settings_menu.c b/apps/menus/settings_menu.c
index ce03e1a646..363792870d 100644
--- a/apps/menus/settings_menu.c
+++ b/apps/menus/settings_menu.c
@@ -28,6 +28,7 @@
28#include "action.h" 28#include "action.h"
29#include "settings.h" 29#include "settings.h"
30#include "menu.h" 30#include "menu.h"
31#include "keyboard.h"
31#include "sound_menu.h" 32#include "sound_menu.h"
32#include "exported_menus.h" 33#include "exported_menus.h"
33#include "tree.h" 34#include "tree.h"
@@ -368,6 +369,64 @@ MAKE_MENU(bookmark_settings_menu, ID2P(LANG_BOOKMARK_SETTINGS), 0,
368/***********************************/ 369/***********************************/
369 370
370/***********************************/ 371/***********************************/
372/* AUTORESUME MENU */
373#ifdef HAVE_TAGCACHE
374#if CONFIG_CODEC == SWCODEC
375
376static int autoresume_callback(int action, const struct menu_item_ex *this_item)
377{
378 (void)this_item;
379
380 if (action == ACTION_EXIT_MENUITEM /* on exit */
381 && global_settings.autoresume_enable
382 && !tagcache_is_usable())
383 {
384 static const char *lines[] = {ID2P(LANG_TAGCACHE_BUSY),
385 ID2P(LANG_TAGCACHE_FORCE_UPDATE)};
386 static const struct text_message message = {lines, 2};
387
388 if (gui_syncyesno_run(&message, NULL, NULL) == YESNO_YES)
389 tagcache_rebuild_with_splash();
390 }
391 return action;
392}
393
394static int autoresume_nexttrack_callback(int action,
395 const struct menu_item_ex *this_item)
396{
397 (void)this_item;
398 static int oldval = 0;
399 switch (action)
400 {
401 case ACTION_ENTER_MENUITEM:
402 oldval = global_settings.autoresume_automatic;
403 break;
404 case ACTION_EXIT_MENUITEM:
405 if (global_settings.autoresume_automatic == AUTORESUME_NEXTTRACK_CUSTOM
406 && kbd_input ((char*) &global_settings.autoresume_strpat,
407 MAX_PATHNAME+1) < 0)
408 {
409 global_settings.autoresume_automatic = oldval;
410 }
411 }
412 return action;
413}
414
415MENUITEM_SETTING(autoresume_enable, &global_settings.autoresume_enable,
416 autoresume_callback);
417MENUITEM_SETTING(autoresume_automatic, &global_settings.autoresume_automatic,
418 autoresume_nexttrack_callback);
419
420MAKE_MENU(autoresume_menu, ID2P(LANG_AUTORESUME),
421 0, Icon_NOICON,
422 &autoresume_enable, &autoresume_automatic);
423
424#endif /* CONFIG_CODEC == SWCODEC */
425#endif /* HAVE_TAGCACHE */
426/* AUTORESUME MENU */
427/***********************************/
428
429/***********************************/
371/* VOICE MENU */ 430/* VOICE MENU */
372static int talk_callback(int action,const struct menu_item_ex *this_item); 431static int talk_callback(int action,const struct menu_item_ex *this_item);
373MENUITEM_SETTING(talk_menu_item, &global_settings.talk_menu, NULL); 432MENUITEM_SETTING(talk_menu_item, &global_settings.talk_menu, NULL);
@@ -425,31 +484,6 @@ MAKE_MENU(hotkey_menu, ID2P(LANG_HOTKEY), 0, Icon_NOICON,
425/***********************************/ 484/***********************************/
426/* SETTINGS MENU */ 485/* SETTINGS MENU */
427 486
428#ifdef HAVE_TAGCACHE
429#if CONFIG_CODEC == SWCODEC
430static int autoresume_callback(int action, const struct menu_item_ex *this_item)
431{
432 (void)this_item;
433
434 if (action == ACTION_EXIT_MENUITEM /* on exit */
435 && global_settings.autoresume_enable
436 && !tagcache_is_usable())
437 {
438 static const char *lines[] = {ID2P(LANG_TAGCACHE_BUSY),
439 ID2P(LANG_TAGCACHE_FORCE_UPDATE)};
440 static const struct text_message message = {lines, 2};
441
442 if (gui_syncyesno_run(&message, NULL, NULL) == YESNO_YES)
443 tagcache_rebuild_with_splash();
444 }
445 return action;
446}
447
448MENUITEM_SETTING(autoresume_enable, &global_settings.autoresume_enable,
449 autoresume_callback);
450#endif
451#endif
452
453static struct browse_folder_info langs = { LANG_DIR, SHOW_LNG }; 487static struct browse_folder_info langs = { LANG_DIR, SHOW_LNG };
454 488
455MENUITEM_FUNCTION(browse_langs, MENU_FUNC_USEPARAM, ID2P(LANG_LANGUAGE), 489MENUITEM_FUNCTION(browse_langs, MENU_FUNC_USEPARAM, ID2P(LANG_LANGUAGE),
@@ -465,7 +499,7 @@ MAKE_MENU(settings_menu_item, ID2P(LANG_GENERAL_SETTINGS), 0,
465 &bookmark_settings_menu, 499 &bookmark_settings_menu,
466#ifdef HAVE_TAGCACHE 500#ifdef HAVE_TAGCACHE
467#if CONFIG_CODEC == SWCODEC 501#if CONFIG_CODEC == SWCODEC
468 &autoresume_enable, 502 &autoresume_menu,
469#endif 503#endif
470#endif 504#endif
471 &browse_langs, &voice_settings_menu, 505 &browse_langs, &voice_settings_menu,
diff --git a/apps/metadata.c b/apps/metadata.c
index 47c0e7449b..da20a0df2b 100644
--- a/apps/metadata.c
+++ b/apps/metadata.c
@@ -25,6 +25,7 @@
25 25
26#include "debug.h" 26#include "debug.h"
27#include "logf.h" 27#include "logf.h"
28#include "settings.h"
28#include "cuesheet.h" 29#include "cuesheet.h"
29#include "metadata.h" 30#include "metadata.h"
30 31
@@ -425,3 +426,49 @@ void copy_mp3entry(struct mp3entry *dest, const struct mp3entry *orig)
425 memcpy(dest, orig, sizeof(struct mp3entry)); 426 memcpy(dest, orig, sizeof(struct mp3entry));
426 adjust_mp3entry(dest, dest, orig); 427 adjust_mp3entry(dest, dest, orig);
427} 428}
429
430#ifdef HAVE_TAGCACHE
431#if CONFIG_CODEC == SWCODEC
432
433enum { AUTORESUMABLE_UNKNOWN = 0, AUTORESUMABLE_TRUE, AUTORESUMABLE_FALSE };
434
435bool autoresumable(struct mp3entry *id3)
436{
437 unsigned char search[MAX_PATHNAME+1];
438 char *saveptr, *substr;
439 bool is_resumable;
440
441 if (id3->autoresumable) /* result cached? */
442 return id3->autoresumable == AUTORESUMABLE_TRUE;
443
444 is_resumable = true;
445
446 strcpy(search, global_settings.autoresume_strpat);
447
448 for (substr = strtok_r(search, ",", &saveptr);
449 substr;
450 substr = strtok_r(NULL, ",", &saveptr))
451 {
452 if (id3->path && strcasestr(id3->path, substr))
453 goto out;
454 if (id3->genre_string && strcasestr(id3->genre_string, substr))
455 goto out;
456 }
457
458 is_resumable = false;
459
460 out:
461 /* cache result */
462 id3->autoresumable =
463 is_resumable ? AUTORESUMABLE_TRUE : AUTORESUMABLE_FALSE;
464
465 logf("autoresumable: %s with genre %s is%s resumable",
466 id3->path,
467 id3->genre_string ? id3->genre_string : "(NULL)",
468 is_resumable ? "" : " not");
469
470 return is_resumable;
471}
472
473#endif /* SWCODEC */
474#endif /* HAVE_TAGCACHE */
diff --git a/apps/metadata.h b/apps/metadata.h
index 3831062418..b99d4d09d6 100644
--- a/apps/metadata.h
+++ b/apps/metadata.h
@@ -255,6 +255,8 @@ struct mp3entry {
255 int index; /* playlist index */ 255 int index; /* playlist index */
256 256
257#ifdef HAVE_TAGCACHE 257#ifdef HAVE_TAGCACHE
258 unsigned char autoresumable; /* caches result of autoresumable() */
259
258 /* runtime database fields */ 260 /* runtime database fields */
259 long tagcache_idx; /* 0=invalid, otherwise idx+1 */ 261 long tagcache_idx; /* 0=invalid, otherwise idx+1 */
260 int rating; 262 int rating;
@@ -287,10 +289,15 @@ bool get_metadata(struct mp3entry* id3, int fd, const char* trackname);
287bool mp3info(struct mp3entry *entry, const char *filename); 289bool mp3info(struct mp3entry *entry, const char *filename);
288void adjust_mp3entry(struct mp3entry *entry, void *dest, const void *orig); 290void adjust_mp3entry(struct mp3entry *entry, void *dest, const void *orig);
289void copy_mp3entry(struct mp3entry *dest, const struct mp3entry *orig); 291void copy_mp3entry(struct mp3entry *dest, const struct mp3entry *orig);
292
290#if CONFIG_CODEC == SWCODEC 293#if CONFIG_CODEC == SWCODEC
291void strip_tags(int handle_id); 294void strip_tags(int handle_id);
292#endif 295#endif
293 296
297#ifdef HAVE_TAGCACHE
298bool autoresumable(struct mp3entry *id3);
299#endif
300
294#endif 301#endif
295 302
296 303
diff --git a/apps/playback.c b/apps/playback.c
index e33a4ac507..fe7b74893a 100644
--- a/apps/playback.c
+++ b/apps/playback.c
@@ -1002,8 +1002,13 @@ static void audio_update_trackinfo(void)
1002 thistrack_id3->elapsed = 0; 1002 thistrack_id3->elapsed = 0;
1003 1003
1004#ifdef HAVE_TAGCACHE 1004#ifdef HAVE_TAGCACHE
1005 /* Resume all manually selected tracks if so configured */ 1005 /* Ignoring resume position for automatic track change if so configured */
1006 resume = global_settings.autoresume_enable && !automatic_skip; 1006 resume = global_settings.autoresume_enable &&
1007 (!automatic_skip /* Resume all manually selected tracks */
1008 || global_settings.autoresume_automatic == AUTORESUME_NEXTTRACK_ALWAYS
1009 || (global_settings.autoresume_automatic != AUTORESUME_NEXTTRACK_NEVER
1010 /* Not never resume? */
1011 && autoresumable(thistrack_id3))); /* Pass Resume filter? */
1007#endif 1012#endif
1008 1013
1009 if (!resume) 1014 if (!resume)
diff --git a/apps/settings.h b/apps/settings.h
index 131ff181dd..ae32a65bc6 100644
--- a/apps/settings.h
+++ b/apps/settings.h
@@ -125,6 +125,10 @@ enum { SHOW_PATH_OFF = 0, SHOW_PATH_CURRENT, SHOW_PATH_FULL };
125/* scrollbar visibility/position */ 125/* scrollbar visibility/position */
126enum { SCROLLBAR_OFF = 0, SCROLLBAR_LEFT, SCROLLBAR_RIGHT }; 126enum { SCROLLBAR_OFF = 0, SCROLLBAR_LEFT, SCROLLBAR_RIGHT };
127 127
128/* autoresume settings */
129enum { AUTORESUME_NEXTTRACK_NEVER = 0, AUTORESUME_NEXTTRACK_ALWAYS,
130 AUTORESUME_NEXTTRACK_CUSTOM};
131
128/* Alarm settings */ 132/* Alarm settings */
129#ifdef HAVE_RTC_ALARM 133#ifdef HAVE_RTC_ALARM
130enum { ALARM_START_WPS = 0, 134enum { ALARM_START_WPS = 0,
@@ -577,6 +581,9 @@ struct user_settings
577#endif 581#endif
578 bool tagcache_autoupdate; /* automatically keep tagcache in sync? */ 582 bool tagcache_autoupdate; /* automatically keep tagcache in sync? */
579 bool autoresume_enable; /* enable auto-resume feature? */ 583 bool autoresume_enable; /* enable auto-resume feature? */
584 int autoresume_automatic; /* resume next track? 0=never, 1=always,
585 2=custom */
586 unsigned char autoresume_strpat[MAX_PATHNAME+1]; /* comma-separated list */
580 bool runtimedb; /* runtime database active? */ 587 bool runtimedb; /* runtime database active? */
581#endif /* HAVE_TAGCACHE */ 588#endif /* HAVE_TAGCACHE */
582 589
diff --git a/apps/settings_list.c b/apps/settings_list.c
index 0521d4fb90..75e989eb10 100644
--- a/apps/settings_list.c
+++ b/apps/settings_list.c
@@ -1261,6 +1261,15 @@ const struct settings_list settings[] = {
1261 BOOL_SETTING(0, autoresume_enable, LANG_AUTORESUME, false, 1261 BOOL_SETTING(0, autoresume_enable, LANG_AUTORESUME, false,
1262 "autoresume enable", off_on, 1262 "autoresume enable", off_on,
1263 LANG_SET_BOOL_YES, LANG_SET_BOOL_NO, NULL), 1263 LANG_SET_BOOL_YES, LANG_SET_BOOL_NO, NULL),
1264 CHOICE_SETTING(0, autoresume_automatic, LANG_AUTORESUME_AUTOMATIC,
1265 AUTORESUME_NEXTTRACK_NEVER,
1266 "autoresume next track", "never,all,custom",
1267 NULL, 3,
1268 ID2P(LANG_SET_BOOL_NO),
1269 ID2P(LANG_ALWAYS),
1270 ID2P(LANG_AUTORESUME_CUSTOM)),
1271 TEXT_SETTING(0, autoresume_strpat, "autoresume next track patterns",
1272 "podcast", NULL, NULL),
1264#endif 1273#endif
1265 1274
1266 OFFON_SETTING(0, runtimedb, LANG_RUNTIMEDB_ACTIVE, false, 1275 OFFON_SETTING(0, runtimedb, LANG_RUNTIMEDB_ACTIVE, false,