From 82af1df465181da783d85256afdda26942eaecbf Mon Sep 17 00:00:00 2001 From: Jaroslav Kysela Date: Fri, 11 Apr 2008 14:11:04 +0200 Subject: [PATCH] added snd_pcm_hw_params_is_monotonic/can_forward/can_rewind functions --- include/pcm.h | 3 +++ src/pcm/pcm.c | 63 +++++++++++++++++++++++++++++++++++++++++++++ src/pcm/pcm_hw.c | 7 +++++ src/pcm/pcm_local.h | 4 +++ 4 files changed, 77 insertions(+) diff --git a/include/pcm.h b/include/pcm.h index 4c2d456b..9a592e3d 100644 --- a/include/pcm.h +++ b/include/pcm.h @@ -518,7 +518,10 @@ int snd_pcm_hw_params_can_mmap_sample_resolution(const snd_pcm_hw_params_t *para int snd_pcm_hw_params_is_double(const snd_pcm_hw_params_t *params); int snd_pcm_hw_params_is_batch(const snd_pcm_hw_params_t *params); int snd_pcm_hw_params_is_block_transfer(const snd_pcm_hw_params_t *params); +int snd_pcm_hw_params_is_monotonic(const snd_pcm_hw_params_t *params); int snd_pcm_hw_params_can_overrange(const snd_pcm_hw_params_t *params); +int snd_pcm_hw_params_can_forward(const snd_pcm_hw_params_t *params); +int snd_pcm_hw_params_can_rewind(const snd_pcm_hw_params_t *params); int snd_pcm_hw_params_can_pause(const snd_pcm_hw_params_t *params); int snd_pcm_hw_params_can_resume(const snd_pcm_hw_params_t *params); int snd_pcm_hw_params_is_half_duplex(const snd_pcm_hw_params_t *params); diff --git a/src/pcm/pcm.c b/src/pcm/pcm.c index a30d319a..e0f808c3 100644 --- a/src/pcm/pcm.c +++ b/src/pcm/pcm.c @@ -2811,6 +2811,27 @@ int snd_pcm_hw_params_is_block_transfer(const snd_pcm_hw_params_t *params) return !!(params->info & SNDRV_PCM_INFO_BLOCK_TRANSFER); } +/** + * \brief Check, if timestamps are monotonic for given configuration + * \param params Configuration space + * \return Boolean value + * \retval 0 Device doesn't do monotomic timestamps + * \retval 1 Device does monotonic timestamps + * + * It is not allowed to call this function when given configuration is not exactly one. + * Usually, #snd_pcm_hw_params() function chooses one configuration + * from the configuration space. + */ +int snd_pcm_hw_params_is_monotonic(const snd_pcm_hw_params_t *params) +{ + assert(params); + if (CHECK_SANITY(params->info == ~0U)) { + SNDMSG("invalid PCM info field"); + return 0; /* FIXME: should be a negative error? */ + } + return !!(params->info & SND_PCM_INFO_MONOTONIC); +} + /** * \brief Check, if hardware supports overrange detection * \param params Configuration space @@ -2832,6 +2853,48 @@ int snd_pcm_hw_params_can_overrange(const snd_pcm_hw_params_t *params) return !!(params->info & SNDRV_PCM_INFO_OVERRANGE); } +/** + * \brief Check, if device supports forward + * \param params Configuration space + * \return Boolean value + * \retval 0 Device doesn't support forward + * \retval 1 Device supports forward + * + * It is not allowed to call this function when given configuration is not exactly one. + * Usually, #snd_pcm_hw_params() function chooses one configuration + * from the configuration space. + */ +int snd_pcm_hw_params_can_forward(const snd_pcm_hw_params_t *params) +{ + assert(params); + if (CHECK_SANITY(params->info == ~0U)) { + SNDMSG("invalid PCM info field"); + return 0; /* FIXME: should be a negative error? */ + } + return !!(params->info & SND_PCM_INFO_FORWARD); +} + +/** + * \brief Check, if device supports rewind + * \param params Configuration space + * \return Boolean value + * \retval 0 Device doesn't support rewind + * \retval 1 Device supports rewind + * + * It is not allowed to call this function when given configuration is not exactly one. + * Usually, #snd_pcm_hw_params() function chooses one configuration + * from the configuration space. + */ +int snd_pcm_hw_params_can_rewind(const snd_pcm_hw_params_t *params) +{ + assert(params); + if (CHECK_SANITY(params->info == ~0U)) { + SNDMSG("invalid PCM info field"); + return 0; /* FIXME: should be a negative error? */ + } + return !!(params->info & SND_PCM_INFO_REWIND); +} + /** * \brief Check, if hardware supports pause * \param params Configuration space diff --git a/src/pcm/pcm_hw.c b/src/pcm/pcm_hw.c index 88b5e048..ebead2ff 100644 --- a/src/pcm/pcm_hw.c +++ b/src/pcm/pcm_hw.c @@ -245,6 +245,13 @@ static int snd_pcm_hw_hw_refine(snd_pcm_t *pcm, snd_pcm_hw_params_t *params) // SYSMSG("SNDRV_PCM_IOCTL_HW_REFINE failed"); return err; } + + if (params->info != ~0UL) { + params->info &= ~0xf0000000; + params->info |= (pcm->monotonic ? SND_PCM_INFO_MONOTONIC : 0) | + SND_PCM_INFO_REWIND | + SND_PCM_INFO_FORWARD; + } return 0; } diff --git a/src/pcm/pcm_local.h b/src/pcm/pcm_local.h index 661d40ee..f0dae7cb 100644 --- a/src/pcm/pcm_local.h +++ b/src/pcm/pcm_local.h @@ -95,6 +95,10 @@ typedef enum sndrv_pcm_hw_param snd_pcm_hw_param_t; #define SND_PCM_HW_PARAMS_NORESAMPLE SNDRV_PCM_HW_PARAMS_NORESAMPLE #define SND_PCM_HW_PARAMS_EXPORT_BUFFER SNDRV_PCM_HW_PARAMS_EXPORT_BUFFER +#define SND_PCM_INFO_FORWARD 0x10000000 +#define SND_PCM_INFO_REWIND 0x20000000 +#define SND_PCM_INFO_MONOTONIC 0x80000000 + typedef struct _snd_pcm_rbptr { snd_pcm_t *master; volatile snd_pcm_uframes_t *ptr; -- 2.47.1