parent
87f5eddea0
commit
859c9d2737
44
nncmpp.c
44
nncmpp.c
|
@ -130,6 +130,14 @@ update_curses_terminal_size (void)
|
||||||
#endif // HAVE_RESIZETERM && TIOCGWINSZ
|
#endif // HAVE_RESIZETERM && TIOCGWINSZ
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int64_t
|
||||||
|
clock_msec (clockid_t clock)
|
||||||
|
{
|
||||||
|
struct timespec tp;
|
||||||
|
hard_assert (clock_gettime (clock, &tp) != -1);
|
||||||
|
return (int64_t) tp.tv_sec * 1000 + (int64_t) tp.tv_nsec / 1000000;
|
||||||
|
}
|
||||||
|
|
||||||
// --- Application -------------------------------------------------------------
|
// --- Application -------------------------------------------------------------
|
||||||
|
|
||||||
// Function names are prefixed mostly because of curses which clutters the
|
// Function names are prefixed mostly because of curses which clutters the
|
||||||
|
@ -215,6 +223,8 @@ static struct app_context
|
||||||
struct str_map song_info; ///< Current song info
|
struct str_map song_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 next tick
|
||||||
|
|
||||||
// TODO: initialize these to -1
|
// TODO: initialize these to -1
|
||||||
int song_elapsed; ///< Song elapsed in seconds
|
int song_elapsed; ///< Song elapsed in seconds
|
||||||
int song_duration; ///< Song duration in seconds
|
int song_duration; ///< Song duration in seconds
|
||||||
|
@ -1584,8 +1594,12 @@ mpd_on_info_response (const struct mpd_response *response,
|
||||||
|
|
||||||
// Note that we may receive a "time" field twice, however the right one
|
// Note that we may receive a "time" field twice, however the right one
|
||||||
// wins here due to the order we send the commands in
|
// wins here due to the order we send the commands in
|
||||||
|
|
||||||
|
// The contents of these values overlap and we try to get what we can
|
||||||
|
// FIXME: don't change the values, for fuck's sake
|
||||||
char *time = str_map_find (&map, "time");
|
char *time = str_map_find (&map, "time");
|
||||||
char *duration = str_map_find (&map, "duration");
|
char *duration = str_map_find (&map, "duration");
|
||||||
|
char *elapsed = str_map_find (&map, "elapsed");
|
||||||
if (time)
|
if (time)
|
||||||
{
|
{
|
||||||
char *colon = strchr (time, ':');
|
char *colon = strchr (time, ':');
|
||||||
|
@ -1602,8 +1616,10 @@ mpd_on_info_response (const struct mpd_response *response,
|
||||||
if (duration && xstrtoul (&tmp, duration, 10))
|
if (duration && xstrtoul (&tmp, duration, 10))
|
||||||
g_ctx.song_duration = tmp;
|
g_ctx.song_duration = tmp;
|
||||||
|
|
||||||
// TODO: use "time" as a fallback (no milliseconds there)
|
// We could also just poll the server each half a second but let's not
|
||||||
char *period, *elapsed = str_map_find (&map, "elapsed");
|
int msec_past_second = 0;
|
||||||
|
|
||||||
|
char *period;
|
||||||
if (elapsed && (period = strchr (elapsed, '.')))
|
if (elapsed && (period = strchr (elapsed, '.')))
|
||||||
{
|
{
|
||||||
// For some reason this is much more precise
|
// For some reason this is much more precise
|
||||||
|
@ -1613,12 +1629,12 @@ mpd_on_info_response (const struct mpd_response *response,
|
||||||
|
|
||||||
if (g_ctx.state == PLAYER_PLAYING
|
if (g_ctx.state == PLAYER_PLAYING
|
||||||
&& xstrtoul (&tmp, period, 10))
|
&& xstrtoul (&tmp, period, 10))
|
||||||
{
|
msec_past_second = tmp;
|
||||||
// TODO: initialize the timer and create a callback
|
|
||||||
poller_timer_set (&g_ctx.elapsed_event, 1000 - tmp);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
poller_timer_set (&g_ctx.elapsed_event, 1000 - msec_past_second);
|
||||||
|
g_ctx.elapsed_since = clock_msec (CLOCK_BEST) - msec_past_second;
|
||||||
|
|
||||||
|
// The server sends -1 when nothing is being played right now
|
||||||
char *volume = str_map_find (&map, "volume");
|
char *volume = str_map_find (&map, "volume");
|
||||||
if (volume && xstrtoul (&tmp, volume, 10))
|
if (volume && xstrtoul (&tmp, volume, 10))
|
||||||
g_ctx.volume = tmp;
|
g_ctx.volume = tmp;
|
||||||
|
@ -1631,10 +1647,14 @@ static void
|
||||||
mpd_on_tick (void *user_data)
|
mpd_on_tick (void *user_data)
|
||||||
{
|
{
|
||||||
(void) user_data;
|
(void) user_data;
|
||||||
// FIXME: this is doomed to drift unless we use POSIX CLOCK_MONOTONIC
|
int64_t diff_msec = clock_msec (CLOCK_BEST) - g_ctx.elapsed_since;
|
||||||
poller_timer_set (&g_ctx.elapsed_event, 1000);
|
int elapsed_sec = diff_msec / 1000;
|
||||||
|
int elapsed_msec = diff_msec % 1000;
|
||||||
|
|
||||||
|
g_ctx.song_elapsed += elapsed_sec;
|
||||||
|
g_ctx.elapsed_since += elapsed_sec * 1000;
|
||||||
|
poller_timer_set (&g_ctx.elapsed_event, 1000 - elapsed_msec);
|
||||||
|
|
||||||
g_ctx.song_elapsed++;
|
|
||||||
// TODO: try to be more efficient in the redrawing procedures
|
// TODO: try to be more efficient in the redrawing procedures
|
||||||
app_redraw ();
|
app_redraw ();
|
||||||
}
|
}
|
||||||
|
@ -1891,11 +1911,7 @@ debug_tab_push (const char *message, chtype attrs)
|
||||||
&g_debug_tab.items[g_debug_tab.super.item_count++];
|
&g_debug_tab.items[g_debug_tab.super.item_count++];
|
||||||
item->text = xstrdup (message);
|
item->text = xstrdup (message);
|
||||||
item->attrs = attrs;
|
item->attrs = attrs;
|
||||||
|
item->timestamp = clock_msec (CLOCK_REALTIME);
|
||||||
struct timespec tp;
|
|
||||||
hard_assert (clock_gettime (CLOCK_REALTIME, &tp) != -1);
|
|
||||||
item->timestamp = (int64_t) tp.tv_sec * 1000
|
|
||||||
+ (int64_t) tp.tv_nsec / 1000000;
|
|
||||||
|
|
||||||
app_redraw_view ();
|
app_redraw_view ();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue