Esempio n. 1
0
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));
}
enum playlist_result
playlist_play(struct playlist *playlist, struct player_control *pc,
	      int song)
{
	unsigned i = song;

	pc_clear_error(pc);

	if (song == -1) {
		/* play any song ("current" song, or the first song */

		if (queue_is_empty(&playlist->queue))
			return PLAYLIST_RESULT_SUCCESS;

		if (playlist->playing) {
			/* already playing: unpause playback, just in
			   case it was paused, and return */
			pc_set_pause(pc, false);
			return PLAYLIST_RESULT_SUCCESS;
		}

		/* select a song: "current" song, or the first one */
		i = playlist->current >= 0
			? playlist->current
			: 0;
	} else if (!queue_valid_position(&playlist->queue, song))
		return PLAYLIST_RESULT_BAD_RANGE;

	if (playlist->queue.random) {
		if (song >= 0)
			/* "i" is currently the song position (which
			   would be equal to the order number in
			   no-random mode); convert it to a order
			   number, because random mode is enabled */
			i = queue_position_to_order(&playlist->queue, song);

		if (!playlist->playing)
			playlist->current = 0;

		/* swap the new song with the previous "current" one,
		   so playback continues as planned */
		queue_swap_order(&playlist->queue,
				 i, playlist->current);
		i = playlist->current;
	}

	playlist->stop_on_error = false;
	playlist->error_count = 0;

	playlist_play_order(playlist, pc, i);
	return PLAYLIST_RESULT_SUCCESS;
}
Esempio n. 3
0
void
playlist_set_random(struct playlist *playlist, struct player_control *pc,
		    bool status)
{
	const struct song *queued;

	if (status == playlist->queue.random)
		return;

	queued = playlist_get_queued_song(playlist);

	playlist->queue.random = status;

	if (playlist->queue.random) {
		/* shuffle the queue order, but preserve
		   playlist->current */

		int current_position =
			playlist->playing && playlist->current >= 0
			? (int)queue_order_to_position(&playlist->queue,
						       playlist->current)
			: -1;

		queue_shuffle_order(&playlist->queue);

		if (current_position >= 0) {
			/* make sure the current song is the first in
			   the order list, so the whole rest of the
			   playlist is played after that */
			unsigned current_order =
				queue_position_to_order(&playlist->queue,
							current_position);
			queue_swap_order(&playlist->queue, 0, current_order);
			playlist->current = 0;
		} else
			playlist->current = -1;
	} else
		playlist_order(playlist);

	playlist_update_queued_song(playlist, pc, queued);

	idle_add(IDLE_OPTIONS);
}
Esempio n. 4
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;
}
Esempio n. 5
0
void
queue_shuffle_order_last(struct queue *queue, unsigned start, unsigned end)
{
	queue_swap_order(queue, end - 1,
			 g_rand_int_range(queue->rand, start, end));
}