aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMax Kellermann <max@duempel.org>2009-01-23 00:08:40 +0100
committerMax Kellermann <max@duempel.org>2009-01-23 00:08:40 +0100
commit3a1de741bbb8cf412a72d53793d205a139c101ac (patch)
tree434675ff438787592d7f9abe14496bf0dcbb1906
parentfb2ef107d1b43d5ba34918059113ec68293d379e (diff)
downloadmpd-3a1de741bbb8cf412a72d53793d205a139c101ac.tar.gz
mpd-3a1de741bbb8cf412a72d53793d205a139c101ac.tar.xz
mpd-3a1de741bbb8cf412a72d53793d205a139c101ac.zip
queue: added queue_shuffle_order()
The function shuffles the virtual order of songs, but does not move them physically. This is used in random mode. The new function replaces playlist.c's randomizeOrder() function, which was aware of playlist.current and playlist.queued. The latter is always -1 anyway, and the former as preserved by the caller, by converting playlist.current to a position, and then back to an order number.
-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.
*/