diff options
author | waker <wakeroid@gmail.com> | 2009-08-08 13:56:28 +0200 |
---|---|---|
committer | waker <wakeroid@gmail.com> | 2009-08-08 13:56:28 +0200 |
commit | a55df275a9d859169499c8e031429f2207197deb (patch) | |
tree | 1c280421d7cfedc60c5e816522a104432d3a1cd8 | |
parent | 7bfe216b85c93e2050c139ff48dc099db78a0a0b (diff) |
added shuffle support (default by now)
-rw-r--r-- | callbacks.c | 2 | ||||
-rw-r--r-- | gtkplaylist.c | 46 | ||||
-rw-r--r-- | main.c | 12 | ||||
-rw-r--r-- | playlist.c | 114 | ||||
-rw-r--r-- | playlist.h | 8 | ||||
-rw-r--r-- | streamer.c | 19 |
6 files changed, 138 insertions, 63 deletions
diff --git a/callbacks.c b/callbacks.c index 4f92a8f2..1a5fa460 100644 --- a/callbacks.c +++ b/callbacks.c @@ -167,6 +167,7 @@ on_add_files_activate (GtkMenuItem *menuitem, g_slist_free (lst); } gtk_widget_destroy (dlg); + ps_shuffle (); gtkps_setup_scrollbar (); GtkWidget *widget = lookup_widget (mainwin, "playlist"); draw_playlist (widget, 0, 0, widget->allocation.width, widget->allocation.height); @@ -190,6 +191,7 @@ on_add_folder1_activate (GtkMenuItem *menuitem, } } gtk_widget_destroy (dlg); + ps_shuffle (); gtkps_setup_scrollbar (); GtkWidget *widget = lookup_widget (mainwin, "playlist"); draw_playlist (widget, 0, 0, widget->allocation.width, widget->allocation.height); diff --git a/gtkplaylist.c b/gtkplaylist.c index 9c90c5f7..01bcaca3 100644 --- a/gtkplaylist.c +++ b/gtkplaylist.c @@ -677,6 +677,7 @@ gtkps_playsong (void) { } } +#if 0 void gtkps_prevsong (void) { GtkWidget *widget = lookup_widget (mainwin, "playlist"); @@ -699,28 +700,7 @@ gtkps_prevsong (void) { } } } - -void -gtkps_nextsong (void) { - GtkWidget *widget = lookup_widget (mainwin, "playlist"); - playItem_t *prev = playlist_current_ptr; - if (playlist_current_ptr) { - printf ("gtkps_nextsong\n"); - ps_set_current (playlist_current_ptr->next); - } - if (!playlist_current_ptr) { - printf ("gtkps_nextsong2\n"); - ps_set_current (playlist_head); - } - if (playlist_current_ptr != prev) { - if (prev) { - redraw_ps_row (widget, ps_get_idx_of (prev)); - } - if (playlist_current_ptr) { - redraw_ps_row (widget, ps_get_idx_of (playlist_current_ptr)); - } - } -} +#endif void gtkps_randomsong (void) { @@ -729,24 +709,9 @@ gtkps_randomsong (void) { } GtkWidget *widget = lookup_widget (mainwin, "playlist"); playItem_t *prev = playlist_current_ptr; - int r = rand () % ps_getcount (); - playItem_t *it = ps_get_for_idx (r); - if (it) { - printf ("gtkps_randomsong\n"); - ps_set_current (it); - } - else { - printf ("gtkps_randomsong2\n"); - ps_set_current (NULL); - } - if (playlist_current_ptr != prev) { - if (prev) { - redraw_ps_row (widget, ps_get_idx_of (prev)); - } - if (playlist_current_ptr) { - redraw_ps_row (widget, ps_get_idx_of (playlist_current_ptr)); - } - } + int r = (float)rand ()/RAND_MAX * ps_getcount (); + p_stop (); + streamer_set_nextsong (r, 1); } void @@ -1178,6 +1143,7 @@ gtkps_handle_fm_drag_drop (int drop_y, void *ptr, int length) { p++; } } + ps_shuffle (); gtkps_setup_scrollbar (); GtkWidget *widget = lookup_widget (mainwin, "playlist"); @@ -30,12 +30,6 @@ psdl_thread (uintptr_t ctx) { case M_SONGCHANGED: gtkps_songchanged (p1, p2); break; - case M_SONGFINISHED: - // play next song in playlists - GDK_THREADS_ENTER(); - gtkps_nextsong (); - GDK_THREADS_LEAVE(); - break; case M_PLAYSONG: GDK_THREADS_ENTER(); gtkps_playsong (); @@ -53,12 +47,14 @@ psdl_thread (uintptr_t ctx) { break; case M_NEXTSONG: GDK_THREADS_ENTER(); - gtkps_nextsong (); + p_stop (); + ps_nextsong (); GDK_THREADS_LEAVE(); break; case M_PREVSONG: GDK_THREADS_ENTER(); - gtkps_prevsong (); + p_stop (); + ps_prevsong (); GDK_THREADS_LEAVE(); break; case M_PAUSESONG: @@ -19,11 +19,13 @@ #include "streamer.h" #include "messagepump.h" #include "messages.h" +#include "playback.h" #define SKIP_BLANK_CUE_TRACKS 1 playItem_t *playlist_head; playItem_t *playlist_tail; +playItem_t *playlist_shuffle_head; playItem_t playlist_current; playItem_t *playlist_current_ptr; int ps_count = 0; @@ -407,6 +409,19 @@ ps_remove (playItem_t *it) { if (!it) return -1; ps_count--; + + // remove from shuffle list + for (playItem_t *i = playlist_head; i; i = i->next) { + if (i->shufflenext == it) { + i->shufflenext = it->shufflenext; + if (it == playlist_shuffle_head) { + playlist_shuffle_head = it->shufflenext; + } + break; + } + } + + // remove from linear list if (it->prev) { it->prev->next = it->next; } @@ -518,6 +533,7 @@ ps_item_copy (playItem_t *out, playItem_t *it) { out->filetype = it->filetype; out->next = it->next; out->prev = it->prev; + out->shufflenext = it->shufflenext; // copy metainfo metaInfo_t *prev = NULL; metaInfo_t *meta = it->meta; @@ -594,17 +610,63 @@ ps_set_current (playItem_t *it) { } int +ps_prevsong (void) { + //if (shuffle) + { + if (!playlist_current_ptr) { + return ps_nextsong (); + } + else { + playItem_t *it = NULL; + for (it = playlist_shuffle_head; it; it = it->shufflenext) { + if (it->shufflenext == playlist_current_ptr) { + break; + } + } + int r = ps_get_idx_of (it); + streamer_set_nextsong (r, 1); + return 0; + } + } +#if 0 + else { + } +#endif + return -1; +} + +int ps_nextsong (void) { - if (playlist_current_ptr && playlist_current_ptr->next) { - return ps_set_current (playlist_current_ptr->next); + //if (shuffle) + { + if (!playlist_current_ptr) { + playItem_t *it = playlist_shuffle_head; + int r = ps_get_idx_of (it); + streamer_set_nextsong (r, 1); + return 0; + } + else { + playItem_t *it = playlist_current_ptr->shufflenext; + int r = ps_get_idx_of (it); + streamer_set_nextsong (r, 1); + return 0; + } } - if (playlist_head) { - return ps_set_current (playlist_head); +#if 0 + else { + if (playlist_current_ptr && playlist_current_ptr->next) { + return ps_set_current (playlist_current_ptr->next); + } + if (playlist_head) { + return ps_set_current (playlist_head); + } + ps_set_current (NULL); } - ps_set_current (NULL); +#endif return -1; } +#if 0 playItem_t * ps_getnext (void) { if (playlist_current_ptr && playlist_current_ptr->next) { @@ -615,6 +677,7 @@ ps_getnext (void) { } return NULL; } +#endif void ps_start_current (void) { @@ -749,3 +812,44 @@ ps_delete_selected (void) { } } +void +ps_shuffle (void) { + playItem_t *head = NULL; + playItem_t *tail = NULL; + playItem_t *it; + int cnt = 0; + for (it = playlist_head; it; it = it->next) { + it->shufflenext = head; + head = it; + cnt++; + } + playlist_shuffle_head = NULL; + while (cnt > 0) { + int idx = (float)rand ()/RAND_MAX * cnt; + int i = 0; + playItem_t *prev = NULL; + for (it = head; it; it = it->shufflenext, i++) { + if (i == idx) { + if (prev) { + prev->shufflenext = it->shufflenext; + } + else { + head = it->shufflenext; + } + // prepend to shuffled playlist + it->shufflenext = playlist_shuffle_head; + if (!playlist_shuffle_head) { + tail = it; + } + playlist_shuffle_head = it; + cnt--; + break; + } + prev = it; + } + } + // loop this list + if (tail) { + tail->shufflenext = playlist_shuffle_head; + } +} @@ -17,12 +17,14 @@ typedef struct playItem_s { const char *filetype; // e.g. MP3 or OGG struct playItem_s *next; // next item in linked list struct playItem_s *prev; // prev item in linked list + struct playItem_s *shufflenext; // next item in shuffle list struct metaInfo_s *meta; // linked list storing metainfo unsigned selected : 1; } playItem_t; extern playItem_t *playlist_head; // head of linked list extern playItem_t *playlist_tail; // tail of linked list +extern playItem_t *playlist_shuffle_head; // head of shuffled playlist extern playItem_t *playlist_current_ptr; // pointer to a real current playlist item extern playItem_t playlist_current; // copy of playlist item being played (stays in memory even if removed from playlist) @@ -75,6 +77,9 @@ ps_set_current (playItem_t *it); int ps_nextsong (void); +int +ps_prevsong (void); + // starts current playlist item from position 0 // only if the item is still in playlist void @@ -92,4 +97,7 @@ ps_find_meta (playItem_t *it, const char *key); void ps_delete_selected (void); +void +ps_shuffle (void); + #endif // __PLAYLIST_H @@ -53,16 +53,14 @@ streamer_thread (uintptr_t ctx) { usleep (3000); } } - if (pstate >= 0) { - if (pstate == 0) { - p_stop (); - } - else if (pstate == 1) { - p_play (); - } - else if (pstate == 2) { - p_pause (); - } + if (pstate == 0) { + p_stop (); + } + else if (pstate == 1) { + p_play (); + } + else if (pstate == 2) { + p_pause (); } } streamer_lock (); @@ -226,6 +224,7 @@ streamer_read_async (char *bytes, int size) { while (ps_nextsong () < 0) { usleep (3000); } + break; } } return initsize - size; |