[alsa-devel] [alsa-lib][PATCH 2/2] pcm: add support for interface version 2.0.14
Takashi Sakamoto
o-takashi at sakamocchi.jp
Sun Jun 18 18:49:21 CEST 2017
In interface version 2.0.14, ALSA PCM core request feedback to
applications when they operate any PCM frames in mmap operation for a
type of devices with SNDRV_PCM_INFO_ACK_APPLPTR flag.
This commit adds support for this change to keep compatibility for
existent applications which uses alsa-lib API.
Signed-off-by: Takashi Sakamoto <o-takashi at sakamocchi.jp>
---
src/pcm/pcm_hw.c | 43 +++++++++++++++++++++++++++++++++++++------
1 file changed, 37 insertions(+), 6 deletions(-)
diff --git a/src/pcm/pcm_hw.c b/src/pcm/pcm_hw.c
index 30cd5d0f..880109ad 100644
--- a/src/pcm/pcm_hw.c
+++ b/src/pcm/pcm_hw.c
@@ -105,6 +105,7 @@ typedef struct {
/* for chmap */
unsigned int chmap_caps;
snd_pcm_chmap_query_t **chmap_override;
+ int ack_applptr;
} snd_pcm_hw_t;
#define SNDRV_FILE_PCM_STREAM_PLAYBACK ALSA_DEVICE_DIRECTORY "pcmC%iD%ip"
@@ -128,11 +129,12 @@ struct timespec snd_pcm_hw_fast_tstamp(snd_pcm_t *pcm)
}
#endif /* DOC_HIDDEN */
-static int sync_ptr1(snd_pcm_hw_t *hw, unsigned int flags)
+static int sync_ptr1(snd_pcm_hw_t *hw, struct snd_pcm_sync_ptr *sync_ptr,
+ unsigned int flags)
{
int err;
- hw->sync_ptr->flags = flags;
- err = ioctl((hw)->fd, SNDRV_PCM_IOCTL_SYNC_PTR, (hw)->sync_ptr);
+ sync_ptr->flags = flags;
+ err = ioctl((hw)->fd, SNDRV_PCM_IOCTL_SYNC_PTR, sync_ptr);
if (err < 0) {
err = -errno;
SYSMSG("SNDRV_PCM_IOCTL_SYNC_PTR failed (%i)", err);
@@ -143,7 +145,7 @@ static int sync_ptr1(snd_pcm_hw_t *hw, unsigned int flags)
static inline int sync_ptr(snd_pcm_hw_t *hw, unsigned int flags)
{
- return hw->sync_ptr ? sync_ptr1(hw, flags) : 0;
+ return hw->sync_ptr ? sync_ptr1(hw, hw->sync_ptr, flags) : 0;
}
static int snd_pcm_hw_clear_timer_queue(snd_pcm_hw_t *hw)
@@ -295,6 +297,14 @@ static int snd_pcm_hw_hw_refine(snd_pcm_t *pcm, snd_pcm_hw_params_t *params)
return err;
}
+ /*
+ * For drivers with SNDRV_PCM_INFO_ACK_APPLPTR, this has an effect
+ * to tell that user land can perform MMAP operation as corresponding
+ * hardware expects. For the other drivers, this has no side-effect.
+ */
+ if (hw->version >= SNDRV_PROTOCOL_VERSION(2, 0, 14))
+ params->flags |= SNDRV_PCM_INFO_ACK_APPLPTR;
+
if (hw_refine_call(hw, params) < 0) {
err = -errno;
// SYSMSG("SNDRV_PCM_IOCTL_HW_REFINE failed");
@@ -322,6 +332,15 @@ static int snd_pcm_hw_hw_params(snd_pcm_t *pcm, snd_pcm_hw_params_t * params)
{
snd_pcm_hw_t *hw = pcm->private_data;
int err;
+
+ /*
+ * For drivers with SNDRV_PCM_INFO_ACK_APPLPTR, this has an effect
+ * to tell that user land can perform MMAP operation as corresponding
+ * hardware expects. For the other drivers, this has no side-effect.
+ */
+ if (hw->version >= SNDRV_PROTOCOL_VERSION(2, 0, 14))
+ params->flags |= SNDRV_PCM_INFO_ACK_APPLPTR;
+
if (hw_params_call(hw, params) < 0) {
err = -errno;
SYSMSG("SNDRV_PCM_IOCTL_HW_PARAMS failed (%i)", err);
@@ -337,6 +356,11 @@ static int snd_pcm_hw_hw_params(snd_pcm_t *pcm, snd_pcm_hw_params_t * params)
snd_pcm_set_appl_ptr(pcm, &hw->mmap_control->appl_ptr, hw->fd,
SNDRV_PCM_MMAP_OFFSET_CONTROL);
}
+
+ if (hw->version >= SNDRV_PROTOCOL_VERSION(2, 0, 14) &&
+ (params->info & SNDRV_PCM_INFO_ACK_APPLPTR))
+ hw->ack_applptr = 1;
+
return 0;
}
@@ -568,7 +592,8 @@ static int snd_pcm_hw_hwsync(snd_pcm_t *pcm)
int fd = hw->fd, err;
if (SNDRV_PROTOCOL_VERSION(2, 0, 3) <= hw->version) {
if (hw->sync_ptr) {
- err = sync_ptr1(hw, SNDRV_PCM_SYNC_PTR_HWSYNC);
+ err = sync_ptr1(hw, hw->sync_ptr,
+ SNDRV_PCM_SYNC_PTR_HWSYNC);
if (err < 0)
return err;
} else {
@@ -995,7 +1020,13 @@ static snd_pcm_sframes_t snd_pcm_hw_mmap_commit(snd_pcm_t *pcm,
snd_pcm_hw_t *hw = pcm->private_data;
snd_pcm_mmap_appl_forward(pcm, size);
- sync_ptr(hw, 0);
+ if (hw->sync_ptr) {
+ sync_ptr1(hw, hw->sync_ptr, 0);
+ } else if (hw->ack_applptr) {
+ struct snd_pcm_sync_ptr sync_ptr = {0};
+ sync_ptr.c.control = *hw->mmap_control;
+ sync_ptr1(hw, &sync_ptr, 0);
+ }
#ifdef DEBUG_MMAP
fprintf(stderr, "appl_forward: hw_ptr = %li, appl_ptr = %li, size = %li\n", *pcm->hw.ptr, *pcm->appl.ptr, size);
#endif
--
2.11.0
More information about the Alsa-devel
mailing list