summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Alexey Yakovenko <wakeroid@gmail.com>2009-10-26 20:36:16 +0100
committerGravatar Alexey Yakovenko <wakeroid@gmail.com>2009-10-26 20:36:53 +0100
commit7d0f7176f06f933ae2c8d5ca6e7336b70875ffdc (patch)
treeea8fc67ebc633615adcab5274f805fd57a5aa89d
parent9905caa983fb72d6feb9105ebe7adb063c1cb625 (diff)
added buffering indication to playing status
fixed replaygain scale bug
-rw-r--r--gtkplaylist.c83
-rw-r--r--gtkplaylist.h9
-rw-r--r--main.c49
-rw-r--r--pixmaps/Makefile.am5
-rw-r--r--pixmaps/buffering_16.pngbin0 -> 228 bytes
-rw-r--r--playlist.c8
-rw-r--r--streamer.c57
7 files changed, 143 insertions, 68 deletions
diff --git a/gtkplaylist.c b/gtkplaylist.c
index 658c7bd2..a4f4e125 100644
--- a/gtkplaylist.c
+++ b/gtkplaylist.c
@@ -50,6 +50,10 @@
//#define trace(...) { fprintf(stderr, __VA_ARGS__); }
#define trace(fmt,...)
+extern GtkWidget *mainwin;
+extern GtkStatusIcon *trayicon;
+extern gtkplaylist_t main_playlist;
+
// orange on dark color scheme
float colo_dark_orange[COLO_COUNT][3] = {
{ 0x7f/255.f, 0x7f/255.f, 0x7f/255.f }, // cursor
@@ -91,6 +95,7 @@ int rowheight = -1;
static uintptr_t play16_pixbuf;
static uintptr_t pause16_pixbuf;
+static uintptr_t buffering16_pixbuf;
static GdkCursor* cursor_sz;
static GdkCursor* cursor_drag;
@@ -167,7 +172,6 @@ colhdr_anim_swap (gtkplaylist_t *pl, int c1, int c2, int x1, int x2) {
colhdr_anim.anim_active = 1;
timeline_stop (colhdr_anim.timeline, 0);
timeline_init (colhdr_anim.timeline, COLHDR_ANIM_TIME, 100, colhdr_anim_cb, &colhdr_anim);
- printf ("timeline_start\n");
timeline_start (colhdr_anim.timeline);
}
@@ -178,6 +182,7 @@ gtkpl_init (void) {
//memcpy (colo_current, colo_dark_orange, sizeof (colo_current));
play16_pixbuf = draw_load_pixbuf ("play_16.png");
pause16_pixbuf = draw_load_pixbuf ("pause_16.png");
+ buffering16_pixbuf = draw_load_pixbuf ("buffering_16.png");
rowheight = draw_get_font_size () + 12;
memcpy (colo_current, colo_white_blue, sizeof (colo_current));
}
@@ -330,10 +335,6 @@ gtkpl_draw_pl_row (gtkplaylist_t *ps, int row, playItem_t *it) {
}
int width, height;
draw_get_canvas_size ((uintptr_t)ps->backbuf, &width, &height);
-// if (it == playlist_current_ptr && ps->colwidths[0] > 0 && !p_isstopped ()) {
-// uintptr_t pixbuf = p_ispaused () ? pause16_pixbuf : play16_pixbuf;
-// draw_pixbuf ((uintptr_t)ps->backbuf, pixbuf, ps->colwidths[0]/2-8-ps->hscrollpos, (row - ps->scrollpos) * rowheight + rowheight/2 - 8, 0, 0, 16, 16);
-// }
if (it && ((it->selected && ps->multisel) || (row == ps->row && !ps->multisel))) {
if (row % 2) {
theme_set_bg_color (COLO_PLAYLIST_SEL_EVEN);
@@ -386,8 +387,19 @@ gtkpl_draw_pl_row (gtkplaylist_t *ps, int row, playItem_t *it) {
int x = -ps->hscrollpos;
gtkpl_column_t *c;
for (c = ps->columns; c; c = c->next) {
- if (it == playlist_current_ptr && c->id == DB_COLUMN_PLAYING && !p_isstopped ()) {
- uintptr_t pixbuf = p_ispaused () ? pause16_pixbuf : play16_pixbuf;
+ if (it == playlist_current_ptr && c->id == DB_COLUMN_PLAYING/* && !p_isstopped ()*/) {
+ int paused = p_ispaused ();
+ int buffering = !streamer_ok_to_read (-1);
+ uintptr_t pixbuf;
+ if (paused) {
+ pixbuf = pause16_pixbuf;
+ }
+ else if (!buffering) {
+ pixbuf = play16_pixbuf;
+ }
+ else {
+ pixbuf = buffering16_pixbuf;
+ }
draw_pixbuf ((uintptr_t)ps->backbuf, pixbuf, x + c->width/2 - 8 - ps->hscrollpos, (row - ps->scrollpos) * rowheight + rowheight/2 - 8, 0, 0, 16, 16);
}
else {
@@ -1055,7 +1067,6 @@ gtkpl_handle_drag_drop (gtkplaylist_t *ps, int drop_y, uint32_t *d, int length)
int idx = 0;
playItem_t *next = NULL;
for (playItem_t *it = playlist_head[ps->iterator]; it && processed < length; it = next, idx++) {
- // printf ("idx: %d\n", d[i]);
next = it->next[ps->iterator];
if (idx == d[processed]) {
if (it->prev[ps->iterator]) {
@@ -1439,7 +1450,6 @@ on_header_motion_notify_event (GtkWidget *widget,
if (event->time - last_header_motion_ev < 50 || prev_header_x == event->x) {
return FALSE;
}
- //printf ("%f\n", event->time - last_header_motion_ev);
last_header_motion_ev = event->time;
prev_header_x = event->x;
gdk_window_set_cursor (widget->window, cursor_sz);
@@ -1864,3 +1874,58 @@ gtkpl_column_rewrite_config (gtkplaylist_t *pl) {
conf_set_str (key, value);
}
}
+
+void
+set_tray_tooltip (const char *text) {
+#if (GTK_MINOR_VERSION < 16)
+ gtk_status_icon_set_tooltip (trayicon, text);
+#else
+ gtk_status_icon_set_tooltip_text (trayicon, text);
+#endif
+}
+
+void
+gtkpl_current_track_changed (playItem_t *it) {
+ char str[600];
+ char dname[512];
+ pl_format_item_display_name (it, dname, 512);
+ snprintf (str, 600, "DeaDBeeF - %s", dname);
+ gtk_window_set_title (GTK_WINDOW (mainwin), str);
+ set_tray_tooltip (str);
+}
+
+struct songchange_t {
+ int from, to;
+};
+
+static gboolean
+gtkpl_songchanged_callback (void *data) {
+ struct songchange_t *sc = (struct songchange_t *)data;
+ int from = sc->from;
+ int to = sc->to;
+ free (sc);
+ // update window title
+ if (from >= 0 || to >= 0) {
+ if (to >= 0) {
+ playItem_t *it = pl_get_for_idx (to);
+ if (it) { // it might have been deleted after event was sent
+ gtkpl_current_track_changed (it);
+ }
+ }
+ else {
+ gtk_window_set_title (GTK_WINDOW (mainwin), "DeaDBeeF");
+ set_tray_tooltip ("DeaDBeeF");
+ }
+ }
+ // update playlist view
+ gtkpl_songchanged (&main_playlist, from, to);
+ return FALSE;
+}
+
+void
+gtkpl_songchanged_wrapper (int from, int to) {
+ struct songchange_t *sc = malloc (sizeof (struct songchange_t));
+ sc->from = from;
+ sc->to = to;
+ g_idle_add (gtkpl_songchanged_callback, sc);
+}
diff --git a/gtkplaylist.h b/gtkplaylist.h
index b060947e..2e827839 100644
--- a/gtkplaylist.h
+++ b/gtkplaylist.h
@@ -249,4 +249,13 @@ gtkpl_column_rewrite_config (gtkplaylist_t *pl);
void
gtkpl_expose_header (gtkplaylist_t *ps, int x, int y, int w, int h);
+void
+set_tray_tooltip (const char *text);
+
+void
+gtkpl_songchanged_wrapper (int from, int to);
+
+void
+gtkpl_current_track_changed (playItem_t *it);
+
#endif // __GTKPLAYLIST_H
diff --git a/main.c b/main.c
index 89577ffd..5bf14332 100644
--- a/main.c
+++ b/main.c
@@ -66,15 +66,6 @@ GtkWidget *searchwin;
GtkStatusIcon *trayicon;
GtkWidget *traymenu;
-void
-set_tray_tooltip (const char *text) {
-#if (GTK_MINOR_VERSION < 16)
- gtk_status_icon_set_tooltip (trayicon, text);
-#else
- gtk_status_icon_set_tooltip_text (trayicon, text);
-#endif
-}
-
// playlist configuration structures
gtkplaylist_t main_playlist;
gtkplaylist_t search_playlist;
@@ -109,7 +100,7 @@ update_songinfo (void) {
songpos = 0;
}
else if (str_playing_song.decoder) {
- codec_lock ();
+// codec_lock ();
DB_decoder_t *c = str_playing_song.decoder;
float playpos = streamer_get_playpos ();
int minpos = playpos / 60;
@@ -121,7 +112,7 @@ update_songinfo (void) {
int samplerate = c->info.samplerate;
int bitspersample = c->info.bps;
songpos = playpos;
- codec_unlock ();
+// codec_unlock ();
char t[100];
if (str_playing_song._duration >= 0) {
@@ -340,16 +331,6 @@ server_update (void) {
}
void
-current_track_changed (playItem_t *it) {
- char str[600];
- char dname[512];
- pl_format_item_display_name (it, dname, 512);
- snprintf (str, 600, "DeaDBeeF - %s", dname);
- gtk_window_set_title (GTK_WINDOW (mainwin), str);
- set_tray_tooltip (str);
-}
-
-void
player_thread (uintptr_t ctx) {
prctl (PR_SET_NAME, "deadbeef-player", 0, 0, 0, 0);
for (;;) {
@@ -388,26 +369,12 @@ player_thread (uintptr_t ctx) {
GDK_THREADS_LEAVE();
return;
case M_SONGCHANGED:
- GDK_THREADS_ENTER();
- // update window title
- int from = p1;
- int to = p2;
- if (from >= 0 || to >= 0) {
- if (to >= 0) {
- playItem_t *it = pl_get_for_idx (to);
- if (it) { // it might have been deleted after event was sent
- current_track_changed (it);
- }
- }
- else {
- gtk_window_set_title (GTK_WINDOW (mainwin), "DeaDBeeF");
- set_tray_tooltip ("DeaDBeeF");
- }
+ {
+ int from = p1;
+ int to = p2;
+ gtkpl_songchanged_wrapper (from, to);
+ plug_trigger_event (DB_EV_SONGCHANGED, 0);
}
- // update playlist view
- gtkpl_songchanged (&main_playlist, p1, p2);
- GDK_THREADS_LEAVE();
- plug_trigger_event (DB_EV_SONGCHANGED, 0);
break;
case M_PLAYSONG:
gtkpl_playsong (&main_playlist);
@@ -424,7 +391,7 @@ player_thread (uintptr_t ctx) {
GDK_THREADS_ENTER();
gtkpl_redraw_pl_row (&main_playlist, p1, it);
if (it == playlist_current_ptr) {
- current_track_changed (it);
+ gtkpl_current_track_changed (it);
}
GDK_THREADS_LEAVE();
}
diff --git a/pixmaps/Makefile.am b/pixmaps/Makefile.am
index 86bc3ef0..fd8452cd 100644
--- a/pixmaps/Makefile.am
+++ b/pixmaps/Makefile.am
@@ -1,10 +1,11 @@
pixmapsdir = $(pkgdatadir)/pixmaps
pixmaps_DATA =\
-next_24.png\
pause_16.png\
-pause_24.png\
play_16.png\
+buffering_16.png\
+next_24.png\
+pause_24.png\
play_24.png\
prev_24.png\
random_24.png\
diff --git a/pixmaps/buffering_16.png b/pixmaps/buffering_16.png
new file mode 100644
index 00000000..bf5b8887
--- /dev/null
+++ b/pixmaps/buffering_16.png
Binary files differ
diff --git a/playlist.c b/playlist.c
index e437adc2..13a1c3f8 100644
--- a/playlist.c
+++ b/playlist.c
@@ -648,6 +648,8 @@ playItem_t *
pl_item_alloc (void) {
playItem_t *it = malloc (sizeof (playItem_t));
memset (it, 0, sizeof (playItem_t));
+ it->replaygain_album_peak = 1;
+ it->replaygain_track_peak = 1;
return it;
}
@@ -1202,12 +1204,18 @@ pl_load (const char *fname) {
if (fread (&it->replaygain_album_peak, 1, 4, fp) != 4) {
goto load_fail;
}
+ if (it->replaygain_album_peak == 0) {
+ it->replaygain_album_peak = 1;
+ }
if (fread (&it->replaygain_track_gain, 1, 4, fp) != 4) {
goto load_fail;
}
if (fread (&it->replaygain_track_peak, 1, 4, fp) != 4) {
goto load_fail;
}
+ if (it->replaygain_track_peak == 0) {
+ it->replaygain_track_peak = 1;
+ }
// printf ("loading file %s\n", it->fname);
int16_t nm = 0;
if (fread (&nm, 1, 2, fp) != 2) {
diff --git a/streamer.c b/streamer.c
index 70abb550..ef8618e5 100644
--- a/streamer.c
+++ b/streamer.c
@@ -85,6 +85,8 @@ playItem_t str_streaming_song;
static playItem_t *orig_playing_song;
static playItem_t *orig_streaming_song;
+static int streamer_buffering;
+
// playlist must call that whenever item was removed
void
streamer_song_removed_notify (playItem_t *it) {
@@ -105,19 +107,24 @@ streamer_song_removed_notify (playItem_t *it) {
// that must be called after last sample from str_playing_song was done reading
static int
streamer_set_current (playItem_t *it) {
+ int from, to;
+ streamer_buffering = 1;
+ from = orig_playing_song ? pl_get_idx_of (orig_playing_song) : -1;
+ to = it ? pl_get_idx_of (it) : -1;
+ if (!orig_playing_song || p_isstopped ()) {
+ playlist_current_ptr = it;
+ }
+ trace ("from=%d, to=%d\n", from, to);
+ trace ("sending songchanged\n");
+ messagepump_push (M_SONGCHANGED, 0, from, to);
trace ("streamer_set_current %p, buns=%d\n", it);
-// if (str_streaming_song.decoder) {
-// trace ("sending songfinished to plugins [1]\n");
-// plug_trigger_event (DB_EV_SONGFINISHED);
-// str_streaming_song.decoder->free ();
-// }
if(str_streaming_song.decoder) {
str_streaming_song.decoder->free ();
pl_item_free (&str_streaming_song);
}
orig_streaming_song = it;
if (!it) {
- return 0;
+ goto success;
}
if (!it->decoder && it->filetype && !strcmp (it->filetype, "content")) {
// try to get content-type
@@ -173,6 +180,8 @@ streamer_set_current (playItem_t *it) {
if (bytes_until_next_song == -1) {
bytes_until_next_song = 0;
}
+success:
+ messagepump_push (M_TRACKCHANGED, 0, to, 0);
return 0;
}
@@ -242,7 +251,6 @@ streamer_thread (uintptr_t ctx) {
badsong = sng;
}
// try jump to next song
- playlist_current_ptr = try;
pl_nextsong (0);
usleep (50000);
continue;
@@ -266,7 +274,7 @@ streamer_thread (uintptr_t ctx) {
trace ("sending songfinished to plugins [1]\n");
plug_trigger_event (DB_EV_SONGFINISHED, 0);
}
- messagepump_push (M_SONGCHANGED, 0, pl_get_idx_of (orig_playing_song), -1);
+// messagepump_push (M_SONGCHANGED, 0, pl_get_idx_of (orig_playing_song), -1);
streamer_set_current (NULL);
pl_item_free (&str_playing_song);
orig_playing_song = NULL;
@@ -282,11 +290,16 @@ streamer_thread (uintptr_t ctx) {
// means last song was deleted during final drain
nextsong = -1;
p_stop ();
- messagepump_push (M_SONGCHANGED, 0, pl_get_idx_of (playlist_current_ptr), -1);
+// messagepump_push (M_SONGCHANGED, 0, pl_get_idx_of (playlist_current_ptr), -1);
streamer_set_current (NULL);
continue;
}
trace ("bytes_until_next_song=0, starting playback of new song\n");
+ int from = orig_playing_song ? pl_get_idx_of (orig_playing_song) : -1;
+ int to = orig_streaming_song ? pl_get_idx_of (orig_streaming_song) : -1;
+ trace ("from=%d, to=%d\n", from, to);
+ trace ("sending songchanged\n");
+ messagepump_push (M_SONGCHANGED, 0, from, to);
bytes_until_next_song = -1;
// plugin will get pointer to str_playing_song
if (str_playing_song.decoder) {
@@ -297,9 +310,6 @@ streamer_thread (uintptr_t ctx) {
pl_item_free (&str_playing_song);
// copy streaming into playing
pl_item_copy (&str_playing_song, &str_streaming_song);
- int from = orig_playing_song ? pl_get_idx_of (orig_playing_song) : -1;
- int to = orig_streaming_song ? pl_get_idx_of (orig_streaming_song) : -1;
- trace ("from=%d, to=%d\n", from, to);
orig_playing_song = orig_streaming_song;
if (orig_playing_song) {
orig_playing_song->played = 1;
@@ -308,8 +318,6 @@ streamer_thread (uintptr_t ctx) {
}
playlist_current_ptr = orig_playing_song;
// that is needed for playlist drawing
- trace ("sending songchanged\n");
- messagepump_push (M_SONGCHANGED, 0, from, to);
// plugin will get pointer to new str_playing_song
trace ("sending songstarted to plugins\n");
plug_trigger_event (DB_EV_SONGSTARTED, 0);
@@ -338,6 +346,11 @@ streamer_thread (uintptr_t ctx) {
bytes_until_next_song = -1;
}
+ streamer_buffering = 1;
+ int trk = pl_get_idx_of (orig_streaming_song);
+ if (trk != -1) {
+ messagepump_push (M_TRACKCHANGED, 0, trk, 0);
+ }
streamer_lock ();
streambuffer_fill = 0;
streambuffer_pos = 0;
@@ -780,10 +793,22 @@ streamer_get_fill (void) {
int
streamer_ok_to_read (int len) {
- if (bytes_until_next_song > 0) {
+ if (len >= 0 && (bytes_until_next_song > 0 || streambuffer_fill >= (len*2))) {
+ if (streamer_buffering) {
+ streamer_buffering = 0;
+ if (orig_streaming_song) {
+ int trk = pl_get_idx_of (orig_streaming_song);
+ if (trk != -1) {
+ messagepump_push (M_TRACKCHANGED, 0, trk, 0);
+ }
+ }
+ }
return 1;
}
- return streambuffer_fill >= (len*2);
+ else {
+ return 1-streamer_buffering;
+ }
+ return 0;
}
int