enum playlist_result playlist_delete_id(struct playlist *playlist, unsigned id) { int song = queue_id_to_position(&playlist->queue, id); if (song < 0) return PLAYLIST_RESULT_NO_SUCH_SONG; return playlist_delete(playlist, song); }
void playlist_delete_song(struct playlist *playlist, const struct song *song) { for (int i = queue_length(&playlist->queue) - 1; i >= 0; --i) if (song == queue_get(&playlist->queue, i)) playlist_delete(playlist, i); pc_song_deleted(song); }
void playlist_next(struct playlist *playlist, struct player_control *pc) { int next_order; int current; if (!playlist->playing) return; assert(!queue_is_empty(&playlist->queue)); assert(queue_valid_order(&playlist->queue, playlist->current)); current = playlist->current; playlist->stop_on_error = false; /* determine the next song from the queue's order list */ next_order = queue_next_order(&playlist->queue, playlist->current); if (next_order < 0) { /* no song after this one: stop playback */ playlist_stop(playlist, pc); /* reset "current song" */ playlist->current = -1; } else { if (next_order == 0 && playlist->queue.random) { /* The queue told us that the next song is the first song. This means we are in repeat mode. Shuffle the queue order, so this time, the user hears the songs in a different than before */ assert(playlist->queue.repeat); queue_shuffle_order(&playlist->queue); /* note that playlist->current and playlist->queued are now invalid, but playlist_play_order() will discard them anyway */ } playlist_play_order(playlist, pc, next_order); } /* Consume mode removes each played songs. */ if(playlist->queue.consume) playlist_delete(playlist, pc, queue_order_to_position(&playlist->queue, current)); }
/** * 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); }
/** * Called if the player thread has started playing the "queued" song. */ static void playlist_song_started(struct playlist *playlist) { 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; /* Pause if we are in single mode. */ if(playlist->queue.single && !playlist->queue.repeat) { pc_set_pause(true); } if(playlist->queue.consume) playlist_delete(playlist, queue_order_to_position(&playlist->queue, current)); idle_add(IDLE_PLAYER); }
/* Menu of playlist commands. Invoked via ON+PLAY on main viewer screen. Returns -1 if USB attached, 0 if no playlist change, and 1 if playlist changed. */ static int onplay_menu(int index) { int result, ret = 0; struct playlist_entry * current_track = playlist_buffer_get_track(&viewer.buffer, index); MENUITEM_STRINGLIST(menu_items, ID2P(LANG_PLAYLIST), NULL, ID2P(LANG_CURRENT_PLAYLIST), ID2P(LANG_CATALOG), ID2P(LANG_REMOVE), ID2P(LANG_MOVE), ID2P(LANG_SHUFFLE), ID2P(LANG_SAVE_DYNAMIC_PLAYLIST)); bool current = (current_track->index == viewer.current_playing_track); result = do_menu(&menu_items, NULL, NULL, false); if (result == MENU_ATTACHED_USB) { ret = -1; } else if (result >= 0) { /* Abort current move */ viewer.moving_track = -1; viewer.moving_playlist_index = -1; switch (result) { case 0: /* playlist */ onplay_show_playlist_menu(current_track->name); ret = 0; break; case 1: /* add to catalog */ onplay_show_playlist_cat_menu(current_track->name); ret = 0; break; case 2: /* delete track */ playlist_delete(viewer.playlist, current_track->index); if (current) { if (playlist_amount_ex(viewer.playlist) <= 0) audio_stop(); else { /* Start playing new track except if it's the lasttrack track in the playlist and repeat mode is disabled */ current_track = playlist_buffer_get_track(&viewer.buffer, index); if (current_track->display_index!=viewer.num_tracks || global_settings.repeat_mode == REPEAT_ALL) { audio_play(0); viewer.current_playing_track = -1; } } } ret = 1; break; case 3: /* move track */ viewer.moving_track = index; viewer.moving_playlist_index = current_track->index; ret = 0; break; case 4: /* shuffle */ playlist_randomise(viewer.playlist, current_tick, false); ret = 1; break; case 5: /* save playlist */ save_playlist_screen(viewer.playlist); ret = 0; break; } } return ret; }
/* Menu of playlist commands. Invoked via ON+PLAY on main viewer screen. Returns -1 if USB attached, 0 if no playlist change, and 1 if playlist changed. */ static int onplay_menu(int index) { int result, ret = 0; struct playlist_entry * current_track= playlist_buffer_get_track(&viewer.buffer, index); MENUITEM_STRINGLIST(menu_items, ID2P(LANG_PLAYLIST), NULL, ID2P(LANG_REMOVE), ID2P(LANG_MOVE), ID2P(LANG_CATALOG_ADD_TO), ID2P(LANG_CATALOG_ADD_TO_NEW), ID2P(LANG_PLAYLISTVIEWER_SETTINGS)); bool current = (current_track->index == viewer.current_playing_track); result = do_menu(&menu_items, NULL, NULL, false); if (result == MENU_ATTACHED_USB) { ret = -1; } else if (result >= 0) { /* Abort current move */ viewer.moving_track = -1; viewer.moving_playlist_index = -1; switch (result) { case 0: /* delete track */ playlist_delete(viewer.playlist, current_track->index); if (current) { if (playlist_amount_ex(viewer.playlist) <= 0) audio_stop(); else { /* Start playing new track except if it's the lasttrack track in the playlist and repeat mode is disabled */ current_track = playlist_buffer_get_track(&viewer.buffer, index); if (current_track->display_index!=viewer.num_tracks || global_settings.repeat_mode == REPEAT_ALL) { #if CONFIG_CODEC != SWCODEC talk_buffer_steal(); /* will use the mp3 buffer */ #endif audio_play(0); viewer.current_playing_track = -1; } } } ret = 1; break; case 1: /* move track */ viewer.moving_track = index; viewer.moving_playlist_index = current_track->index; ret = 0; break; case 2: /* add to catalog */ case 3: /* add to a new one */ catalog_add_to_a_playlist(current_track->name, FILE_ATTR_AUDIO, result==3, NULL); ret = 0; break; case 4: /* playlist viewer settings */ /* true on usb connect */ ret = viewer_menu() ? -1 : 0; break; } } return ret; }