aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/pcm.c41
1 files changed, 20 insertions, 21 deletions
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 @@ int pcm_avail_update(struct pcm *pcm)
* 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_avail_update(struct pcm *pcm)
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:
- *tstamp = pcm->mmap_status->tstamp;
- if (tstamp->tv_sec == 0 && tstamp->tv_nsec == 0)
- return -1;
+ tmp = pcm_avail_update(pcm);
+ if (tmp < 0)
+ return tmp; /* error */
- 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;
+ if (checking && (unsigned int) tmp == *avail)
+ return 0;
- if (frames < 0)
- return -1;
+ *avail = (unsigned int) tmp;
+ *tstamp = pcm->mmap_status->tstamp;
- *avail = (unsigned int)frames;
+ /*
+ * When status is mmaped, get avail again to ensure
+ * valid timestamp.
+ */
+ if (!pcm->sync_ptr) {
+ checking = 1;
+ goto again;
+ }
+ /* SYNC_PTR ioctl was used, no need to check avail */
return 0;
}