summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar waker <wakeroid@gmail.com>2009-08-08 13:56:28 +0200
committerGravatar waker <wakeroid@gmail.com>2009-08-08 13:56:28 +0200
commita55df275a9d859169499c8e031429f2207197deb (patch)
tree1c280421d7cfedc60c5e816522a104432d3a1cd8
parent7bfe216b85c93e2050c139ff48dc099db78a0a0b (diff)
added shuffle support (default by now)
-rw-r--r--callbacks.c2
-rw-r--r--gtkplaylist.c46
-rw-r--r--main.c12
-rw-r--r--playlist.c114
-rw-r--r--playlist.h8
-rw-r--r--streamer.c19
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");
diff --git a/main.c b/main.c
index d1785f9f..f5a85a65 100644
--- a/main.c
+++ b/main.c
@@ -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:
diff --git a/playlist.c b/playlist.c
index 51e17b37..86693fba 100644
--- a/playlist.c
+++ b/playlist.c
@@ -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;
+ }
+}
diff --git a/playlist.h b/playlist.h
index 6e3f7541..29d800c0 100644
--- a/playlist.h
+++ b/playlist.h
@@ -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
diff --git a/streamer.c b/streamer.c
index a2941eee..7796b3e2 100644
--- a/streamer.c
+++ b/streamer.c
@@ -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;