aboutsummaryrefslogtreecommitdiff
path: root/src/playlist.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/playlist.c')
-rw-r--r--src/playlist.c452
1 files changed, 0 insertions, 452 deletions
diff --git a/src/playlist.c b/src/playlist.c
deleted file mode 100644
index dc6d8c34..00000000
--- a/src/playlist.c
+++ /dev/null
@@ -1,452 +0,0 @@
-/*
- * Copyright (C) 2003-2011 The Music Player Daemon Project
- * http://www.musicpd.org
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#include "config.h"
-#include "playlist_internal.h"
-#include "playlist_save.h"
-#include "player_control.h"
-#include "command.h"
-#include "tag.h"
-#include "song.h"
-#include "conf.h"
-#include "stored_playlist.h"
-#include "idle.h"
-
-#include <glib.h>
-
-#include <assert.h>
-
-#undef G_LOG_DOMAIN
-#define G_LOG_DOMAIN "playlist"
-
-void
-playlist_increment_version_all(struct playlist *playlist)
-{
- queue_modify_all(&playlist->queue);
- idle_add(IDLE_PLAYLIST);
-}
-
-void
-playlist_tag_changed(struct playlist *playlist)
-{
- if (!playlist->playing)
- return;
-
- assert(playlist->current >= 0);
-
- queue_modify(&playlist->queue, playlist->current);
- idle_add(IDLE_PLAYLIST);
-}
-
-void
-playlist_init(struct playlist *playlist)
-{
- queue_init(&playlist->queue,
- config_get_positive(CONF_MAX_PLAYLIST_LENGTH,
- DEFAULT_PLAYLIST_MAX_LENGTH));
-
- playlist->queued = -1;
- playlist->current = -1;
-}
-
-void
-playlist_finish(struct playlist *playlist)
-{
- queue_finish(&playlist->queue);
-}
-
-/**
- * Queue a song, addressed by its order number.
- */
-static void
-playlist_queue_song_order(struct playlist *playlist, struct player_control *pc,
- unsigned order)
-{
- struct song *song;
- char *uri;
-
- assert(queue_valid_order(&playlist->queue, order));
-
- playlist->queued = order;
-
- song = queue_get_order(&playlist->queue, order);
- uri = song_get_uri(song);
- g_debug("queue song %i:\"%s\"", playlist->queued, uri);
- g_free(uri);
-
- pc_enqueue_song(pc, song);
-}
-
-/**
- * Called if the player thread has started playing the "queued" song.
- */
-static void
-playlist_song_started(struct playlist *playlist, struct player_control *pc)
-{
- assert(pc->next_song == NULL);
- assert(playlist->queued >= -1);
-
- /* queued song has started: copy queued to current,
- and notify the clients */
-
- int current = playlist->current;
- playlist->current = playlist->queued;
- playlist->queued = -1;
-
- if(playlist->queue.consume)
- playlist_delete(playlist, pc,
- queue_order_to_position(&playlist->queue,
- current));
-
- idle_add(IDLE_PLAYER);
-}
-
-const struct song *
-playlist_get_queued_song(struct playlist *playlist)
-{
- if (!playlist->playing || playlist->queued < 0)
- return NULL;
-
- return queue_get_order(&playlist->queue, playlist->queued);
-}
-
-void
-playlist_update_queued_song(struct playlist *playlist,
- struct player_control *pc,
- const struct song *prev)
-{
- int next_order;
- const struct song *next_song;
-
- if (!playlist->playing)
- return;
-
- assert(!queue_is_empty(&playlist->queue));
- assert((playlist->queued < 0) == (prev == NULL));
-
- next_order = playlist->current >= 0
- ? queue_next_order(&playlist->queue, playlist->current)
- : 0;
-
- if (next_order == 0 && playlist->queue.random &&
- !playlist->queue.single) {
- /* shuffle the song order again, so we get a different
- order each time the playlist is played
- completely */
- unsigned current_position =
- queue_order_to_position(&playlist->queue,
- playlist->current);
-
- queue_shuffle_order(&playlist->queue);
-
- /* make sure that the playlist->current still points to
- the current song, after the song order has been
- shuffled */
- playlist->current =
- queue_position_to_order(&playlist->queue,
- current_position);
- }
-
- if (next_order >= 0)
- next_song = queue_get_order(&playlist->queue, next_order);
- else
- next_song = NULL;
-
- if (prev != NULL && next_song != prev) {
- /* clear the currently queued song */
- pc_cancel(pc);
- playlist->queued = -1;
- }
-
- if (next_order >= 0) {
- if (next_song != prev)
- playlist_queue_song_order(playlist, pc, next_order);
- else
- playlist->queued = next_order;
- }
-}
-
-void
-playlist_play_order(struct playlist *playlist, struct player_control *pc,
- int orderNum)
-{
- struct song *song;
- char *uri;
-
- playlist->playing = true;
- playlist->queued = -1;
-
- song = queue_get_order(&playlist->queue, orderNum);
-
- uri = song_get_uri(song);
- g_debug("play %i:\"%s\"", orderNum, uri);
- g_free(uri);
-
- pc_play(pc, song);
- playlist->current = orderNum;
-}
-
-static void
-playlist_resume_playback(struct playlist *playlist, struct player_control *pc);
-
-/**
- * This is the "PLAYLIST" event handler. It is invoked by the player
- * thread whenever it requests a new queued song, or when it exits.
- */
-void
-playlist_sync(struct playlist *playlist, struct player_control *pc)
-{
- if (!playlist->playing)
- /* this event has reached us out of sync: we aren't
- playing anymore; ignore the event */
- return;
-
- player_lock(pc);
- enum player_state pc_state = pc_get_state(pc);
- const struct song *pc_next_song = pc->next_song;
- player_unlock(pc);
-
- if (pc_state == PLAYER_STATE_STOP)
- /* the player thread has stopped: check if playback
- should be restarted with the next song. That can
- happen if the playlist isn't filling the queue fast
- enough */
- playlist_resume_playback(playlist, pc);
- else {
- /* check if the player thread has already started
- playing the queued song */
- if (pc_next_song == NULL && playlist->queued != -1)
- playlist_song_started(playlist, pc);
-
- player_lock(pc);
- pc_next_song = pc->next_song;
- player_unlock(pc);
-
- /* make sure the queued song is always set (if
- possible) */
- if (pc_next_song == NULL && playlist->queued < 0)
- playlist_update_queued_song(playlist, pc, NULL);
- }
-}
-
-/**
- * The player has stopped for some reason. Check the error, and
- * decide whether to re-start playback
- */
-static void
-playlist_resume_playback(struct playlist *playlist, struct player_control *pc)
-{
- enum player_error error;
-
- assert(playlist->playing);
- assert(pc_get_state(pc) == PLAYER_STATE_STOP);
-
- error = pc_get_error(pc);
- if (error == PLAYER_ERROR_NOERROR)
- playlist->error_count = 0;
- else
- ++playlist->error_count;
-
- if ((playlist->stop_on_error && error != PLAYER_ERROR_NOERROR) ||
- error == PLAYER_ERROR_AUDIO || error == PLAYER_ERROR_SYSTEM ||
- playlist->error_count >= queue_length(&playlist->queue))
- /* too many errors, or critical error: stop
- playback */
- playlist_stop(playlist, pc);
- else
- /* continue playback at the next song */
- playlist_next(playlist, pc);
-}
-
-bool
-playlist_get_repeat(const struct playlist *playlist)
-{
- return playlist->queue.repeat;
-}
-
-bool
-playlist_get_random(const struct playlist *playlist)
-{
- return playlist->queue.random;
-}
-
-bool
-playlist_get_single(const struct playlist *playlist)
-{
- return playlist->queue.single;
-}
-
-bool
-playlist_get_consume(const struct playlist *playlist)
-{
- return playlist->queue.consume;
-}
-
-void
-playlist_set_repeat(struct playlist *playlist, struct player_control *pc,
- bool status)
-{
- if (status == playlist->queue.repeat)
- return;
-
- struct queue *queue = &playlist->queue;
-
- queue->repeat = status;
-
- pc_set_border_pause(pc, queue->single && !queue->repeat);
-
- /* if the last song is currently being played, the "next song"
- might change when repeat mode is toggled */
- playlist_update_queued_song(playlist, pc,
- playlist_get_queued_song(playlist));
-
- idle_add(IDLE_OPTIONS);
-}
-
-static void
-playlist_order(struct playlist *playlist)
-{
- if (playlist->current >= 0)
- /* update playlist.current, order==position now */
- playlist->current = queue_order_to_position(&playlist->queue,
- playlist->current);
-
- queue_restore_order(&playlist->queue);
-}
-
-void
-playlist_set_single(struct playlist *playlist, struct player_control *pc,
- bool status)
-{
- if (status == playlist->queue.single)
- return;
-
- struct queue *queue = &playlist->queue;
-
- queue->single = status;
-
- pc_set_border_pause(pc, queue->single && !queue->repeat);
-
- /* if the last song is currently being played, the "next song"
- might change when single mode is toggled */
- playlist_update_queued_song(playlist, pc,
- playlist_get_queued_song(playlist));
-
- idle_add(IDLE_OPTIONS);
-}
-
-void
-playlist_set_consume(struct playlist *playlist, bool status)
-{
- if (status == playlist->queue.consume)
- return;
-
- playlist->queue.consume = status;
- idle_add(IDLE_OPTIONS);
-}
-
-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);
-}
-
-int
-playlist_get_current_song(const struct playlist *playlist)
-{
- if (playlist->current >= 0)
- return queue_order_to_position(&playlist->queue,
- playlist->current);
-
- return -1;
-}
-
-int
-playlist_get_next_song(const struct playlist *playlist)
-{
- if (playlist->current >= 0)
- {
- if (playlist->queue.single == 1 && playlist->queue.repeat == 1)
- return queue_order_to_position(&playlist->queue,
- playlist->current);
- else if (playlist->current + 1 < (int)queue_length(&playlist->queue))
- return queue_order_to_position(&playlist->queue,
- playlist->current + 1);
- else if (playlist->queue.repeat == 1)
- return queue_order_to_position(&playlist->queue, 0);
- }
-
- return -1;
-}
-
-unsigned long
-playlist_get_version(const struct playlist *playlist)
-{
- return playlist->queue.version;
-}
-
-int
-playlist_get_length(const struct playlist *playlist)
-{
- return queue_length(&playlist->queue);
-}
-
-unsigned
-playlist_get_song_id(const struct playlist *playlist, unsigned song)
-{
- return queue_position_to_id(&playlist->queue, song);
-}