summaryrefslogtreecommitdiffstats
path: root/apps
diff options
context:
space:
mode:
authorChristian Soffke <christian.soffke@gmail.com>2021-11-30 21:02:32 +0100
committerAidan MacDonald <amachronic@protonmail.com>2021-12-11 11:43:39 -0500
commit69d08be0830966175b92d68ece8ad0119898fef2 (patch)
treed93941dfe1e33f294a073c82dd00cd90e1a259fb /apps
parent8060c797752c3addbaa8c75e84721fbd3127860f (diff)
downloadrockbox-69d08be0830966175b92d68ece8ad0119898fef2.tar.gz
rockbox-69d08be0830966175b92d68ece8ad0119898fef2.zip
Additional Single Mode options
In addition to the existing behavior of pausing after each song, this adds options to pause after playing current: Album, Album Artist, Artist, Composer, Grouping / Work, or Genre. Allows you, for example, to only listen to the remaining movements of a classical work without having to purge your playlist of any upcoming songs. Change-Id: If18f4a5d139320026cc5fcc9adf29dd8e4e028a8
Diffstat (limited to 'apps')
-rw-r--r--apps/pcmbuf.c2
-rw-r--r--apps/playback.c45
-rw-r--r--apps/settings.h15
-rw-r--r--apps/settings_list.c13
4 files changed, 68 insertions, 7 deletions
diff --git a/apps/pcmbuf.c b/apps/pcmbuf.c
index c4164c3b4b..8718d730fb 100644
--- a/apps/pcmbuf.c
+++ b/apps/pcmbuf.c
@@ -741,7 +741,7 @@ void pcmbuf_start_track_change(enum pcm_track_change_type type)
}
}
- if (auto_skip && global_settings.single_mode && !global_settings.party_mode)
+ if (auto_skip && global_settings.single_mode != SINGLE_MODE_OFF && !global_settings.party_mode)
crossfade = false;
if (crossfade)
diff --git a/apps/playback.c b/apps/playback.c
index 5d980b5634..4162d9b647 100644
--- a/apps/playback.c
+++ b/apps/playback.c
@@ -2367,6 +2367,31 @@ static void audio_on_handle_finished(int hid)
}
}
+static inline char* single_mode_get_id3_tag(struct mp3entry *id3)
+{
+ struct mp3entry *valid_id3 = valid_mp3entry(id3);
+ if (valid_id3 == NULL)
+ return NULL;
+
+ switch (global_settings.single_mode)
+ {
+ case SINGLE_MODE_ALBUM:
+ return valid_id3->album;
+ case SINGLE_MODE_ALBUM_ARTIST:
+ return valid_id3->albumartist;
+ case SINGLE_MODE_ARTIST:
+ return valid_id3->artist;
+ case SINGLE_MODE_COMPOSER:
+ return valid_id3->composer;
+ case SINGLE_MODE_GROUPING:
+ return valid_id3->grouping;
+ case SINGLE_MODE_GENRE:
+ return valid_id3->genre_string;
+ }
+
+ return NULL;
+}
+
/* Called to make an outstanding track skip the current track and to send the
transition events */
static void audio_finalise_track_change(void)
@@ -2422,15 +2447,27 @@ static void audio_finalise_track_change(void)
track_id3 = bufgetid3(info.id3_hid);
}
- id3_write(PLAYING_ID3, track_id3);
+ if (SINGLE_MODE_OFF != global_settings.single_mode && global_settings.party_mode == 0 &&
+ ((skip_pending == TRACK_SKIP_AUTO) || (skip_pending == TRACK_SKIP_AUTO_NEW_PLAYLIST)))
+ {
+ bool single_mode_do_pause = true;
+ if (SINGLE_MODE_TRACK != global_settings.single_mode)
+ {
+ char *previous_tag = single_mode_get_id3_tag(id3_get(PLAYING_ID3));
+ char *new_tag = single_mode_get_id3_tag(track_id3);
+ single_mode_do_pause = previous_tag == NULL ||
+ new_tag == NULL ||
+ strcmp(previous_tag, new_tag) != 0;
+ }
- if (global_settings.single_mode)
- if ( ((skip_pending == TRACK_SKIP_AUTO) || (skip_pending == TRACK_SKIP_AUTO_NEW_PLAYLIST))
- && (global_settings.party_mode == 0) )
+ if (single_mode_do_pause)
{
play_status = PLAY_PAUSED;
pcmbuf_pause(true);
}
+ }
+
+ id3_write(PLAYING_ID3, track_id3);
/* The skip is technically over */
skip_pending = TRACK_SKIP_NONE;
diff --git a/apps/settings.h b/apps/settings.h
index 79b47f6a0f..b3c31476e3 100644
--- a/apps/settings.h
+++ b/apps/settings.h
@@ -108,6 +108,18 @@ enum
NUM_REPEAT_MODES
};
+/* single mode options */
+enum {
+ SINGLE_MODE_OFF = 0,
+ SINGLE_MODE_TRACK,
+ SINGLE_MODE_ALBUM,
+ SINGLE_MODE_ALBUM_ARTIST,
+ SINGLE_MODE_ARTIST,
+ SINGLE_MODE_COMPOSER,
+ SINGLE_MODE_GROUPING,
+ SINGLE_MODE_GENRE
+};
+
enum
{
QUEUE_HIDE = 0,
@@ -476,7 +488,8 @@ struct user_settings
int default_codepage; /* set default codepage for tag conversion */
bool hold_lr_for_scroll_in_list; /* hold L/R scrolls the list left/right */
bool play_selected; /* Plays selected file even in shuffle mode */
- bool single_mode; /* single mode - stop after every track */
+ int single_mode; /* single mode - stop after every track, album, album artist,
+ artist, composer, work, or genre */
bool party_mode; /* party mode - unstoppable music */
bool audioscrobbler; /* Audioscrobbler logging */
bool cuesheet;
diff --git a/apps/settings_list.c b/apps/settings_list.c
index f93b3c272a..982b483874 100644
--- a/apps/settings_list.c
+++ b/apps/settings_list.c
@@ -1243,7 +1243,18 @@ const struct settings_list settings[] = {
#endif
/* more playback */
OFFON_SETTING(0,play_selected,LANG_PLAY_SELECTED,true,"play selected",NULL),
- OFFON_SETTING(0,single_mode,LANG_SINGLE_MODE,false,"single mode",NULL),
+ CHOICE_SETTING(0, single_mode, LANG_SINGLE_MODE, 0,
+ "single mode",
+ "off,track,album,album artist,artist,composer,work,genre",
+ NULL, 8,
+ ID2P(LANG_OFF),
+ ID2P(LANG_TRACK),
+ ID2P(LANG_ID3_ALBUM),
+ ID2P(LANG_ID3_ALBUMARTIST),
+ ID2P(LANG_ID3_ARTIST),
+ ID2P(LANG_ID3_COMPOSER),
+ ID2P(LANG_ID3_GROUPING),
+ ID2P(LANG_ID3_GENRE)),
OFFON_SETTING(0,party_mode,LANG_PARTY_MODE,false,"party mode",NULL),
OFFON_SETTING(0,fade_on_stop,LANG_FADE_ON_STOP,true,"volume fade",NULL),
INT_SETTING(F_TIME_SETTING, ff_rewind_min_step, LANG_FFRW_STEP, 1,