예제 #1
0
void
queue_shuffle_range(struct queue *queue, unsigned start, unsigned end)
{
	assert(start <= end);
	assert(end <= queue->length);

	for (unsigned i = start; i < end; i++) {
		unsigned ri = g_rand_int_range(queue->rand, i, end);
		queue_swap(queue, i, ri);
	}
}
예제 #2
0
void
playlist_shuffle(struct playlist *playlist, struct player_control *pc,
		 unsigned start, unsigned end)
{
	const struct song *queued;

	if (end > queue_length(&playlist->queue))
		/* correct the "end" offset */
		end = queue_length(&playlist->queue);

	if ((start+1) >= end)
		/* needs at least two entries. */
		return;

	queued = playlist_get_queued_song(playlist);
	if (playlist->playing && playlist->current >= 0) {
		unsigned current_position;
		current_position = queue_order_to_position(&playlist->queue,
	                                                   playlist->current);

		if (current_position >= start && current_position < end)
		{
			/* put current playing song first */
			queue_swap(&playlist->queue, start, current_position);

			if (playlist->queue.random) {
				playlist->current =
					queue_position_to_order(&playlist->queue, start);
			} else
				playlist->current = start;

			/* start shuffle after the current song */
			start++;
		}
	} else {
		/* no playback currently: reset playlist->current */

		playlist->current = -1;
	}

	queue_shuffle_range(&playlist->queue, start, end);

	playlist_increment_version(playlist);

	playlist_update_queued_song(playlist, pc, queued);
}
예제 #3
0
enum playlist_result
playlist_swap_songs(struct playlist *playlist, struct player_control *pc,
		    unsigned song1, unsigned song2)
{
	const struct song *queued;

	if (!queue_valid_position(&playlist->queue, song1) ||
	    !queue_valid_position(&playlist->queue, song2))
		return PLAYLIST_RESULT_BAD_RANGE;

	queued = playlist_get_queued_song(playlist);

	queue_swap(&playlist->queue, song1, song2);

	if (playlist->queue.random) {
		/* update the queue order, so that playlist->current
		   still points to the current song order */

		queue_swap_order(&playlist->queue,
				 queue_position_to_order(&playlist->queue,
							 song1),
				 queue_position_to_order(&playlist->queue,
							 song2));
	} else {
		/* correct the "current" song order */

		if (playlist->current == (int)song1)
			playlist->current = song2;
		else if (playlist->current == (int)song2)
			playlist->current = song1;
	}

	playlist_increment_version(playlist);

	playlist_update_queued_song(playlist, pc, queued);

	return PLAYLIST_RESULT_SUCCESS;
}