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
This commit is contained in:
Christian Soffke 2021-11-30 21:02:32 +01:00 committed by Aidan MacDonald
parent 8060c79775
commit 69d08be083
6 changed files with 76 additions and 11 deletions

View file

@ -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; crossfade = false;
if (crossfade) if (crossfade)

View file

@ -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 /* Called to make an outstanding track skip the current track and to send the
transition events */ transition events */
static void audio_finalise_track_change(void) static void audio_finalise_track_change(void)
@ -2422,15 +2447,27 @@ static void audio_finalise_track_change(void)
track_id3 = bufgetid3(info.id3_hid); 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 (single_mode_do_pause)
if ( ((skip_pending == TRACK_SKIP_AUTO) || (skip_pending == TRACK_SKIP_AUTO_NEW_PLAYLIST))
&& (global_settings.party_mode == 0) )
{ {
play_status = PLAY_PAUSED; play_status = PLAY_PAUSED;
pcmbuf_pause(true); pcmbuf_pause(true);
} }
}
id3_write(PLAYING_ID3, track_id3);
/* The skip is technically over */ /* The skip is technically over */
skip_pending = TRACK_SKIP_NONE; skip_pending = TRACK_SKIP_NONE;

View file

@ -108,6 +108,18 @@ enum
NUM_REPEAT_MODES 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 enum
{ {
QUEUE_HIDE = 0, QUEUE_HIDE = 0,
@ -476,7 +488,8 @@ struct user_settings
int default_codepage; /* set default codepage for tag conversion */ 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 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 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 party_mode; /* party mode - unstoppable music */
bool audioscrobbler; /* Audioscrobbler logging */ bool audioscrobbler; /* Audioscrobbler logging */
bool cuesheet; bool cuesheet;

View file

@ -1243,7 +1243,18 @@ const struct settings_list settings[] = {
#endif #endif
/* more playback */ /* more playback */
OFFON_SETTING(0,play_selected,LANG_PLAY_SELECTED,true,"play selected",NULL), 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,party_mode,LANG_PARTY_MODE,false,"party mode",NULL),
OFFON_SETTING(0,fade_on_stop,LANG_FADE_ON_STOP,true,"volume fade",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, INT_SETTING(F_TIME_SETTING, ff_rewind_min_step, LANG_FFRW_STEP, 1,

View file

@ -37,7 +37,8 @@
repeat & off, all, one, shuffle, ab repeat & off, all, one, shuffle, ab
& N/A\\ & N/A\\
play selected & on, off & N/A\\ play selected & on, off & N/A\\
single mode & on, off & N/A\\ single mode & off, track, album, album artist, artist, composer, work, genre
& N/A\\
party mode & on, off & N/A\\ party mode & on, off & N/A\\
scan min step & 1, 2, 3, 4, 5, 6, 8, 10, 15, 20, 25, 30, 45, 60 scan min step & 1, 2, 3, 4, 5, 6, 8, 10, 15, 20, 25, 30, 45, 60
& s\\ & s\\

View file

@ -83,9 +83,12 @@ you to configure settings related to audio playback.
playback, and fade in when you resume playback. playback, and fade in when you resume playback.
\section{Single Mode} \section{Single Mode}
If the Single Mode option is set to \setting{Yes}, your music If the Single Mode option is set to \setting{Track}, your music
will pause at every automatic track change. Crossfade on track will pause at every automatic track change.
change will be ignored if this setting is enabled. If it is set to \setting{Album}, \setting{Album Artist}, \setting{Artist},
\setting{Composer}, \setting{Work}, or \setting{Genre},
your music will pause at the next track change where this tag also
changes. Crossfade on track change will be ignored if this setting is enabled.
\section{Party Mode} \section{Party Mode}
Enables unstoppable music playback. When new songs are Enables unstoppable music playback. When new songs are