alsa_write: Print duration of buffer undderuns.
authorAndre Noll <maan@systemlinux.org>
Mon, 30 Nov 2009 22:40:05 +0000 (23:40 +0100)
committerAndre Noll <maan@systemlinux.org>
Mon, 30 Nov 2009 22:40:05 +0000 (23:40 +0100)
Idea taken from aplay.

alsa_write.c

index 67ab59a..9d99c8e 100644 (file)
@@ -16,6 +16,7 @@
 #include <sys/types.h>
 #include <dirent.h>
 #include <alsa/asoundlib.h>
+#include <sys/time.h>
 
 #include "para.h"
 #include "fd.h"
@@ -181,6 +182,23 @@ static int alsa_write_pre_select(struct sched *s, struct writer_node *wn)
        return 1;
 }
 
+static void xrun(snd_pcm_t *handle)
+{
+       snd_pcm_status_t *status;
+       int ret;
+       struct timeval tv, diff;
+
+       snd_pcm_status_alloca(&status);
+       ret = snd_pcm_status(handle, status);
+       if (ret < 0)
+               return;
+       if (snd_pcm_status_get_state(status) != SND_PCM_STATE_XRUN)
+               return;
+       snd_pcm_status_get_trigger_tstamp(status, &tv);
+       tv_diff(now, &tv, &diff);
+       PARA_WARNING_LOG("underrun: %lums\n", tv2ms(&diff));
+}
+
 static int alsa_write_post_select(__a_unused struct sched *s,
                struct writer_node *wn)
 {
@@ -213,11 +231,12 @@ static int alsa_write_post_select(__a_unused struct sched *s,
                wn->written += ret * pad->bytes_per_frame;
                return 1;
        }
-       PARA_WARNING_LOG("%s\n", snd_strerror(-ret));
        if (ret == -EPIPE) {
+               xrun(pad->handle);
                snd_pcm_prepare(pad->handle);
                return 0;
        }
+       PARA_WARNING_LOG("%s\n", snd_strerror(-ret));
        if (ret == -EAGAIN)
                return 0;
        return -E_ALSA_WRITE;