Skip to content

Commit

Permalink
feat: commands for next/previous album that respect shuffle settings (#…
Browse files Browse the repository at this point in the history
…3007)

* refactor checking if items belong to same album

* streamer: refactor finding minimal notplayed into separate function

preparation for album navigation

* feat: commands for next/previous album that respect shuffle settings

* linting: trim some empty lines

* fix: add version check to DB_EV_PLAY_*_ALBUM enum values
  • Loading branch information
rsekman authored Oct 9, 2023
1 parent 10cbe7b commit 03365d9
Show file tree
Hide file tree
Showing 9 changed files with 1,147 additions and 84 deletions.
678 changes: 678 additions & 0 deletions Tests/AlbumNavigationTests.cpp

Large diffs are not rendered by default.

21 changes: 21 additions & 0 deletions Tests/TestData/AlbumNavigation.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
0 Metallica Master of Puppets Battery
0 Metallica Master of Puppets Master of Puppets
0 Metallica Master of Puppets The Thing That Should Not Be
0 Metallica Master of Puppets Welcome Home (Sanitarium)
0 Metallica Master of Puppets Disposable Heroes
0 Metallica Master of Puppets Leper Messiah
0 Metallica Master of Puppets Orion
0 Metallica Master of Puppets Damage, Inc.
2 Iron Maiden Powerslave Aces High
2 Iron Maiden Powerslave 2 Minutes to Midnight
2 Iron Maiden Powerslave Losfer Words (Big 'Orra)
2 Iron Maiden Powerslave Flash of the Blade
2 Iron Maiden Powerslave The Duellists
2 Iron Maiden Powerslave Back in the Village
2 Iron Maiden Powerslave Powerslave
2 Iron Maiden Powerslave Rime of the Ancient Mariner
1 King Crimson Red Red
1 King Crimson Red Fallen Angel
1 King Crimson Red One More Red Nightmare
1 King Crimson Red Providence
1 King Crimson Red Starless
5 changes: 4 additions & 1 deletion include/deadbeef/deadbeef.h
Original file line number Diff line number Diff line change
Expand Up @@ -525,8 +525,11 @@ enum {
// which includes a switch to another output plugin.
// p1 contains the new state.
DB_EV_PLAYBACK_STATE_DID_CHANGE = 25,
#endif

DB_EV_PLAY_NEXT_ALBUM = 26, // switch to next album
DB_EV_PLAY_PREV_ALBUM = 27, // switch to prev album
DB_EV_PLAY_RANDOM_ALBUM = 28, // play random album
#endif
// -----------------
// structured events

Expand Down
44 changes: 43 additions & 1 deletion plugins/hotkeys/hotkeys.c
Original file line number Diff line number Diff line change
Expand Up @@ -675,6 +675,24 @@ action_play_random_cb (struct DB_plugin_action_s *action, ddb_action_context_t c
return 0;
}

int
action_play_random_album_cb (struct DB_plugin_action_s *action, ddb_action_context_t ctx) {
deadbeef->sendmessage (DB_EV_PLAY_RANDOM_ALBUM, 0, 0, 0);
return 0;
}

int
action_play_next_album_cb (struct DB_plugin_action_s *action, ddb_action_context_t ctx) {
deadbeef->sendmessage (DB_EV_PLAY_NEXT_ALBUM, 0, 0, 0);
return 0;
}

int
action_play_prev_album_cb (struct DB_plugin_action_s *action, ddb_action_context_t ctx) {
deadbeef->sendmessage (DB_EV_PLAY_PREV_ALBUM, 0, 0, 0);
return 0;
}

int
action_seek_5p_forward_cb (struct DB_plugin_action_s *action, ddb_action_context_t ctx) {
DB_playItem_t *it = deadbeef->streamer_get_playing_track_safe ();
Expand Down Expand Up @@ -1189,12 +1207,36 @@ static DB_plugin_action_t action_play_pause = {
.next = &action_toggle_pause
};

static DB_plugin_action_t action_play_next_album = {
.title = "Playback/Play Next Album",
.name = "playback_next_album",
.flags = DB_ACTION_COMMON,
.callback2 = action_play_next_album_cb,
.next = &action_play_pause
};

static DB_plugin_action_t action_play_prev_album = {
.title = "Playback/Play Previous Album",
.name = "playback_prev_album",
.flags = DB_ACTION_COMMON,
.callback2 = action_play_prev_album_cb,
.next = &action_play_next_album
};

static DB_plugin_action_t action_play_random_album = {
.title = "Playback/Play Random Album",
.name = "playback_random_album",
.flags = DB_ACTION_COMMON,
.callback2 = action_play_random_album_cb,
.next = &action_play_prev_album
};

static DB_plugin_action_t action_play_random = {
.title = "Playback/Play Random",
.name = "playback_random",
.flags = DB_ACTION_COMMON,
.callback2 = action_play_random_cb,
.next = &action_play_pause
.next = &action_play_random_album
};

static DB_plugin_action_t action_seek_1s_forward = {
Expand Down
9 changes: 9 additions & 0 deletions src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -871,6 +871,12 @@ player_mainloop (void) {
case DB_EV_PREV:
streamer_move_to_prevsong (1);
break;
case DB_EV_PLAY_NEXT_ALBUM:
streamer_move_to_nextalbum (1);
break;
case DB_EV_PLAY_PREV_ALBUM:
streamer_move_to_prevalbum (1);
break;
case DB_EV_PAUSE:
if (output->state () != DDB_PLAYBACK_STATE_PAUSED) {
output->pause ();
Expand All @@ -889,6 +895,9 @@ player_mainloop (void) {
case DB_EV_PLAY_RANDOM:
streamer_move_to_randomsong (1);
break;
case DB_EV_PLAY_RANDOM_ALBUM:
streamer_move_to_randomalbum (1);
break;
case DB_EV_CONFIGCHANGED:
conf_save ();
streamer_configchanged ();
Expand Down
61 changes: 28 additions & 33 deletions src/playlist.c
Original file line number Diff line number Diff line change
Expand Up @@ -1679,24 +1679,7 @@ plt_insert_item (playlist_t *playlist, playItem_t *after, playItem_t *it) {

// shuffle
playItem_t *prev = it->prev[PL_MAIN];
const char *aa = NULL, *prev_aa = NULL;
if (prev) {
aa = pl_find_meta_raw (it, "band");
if (!aa) {
aa = pl_find_meta_raw (it, "album artist");
}
if (!aa) {
aa = pl_find_meta_raw (it, "albumartist");
}
prev_aa = pl_find_meta_raw (prev, "band");
if (!prev_aa) {
prev_aa = pl_find_meta_raw (prev, "album artist");
}
if (!prev_aa) {
prev_aa = pl_find_meta_raw (prev, "albumartist");
}
}
if (streamer_get_shuffle () == DDB_SHUFFLE_ALBUMS && prev && pl_find_meta_raw (prev, "album") == pl_find_meta_raw (it, "album") && ((aa && prev_aa && aa == prev_aa) || pl_find_meta_raw (prev, "artist") == pl_find_meta_raw (it, "artist"))) {
if (streamer_get_shuffle () == DDB_SHUFFLE_ALBUMS && prev && pl_items_from_same_album(prev, it)) {
it->shufflerating = prev->shufflerating;
}
else {
Expand Down Expand Up @@ -2610,27 +2593,13 @@ plt_reshuffle (playlist_t *playlist, playItem_t **ppmin, playItem_t **ppmax) {
playItem_t *pmin = NULL;
playItem_t *pmax = NULL;
playItem_t *prev = NULL;
const char *alb = NULL;
const char *art = NULL;
const char *aa = NULL;
for (playItem_t *it = playlist->head[PL_MAIN]; it; it = it->next[PL_MAIN]) {
const char *new_aa = NULL;
new_aa = pl_find_meta_raw (it, "band");
if (!new_aa) {
new_aa = pl_find_meta_raw (it, "album artist");
}
if (!new_aa) {
new_aa = pl_find_meta_raw (it, "albumartist");
}
if (streamer_get_shuffle () == DDB_SHUFFLE_ALBUMS && prev && alb == pl_find_meta_raw (it, "album") && ((aa && new_aa && aa == new_aa) || art == pl_find_meta_raw (it, "artist"))) {
if (streamer_get_shuffle () == DDB_SHUFFLE_ALBUMS && prev && pl_items_from_same_album(it, prev)) {
it->shufflerating = prev->shufflerating;
}
else {
prev = it;
it->shufflerating = rand ();
alb = pl_find_meta_raw (it, "album");
art = pl_find_meta_raw (it, "artist");
aa = new_aa;
}
if (!pmin || it->shufflerating < pmin->shufflerating) {
pmin = it;
Expand Down Expand Up @@ -4170,3 +4139,29 @@ pl_set_shufflerating (playItem_t *it, int rating) {
it->shufflerating = rating;
pl_unlock();
}

int
pl_items_from_same_album (playItem_t* a, playItem_t* b){
const char *keys[] = {
"band",
"album artist",
"albumartist",
"artist",
NULL
};

const char *a_artist = NULL;
const char *b_artist = NULL;
for (int i = 0; keys[i]; i++) {
if (!a_artist) {
a_artist = pl_find_meta_raw (a, keys[i]);
}
if (!b_artist) {
b_artist = pl_find_meta_raw (b, keys[i]);
}
if (a_artist && b_artist) {
break;
}
}
return pl_find_meta_raw(a, "album") == pl_find_meta_raw (b, "album") && a_artist == b_artist;
}
3 changes: 3 additions & 0 deletions src/playlist.h
Original file line number Diff line number Diff line change
Expand Up @@ -563,6 +563,9 @@ pl_get_shufflerating (playItem_t *it);
void
pl_set_shufflerating (playItem_t *it, int rating);

int
pl_items_from_same_album(playItem_t* a, playItem_t* b);

#ifdef __cplusplus
}
#endif
Expand Down
Loading

0 comments on commit 03365d9

Please sign in to comment.