Compare commits

..

3 Commits

Author SHA1 Message Date
2d3909fdd1
Cleanup
No functional change.
2020-10-23 02:57:34 +02:00
b6ce8a0913
Avoid jumping around in polling mode
While still avoiding busy loops.

It works well enough to enable this by default.

Closes #1
2020-10-23 02:42:18 +02:00
9928eca274
Add a comment and update another one 2020-10-18 21:09:03 +02:00

View File

@ -82,6 +82,9 @@ enum
// ncurses is notoriously retarded for input handling, we need something // ncurses is notoriously retarded for input handling, we need something
// different if only to receive mouse events reliably. // different if only to receive mouse events reliably.
//
// 2020 update: ncurses is mostly reliable now but rxvt-unicode needs to start
// supporting 1006, or ncurses needs to start supporting the 1015 mode.
#include "termo.h" #include "termo.h"
@ -609,7 +612,7 @@ static struct app_context
struct str_map playback_info; ///< Current song info struct str_map playback_info; ///< Current song info
struct poller_timer elapsed_event; ///< Seconds elapsed event struct poller_timer elapsed_event; ///< Seconds elapsed event
int64_t elapsed_since; ///< Time of the last tick int64_t elapsed_since; ///< Last tick ts or last elapsed time
bool elapsed_poll; ///< Poll MPD for the elapsed time? bool elapsed_poll; ///< Poll MPD for the elapsed time?
// TODO: initialize these to -1 // TODO: initialize these to -1
@ -716,7 +719,7 @@ static struct config_schema g_config_settings[] =
.comment = "Whether to actively poll MPD for the elapsed time", .comment = "Whether to actively poll MPD for the elapsed time",
.type = CONFIG_ITEM_BOOLEAN, .type = CONFIG_ITEM_BOOLEAN,
.on_change = on_poll_elapsed_time_changed, .on_change = on_poll_elapsed_time_changed,
.default_ = "off" }, .default_ = "on" },
{} {}
}; };
@ -3360,6 +3363,7 @@ mpd_read_time (const char *value, int *sec, int *optional_msec)
unsigned long n = strtoul (period + 1, &end, 10); unsigned long n = strtoul (period + 1, &end, 10);
if (*end) if (*end)
return; return;
// XXX: this relies on three decimal places
*optional_msec = MIN (INT_MAX, n); *optional_msec = MIN (INT_MAX, n);
} }
unsigned long n = strtoul (value, &end, 10); unsigned long n = strtoul (value, &end, 10);
@ -3383,6 +3387,33 @@ mpd_update_playlist_time (void)
} }
} }
static void
mpd_set_elapsed_timer (int msec_past_second)
{
int delay_msec = 1000 - msec_past_second; // Until the next round second
if (!g.elapsed_poll)
{
poller_timer_set (&g.elapsed_event, delay_msec);
// Remember when the last round second was, relative to monotonic time
g.elapsed_since = clock_msec (CLOCK_BEST) - msec_past_second;
return;
}
// We may receive an earlier time, this seems to compensate for it well
// (I haven't seen it trigger more than 50ms too early)
delay_msec += 100;
// When playback stalls, avoid busy looping with the server
int elapsed_msec = g.song_elapsed * 1000 + msec_past_second;
if (elapsed_msec == g.elapsed_since)
delay_msec = MAX (delay_msec, 500);
// In polling mode, we're interested in progress rather than stability.
// We can reuse both the poller_timer struct and the timestamp field.
poller_timer_set (&g.elapsed_event, delay_msec);
g.elapsed_since = elapsed_msec;
}
static void static void
mpd_update_playback_state (void) mpd_update_playback_state (void)
{ {
@ -3421,20 +3452,9 @@ mpd_update_playback_state (void)
poller_timer_reset (&g.elapsed_event); poller_timer_reset (&g.elapsed_event);
if (g.state == PLAYER_PLAYING) if (g.state == PLAYER_PLAYING)
{ mpd_set_elapsed_timer (msec_past_second);
int until_next = 1000 - msec_past_second; else
g.elapsed_since = -1;
// 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, until_next);
// Remember when the last round second was, relative to monotonic time
g.elapsed_since = clock_msec (CLOCK_BEST) - msec_past_second;
}
// The server sends -1 when nothing is being played right now // The server sends -1 when nothing is being played right now
unsigned long n; unsigned long n;