From 69d08be0830966175b92d68ece8ad0119898fef2 Mon Sep 17 00:00:00 2001 From: Christian Soffke Date: Tue, 30 Nov 2021 21:02:32 +0100 Subject: 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 --- apps/pcmbuf.c | 2 +- apps/playback.c | 45 +++++++++++++++++++++++++++++++++++++++++---- apps/settings.h | 15 ++++++++++++++- apps/settings_list.c | 13 ++++++++++++- 4 files changed, 68 insertions(+), 7 deletions(-) (limited to 'apps') 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, -- cgit v1.2.3