aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPřemysl Eric Janouch <p@janouch.name>2020-10-18 06:55:03 +0200
committerPřemysl Eric Janouch <p@janouch.name>2020-10-18 07:28:14 +0200
commit6c2ae2f6bb57554e0d153f5bf8b246dfefef162b (patch)
treef0317c70ebca2e6c7fa51d264023d1235688c1cf
parentb3579d11282ec055a42fff56a1adcc50357d46f5 (diff)
downloadnncmpp-6c2ae2f6bb57554e0d153f5bf8b246dfefef162b.tar.gz
nncmpp-6c2ae2f6bb57554e0d153f5bf8b246dfefef162b.tar.xz
nncmpp-6c2ae2f6bb57554e0d153f5bf8b246dfefef162b.zip
Give up and implement elapsed time polling
Playback may sometimes stall but it won't produce any events. This popular workaround likes to jump around, though. It might be a good idea to use some kind of hybrid approach. Therefore this is disabled by default so far. Updates #1
-rw-r--r--nncmpp.c39
1 files changed, 35 insertions, 4 deletions
diff --git a/nncmpp.c b/nncmpp.c
index 51ba3b9..859f292 100644
--- a/nncmpp.c
+++ b/nncmpp.c
@@ -610,6 +610,7 @@ static struct app_context
struct poller_timer elapsed_event; ///< Seconds elapsed event
int64_t elapsed_since; ///< Time of the last tick
+ bool elapsed_poll; ///< Poll MPD for the elapsed time?
// TODO: initialize these to -1
int song; ///< Current song index
@@ -692,6 +693,13 @@ tab_selection_range (struct tab *self)
// --- Configuration -----------------------------------------------------------
+static void
+on_poll_elapsed_time_changed (struct config_item *item)
+{
+ // This is only set once, on application startup
+ g.elapsed_poll = item->value.boolean;
+}
+
static struct config_schema g_config_settings[] =
{
{ .name = "address",
@@ -704,6 +712,11 @@ static struct config_schema g_config_settings[] =
{ .name = "root",
.comment = "Where all the files MPD is playing are located",
.type = CONFIG_ITEM_STRING },
+ { .name = "poll_elapsed_time",
+ .comment = "Whether to actively poll MPD for the elapsed time",
+ .type = CONFIG_ITEM_BOOLEAN,
+ .on_change = on_poll_elapsed_time_changed,
+ .default_ = "off" },
{}
};
@@ -3406,12 +3419,19 @@ mpd_update_playback_state (void)
mpd_read_time (duration, &g.song_duration, NULL);
strv_free (&fields);
- // We could also just poll the server each half a second but let's not
poller_timer_reset (&g.elapsed_event);
if (g.state == PLAYER_PLAYING)
{
+ int until_next = 1000 - msec_past_second;
+
+ // We could make use of "until_next", however this might create
+ // an intensive busy loop when playback stalls (typically because of
+ // some network issues). Half a second will work reasonably well.
+ if (g.elapsed_poll)
+ until_next = 500;
+
// Set a timer for when the next round second of playback happens
- poller_timer_set (&g.elapsed_event, 1000 - msec_past_second);
+ poller_timer_set (&g.elapsed_event, until_next);
// Remember when the last round second was, relative to monotonic time
g.elapsed_since = clock_msec (CLOCK_BEST) - msec_past_second;
}
@@ -3539,7 +3559,7 @@ mpd_on_info_response (const struct mpd_response *response,
}
static void
-mpd_on_tick (void *user_data)
+mpd_on_elapsed_time_tick (void *user_data)
{
(void) user_data;
@@ -3573,6 +3593,15 @@ mpd_request_info (void)
}
static void
+mpd_on_elapsed_time_tick_poll (void *user_data)
+{
+ (void) user_data;
+
+ // As soon as the reply arrives, we (may) set the timer again
+ mpd_request_info ();
+}
+
+static void
mpd_on_events (unsigned subsystems, void *user_data)
{
(void) user_data;
@@ -3923,7 +3952,9 @@ app_init_poller_events (void)
poller_timer_set (&g.connect_event, 0);
g.elapsed_event = poller_timer_make (&g.poller);
- g.elapsed_event.dispatcher = mpd_on_tick;
+ g.elapsed_event.dispatcher = g.elapsed_poll
+ ? mpd_on_elapsed_time_tick_poll
+ : mpd_on_elapsed_time_tick;
g.refresh_event = poller_idle_make (&g.poller);
g.refresh_event.dispatcher = app_on_refresh;