diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/pcm.c | 41 |
1 files changed, 20 insertions, 21 deletions
@@ -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; } |