diff options
author | Alexey Yakovenko <wakeroid@gmail.com> | 2010-01-09 23:22:46 +0100 |
---|---|---|
committer | Alexey Yakovenko <wakeroid@gmail.com> | 2010-01-09 23:22:46 +0100 |
commit | 46aff62aae4282d18073685fe9316a9302fc41f0 (patch) | |
tree | c787537cb3ff8829d3cf8f26bcd9c06896969be6 | |
parent | 0a3d9fb2fab7e7f5c68203a92479ea9dd5a172ed (diff) |
moved relevant stuff from playlist to streamer code
-rw-r--r-- | main.c | 6 | ||||
-rw-r--r-- | playlist.c | 212 | ||||
-rw-r--r-- | playlist.h | 28 | ||||
-rw-r--r-- | plugins.c | 2 | ||||
-rw-r--r-- | streamer.c | 230 | ||||
-rw-r--r-- | streamer.h | 14 |
6 files changed, 248 insertions, 244 deletions
@@ -325,11 +325,11 @@ player_mainloop (void) { break; case M_NEXTSONG: p_stop (); - pl_nextsong (1); + streamer_move_nextsong (1); break; case M_PREVSONG: p_stop (); - pl_prevsong (); + streamer_move_prevsong (); break; case M_PAUSESONG: if (p_get_state () == OUTPUT_STATE_PAUSED) { @@ -343,7 +343,7 @@ player_mainloop (void) { break; case M_PLAYRANDOM: p_stop (); - pl_randomsong (); + streamer_move_randomsong (); break; case M_PLAYLISTREFRESH: plug_trigger_event_playlistchanged (); @@ -53,7 +53,6 @@ playItem_t *playlist_head[PL_MAX_ITERATORS]; playItem_t *playlist_tail[PL_MAX_ITERATORS]; int playlist_current_row[PL_MAX_ITERATORS]; -playItem_t *playlist_current_ptr; static int pl_count[2]; static float pl_totaltime = 0; @@ -726,9 +725,6 @@ pl_remove (playItem_t *it) { if (!it) return -1; streamer_song_removed_notify (it); - if (playlist_current_ptr == it) { - playlist_current_ptr = NULL; - } pl_playqueue_remove (it); // remove from both lists list @@ -911,204 +907,6 @@ pl_item_free (playItem_t *it) { } } -int -pl_prevsong (void) { - pl_playqueue_clear (); - if (!playlist_head[PL_MAIN]) { - streamer_set_nextsong (-2, 1); - return 0; - } - int pl_order = conf_get_int ("playback.order", 0); - int pl_loop_mode = conf_get_int ("playback.loop", 0); - if (pl_order == PLAYBACK_ORDER_SHUFFLE) { // shuffle - if (!playlist_current_ptr) { - return pl_nextsong (1); - } - else { - playlist_current_ptr->played = 0; - // find already played song with maximum shuffle rating below prev song - int rating = playlist_current_ptr->shufflerating; - playItem_t *pmax = NULL; // played maximum - playItem_t *amax = NULL; // absolute maximum - for (playItem_t *i = playlist_head[PL_MAIN]; i; i = i->next[PL_MAIN]) { - if (i != playlist_current_ptr && i->played && (!amax || i->shufflerating > amax->shufflerating)) { - amax = i; - } - if (i == playlist_current_ptr || i->shufflerating > rating || !i->played) { - continue; - } - if (!pmax || i->shufflerating > pmax->shufflerating) { - pmax = i; - } - } - playItem_t *it = pmax; - if (!it) { - // that means 1st in playlist, take amax - if (pl_loop_mode == PLAYBACK_MODE_LOOP_ALL) { - if (!amax) { - pl_reshuffle (NULL, &amax); - } - it = amax; - } - } - - if (!it) { - return -1; - } - int r = pl_get_idx_of (it); - streamer_set_nextsong (r, 1); - return 0; - } - } - else if (pl_order == PLAYBACK_ORDER_LINEAR) { // linear - playItem_t *it = NULL; - if (playlist_current_ptr) { - it = playlist_current_ptr->prev[PL_MAIN]; - } - if (!it) { - if (pl_loop_mode == PLAYBACK_MODE_LOOP_ALL) { - it = playlist_tail[PL_MAIN]; - } - } - if (!it) { - return -1; - } - int r = pl_get_idx_of (it); - streamer_set_nextsong (r, 1); - return 0; - } - else if (pl_order == PLAYBACK_ORDER_RANDOM) { // random - pl_randomsong (); - } - return -1; -} - -int -pl_nextsong (int reason) { - if (playqueue_count > 0) { - playItem_t *it = playqueue[0]; - pl_playqueue_pop (); - int r = pl_get_idx_of (it); - streamer_set_nextsong (r, 1); - return 0; - } - - playItem_t *curr = streamer_get_streaming_track (); - if (!playlist_head[PL_MAIN]) { - streamer_set_nextsong (-2, 1); - return 0; - } - int pl_order = conf_get_int ("playback.order", 0); - int pl_loop_mode = conf_get_int ("playback.loop", 0); - if (pl_order == PLAYBACK_ORDER_SHUFFLE) { // shuffle - if (!curr) { - // find minimal notplayed - playItem_t *pmin = NULL; // notplayed minimum - for (playItem_t *i = playlist_head[PL_MAIN]; i; i = i->next[PL_MAIN]) { - if (i->played) { - continue; - } - if (!pmin || i->shufflerating < pmin->shufflerating) { - pmin = i; - } - } - playItem_t *it = pmin; - if (!it) { - // all songs played, reshuffle and try again - if (pl_loop_mode == PLAYBACK_MODE_LOOP_ALL) { // loop - pl_reshuffle (&it, NULL); - } - } - if (!it) { - return -1; - } - int r = pl_get_idx_of (it); - streamer_set_nextsong (r, 1); - return 0; - } - else { - trace ("pl_next_song: reason=%d, loop=%d\n", reason, pl_loop_mode); - if (reason == 0 && pl_loop_mode == PLAYBACK_MODE_LOOP_SINGLE) { // song finished, loop mode is "loop 1 track" - int r = pl_get_idx_of (curr); - streamer_set_nextsong (r, 1); - return 0; - } - // find minimal notplayed above current - int rating = curr->shufflerating; - playItem_t *pmin = NULL; // notplayed minimum - for (playItem_t *i = playlist_head[PL_MAIN]; i; i = i->next[PL_MAIN]) { - if (i->played || i->shufflerating < rating) { - continue; - } - if (!pmin || i->shufflerating < pmin->shufflerating) { - pmin = i; - } - } - playItem_t *it = pmin; - if (!it) { - trace ("all songs played! reshuffle\n"); - // all songs played, reshuffle and try again - if (pl_loop_mode == PLAYBACK_MODE_LOOP_ALL) { // loop - pl_reshuffle (&it, NULL); - } - } - if (!it) { - return -1; - } - int r = pl_get_idx_of (it); - streamer_set_nextsong (r, 1); - return 0; - } - } - else if (pl_order == PLAYBACK_ORDER_LINEAR) { // linear - playItem_t *it = NULL; - if (curr) { - if (reason == 0 && pl_loop_mode == PLAYBACK_MODE_LOOP_SINGLE) { // loop same track - int r = pl_get_idx_of (curr); - streamer_set_nextsong (r, 1); - return 0; - } - it = curr->next[PL_MAIN]; - } - if (!it) { - trace ("pl_nextsong: was last track\n"); - if (pl_loop_mode == PLAYBACK_MODE_LOOP_ALL) { - it = playlist_head[PL_MAIN]; - } - else { - streamer_set_nextsong (-2, 1); - return 0; - } - } - if (!it) { - return -1; - } - int r = pl_get_idx_of (it); - streamer_set_nextsong (r, 1); - return 0; - } - else if (pl_order == PLAYBACK_ORDER_RANDOM) { // random - if (reason == 0 && pl_loop_mode == PLAYBACK_MODE_LOOP_SINGLE && curr) { - int r = pl_get_idx_of (curr); - streamer_set_nextsong (r, 1); - return 0; - } - return pl_randomsong (); - } - return -1; -} - -int -pl_randomsong (void) { - int cnt = pl_getcount (PL_MAIN); - if (!cnt) { - return -1; - } - int r = rand () / (float)RAND_MAX * cnt; - streamer_set_nextsong (r, 1); - return 0; -} - void pl_add_meta (playItem_t *it, const char *key, const char *value) { // check if it's already set @@ -1894,11 +1692,6 @@ pl_get_totaltime (void) { return pl_totaltime; } -playItem_t * -pl_getcurrent (void) { - return playlist_current_ptr; -} - void pl_set_selected (playItem_t *it, int sel) { it->selected = sel; @@ -2107,3 +1900,8 @@ pl_playqueue_getnext (void) { } return NULL; } + +int +pl_playqueue_getcount (void) { + return playqueue_count; +} @@ -53,10 +53,16 @@ typedef struct playItem_s { unsigned in_playlist : 1; // 1 if item is in playlist } playItem_t; +typedef struct { + playItem_t *playlist_head[PL_MAX_ITERATORS]; // head of linked list + playItem_t *playlist_tail[PL_MAX_ITERATORS]; // tail of linked list + int playlist_current_row[PL_MAX_ITERATORS]; // current row (cursor) + playItem_t *playlist_current_ptr; // pointer to a real current playlist item (or NULL) +} playlist_t; + extern playItem_t *playlist_head[PL_MAX_ITERATORS]; // head of linked list extern playItem_t *playlist_tail[PL_MAX_ITERATORS]; // tail of linked list extern int playlist_current_row[PL_MAX_ITERATORS]; // current row (cursor) -extern playItem_t *playlist_current_ptr; // pointer to a real current playlist item (or NULL) int pl_add_dir (const char *dirname, int (*cb)(playItem_t *it, void *data), void *user_data); @@ -109,20 +115,6 @@ pl_insert_cue_from_buffer (playItem_t *after, playItem_t *origin, const uint8_t playItem_t * pl_insert_cue (playItem_t *after, playItem_t *origin, int numsamples, int samplerate); -//int -//pl_set_current (playItem_t *it); - -// returns -1 if theres no next song, or playlist finished -// reason 0 means "song finished", 1 means "user clicked next" -int -pl_nextsong (int reason); - -int -pl_prevsong (void); - -int -pl_randomsong (void); - void pl_add_meta (playItem_t *it, const char *key, const char *value); @@ -172,9 +164,6 @@ pl_reset_cursor (void); float pl_get_totaltime (void); -playItem_t * -pl_getcurrent (void); - void pl_set_selected (playItem_t *it, int sel); @@ -230,4 +219,7 @@ pl_playqueue_test (playItem_t *it); playItem_t * pl_playqueue_getnext (void); +int +pl_playqueue_getcount (void); + #endif // __PLAYLIST_H @@ -102,7 +102,7 @@ static DB_functions_t deadbeef_api = { .pl_sort = pl_sort, .pl_get_totaltime = pl_get_totaltime, .pl_getcount = pl_getcount, - .pl_getcurrent = (DB_playItem_t *(*)(void))pl_getcurrent, + .pl_getcurrent = (DB_playItem_t *(*)(void))streamer_get_current, .pl_delete_selected = pl_delete_selected, .pl_set_cursor = pl_set_cursor, .pl_get_cursor = pl_get_cursor, @@ -118,7 +118,7 @@ streamer_song_removed_notify (playItem_t *it) { // queue new next song for streaming if (bytes_until_next_song > 0) { streambuffer_fill = bytes_until_next_song; - pl_nextsong (0); + streamer_move_nextsong (0); } } } @@ -134,7 +134,7 @@ streamer_set_current (playItem_t *it) { messagepump_push (M_TRACKCHANGED, 0, to, 0); } if (!orig_playing_song || p_isstopped ()) { - playlist_current_ptr = it; + orig_playing_song = it; //trace ("from=%d, to=%d\n", from, to); //messagepump_push (M_SONGCHANGED, 0, from, to); } @@ -186,8 +186,8 @@ streamer_set_current (playItem_t *it) { if (ret < 0) { trace ("decoder->init returned %d\n", ret); trace ("orig_playing_song = %p\n", orig_playing_song); - if (playlist_current_ptr == it) { - playlist_current_ptr = NULL; + if (orig_playing_song == it) { + orig_playing_song = NULL; messagepump_push (M_TRACKCHANGED, 0, to, 0); } return ret; @@ -296,8 +296,8 @@ streamer_thread (void *ctx) { badsong = sng; } // try jump to next song - pl_nextsong (0); - trace ("pl_nextsong switched to track %d\n", nextsong); + streamer_move_nextsong (0); + trace ("streamer_move_nextsong switched to track %d\n", nextsong); usleep (50000); continue; } @@ -367,7 +367,6 @@ streamer_thread (void *ctx) { orig_playing_song->started_timestamp = time (NULL); str_playing_song.started_timestamp = time (NULL); } - playlist_current_ptr = orig_playing_song; // that is needed for playlist drawing // plugin will get pointer to new str_playing_song trace ("sending songstarted to plugins\n"); @@ -407,8 +406,8 @@ streamer_thread (void *ctx) { messagepump_push (M_TRACKCHANGED, 0, trk, 0); } trace ("failed to restart prev track on seek, trying to jump to next track\n"); - pl_nextsong (0); - trace ("pl_nextsong switched to track %d\n", nextsong); + streamer_move_nextsong (0); + trace ("streamer_move_nextsong switched to track %d\n", nextsong); usleep (50000); continue; } @@ -794,7 +793,7 @@ streamer_read_async (char *bytes, int size) { streamer_set_nextsong (-2, 1); } else { - pl_nextsong (0); + streamer_move_nextsong (0); } } break; @@ -827,11 +826,9 @@ streamer_read (char *bytes, int size) { streambuffer_fill -= sz; playpos += (float)sz/p_get_rate ()/4.f; str_playing_song.playtime += (float)sz/p_get_rate ()/4.f; - if (playlist_current_ptr) { - str_playing_song.filetype = playlist_current_ptr->filetype; - } - if (playlist_current_ptr) { - playlist_current_ptr->playtime = str_playing_song.playtime; + if (orig_playing_song) { + str_playing_song.filetype = orig_playing_song->filetype; + orig_playing_song->playtime = str_playing_song.playtime; } if (bytes_until_next_song > 0) { bytes_until_next_song -= sz; @@ -961,3 +958,206 @@ streamer_play_current_track (void) { } } +int +streamer_move_prevsong (void) { + pl_playqueue_clear (); + if (!playlist_head[PL_MAIN]) { + streamer_set_nextsong (-2, 1); + return 0; + } + int pl_order = conf_get_int ("playback.order", 0); + int pl_loop_mode = conf_get_int ("playback.loop", 0); + if (pl_order == PLAYBACK_ORDER_SHUFFLE) { // shuffle + if (!orig_playing_song) { + return streamer_move_nextsong (1); + } + else { + orig_playing_song->played = 0; + // find already played song with maximum shuffle rating below prev song + int rating = orig_playing_song->shufflerating; + playItem_t *pmax = NULL; // played maximum + playItem_t *amax = NULL; // absolute maximum + for (playItem_t *i = playlist_head[PL_MAIN]; i; i = i->next[PL_MAIN]) { + if (i != orig_playing_song && i->played && (!amax || i->shufflerating > amax->shufflerating)) { + amax = i; + } + if (i == orig_playing_song || i->shufflerating > rating || !i->played) { + continue; + } + if (!pmax || i->shufflerating > pmax->shufflerating) { + pmax = i; + } + } + playItem_t *it = pmax; + if (!it) { + // that means 1st in playlist, take amax + if (pl_loop_mode == PLAYBACK_MODE_LOOP_ALL) { + if (!amax) { + pl_reshuffle (NULL, &amax); + } + it = amax; + } + } + + if (!it) { + return -1; + } + int r = pl_get_idx_of (it); + streamer_set_nextsong (r, 1); + return 0; + } + } + else if (pl_order == PLAYBACK_ORDER_LINEAR) { // linear + playItem_t *it = NULL; + if (orig_playing_song) { + it = orig_playing_song->prev[PL_MAIN]; + } + if (!it) { + if (pl_loop_mode == PLAYBACK_MODE_LOOP_ALL) { + it = playlist_tail[PL_MAIN]; + } + } + if (!it) { + return -1; + } + int r = pl_get_idx_of (it); + streamer_set_nextsong (r, 1); + return 0; + } + else if (pl_order == PLAYBACK_ORDER_RANDOM) { // random + streamer_move_randomsong (); + } + return -1; +} + +int +streamer_move_nextsong (int reason) { + playItem_t *it = pl_playqueue_getnext (); + if (it) { + pl_playqueue_pop (); + int r = pl_get_idx_of (it); + streamer_set_nextsong (r, 1); + return 0; + } + + playItem_t *curr = streamer_get_streaming_track (); + if (!playlist_head[PL_MAIN]) { + streamer_set_nextsong (-2, 1); + return 0; + } + int pl_order = conf_get_int ("playback.order", 0); + int pl_loop_mode = conf_get_int ("playback.loop", 0); + if (pl_order == PLAYBACK_ORDER_SHUFFLE) { // shuffle + if (!curr) { + // find minimal notplayed + playItem_t *pmin = NULL; // notplayed minimum + for (playItem_t *i = playlist_head[PL_MAIN]; i; i = i->next[PL_MAIN]) { + if (i->played) { + continue; + } + if (!pmin || i->shufflerating < pmin->shufflerating) { + pmin = i; + } + } + playItem_t *it = pmin; + if (!it) { + // all songs played, reshuffle and try again + if (pl_loop_mode == PLAYBACK_MODE_LOOP_ALL) { // loop + pl_reshuffle (&it, NULL); + } + } + if (!it) { + return -1; + } + int r = pl_get_idx_of (it); + streamer_set_nextsong (r, 1); + return 0; + } + else { + trace ("pl_next_song: reason=%d, loop=%d\n", reason, pl_loop_mode); + if (reason == 0 && pl_loop_mode == PLAYBACK_MODE_LOOP_SINGLE) { // song finished, loop mode is "loop 1 track" + int r = pl_get_idx_of (curr); + streamer_set_nextsong (r, 1); + return 0; + } + // find minimal notplayed above current + int rating = curr->shufflerating; + playItem_t *pmin = NULL; // notplayed minimum + for (playItem_t *i = playlist_head[PL_MAIN]; i; i = i->next[PL_MAIN]) { + if (i->played || i->shufflerating < rating) { + continue; + } + if (!pmin || i->shufflerating < pmin->shufflerating) { + pmin = i; + } + } + playItem_t *it = pmin; + if (!it) { + trace ("all songs played! reshuffle\n"); + // all songs played, reshuffle and try again + if (pl_loop_mode == PLAYBACK_MODE_LOOP_ALL) { // loop + pl_reshuffle (&it, NULL); + } + } + if (!it) { + return -1; + } + int r = pl_get_idx_of (it); + streamer_set_nextsong (r, 1); + return 0; + } + } + else if (pl_order == PLAYBACK_ORDER_LINEAR) { // linear + playItem_t *it = NULL; + if (curr) { + if (reason == 0 && pl_loop_mode == PLAYBACK_MODE_LOOP_SINGLE) { // loop same track + int r = pl_get_idx_of (curr); + streamer_set_nextsong (r, 1); + return 0; + } + it = curr->next[PL_MAIN]; + } + if (!it) { + trace ("streamer_move_nextsong: was last track\n"); + if (pl_loop_mode == PLAYBACK_MODE_LOOP_ALL) { + it = playlist_head[PL_MAIN]; + } + else { + streamer_set_nextsong (-2, 1); + return 0; + } + } + if (!it) { + return -1; + } + int r = pl_get_idx_of (it); + streamer_set_nextsong (r, 1); + return 0; + } + else if (pl_order == PLAYBACK_ORDER_RANDOM) { // random + if (reason == 0 && pl_loop_mode == PLAYBACK_MODE_LOOP_SINGLE && curr) { + int r = pl_get_idx_of (curr); + streamer_set_nextsong (r, 1); + return 0; + } + return streamer_move_randomsong (); + } + return -1; +} + +int +streamer_move_randomsong (void) { + int cnt = pl_getcount (PL_MAIN); + if (!cnt) { + return -1; + } + int r = rand () / (float)RAND_MAX * cnt; + streamer_set_nextsong (r, 1); + return 0; +} + +playItem_t * +streamer_get_current (void) { + return orig_playing_song; +} + @@ -84,4 +84,18 @@ streamer_set_bitrate (int bitrate); int streamer_get_apx_bitrate (void); +// returns -1 if theres no next song, or playlist finished +// reason 0 means "song finished", 1 means "user clicked next" +int +streamer_move_nextsong (int reason); + +int +streamer_move_prevsong (void); + +int +streamer_move_randomsong (void); + +playItem_t * +streamer_get_current (void); + #endif // __STREAMER_H |