summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Alexey Yakovenko <wakeroid@gmail.com>2010-01-09 23:22:46 +0100
committerGravatar Alexey Yakovenko <wakeroid@gmail.com>2010-01-09 23:22:46 +0100
commit46aff62aae4282d18073685fe9316a9302fc41f0 (patch)
treec787537cb3ff8829d3cf8f26bcd9c06896969be6
parent0a3d9fb2fab7e7f5c68203a92479ea9dd5a172ed (diff)
moved relevant stuff from playlist to streamer code
-rw-r--r--main.c6
-rw-r--r--playlist.c212
-rw-r--r--playlist.h28
-rw-r--r--plugins.c2
-rw-r--r--streamer.c230
-rw-r--r--streamer.h14
6 files changed, 248 insertions, 244 deletions
diff --git a/main.c b/main.c
index 95dbaa71..8c5b717d 100644
--- a/main.c
+++ b/main.c
@@ -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 ();
diff --git a/playlist.c b/playlist.c
index 86cb22da..ed0917cc 100644
--- a/playlist.c
+++ b/playlist.c
@@ -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;
+}
diff --git a/playlist.h b/playlist.h
index 4f51ad8f..0276aea2 100644
--- a/playlist.h
+++ b/playlist.h
@@ -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
diff --git a/plugins.c b/plugins.c
index fc779173..633b85fe 100644
--- a/plugins.c
+++ b/plugins.c
@@ -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,
diff --git a/streamer.c b/streamer.c
index 3a29866f..584b8597 100644
--- a/streamer.c
+++ b/streamer.c
@@ -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;
+}
+
diff --git a/streamer.h b/streamer.h
index cc762477..1c31098b 100644
--- a/streamer.h
+++ b/streamer.h
@@ -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