diff options
author | Jaroslav Kysela <perex@perex.cz> | 2008-04-21 12:46:50 +0200 |
---|---|---|
committer | Jaroslav Kysela <perex@perex.cz> | 2008-04-21 12:46:50 +0200 |
commit | c88672d86fe713e8f049df895fc3b64c472fbf5d (patch) | |
tree | 250bd1e092df6addf3aea29249a80e5a86b2f7d0 | |
parent | 058dde8b7da6f7b725e4ef8b9b237f2a5c6ff01e (diff) | |
download | alsa-lib-c88672d86fe713e8f049df895fc3b64c472fbf5d.tar.gz |
implemented snd_pcm_rewindable() and snd_pcm_forwardable(), removed can_rewind and can_forward
-rw-r--r-- | include/pcm.h | 2 | ||||
-rw-r--r-- | src/pcm/pcm.c | 80 | ||||
-rw-r--r-- | src/pcm/pcm_dmix.c | 12 | ||||
-rw-r--r-- | src/pcm/pcm_dshare.c | 26 | ||||
-rw-r--r-- | src/pcm/pcm_dsnoop.c | 19 | ||||
-rw-r--r-- | src/pcm/pcm_file.c | 22 | ||||
-rw-r--r-- | src/pcm/pcm_generic.c | 12 | ||||
-rw-r--r-- | src/pcm/pcm_generic.h | 6 | ||||
-rw-r--r-- | src/pcm/pcm_hooks.c | 2 | ||||
-rw-r--r-- | src/pcm/pcm_hw.c | 16 | ||||
-rw-r--r-- | src/pcm/pcm_ioplug.c | 12 | ||||
-rw-r--r-- | src/pcm/pcm_local.h | 4 | ||||
-rw-r--r-- | src/pcm/pcm_meter.c | 2 | ||||
-rw-r--r-- | src/pcm/pcm_mmap_emul.c | 2 | ||||
-rw-r--r-- | src/pcm/pcm_plugin.c | 14 | ||||
-rw-r--r-- | src/pcm/pcm_share.c | 24 | ||||
-rw-r--r-- | src/pcm/pcm_shm.c | 12 |
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, |