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; } }
/** * Queue a song, addressed by its order number. */ static void playlist_queue_song_order(struct playlist *playlist, 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(song); }
void playlist_play_order(struct playlist *playlist, 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(song); playlist->current = orderNum; }
enum playlist_result playlist_seek_song(struct playlist *playlist, struct player_control *pc, unsigned song, float seek_time) { const struct song *queued; unsigned i; bool success; if (!queue_valid_position(&playlist->queue, song)) return PLAYLIST_RESULT_BAD_RANGE; queued = playlist_get_queued_song(playlist); if (playlist->queue.random) i = queue_position_to_order(&playlist->queue, song); else i = song; pc_clear_error(pc); playlist->stop_on_error = true; playlist->error_count = 0; if (!playlist->playing || (unsigned)playlist->current != i) { /* seeking is not within the current song - prepare song change */ playlist->playing = true; playlist->current = i; queued = NULL; } success = pc_seek(pc, queue_get_order(&playlist->queue, i), seek_time); if (!success) { playlist_update_queued_song(playlist, pc, queued); return PLAYLIST_RESULT_NOT_PLAYING; } playlist->queued = -1; playlist_update_queued_song(playlist, pc, NULL); return PLAYLIST_RESULT_SUCCESS; }
/** * Queue a song, addressed by its order number. */ static void playlist_queue_song_order(struct playlist *playlist, struct player_control *pc, unsigned order) { char *uri; assert(queue_valid_order(&playlist->queue, order)); playlist->queued = order; struct song *song = song_dup_detached(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); }
void playlist_play_order(struct playlist *playlist, struct player_control *pc, int orderNum) { char *uri; playlist->playing = true; playlist->queued = -1; struct song *song = song_dup_detached(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; }