pcm: Rewrite pcm_get_htimestamp()

Use pcm_avail_update(), check avail for timestamp
coherence.

Signed-off-by: Ricardo Biehl Pasquali <pasqualirb@gmail.com>
diff --git a/src/pcm.c b/src/pcm.c
index 013c007..d037f8d 100644
--- a/src/pcm.c
+++ b/src/pcm.c
@@ -1287,7 +1287,6 @@
  * otherwise the clock is CLOCK_REALTIME.
  * For an input stream, frames available are frames ready for the application to read.
  * For an output stream, frames available are the number of empty frames available for the application to write.
- * Only available for PCMs opened with the @ref PCM_MMAP flag.
  * @param pcm A PCM handle.
  * @param avail The number of available frames
  * @param tstamp The timestamp
@@ -1296,36 +1295,36 @@
 int pcm_get_htimestamp(struct pcm *pcm, unsigned int *avail,
                        struct timespec *tstamp)
 {
-    int frames;
-    int rc;
-    snd_pcm_uframes_t hw_ptr;
+    int checking;
+    int tmp;
 
     if (!pcm_is_ready(pcm))
         return -1;
 
-    rc = pcm_sync_ptr(pcm, SNDRV_PCM_SYNC_PTR_APPL|SNDRV_PCM_SYNC_PTR_HWSYNC);
-    if (rc < 0)
-        return -1;
+    checking = 0;
 
-    if ((pcm->mmap_status->state != PCM_STATE_RUNNING) &&
-            (pcm->mmap_status->state != PCM_STATE_DRAINING))
-        return -1;
+again:
 
+    tmp = pcm_avail_update(pcm);
+    if (tmp < 0)
+        return tmp; /* error */
+
+    if (checking && (unsigned int) tmp == *avail)
+        return 0;
+
+    *avail = (unsigned int) tmp;
     *tstamp = pcm->mmap_status->tstamp;
-    if (tstamp->tv_sec == 0 && tstamp->tv_nsec == 0)
-        return -1;
 
-    hw_ptr = pcm->mmap_status->hw_ptr;
-    if (pcm->flags & PCM_IN)
-        frames = hw_ptr - pcm->mmap_control->appl_ptr;
-    else
-        frames = hw_ptr + pcm->buffer_size - pcm->mmap_control->appl_ptr;
+    /*
+     * When status is mmaped, get avail again to ensure
+     * valid timestamp.
+     */
+    if (!pcm->sync_ptr) {
+        checking = 1;
+        goto again;
+    }
 
-    if (frames < 0)
-        return -1;
-
-    *avail = (unsigned int)frames;
-
+    /* SYNC_PTR ioctl was used, no need to check avail */
     return 0;
 }