aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/playlist.c70
-rw-r--r--src/queue.c11
-rw-r--r--src/queue.h7
3 files changed, 53 insertions, 35 deletions
diff --git a/src/playlist.c b/src/playlist.c
index fb56721a3..0eb0f7da3 100644
--- a/src/playlist.c
+++ b/src/playlist.c
@@ -79,7 +79,6 @@ static int playlist_noGoToNext;
bool playlist_saveAbsolutePaths = DEFAULT_PLAYLIST_SAVE_ABSOLUTE_PATHS;
static void playPlaylistOrderNumber(int orderNum);
-static void randomizeOrder(int start, int end);
static void incrPlaylistVersion(void)
{
@@ -412,11 +411,20 @@ playlist_queue_song_order(unsigned order)
static void queueNextSongInPlaylist(void)
{
+ assert(playlist.queued < 0);
+
if (playlist.current + 1 < (int)queue_length(&playlist.queue)) {
playlist_queue_song_order(playlist.current + 1);
} else if (!queue_is_empty(&playlist.queue) && playlist.queue.repeat) {
- if (queue_length(&playlist.queue) > 1 && playlist.queue.random)
- randomizeOrder(0, queue_length(&playlist.queue) - 1);
+ if (playlist.queue.random) {
+ unsigned current_position =
+ queue_order_to_position(&playlist.queue,
+ playlist.current);
+ queue_shuffle_order(&playlist.queue);
+ playlist.current =
+ queue_position_to_order(&playlist.queue,
+ current_position);
+ }
playlist_queue_song_order(0);
}
@@ -650,8 +658,16 @@ void stopPlaylist(void)
playlist.queued = -1;
playlist_state = PLAYLIST_STATE_STOP;
playlist_noGoToNext = 0;
- if (playlist.queue.random)
- randomizeOrder(0, queue_length(&playlist.queue) - 1);
+
+ if (playlist.queue.random) {
+ unsigned current_position =
+ queue_order_to_position(&playlist.queue,
+ playlist.current);
+ queue_shuffle_order(&playlist.queue);
+ playlist.current =
+ queue_position_to_order(&playlist.queue,
+ current_position);
+ }
}
static void playPlaylistOrderNumber(int orderNum)
@@ -696,7 +712,7 @@ enum playlist_result playPlaylist(int song, int stopOnError)
if (playlist.queue.random) {
if (song == -1 && playlist_state == PLAYLIST_STATE_PLAY) {
- randomizeOrder(0, queue_length(&playlist.queue) - 1);
+ queue_shuffle_order(&playlist.queue);
} else {
if (song >= 0)
i = queue_position_to_order(&playlist.queue, song);
@@ -787,7 +803,7 @@ void nextSongInPlaylist(void)
if (next_order == 0) {
assert(playlist.queue.repeat);
- randomizeOrder(0, queue_length(&playlist.queue) - 1);
+ queue_shuffle_order(&playlist.queue);
}
playPlaylistOrderNumber(next_order);
@@ -928,27 +944,6 @@ static void orderPlaylist(void)
queue_restore_order(&playlist.queue);
}
-static void randomizeOrder(int start, int end)
-{
- int i;
- int ri;
-
- g_debug("playlist: randomize from %i to %i\n", start, end);
-
- if (playlist_state == PLAYLIST_STATE_PLAY &&
- playlist.queued >= start && playlist.queued <= end)
- clearPlayerQueue();
-
- for (i = start; i <= end; i++) {
- ri = g_rand_int_range(g_rand, i, end + 1);
- if (ri == playlist.current)
- playlist.current = i;
- else if (i == playlist.current)
- playlist.current = ri;
- queue_swap_order(&playlist.queue, i, ri);
- }
-}
-
void setPlaylistRandomStatus(bool status)
{
if (status == playlist.queue.random)
@@ -960,13 +955,18 @@ void setPlaylistRandomStatus(bool status)
playlist.queue.random = status;
if (playlist.queue.random) {
- /*if(playlist_state==PLAYLIST_STATE_PLAY) {
- randomizeOrder(playlist.current+1,
- playlist.length-1);
- }
- else */ randomizeOrder(0, queue_length(&playlist.queue) - 1);
- if (playlist.current >= 0) {
- queue_swap_order(&playlist.queue, playlist.current, 0);
+ int current_position = playlist.current >= 0
+ ? (int)queue_order_to_position(&playlist.queue,
+ playlist.current)
+ : -1;
+
+ queue_shuffle_order(&playlist.queue);
+
+ if (current_position >= 0) {
+ unsigned current_order =
+ queue_position_to_order(&playlist.queue,
+ current_position);
+ queue_swap_order(&playlist.queue, 0, current_order);
playlist.current = 0;
}
} else
diff --git a/src/queue.c b/src/queue.c
index e7ecb3d3a..30ecafeaa 100644
--- a/src/queue.c
+++ b/src/queue.c
@@ -243,6 +243,17 @@ queue_finish(struct queue *queue)
}
void
+queue_shuffle_order(struct queue *queue)
+{
+ assert(queue->random);
+
+ for (unsigned i = 0; i < queue->length; i++)
+ queue_swap_order(queue, i,
+ g_rand_int_range(queue->rand, i,
+ queue->length));
+}
+
+void
queue_shuffle_range(struct queue *queue, unsigned start, unsigned end)
{
assert(start <= end);
diff --git a/src/queue.h b/src/queue.h
index e27a470d9..b355a6a3e 100644
--- a/src/queue.h
+++ b/src/queue.h
@@ -313,6 +313,13 @@ queue_restore_order(struct queue *queue)
}
/**
+ * Shuffles the virtual order of songs, but does not move them
+ * physically. This is used in random mode.
+ */
+void
+queue_shuffle_order(struct queue *queue);
+
+/**
* Shuffles a (position) range in the queue. The songs are physically
* shuffled, not by using the "order" mapping.
*/