summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJaroslav Kysela <perex@perex.cz>2008-04-21 12:46:50 +0200
committerJaroslav Kysela <perex@perex.cz>2008-04-21 12:46:50 +0200
commitc88672d86fe713e8f049df895fc3b64c472fbf5d (patch)
tree250bd1e092df6addf3aea29249a80e5a86b2f7d0
parent058dde8b7da6f7b725e4ef8b9b237f2a5c6ff01e (diff)
downloadalsa-lib-c88672d86fe713e8f049df895fc3b64c472fbf5d.tar.gz
implemented snd_pcm_rewindable() and snd_pcm_forwardable(), removed can_rewind and can_forward
-rw-r--r--include/pcm.h2
-rw-r--r--src/pcm/pcm.c80
-rw-r--r--src/pcm/pcm_dmix.c12
-rw-r--r--src/pcm/pcm_dshare.c26
-rw-r--r--src/pcm/pcm_dsnoop.c19
-rw-r--r--src/pcm/pcm_file.c22
-rw-r--r--src/pcm/pcm_generic.c12
-rw-r--r--src/pcm/pcm_generic.h6
-rw-r--r--src/pcm/pcm_hooks.c2
-rw-r--r--src/pcm/pcm_hw.c16
-rw-r--r--src/pcm/pcm_ioplug.c12
-rw-r--r--src/pcm/pcm_local.h4
-rw-r--r--src/pcm/pcm_meter.c2
-rw-r--r--src/pcm/pcm_mmap_emul.c2
-rw-r--r--src/pcm/pcm_plugin.c14
-rw-r--r--src/pcm/pcm_share.c24
-rw-r--r--src/pcm/pcm_shm.c12
17 files changed, 212 insertions, 55 deletions
diff --git a/include/pcm.h b/include/pcm.h
index 9a592e3d..4eb5035d 100644
--- a/include/pcm.h
+++ b/include/pcm.h
@@ -441,7 +441,9 @@ int snd_pcm_delay(snd_pcm_t *pcm, snd_pcm_sframes_t *delayp);
int snd_pcm_resume(snd_pcm_t *pcm);
int snd_pcm_htimestamp(snd_pcm_t *pcm, snd_pcm_uframes_t *avail, snd_htimestamp_t *tstamp);
snd_pcm_sframes_t snd_pcm_avail_update(snd_pcm_t *pcm);
+snd_pcm_sframes_t snd_pcm_rewindable(snd_pcm_t *pcm);
snd_pcm_sframes_t snd_pcm_rewind(snd_pcm_t *pcm, snd_pcm_uframes_t frames);
+snd_pcm_sframes_t snd_pcm_forwardable(snd_pcm_t *pcm);
snd_pcm_sframes_t snd_pcm_forward(snd_pcm_t *pcm, snd_pcm_uframes_t frames);
snd_pcm_sframes_t snd_pcm_writei(snd_pcm_t *pcm, const void *buffer, snd_pcm_uframes_t size);
snd_pcm_sframes_t snd_pcm_readi(snd_pcm_t *pcm, void *buffer, snd_pcm_uframes_t size);
diff --git a/src/pcm/pcm.c b/src/pcm/pcm.c
index e0f808c3..88d15152 100644
--- a/src/pcm/pcm.c
+++ b/src/pcm/pcm.c
@@ -1112,6 +1112,25 @@ int snd_pcm_pause(snd_pcm_t *pcm, int enable)
}
/**
+ * \brief Get safe count of frames which can be rewinded
+ * \param pcm PCM handle
+ * \return a positive number of frames or negative error code
+ *
+ * Note: The snd_pcm_rewind() can accept bigger value than returned
+ * by this function. But it is not guaranteed that output stream
+ * will be consistent with bigger value.
+ */
+snd_pcm_sframes_t snd_pcm_rewindable(snd_pcm_t *pcm)
+{
+ assert(pcm);
+ if (CHECK_SANITY(! pcm->setup)) {
+ SNDMSG("PCM not set up");
+ return -EIO;
+ }
+ return pcm->fast_ops->rewindable(pcm->fast_op_arg);
+}
+
+/**
* \brief Move application frame position backward
* \param pcm PCM handle
* \param frames wanted displacement in frames
@@ -1131,6 +1150,25 @@ snd_pcm_sframes_t snd_pcm_rewind(snd_pcm_t *pcm, snd_pcm_uframes_t frames)
}
/**
+ * \brief Get safe count of frames which can be forwarded
+ * \param pcm PCM handle
+ * \return a positive number of frames or negative error code
+ *
+ * Note: The snd_pcm_forward() can accept bigger value than returned
+ * by this function. But it is not guaranteed that output stream
+ * will be consistent with bigger value.
+ */
+snd_pcm_sframes_t snd_pcm_forwardable(snd_pcm_t *pcm)
+{
+ assert(pcm);
+ if (CHECK_SANITY(! pcm->setup)) {
+ SNDMSG("PCM not set up");
+ return -EIO;
+ }
+ return pcm->fast_ops->forwardable(pcm->fast_op_arg);
+}
+
+/**
* \brief Move application frame position forward
* \param pcm PCM handle
* \param frames wanted skip in frames
@@ -2854,48 +2892,6 @@ int snd_pcm_hw_params_can_overrange(const snd_pcm_hw_params_t *params)
}
/**
- * \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
* \return Boolean value
diff --git a/src/pcm/pcm_dmix.c b/src/pcm/pcm_dmix.c
index 9a6887d5..bb79ec61 100644
--- a/src/pcm/pcm_dmix.c
+++ b/src/pcm/pcm_dmix.c
@@ -649,6 +649,11 @@ static int snd_pcm_dmix_pause(snd_pcm_t *pcm ATTRIBUTE_UNUSED, int enable ATTRIB
return -EIO;
}
+static snd_pcm_sframes_t snd_pcm_dmix_rewindable(snd_pcm_t *pcm)
+{
+ return snd_pcm_mmap_hw_avail(pcm);
+}
+
static snd_pcm_sframes_t snd_pcm_dmix_rewind(snd_pcm_t *pcm, snd_pcm_uframes_t frames)
{
snd_pcm_direct_t *dmix = pcm->private_data;
@@ -723,6 +728,11 @@ static snd_pcm_sframes_t snd_pcm_dmix_rewind(snd_pcm_t *pcm, snd_pcm_uframes_t f
return result + frames;
}
+static snd_pcm_sframes_t snd_pcm_dmix_forwardable(snd_pcm_t *pcm)
+{
+ return snd_pcm_mmap_avail(pcm);
+}
+
static snd_pcm_sframes_t snd_pcm_dmix_forward(snd_pcm_t *pcm, snd_pcm_uframes_t frames)
{
snd_pcm_sframes_t avail;
@@ -885,7 +895,9 @@ static snd_pcm_fast_ops_t snd_pcm_dmix_fast_ops = {
.drop = snd_pcm_dmix_drop,
.drain = snd_pcm_dmix_drain,
.pause = snd_pcm_dmix_pause,
+ .rewindable = snd_pcm_dmix_rewindable,
.rewind = snd_pcm_dmix_rewind,
+ .forwardable = snd_pcm_dmix_forwardable,
.forward = snd_pcm_dmix_forward,
.resume = snd_pcm_direct_resume,
.link = NULL,
diff --git a/src/pcm/pcm_dshare.c b/src/pcm/pcm_dshare.c
index 8d403547..bfe66a8b 100644
--- a/src/pcm/pcm_dshare.c
+++ b/src/pcm/pcm_dshare.c
@@ -410,15 +410,27 @@ static int snd_pcm_dshare_pause(snd_pcm_t *pcm ATTRIBUTE_UNUSED, int enable ATTR
return -EIO;
}
-static snd_pcm_sframes_t snd_pcm_dshare_rewind(snd_pcm_t *pcm ATTRIBUTE_UNUSED, snd_pcm_uframes_t frames ATTRIBUTE_UNUSED)
+static snd_pcm_sframes_t snd_pcm_dshare_rewindable(snd_pcm_t *pcm)
{
-#if 0
- /* FIXME: substract samples from the mix ring buffer, too? */
+ return snd_pcm_mmap_playback_hw_avail(pcm);
+}
+
+static snd_pcm_sframes_t snd_pcm_dshare_rewind(snd_pcm_t *pcm, snd_pcm_uframes_t frames)
+{
+ snd_pcm_sframes_t avail;
+
+ avail = snd_pcm_mmap_playback_hw_avail(pcm);
+ if (avail < 0)
+ return 0;
+ if (frames > (snd_pcm_uframes_t)avail)
+ frames = avail;
snd_pcm_mmap_appl_backward(pcm, frames);
return frames;
-#else
- return -EIO;
-#endif
+}
+
+static snd_pcm_sframes_t snd_pcm_dshare_forwardable(snd_pcm_t *pcm)
+{
+ return snd_pcm_mmap_playback_avail(pcm);
}
static snd_pcm_sframes_t snd_pcm_dshare_forward(snd_pcm_t *pcm, snd_pcm_uframes_t frames)
@@ -574,7 +586,9 @@ static snd_pcm_fast_ops_t snd_pcm_dshare_fast_ops = {
.drop = snd_pcm_dshare_drop,
.drain = snd_pcm_dshare_drain,
.pause = snd_pcm_dshare_pause,
+ .rewindable = snd_pcm_dshare_rewindable,
.rewind = snd_pcm_dshare_rewind,
+ .forwardable = snd_pcm_dshare_forwardable,
.forward = snd_pcm_dshare_forward,
.resume = snd_pcm_direct_resume,
.link = NULL,
diff --git a/src/pcm/pcm_dsnoop.c b/src/pcm/pcm_dsnoop.c
index e9ea81bf..1f602c3f 100644
--- a/src/pcm/pcm_dsnoop.c
+++ b/src/pcm/pcm_dsnoop.c
@@ -313,12 +313,29 @@ static int snd_pcm_dsnoop_pause(snd_pcm_t *pcm ATTRIBUTE_UNUSED, int enable ATTR
return -EIO;
}
+static snd_pcm_sframes_t snd_pcm_dsnoop_rewindable(snd_pcm_t *pcm)
+{
+ return snd_pcm_mmap_capture_avail(pcm);
+}
+
static snd_pcm_sframes_t snd_pcm_dsnoop_rewind(snd_pcm_t *pcm, snd_pcm_uframes_t frames)
{
+ snd_pcm_sframes_t avail;
+
+ avail = snd_pcm_mmap_capture_avail(pcm);
+ if (avail < 0)
+ return 0;
+ if (frames > (snd_pcm_uframes_t)avail)
+ frames = avail;
snd_pcm_mmap_appl_backward(pcm, frames);
return frames;
}
+static snd_pcm_sframes_t snd_pcm_dsnoop_forwardable(snd_pcm_t *pcm)
+{
+ return snd_pcm_mmap_capture_hw_avail(pcm);
+}
+
static snd_pcm_sframes_t snd_pcm_dsnoop_forward(snd_pcm_t *pcm, snd_pcm_uframes_t frames)
{
snd_pcm_sframes_t avail;
@@ -464,7 +481,9 @@ static snd_pcm_fast_ops_t snd_pcm_dsnoop_fast_ops = {
.drop = snd_pcm_dsnoop_drop,
.drain = snd_pcm_dsnoop_drain,
.pause = snd_pcm_dsnoop_pause,
+ .rewindable = snd_pcm_dsnoop_rewindable,
.rewind = snd_pcm_dsnoop_rewind,
+ .forwardable = snd_pcm_dsnoop_forwardable,
.forward = snd_pcm_dsnoop_forward,
.resume = snd_pcm_direct_resume,
.link = NULL,
diff --git a/src/pcm/pcm_file.c b/src/pcm/pcm_file.c
index 289a434c..e3216da7 100644
--- a/src/pcm/pcm_file.c
+++ b/src/pcm/pcm_file.c
@@ -265,6 +265,16 @@ static int snd_pcm_file_drain(snd_pcm_t *pcm)
return err;
}
+static snd_pcm_sframes_t snd_pcm_file_rewindable(snd_pcm_t *pcm)
+{
+ snd_pcm_file_t *file = pcm->private_data;
+ snd_pcm_sframes_t res = snd_pcm_rewindable(pcm);
+ snd_pcm_sframes_t n = snd_pcm_bytes_to_frames(pcm, file->wbuf_used_bytes);
+ if (res > n)
+ res = n;
+ return res;
+}
+
static snd_pcm_sframes_t snd_pcm_file_rewind(snd_pcm_t *pcm, snd_pcm_uframes_t frames)
{
snd_pcm_file_t *file = pcm->private_data;
@@ -283,6 +293,16 @@ static snd_pcm_sframes_t snd_pcm_file_rewind(snd_pcm_t *pcm, snd_pcm_uframes_t f
return err;
}
+static snd_pcm_sframes_t snd_pcm_file_forwardable(snd_pcm_t *pcm)
+{
+ snd_pcm_file_t *file = pcm->private_data;
+ snd_pcm_sframes_t res = snd_pcm_forwardable(pcm);
+ snd_pcm_sframes_t n = snd_pcm_bytes_to_frames(pcm, file->wbuf_size_bytes - file->wbuf_used_bytes);
+ if (res > n)
+ res = n;
+ return res;
+}
+
static snd_pcm_sframes_t snd_pcm_file_forward(snd_pcm_t *pcm, snd_pcm_uframes_t frames)
{
snd_pcm_file_t *file = pcm->private_data;
@@ -466,7 +486,9 @@ static snd_pcm_fast_ops_t snd_pcm_file_fast_ops = {
.drop = snd_pcm_file_drop,
.drain = snd_pcm_file_drain,
.pause = snd_pcm_generic_pause,
+ .rewindable = snd_pcm_file_rewindable,
.rewind = snd_pcm_file_rewind,
+ .forwardable = snd_pcm_file_forwardable,
.forward = snd_pcm_file_forward,
.resume = snd_pcm_generic_resume,
.link = snd_pcm_generic_link,
diff --git a/src/pcm/pcm_generic.c b/src/pcm/pcm_generic.c
index 85b8d4f8..84ea85f1 100644
--- a/src/pcm/pcm_generic.c
+++ b/src/pcm/pcm_generic.c
@@ -185,12 +185,24 @@ int snd_pcm_generic_delay(snd_pcm_t *pcm, snd_pcm_sframes_t *delayp)
return snd_pcm_delay(generic->slave, delayp);
}
+snd_pcm_sframes_t snd_pcm_generic_forwardable(snd_pcm_t *pcm)
+{
+ snd_pcm_generic_t *generic = pcm->private_data;
+ return snd_pcm_forwardable(generic->slave);
+}
+
snd_pcm_sframes_t snd_pcm_generic_forward(snd_pcm_t *pcm, snd_pcm_uframes_t frames)
{
snd_pcm_generic_t *generic = pcm->private_data;
return INTERNAL(snd_pcm_forward)(generic->slave, frames);
}
+snd_pcm_sframes_t snd_pcm_generic_rewindable(snd_pcm_t *pcm)
+{
+ snd_pcm_generic_t *generic = pcm->private_data;
+ return snd_pcm_rewindable(generic->slave);
+}
+
snd_pcm_sframes_t snd_pcm_generic_rewind(snd_pcm_t *pcm, snd_pcm_uframes_t frames)
{
snd_pcm_generic_t *generic = pcm->private_data;
diff --git a/src/pcm/pcm_generic.h b/src/pcm/pcm_generic.h
index 9874c1b9..430b8cfd 100644
--- a/src/pcm/pcm_generic.h
+++ b/src/pcm/pcm_generic.h
@@ -73,8 +73,12 @@ typedef struct {
snd1_pcm_generic_resume
#define snd_pcm_generic_delay \
snd1_pcm_generic_delay
+#define snd_pcm_generic_forwardable \
+ snd1_pcm_generic_forwardable
#define snd_pcm_generic_forward \
snd1_pcm_generic_forward
+#define snd_pcm_generic_rewindable \
+ snd1_pcm_generic_rewindable
#define snd_pcm_generic_rewind \
snd1_pcm_generic_rewind
#define snd_pcm_generic_link \
@@ -124,7 +128,9 @@ int snd_pcm_generic_drain(snd_pcm_t *pcm);
int snd_pcm_generic_pause(snd_pcm_t *pcm, int enable);
int snd_pcm_generic_resume(snd_pcm_t *pcm);
int snd_pcm_generic_delay(snd_pcm_t *pcm, snd_pcm_sframes_t *delayp);
+snd_pcm_sframes_t snd_pcm_generic_forwardable(snd_pcm_t *pcm);
snd_pcm_sframes_t snd_pcm_generic_forward(snd_pcm_t *pcm, snd_pcm_uframes_t frames);
+snd_pcm_sframes_t snd_pcm_generic_rewindable(snd_pcm_t *pcm);
snd_pcm_sframes_t snd_pcm_generic_rewind(snd_pcm_t *pcm, snd_pcm_uframes_t frames);
int snd_pcm_generic_link(snd_pcm_t *pcm1, snd_pcm_t *pcm2);
int snd_pcm_generic_link_slaves(snd_pcm_t *pcm, snd_pcm_t *master);
diff --git a/src/pcm/pcm_hooks.c b/src/pcm/pcm_hooks.c
index 5f9b6625..0abe8191 100644
--- a/src/pcm/pcm_hooks.c
+++ b/src/pcm/pcm_hooks.c
@@ -147,7 +147,9 @@ static snd_pcm_fast_ops_t snd_pcm_hooks_fast_ops = {
.drop = snd_pcm_generic_drop,
.drain = snd_pcm_generic_drain,
.pause = snd_pcm_generic_pause,
+ .rewindable = snd_pcm_generic_rewindable,
.rewind = snd_pcm_generic_rewind,
+ .forwardable = snd_pcm_generic_forwardable,
.forward = snd_pcm_generic_forward,
.resume = snd_pcm_generic_resume,
.link = snd_pcm_generic_link,
diff --git a/src/pcm/pcm_hw.c b/src/pcm/pcm_hw.c
index ebead2ff..5acad3dd 100644
--- a/src/pcm/pcm_hw.c
+++ b/src/pcm/pcm_hw.c
@@ -248,9 +248,7 @@ static int snd_pcm_hw_hw_refine(snd_pcm_t *pcm, snd_pcm_hw_params_t *params)
if (params->info != ~0UL) {
params->info &= ~0xf0000000;
- params->info |= (pcm->monotonic ? SND_PCM_INFO_MONOTONIC : 0) |
- SND_PCM_INFO_REWIND |
- SND_PCM_INFO_FORWARD;
+ params->info |= (pcm->monotonic ? SND_PCM_INFO_MONOTONIC : 0);
}
return 0;
@@ -510,6 +508,11 @@ static int snd_pcm_hw_pause(snd_pcm_t *pcm, int enable)
return 0;
}
+static snd_pcm_sframes_t snd_pcm_hw_rewindable(snd_pcm_t *pcm)
+{
+ return snd_pcm_mmap_hw_avail(pcm);
+}
+
static snd_pcm_sframes_t snd_pcm_hw_rewind(snd_pcm_t *pcm, snd_pcm_uframes_t frames)
{
snd_pcm_hw_t *hw = pcm->private_data;
@@ -525,6 +528,11 @@ static snd_pcm_sframes_t snd_pcm_hw_rewind(snd_pcm_t *pcm, snd_pcm_uframes_t fra
return frames;
}
+static snd_pcm_sframes_t snd_pcm_hw_forwardable(snd_pcm_t *pcm)
+{
+ return snd_pcm_mmap_avail(pcm);
+}
+
static snd_pcm_sframes_t snd_pcm_hw_forward(snd_pcm_t *pcm, snd_pcm_uframes_t frames)
{
snd_pcm_hw_t *hw = pcm->private_data;
@@ -917,7 +925,9 @@ static snd_pcm_fast_ops_t snd_pcm_hw_fast_ops = {
.drop = snd_pcm_hw_drop,
.drain = snd_pcm_hw_drain,
.pause = snd_pcm_hw_pause,
+ .rewindable = snd_pcm_hw_rewindable,
.rewind = snd_pcm_hw_rewind,
+ .forwardable = snd_pcm_hw_forwardable,
.forward = snd_pcm_hw_forward,
.resume = snd_pcm_hw_resume,
.link = snd_pcm_hw_link,
diff --git a/src/pcm/pcm_ioplug.c b/src/pcm/pcm_ioplug.c
index 642a9051..a30efebd 100644
--- a/src/pcm/pcm_ioplug.c
+++ b/src/pcm/pcm_ioplug.c
@@ -501,12 +501,22 @@ static int snd_pcm_ioplug_pause(snd_pcm_t *pcm, int enable)
return 0;
}
+static snd_pcm_sframes_t snd_pcm_ioplug_rewindable(snd_pcm_t *pcm)
+{
+ return snd_pcm_mmap_hw_avail(pcm);
+}
+
static snd_pcm_sframes_t snd_pcm_ioplug_rewind(snd_pcm_t *pcm, snd_pcm_uframes_t frames)
{
snd_pcm_mmap_appl_backward(pcm, frames);
return frames;
}
+static snd_pcm_sframes_t snd_pcm_ioplug_forwardable(snd_pcm_t *pcm)
+{
+ return snd_pcm_mmap_avail(pcm);
+}
+
static snd_pcm_sframes_t snd_pcm_ioplug_forward(snd_pcm_t *pcm, snd_pcm_uframes_t frames)
{
snd_pcm_mmap_appl_forward(pcm, frames);
@@ -767,7 +777,9 @@ static snd_pcm_fast_ops_t snd_pcm_ioplug_fast_ops = {
.link = NULL,
.link_slaves = NULL,
.unlink = NULL,
+ .rewindable = snd_pcm_ioplug_rewindable,
.rewind = snd_pcm_ioplug_rewind,
+ .forwardable = snd_pcm_ioplug_forwardable,
.forward = snd_pcm_ioplug_forward,
.writei = snd_pcm_ioplug_writei,
.writen = snd_pcm_ioplug_writen,
diff --git a/src/pcm/pcm_local.h b/src/pcm/pcm_local.h
index f0dae7cb..0f1dcad0 100644
--- a/src/pcm/pcm_local.h
+++ b/src/pcm/pcm_local.h
@@ -95,8 +95,6 @@ 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 {
@@ -159,7 +157,9 @@ typedef struct {
int (*link)(snd_pcm_t *pcm1, snd_pcm_t *pcm2);
int (*link_slaves)(snd_pcm_t *pcm, snd_pcm_t *master);
int (*unlink)(snd_pcm_t *pcm);
+ snd_pcm_sframes_t (*rewindable)(snd_pcm_t *pcm);
snd_pcm_sframes_t (*rewind)(snd_pcm_t *pcm, snd_pcm_uframes_t frames);
+ snd_pcm_sframes_t (*forwardable)(snd_pcm_t *pcm);
snd_pcm_sframes_t (*forward)(snd_pcm_t *pcm, snd_pcm_uframes_t frames);
snd_pcm_sframes_t (*writei)(snd_pcm_t *pcm, const void *buffer, snd_pcm_uframes_t size);
snd_pcm_sframes_t (*writen)(snd_pcm_t *pcm, void **bufs, snd_pcm_uframes_t size);
diff --git a/src/pcm/pcm_meter.c b/src/pcm/pcm_meter.c
index 079de1ee..0dedb423 100644
--- a/src/pcm/pcm_meter.c
+++ b/src/pcm/pcm_meter.c
@@ -527,7 +527,9 @@ static snd_pcm_fast_ops_t snd_pcm_meter_fast_ops = {
.drop = snd_pcm_generic_drop,
.drain = snd_pcm_generic_drain,
.pause = snd_pcm_generic_pause,
+ .rewindable = snd_pcm_generic_rewindable,
.rewind = snd_pcm_meter_rewind,
+ .forwardable = snd_pcm_generic_forwardable,
.forward = snd_pcm_meter_forward,
.resume = snd_pcm_generic_resume,
.writei = snd_pcm_mmap_writei,
diff --git a/src/pcm/pcm_mmap_emul.c b/src/pcm/pcm_mmap_emul.c
index a00ddb1e..896e6326 100644
--- a/src/pcm/pcm_mmap_emul.c
+++ b/src/pcm/pcm_mmap_emul.c
@@ -358,7 +358,9 @@ static snd_pcm_fast_ops_t snd_pcm_mmap_emul_fast_ops = {
.drop = snd_pcm_generic_drop,
.drain = snd_pcm_generic_drain,
.pause = snd_pcm_generic_pause,
+ .rewindable = snd_pcm_generic_rewindable,
.rewind = snd_pcm_mmap_emul_rewind,
+ .forwardable = snd_pcm_generic_forwardable,
.forward = snd_pcm_mmap_emul_forward,
.resume = snd_pcm_generic_resume,
.link = snd_pcm_generic_link,
diff --git a/src/pcm/pcm_plugin.c b/src/pcm/pcm_plugin.c
index d5fc5d7d..c73a02b2 100644
--- a/src/pcm/pcm_plugin.c
+++ b/src/pcm/pcm_plugin.c
@@ -192,6 +192,11 @@ static int snd_pcm_plugin_reset(snd_pcm_t *pcm)
return 0;
}
+static snd_pcm_sframes_t snd_pcm_plugin_rewindable(snd_pcm_t *pcm)
+{
+ return snd_pcm_mmap_hw_avail(pcm);
+}
+
static snd_pcm_sframes_t snd_pcm_plugin_rewind(snd_pcm_t *pcm, snd_pcm_uframes_t frames)
{
snd_pcm_plugin_t *plugin = pcm->private_data;
@@ -203,7 +208,6 @@ static snd_pcm_sframes_t snd_pcm_plugin_rewind(snd_pcm_t *pcm, snd_pcm_uframes_t
if (frames == 0)
return 0;
- /* FIXME: rate plugin */
if (plugin->slave_frames)
sframes = plugin->slave_frames(pcm, (snd_pcm_sframes_t) frames);
else
@@ -221,6 +225,11 @@ static snd_pcm_sframes_t snd_pcm_plugin_rewind(snd_pcm_t *pcm, snd_pcm_uframes_t
return n;
}
+static snd_pcm_sframes_t snd_pcm_plugin_forwardable(snd_pcm_t *pcm)
+{
+ return snd_pcm_mmap_avail(pcm);
+}
+
static snd_pcm_sframes_t snd_pcm_plugin_forward(snd_pcm_t *pcm, snd_pcm_uframes_t frames)
{
snd_pcm_plugin_t *plugin = pcm->private_data;
@@ -232,7 +241,6 @@ static snd_pcm_sframes_t snd_pcm_plugin_forward(snd_pcm_t *pcm, snd_pcm_uframes_
if (frames == 0)
return 0;
- /* FIXME: rate plugin */
if (plugin->slave_frames)
sframes = plugin->slave_frames(pcm, (snd_pcm_sframes_t) frames);
else
@@ -563,7 +571,9 @@ snd_pcm_fast_ops_t snd_pcm_plugin_fast_ops = {
.drop = snd_pcm_generic_drop,
.drain = snd_pcm_generic_drain,
.pause = snd_pcm_generic_pause,
+ .rewindable = snd_pcm_plugin_rewindable,
.rewind = snd_pcm_plugin_rewind,
+ .forwardable = snd_pcm_plugin_forwardable,
.forward = snd_pcm_plugin_forward,
.resume = snd_pcm_generic_resume,
.link = snd_pcm_generic_link,
diff --git a/src/pcm/pcm_share.c b/src/pcm/pcm_share.c
index a01e7591..3294c716 100644
--- a/src/pcm/pcm_share.c
+++ b/src/pcm/pcm_share.c
@@ -1039,6 +1039,17 @@ static snd_pcm_sframes_t _snd_pcm_share_rewind(snd_pcm_t *pcm, snd_pcm_uframes_t
return n;
}
+static snd_pcm_sframes_t snd_pcm_share_rewindable(snd_pcm_t *pcm)
+{
+ snd_pcm_share_t *share = pcm->private_data;
+ snd_pcm_share_slave_t *slave = share->slave;
+ snd_pcm_sframes_t ret;
+ Pthread_mutex_lock(&slave->mutex);
+ ret = snd_pcm_rewindable(slave->pcm);
+ Pthread_mutex_unlock(&slave->mutex);
+ return ret;
+}
+
static snd_pcm_sframes_t snd_pcm_share_rewind(snd_pcm_t *pcm, snd_pcm_uframes_t frames)
{
snd_pcm_share_t *share = pcm->private_data;
@@ -1085,6 +1096,17 @@ static snd_pcm_sframes_t _snd_pcm_share_forward(snd_pcm_t *pcm, snd_pcm_uframes_
return n;
}
+static snd_pcm_sframes_t snd_pcm_share_forwardable(snd_pcm_t *pcm)
+{
+ snd_pcm_share_t *share = pcm->private_data;
+ snd_pcm_share_slave_t *slave = share->slave;
+ snd_pcm_sframes_t ret;
+ Pthread_mutex_lock(&slave->mutex);
+ ret = snd_pcm_forwardable(slave->pcm);
+ Pthread_mutex_unlock(&slave->mutex);
+ return ret;
+}
+
static snd_pcm_sframes_t snd_pcm_share_forward(snd_pcm_t *pcm, snd_pcm_uframes_t frames)
{
snd_pcm_share_t *share = pcm->private_data;
@@ -1316,7 +1338,9 @@ static snd_pcm_fast_ops_t snd_pcm_share_fast_ops = {
.writen = snd_pcm_mmap_writen,
.readi = snd_pcm_mmap_readi,
.readn = snd_pcm_mmap_readn,
+ .rewindable = snd_pcm_share_rewindable,
.rewind = snd_pcm_share_rewind,
+ .forwardable = snd_pcm_share_forwardable,
.forward = snd_pcm_share_forward,
.resume = snd_pcm_share_resume,
.avail_update = snd_pcm_share_avail_update,
diff --git a/src/pcm/pcm_shm.c b/src/pcm/pcm_shm.c
index 29f9d233..b0c0bb99 100644
--- a/src/pcm/pcm_shm.c
+++ b/src/pcm/pcm_shm.c
@@ -508,6 +508,11 @@ static int snd_pcm_shm_pause(snd_pcm_t *pcm, int enable)
return snd_pcm_shm_action(pcm);
}
+static snd_pcm_sframes_t snd_pcm_shm_rewindable(snd_pcm_t *pcm ATTRIBUTE_UNUSED)
+{
+ return 0; /* FIX ME */
+}
+
static snd_pcm_sframes_t snd_pcm_shm_rewind(snd_pcm_t *pcm, snd_pcm_uframes_t frames)
{
snd_pcm_shm_t *shm = pcm->private_data;
@@ -517,6 +522,11 @@ static snd_pcm_sframes_t snd_pcm_shm_rewind(snd_pcm_t *pcm, snd_pcm_uframes_t fr
return snd_pcm_shm_action(pcm);
}
+static snd_pcm_sframes_t snd_pcm_shm_forwardable(snd_pcm_t *pcm ATTRIBUTE_UNUSED)
+{
+ return 0; /* FIX ME */
+}
+
static snd_pcm_sframes_t snd_pcm_shm_forward(snd_pcm_t *pcm, snd_pcm_uframes_t frames)
{
snd_pcm_shm_t *shm = pcm->private_data;
@@ -607,7 +617,9 @@ static snd_pcm_fast_ops_t snd_pcm_shm_fast_ops = {
.drop = snd_pcm_shm_drop,
.drain = snd_pcm_shm_drain,
.pause = snd_pcm_shm_pause,
+ .rewindable = snd_pcm_shm_rewindable,
.rewind = snd_pcm_shm_rewind,
+ .forwardable = snd_pcm_shm_forwardable,
.forward = snd_pcm_shm_forward,
.resume = snd_pcm_shm_resume,
.writei = snd_pcm_mmap_writei,