From d9dbb57b946b4db438bf919e30ecdc38c177aba4 Mon Sep 17 00:00:00 2001 From: Jaroslav Kysela Date: Fri, 20 May 2022 10:47:43 +0200 Subject: pcm: rate - rewrite the may_wait_for_avail_min callback for the rate plugin Shuffle the code to avoid special conditions using the plugin type in the generic plugin code. The rate plugin has the own may_wait_for_avail_min callback implementation now. Fixes: d21e0e01 ("pcm: plugin - fix avail_min calculation on rate plugin") Fixes: https://github.com/alsa-project/alsa-lib/pull/218 Signed-off-by: Jaroslav Kysela --- src/pcm/pcm_local.h | 4 ---- src/pcm/pcm_plugin.c | 16 ++++++++++++---- src/pcm/pcm_plugin.h | 4 ++++ src/pcm/pcm_rate.c | 47 +++++++++++++++++++++++++++-------------------- 4 files changed, 43 insertions(+), 28 deletions(-) diff --git a/src/pcm/pcm_local.h b/src/pcm/pcm_local.h index d5393bc9..8d25971f 100644 --- a/src/pcm/pcm_local.h +++ b/src/pcm/pcm_local.h @@ -286,8 +286,6 @@ struct _snd_pcm { snd1_pcm_wait_nocheck #define snd_pcm_rate_get_default_converter \ snd1_pcm_rate_get_default_converter -#define snd_pcm_rate_slave_frames \ - snd1_pcm_rate_slave_frames #define snd_pcm_set_hw_ptr \ snd1_pcm_set_hw_ptr #define snd_pcm_set_appl_ptr \ @@ -1011,8 +1009,6 @@ int snd_pcm_wait_nocheck(snd_pcm_t *pcm, int timeout); const snd_config_t *snd_pcm_rate_get_default_converter(snd_config_t *root); -snd_pcm_uframes_t snd_pcm_rate_slave_frames(snd_pcm_t *pcm, snd_pcm_uframes_t frames); - #define SND_PCM_HW_PARBIT_ACCESS (1U << SND_PCM_HW_PARAM_ACCESS) #define SND_PCM_HW_PARBIT_FORMAT (1U << SND_PCM_HW_PARAM_FORMAT) #define SND_PCM_HW_PARBIT_SUBFORMAT (1U << SND_PCM_HW_PARAM_SUBFORMAT) diff --git a/src/pcm/pcm_plugin.c b/src/pcm/pcm_plugin.c index 7f934e8a..6bb90b8b 100644 --- a/src/pcm/pcm_plugin.c +++ b/src/pcm/pcm_plugin.c @@ -574,8 +574,10 @@ static int snd_pcm_plugin_status(snd_pcm_t *pcm, snd_pcm_status_t * status) return 0; } -int snd_pcm_plugin_may_wait_for_avail_min(snd_pcm_t *pcm, - snd_pcm_uframes_t avail) +int snd_pcm_plugin_may_wait_for_avail_min_conv( + snd_pcm_t *pcm, + snd_pcm_uframes_t avail, + snd_pcm_uframes_t (*conv)(snd_pcm_t *, snd_pcm_uframes_t)) { if (pcm->stream == SND_PCM_STREAM_CAPTURE && pcm->access != SND_PCM_ACCESS_RW_INTERLEAVED && @@ -619,8 +621,8 @@ int snd_pcm_plugin_may_wait_for_avail_min(snd_pcm_t *pcm, * Can happen only on built-in rate plugin. * This code is also used by extplug, but extplug does not allow to alter the sampling rate. */ - if (snd_pcm_type(pcm) == SND_PCM_TYPE_RATE) - needed_slave_avail_min = snd_pcm_rate_slave_frames(pcm, needed_slave_avail_min); + if (conv) + needed_slave_avail_min = conv(pcm, needed_slave_avail_min); if (slave->avail_min != needed_slave_avail_min) { snd_pcm_sw_params_t *swparams; @@ -644,6 +646,12 @@ int snd_pcm_plugin_may_wait_for_avail_min(snd_pcm_t *pcm, return snd_pcm_generic_may_wait_for_avail_min(pcm, avail); } +int snd_pcm_plugin_may_wait_for_avail_min(snd_pcm_t *pcm, + snd_pcm_uframes_t avail) +{ + return snd_pcm_plugin_may_wait_for_avail_min_conv(pcm, avail, NULL); +} + const snd_pcm_fast_ops_t snd_pcm_plugin_fast_ops = { .status = snd_pcm_plugin_status, .state = snd_pcm_generic_state, diff --git a/src/pcm/pcm_plugin.h b/src/pcm/pcm_plugin.h index d7788b2a..9896ee8e 100644 --- a/src/pcm/pcm_plugin.h +++ b/src/pcm/pcm_plugin.h @@ -50,6 +50,8 @@ typedef struct { /* make local functions really local */ #define snd_pcm_plugin_init \ snd1_pcm_plugin_init +#define snd_pcm_plugin_may_wait_for_avail_min_conv \ + snd1_pcm_plugin_may_wait_for_avail_min_conv #define snd_pcm_plugin_may_wait_for_avail_min \ snd1_pcm_plugin_may_wait_for_avail_min #define snd_pcm_plugin_fast_ops \ @@ -66,6 +68,8 @@ typedef struct { void snd_pcm_plugin_init(snd_pcm_plugin_t *plugin); snd_pcm_sframes_t snd_pcm_plugin_rewind(snd_pcm_t *pcm, snd_pcm_uframes_t frames); snd_pcm_sframes_t snd_pcm_plugin_forward(snd_pcm_t *pcm, snd_pcm_uframes_t frames); +int snd_pcm_plugin_may_wait_for_avail_min_conv(snd_pcm_t *pcm, snd_pcm_uframes_t avail, + snd_pcm_uframes_t (*conv)(snd_pcm_t *, snd_pcm_uframes_t)); int snd_pcm_plugin_may_wait_for_avail_min(snd_pcm_t *pcm, snd_pcm_uframes_t avail); extern const snd_pcm_fast_ops_t snd_pcm_plugin_fast_ops; diff --git a/src/pcm/pcm_rate.c b/src/pcm/pcm_rate.c index 9ba36eed..e8815e8b 100644 --- a/src/pcm/pcm_rate.c +++ b/src/pcm/pcm_rate.c @@ -1282,6 +1282,32 @@ static int snd_pcm_rate_close(snd_pcm_t *pcm) return snd_pcm_generic_close(pcm); } +/** + * \brief Convert rate pcm frames to corresponding rate slave pcm frames + * \param pcm PCM handle + * \param frames Frames to be converted to slave frames + * \retval Corresponding slave frames +*/ +static snd_pcm_uframes_t snd_pcm_rate_slave_frames(snd_pcm_t *pcm, snd_pcm_uframes_t frames) +{ + snd_pcm_uframes_t sframes; + snd_pcm_rate_t *rate = pcm->private_data; + + if (pcm->stream == SND_PCM_STREAM_PLAYBACK) + sframes = rate->ops.output_frames(rate->obj, frames); + else + sframes = rate->ops.input_frames(rate->obj, frames); + + return sframes; +} + +static int snd_pcm_rate_may_wait_for_avail_min(snd_pcm_t *pcm, + snd_pcm_uframes_t avail) +{ + return snd_pcm_plugin_may_wait_for_avail_min_conv(pcm, avail, + snd_pcm_rate_slave_frames); +} + static const snd_pcm_fast_ops_t snd_pcm_rate_fast_ops = { .status = snd_pcm_rate_status, .state = snd_pcm_rate_state, @@ -1308,7 +1334,7 @@ static const snd_pcm_fast_ops_t snd_pcm_rate_fast_ops = { .poll_descriptors_count = snd_pcm_generic_poll_descriptors_count, .poll_descriptors = snd_pcm_generic_poll_descriptors, .poll_revents = snd_pcm_rate_poll_revents, - .may_wait_for_avail_min = snd_pcm_plugin_may_wait_for_avail_min, + .may_wait_for_avail_min = snd_pcm_rate_may_wait_for_avail_min, }; static const snd_pcm_ops_t snd_pcm_rate_ops = { @@ -1343,25 +1369,6 @@ const snd_config_t *snd_pcm_rate_get_default_converter(snd_config_t *root) return NULL; } -/** - * \brief Convert rate pcm frames to corresponding rate slave pcm frames - * \param pcm PCM handle - * \param frames Frames to be converted to slave frames - * \retval Corresponding slave frames -*/ -snd_pcm_uframes_t snd_pcm_rate_slave_frames(snd_pcm_t *pcm, snd_pcm_uframes_t frames) -{ - snd_pcm_uframes_t sframes; - snd_pcm_rate_t *rate = pcm->private_data; - - if (pcm->stream == SND_PCM_STREAM_PLAYBACK) - sframes = rate->ops.output_frames(rate->obj, frames); - else - sframes = rate->ops.input_frames(rate->obj, frames); - - return sframes; -} - static void rate_initial_setup(snd_pcm_rate_t *rate) { if (rate->plugin_version == SND_PCM_RATE_PLUGIN_VERSION) -- cgit v1.2.1