From 48ae96f50c2f5cf4551efe6a1c07e38129f073be Mon Sep 17 00:00:00 2001 From: Jaroslav Kysela Date: Tue, 11 Dec 2001 15:10:27 +0000 Subject: [PATCH] Added error passing to some refining functions to disable abort when no configuration can be found. --- src/pcm/pcm.c | 196 ++++++++++++++++++++++++++++++++++++------- src/pcm/pcm_local.h | 16 ++-- src/pcm/pcm_params.c | 156 ++++++++++++++++++++++------------ src/pcm/pcm_plug.c | 20 ++++- 4 files changed, 294 insertions(+), 94 deletions(-) diff --git a/src/pcm/pcm.c b/src/pcm/pcm.c index 4f33c5d8..bb6e53b9 100644 --- a/src/pcm/pcm.c +++ b/src/pcm/pcm.c @@ -2286,6 +2286,17 @@ int snd_pcm_access_mask_test(const snd_pcm_access_mask_t *mask, snd_pcm_access_t return snd_mask_test((const snd_mask_t *) mask, (unsigned long) val); } +/** + * \brief test, if given a #snd_pcm_access_mask_t is empty + * \param mask pointer to mask + * \retval 0 not empty + * \retval 1 empty + */ +int snd_pcm_access_mask_empty(const snd_pcm_access_mask_t *mask) +{ + return snd_mask_empty((const snd_mask_t *) mask); +} + /** * \brief make an access type present in a #snd_pcm_access_mask_t * \param mask pointer to mask @@ -2597,7 +2608,11 @@ int snd_pcm_hw_params_set_access(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, sn */ snd_pcm_access_t snd_pcm_hw_params_set_access_first(snd_pcm_t *pcm, snd_pcm_hw_params_t *params) { - return snd_pcm_hw_param_set_first(pcm, params, SND_PCM_HW_PARAM_ACCESS, NULL); + unsigned int res; + + if (snd_pcm_hw_param_set_first(pcm, params, SND_PCM_HW_PARAM_ACCESS, NULL, &res) < 0) + return 0; + return res; } /** @@ -2608,7 +2623,11 @@ snd_pcm_access_t snd_pcm_hw_params_set_access_first(snd_pcm_t *pcm, snd_pcm_hw_p */ snd_pcm_access_t snd_pcm_hw_params_set_access_last(snd_pcm_t *pcm, snd_pcm_hw_params_t *params) { - return snd_pcm_hw_param_set_last(pcm, params, SND_PCM_HW_PARAM_ACCESS, NULL); + unsigned int res; + + if (snd_pcm_hw_param_set_last(pcm, params, SND_PCM_HW_PARAM_ACCESS, NULL, &res) < 0) + return 0; + return res; } /** @@ -2676,7 +2695,11 @@ int snd_pcm_hw_params_set_format(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, sn */ snd_pcm_format_t snd_pcm_hw_params_set_format_first(snd_pcm_t *pcm, snd_pcm_hw_params_t *params) { - return snd_pcm_hw_param_set_first(pcm, params, SND_PCM_HW_PARAM_FORMAT, NULL); + unsigned int res; + + if (snd_pcm_hw_param_set_first(pcm, params, SND_PCM_HW_PARAM_FORMAT, NULL, &res) < 0) + return 0; + return res; } /** @@ -2687,7 +2710,11 @@ snd_pcm_format_t snd_pcm_hw_params_set_format_first(snd_pcm_t *pcm, snd_pcm_hw_p */ snd_pcm_format_t snd_pcm_hw_params_set_format_last(snd_pcm_t *pcm, snd_pcm_hw_params_t *params) { - return snd_pcm_hw_param_set_last(pcm, params, SND_PCM_HW_PARAM_FORMAT, NULL); + unsigned int res; + + if (snd_pcm_hw_param_set_last(pcm, params, SND_PCM_HW_PARAM_FORMAT, NULL, &res) < 0) + return 0; + return res; } /** @@ -2755,7 +2782,11 @@ int snd_pcm_hw_params_set_subformat(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, */ snd_pcm_subformat_t snd_pcm_hw_params_set_subformat_first(snd_pcm_t *pcm, snd_pcm_hw_params_t *params) { - return snd_pcm_hw_param_set_first(pcm, params, SND_PCM_HW_PARAM_SUBFORMAT, NULL); + unsigned int res; + + if (snd_pcm_hw_param_set_first(pcm, params, SND_PCM_HW_PARAM_SUBFORMAT, NULL, &res) < 0) + return 0; + return res; } /** @@ -2766,7 +2797,11 @@ snd_pcm_subformat_t snd_pcm_hw_params_set_subformat_first(snd_pcm_t *pcm, snd_pc */ snd_pcm_subformat_t snd_pcm_hw_params_set_subformat_last(snd_pcm_t *pcm, snd_pcm_hw_params_t *params) { - return snd_pcm_hw_param_set_last(pcm, params, SND_PCM_HW_PARAM_SUBFORMAT, NULL); + unsigned int res; + + if (snd_pcm_hw_param_set_last(pcm, params, SND_PCM_HW_PARAM_SUBFORMAT, NULL, &res) < 0) + return 0; + return res; } /** @@ -2892,7 +2927,11 @@ int snd_pcm_hw_params_set_channels_minmax(snd_pcm_t *pcm, snd_pcm_hw_params_t *p */ unsigned int snd_pcm_hw_params_set_channels_near(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val) { - return snd_pcm_hw_param_set_near(pcm, params, SND_PCM_HW_PARAM_CHANNELS, val, NULL); + unsigned int res; + + if (snd_pcm_hw_param_set_near(pcm, params, SND_PCM_HW_PARAM_CHANNELS, val, NULL, &res) < 0) + return 0; + return res; } /** @@ -2903,7 +2942,11 @@ unsigned int snd_pcm_hw_params_set_channels_near(snd_pcm_t *pcm, snd_pcm_hw_para */ unsigned int snd_pcm_hw_params_set_channels_first(snd_pcm_t *pcm, snd_pcm_hw_params_t *params) { - return snd_pcm_hw_param_set_first(pcm, params, SND_PCM_HW_PARAM_CHANNELS, NULL); + unsigned int res; + + if (snd_pcm_hw_param_set_first(pcm, params, SND_PCM_HW_PARAM_CHANNELS, NULL, &res) < 0) + return 0; + return res; } /** @@ -2914,7 +2957,11 @@ unsigned int snd_pcm_hw_params_set_channels_first(snd_pcm_t *pcm, snd_pcm_hw_par */ unsigned int snd_pcm_hw_params_set_channels_last(snd_pcm_t *pcm, snd_pcm_hw_params_t *params) { - return snd_pcm_hw_param_set_last(pcm, params, SND_PCM_HW_PARAM_CHANNELS, NULL); + unsigned int res; + + if (snd_pcm_hw_param_set_last(pcm, params, SND_PCM_HW_PARAM_CHANNELS, NULL, &res) < 0) + return 0; + return res; } @@ -3045,7 +3092,11 @@ int snd_pcm_hw_params_set_rate_minmax(snd_pcm_t *pcm, snd_pcm_hw_params_t *param */ unsigned int snd_pcm_hw_params_set_rate_near(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val, int *dir) { - return snd_pcm_hw_param_set_near(pcm, params, SND_PCM_HW_PARAM_RATE, val, dir); + unsigned int res; + + if (snd_pcm_hw_param_set_near(pcm, params, SND_PCM_HW_PARAM_RATE, val, dir, &res) < 0) + return 0; + return res; } /** @@ -3059,7 +3110,11 @@ unsigned int snd_pcm_hw_params_set_rate_near(snd_pcm_t *pcm, snd_pcm_hw_params_t */ unsigned int snd_pcm_hw_params_set_rate_first(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, int *dir) { - return snd_pcm_hw_param_set_first(pcm, params, SND_PCM_HW_PARAM_RATE, dir); + unsigned int res; + + if (snd_pcm_hw_param_set_first(pcm, params, SND_PCM_HW_PARAM_RATE, dir, &res) < 0) + return 0; + return res; } /** @@ -3073,7 +3128,11 @@ unsigned int snd_pcm_hw_params_set_rate_first(snd_pcm_t *pcm, snd_pcm_hw_params_ */ unsigned int snd_pcm_hw_params_set_rate_last(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, int *dir) { - return snd_pcm_hw_param_set_last(pcm, params, SND_PCM_HW_PARAM_RATE, dir); + unsigned int res; + + if (snd_pcm_hw_param_set_last(pcm, params, SND_PCM_HW_PARAM_RATE, dir, &res) < 0) + return 0; + return res; } @@ -3205,7 +3264,11 @@ int snd_pcm_hw_params_set_period_time_minmax(snd_pcm_t *pcm, snd_pcm_hw_params_t */ unsigned int snd_pcm_hw_params_set_period_time_near(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val, int *dir) { - return snd_pcm_hw_param_set_near(pcm, params, SND_PCM_HW_PARAM_PERIOD_TIME, val, dir); + unsigned int res; + + if (snd_pcm_hw_param_set_near(pcm, params, SND_PCM_HW_PARAM_PERIOD_TIME, val, dir, &res) < 0) + return 0; + return res; } /** @@ -3219,7 +3282,11 @@ unsigned int snd_pcm_hw_params_set_period_time_near(snd_pcm_t *pcm, snd_pcm_hw_p */ unsigned int snd_pcm_hw_params_set_period_time_first(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, int *dir) { - return snd_pcm_hw_param_set_first(pcm, params, SND_PCM_HW_PARAM_PERIOD_TIME, dir); + unsigned int res; + + if (snd_pcm_hw_param_set_first(pcm, params, SND_PCM_HW_PARAM_PERIOD_TIME, dir, &res) < 0) + return 0; + return res; } /** @@ -3233,7 +3300,11 @@ unsigned int snd_pcm_hw_params_set_period_time_first(snd_pcm_t *pcm, snd_pcm_hw_ */ unsigned int snd_pcm_hw_params_set_period_time_last(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, int *dir) { - return snd_pcm_hw_param_set_last(pcm, params, SND_PCM_HW_PARAM_PERIOD_TIME, dir); + unsigned int res; + + if (snd_pcm_hw_param_set_last(pcm, params, SND_PCM_HW_PARAM_PERIOD_TIME, dir, &res) < 0) + return 0; + return res; } @@ -3375,7 +3446,11 @@ int snd_pcm_hw_params_set_period_size_minmax(snd_pcm_t *pcm, snd_pcm_hw_params_t */ snd_pcm_uframes_t snd_pcm_hw_params_set_period_size_near(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_uframes_t val, int *dir) { - return snd_pcm_hw_param_set_near(pcm, params, SND_PCM_HW_PARAM_PERIOD_SIZE, val, dir); + unsigned int res; + + if (snd_pcm_hw_param_set_near(pcm, params, SND_PCM_HW_PARAM_PERIOD_SIZE, val, dir, &res) < 0) + return 0; + return res; } /** @@ -3389,7 +3464,11 @@ snd_pcm_uframes_t snd_pcm_hw_params_set_period_size_near(snd_pcm_t *pcm, snd_pcm */ snd_pcm_uframes_t snd_pcm_hw_params_set_period_size_first(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, int *dir) { - return snd_pcm_hw_param_set_first(pcm, params, SND_PCM_HW_PARAM_PERIOD_SIZE, dir); + unsigned int res; + + if (snd_pcm_hw_param_set_first(pcm, params, SND_PCM_HW_PARAM_PERIOD_SIZE, dir, &res) < 0) + return 0; + return res; } /** @@ -3403,7 +3482,11 @@ snd_pcm_uframes_t snd_pcm_hw_params_set_period_size_first(snd_pcm_t *pcm, snd_pc */ snd_pcm_uframes_t snd_pcm_hw_params_set_period_size_last(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, int *dir) { - return snd_pcm_hw_param_set_last(pcm, params, SND_PCM_HW_PARAM_PERIOD_SIZE, dir); + unsigned int res; + + if (snd_pcm_hw_param_set_last(pcm, params, SND_PCM_HW_PARAM_PERIOD_SIZE, dir, &res) < 0) + return 0; + return res; } /** @@ -3545,7 +3628,11 @@ int snd_pcm_hw_params_set_periods_minmax(snd_pcm_t *pcm, snd_pcm_hw_params_t *pa */ unsigned int snd_pcm_hw_params_set_periods_near(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val, int *dir) { - return snd_pcm_hw_param_set_near(pcm, params, SND_PCM_HW_PARAM_PERIODS, val, dir); + unsigned int res; + + if (snd_pcm_hw_param_set_near(pcm, params, SND_PCM_HW_PARAM_PERIODS, val, dir, &res) < 0) + return 0; + return res; } /** @@ -3559,7 +3646,11 @@ unsigned int snd_pcm_hw_params_set_periods_near(snd_pcm_t *pcm, snd_pcm_hw_param */ unsigned int snd_pcm_hw_params_set_periods_first(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, int *dir) { - return snd_pcm_hw_param_set_first(pcm, params, SND_PCM_HW_PARAM_PERIODS, dir); + unsigned int res; + + if (snd_pcm_hw_param_set_first(pcm, params, SND_PCM_HW_PARAM_PERIODS, dir, &res) < 0) + return 0; + return res; } /** @@ -3573,7 +3664,11 @@ unsigned int snd_pcm_hw_params_set_periods_first(snd_pcm_t *pcm, snd_pcm_hw_para */ unsigned int snd_pcm_hw_params_set_periods_last(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, int *dir) { - return snd_pcm_hw_param_set_last(pcm, params, SND_PCM_HW_PARAM_PERIODS, dir); + unsigned int res; + + if (snd_pcm_hw_param_set_last(pcm, params, SND_PCM_HW_PARAM_PERIODS, dir, &res) < 0) + return 0; + return res; } /** @@ -3715,7 +3810,11 @@ int snd_pcm_hw_params_set_buffer_time_minmax(snd_pcm_t *pcm, snd_pcm_hw_params_t */ unsigned int snd_pcm_hw_params_set_buffer_time_near(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val, int *dir) { - return snd_pcm_hw_param_set_near(pcm, params, SND_PCM_HW_PARAM_BUFFER_TIME, val, dir); + unsigned int res; + + if (snd_pcm_hw_param_set_near(pcm, params, SND_PCM_HW_PARAM_BUFFER_TIME, val, dir, &res) < 0) + return 0; + return res; } /** @@ -3729,7 +3828,11 @@ unsigned int snd_pcm_hw_params_set_buffer_time_near(snd_pcm_t *pcm, snd_pcm_hw_p */ unsigned int snd_pcm_hw_params_set_buffer_time_first(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, int *dir) { - return snd_pcm_hw_param_set_first(pcm, params, SND_PCM_HW_PARAM_BUFFER_TIME, dir); + unsigned int res; + + if (snd_pcm_hw_param_set_first(pcm, params, SND_PCM_HW_PARAM_BUFFER_TIME, dir, &res) < 0) + return 0; + return res; } /** @@ -3743,7 +3846,11 @@ unsigned int snd_pcm_hw_params_set_buffer_time_first(snd_pcm_t *pcm, snd_pcm_hw_ */ unsigned int snd_pcm_hw_params_set_buffer_time_last(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, int *dir) { - return snd_pcm_hw_param_set_last(pcm, params, SND_PCM_HW_PARAM_BUFFER_TIME, dir); + unsigned int res; + + if (snd_pcm_hw_param_set_last(pcm, params, SND_PCM_HW_PARAM_BUFFER_TIME, dir, &res) < 0) + return 0; + return res; } @@ -3881,7 +3988,11 @@ int snd_pcm_hw_params_set_buffer_size_minmax(snd_pcm_t *pcm, snd_pcm_hw_params_t */ snd_pcm_uframes_t snd_pcm_hw_params_set_buffer_size_near(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_uframes_t val) { - return snd_pcm_hw_param_set_near(pcm, params, SND_PCM_HW_PARAM_BUFFER_SIZE, val, NULL); + unsigned int res; + + if (snd_pcm_hw_param_set_near(pcm, params, SND_PCM_HW_PARAM_BUFFER_SIZE, val, NULL, &res) < 0) + return 0; + return res; } /** @@ -3892,7 +4003,11 @@ snd_pcm_uframes_t snd_pcm_hw_params_set_buffer_size_near(snd_pcm_t *pcm, snd_pcm */ snd_pcm_uframes_t snd_pcm_hw_params_set_buffer_size_first(snd_pcm_t *pcm, snd_pcm_hw_params_t *params) { - return snd_pcm_hw_param_set_first(pcm, params, SND_PCM_HW_PARAM_BUFFER_SIZE, NULL); + unsigned int res; + + if (snd_pcm_hw_param_set_first(pcm, params, SND_PCM_HW_PARAM_BUFFER_SIZE, NULL, &res) < 0) + return 0; + return res; } /** @@ -3903,7 +4018,11 @@ snd_pcm_uframes_t snd_pcm_hw_params_set_buffer_size_first(snd_pcm_t *pcm, snd_pc */ snd_pcm_uframes_t snd_pcm_hw_params_set_buffer_size_last(snd_pcm_t *pcm, snd_pcm_hw_params_t *params) { - return snd_pcm_hw_param_set_last(pcm, params, SND_PCM_HW_PARAM_BUFFER_SIZE, NULL); + unsigned int res; + + if (snd_pcm_hw_param_set_last(pcm, params, SND_PCM_HW_PARAM_BUFFER_SIZE, NULL, &res) < 0) + return 0; + return res; } @@ -4034,7 +4153,11 @@ int snd_pcm_hw_params_set_tick_time_minmax(snd_pcm_t *pcm, snd_pcm_hw_params_t * */ unsigned int snd_pcm_hw_params_set_tick_time_near(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val, int *dir) { - return snd_pcm_hw_param_set_near(pcm, params, SND_PCM_HW_PARAM_TICK_TIME, val, dir); + unsigned int res; + + if (snd_pcm_hw_param_set_near(pcm, params, SND_PCM_HW_PARAM_TICK_TIME, val, dir, &res) < 0) + return 0; + return res; } /** @@ -4048,7 +4171,11 @@ unsigned int snd_pcm_hw_params_set_tick_time_near(snd_pcm_t *pcm, snd_pcm_hw_par */ unsigned int snd_pcm_hw_params_set_tick_time_first(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, int *dir) { - return snd_pcm_hw_param_set_first(pcm, params, SND_PCM_HW_PARAM_TICK_TIME, dir); + unsigned int res; + + if (snd_pcm_hw_param_set_first(pcm, params, SND_PCM_HW_PARAM_TICK_TIME, dir, &res) < 0) + return 0; + return res; } /** @@ -4062,7 +4189,11 @@ unsigned int snd_pcm_hw_params_set_tick_time_first(snd_pcm_t *pcm, snd_pcm_hw_pa */ unsigned int snd_pcm_hw_params_set_tick_time_last(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, int *dir) { - return snd_pcm_hw_param_set_last(pcm, params, SND_PCM_HW_PARAM_TICK_TIME, dir); + unsigned int res; + + if (snd_pcm_hw_param_set_last(pcm, params, SND_PCM_HW_PARAM_TICK_TIME, dir, &res) < 0) + return 0; + return res; } /** @@ -5163,7 +5294,10 @@ snd_pcm_sframes_t snd_pcm_write_areas(snd_pcm_t *pcm, const snd_pcm_channel_area if (state == SND_PCM_STATE_PREPARED) { snd_pcm_sframes_t hw_avail = pcm->buffer_size - avail; hw_avail += frames; - if (hw_avail >= (snd_pcm_sframes_t) pcm->start_threshold) { + /* some plugins might automatically start the stream */ + state = snd_pcm_state(pcm); + if (state == SND_PCM_STATE_PREPARED && + hw_avail >= (snd_pcm_sframes_t) pcm->start_threshold) { err = snd_pcm_start(pcm); if (err < 0) goto _end; diff --git a/src/pcm/pcm_local.h b/src/pcm/pcm_local.h index 23ae80e0..3db0f1ba 100644 --- a/src/pcm/pcm_local.h +++ b/src/pcm/pcm_local.h @@ -473,6 +473,8 @@ void snd_pcm_hw_param_refine_near(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_hw_param_t var, const snd_pcm_hw_params_t *src); +int snd_pcm_hw_param_empty(const snd_pcm_hw_params_t *params, + snd_pcm_hw_param_t var); int snd_pcm_hw_param_always_eq(const snd_pcm_hw_params_t *params, snd_pcm_hw_param_t var, const snd_pcm_hw_params_t *params1); @@ -489,13 +491,13 @@ int snd_pcm_hw_param_any(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, int snd_pcm_hw_param_set_integer(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_set_mode_t mode, snd_pcm_hw_param_t var); -unsigned int snd_pcm_hw_param_set_first(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, - snd_pcm_hw_param_t var, int *dir); -unsigned int snd_pcm_hw_param_set_last(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, - snd_pcm_hw_param_t var, int *dir); -unsigned int snd_pcm_hw_param_set_near(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, - snd_pcm_hw_param_t var, unsigned int val, - int *dir); +int snd_pcm_hw_param_set_first(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, + snd_pcm_hw_param_t var, int *dir, unsigned int *rval); +int snd_pcm_hw_param_set_last(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, + snd_pcm_hw_param_t var, int *dir, unsigned int *rval); +int snd_pcm_hw_param_set_near(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, + snd_pcm_hw_param_t var, unsigned int val, + int *dir, unsigned int *rval); int snd_pcm_hw_param_set_min(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_set_mode_t mode, snd_pcm_hw_param_t var, diff --git a/src/pcm/pcm_params.c b/src/pcm/pcm_params.c index 16b091b2..0bf87608 100644 --- a/src/pcm/pcm_params.c +++ b/src/pcm/pcm_params.c @@ -23,8 +23,12 @@ static inline int hw_is_mask(snd_pcm_hw_param_t var) { +#if SND_PCM_HW_PARAM_FIRST_MASK == 0 + return var <= SND_PCM_HW_PARAM_LAST_MASK; +#else return var >= SND_PCM_HW_PARAM_FIRST_MASK && var <= SND_PCM_HW_PARAM_LAST_MASK; +#endif } static inline int hw_is_interval(snd_pcm_hw_param_t var) @@ -285,16 +289,26 @@ static int _snd_pcm_hw_param_set_first(snd_pcm_hw_params_t *params, values > minimum. Reduce configuration space accordingly. Return the minimum. */ -unsigned int snd_pcm_hw_param_set_first(snd_pcm_t *pcm, - snd_pcm_hw_params_t *params, - snd_pcm_hw_param_t var, int *dir) +int snd_pcm_hw_param_set_first(snd_pcm_t *pcm, + snd_pcm_hw_params_t *params, + snd_pcm_hw_param_t var, + int *dir, unsigned int *rval) { - _snd_pcm_hw_param_set_first(params, var); + int err; + unsigned int val; + + err = _snd_pcm_hw_param_set_first(params, var); + if (err < 0) + return err; if (params->rmask) { - int err = snd_pcm_hw_refine(pcm, params); - assert(err >= 0); + err = snd_pcm_hw_refine(pcm, params); + if (err < 0) + return err; } - return snd_pcm_hw_param_get(params, var, dir); + val = snd_pcm_hw_param_get(params, var, dir); + if (rval) + *rval = val; + return 0; } static int _snd_pcm_hw_param_set_last(snd_pcm_hw_params_t *params, @@ -321,16 +335,26 @@ static int _snd_pcm_hw_param_set_last(snd_pcm_hw_params_t *params, values < maximum. Reduce configuration space accordingly. Return the maximum. */ -unsigned int snd_pcm_hw_param_set_last(snd_pcm_t *pcm, - snd_pcm_hw_params_t *params, - snd_pcm_hw_param_t var, int *dir) +int snd_pcm_hw_param_set_last(snd_pcm_t *pcm, + snd_pcm_hw_params_t *params, + snd_pcm_hw_param_t var, + int *dir, unsigned int *rval) { - _snd_pcm_hw_param_set_last(params, var); + int err; + unsigned int val; + + err = _snd_pcm_hw_param_set_last(params, var); + if (err < 0) + return err; if (params->rmask) { - int err = snd_pcm_hw_refine(pcm, params); - assert(err >= 0); + err = snd_pcm_hw_refine(pcm, params); + if (err < 0) + return err; } - return snd_pcm_hw_param_get(params, var, dir); + val = snd_pcm_hw_param_get(params, var, dir); + if (rval) + *rval = val; + return 0; } int _snd_pcm_hw_param_set_min(snd_pcm_hw_params_t *params, @@ -503,7 +527,7 @@ int _snd_pcm_hw_param_set_minmax(snd_pcm_hw_params_t *params, if (hw_is_mask(var)) { snd_mask_t *mask = hw_param_mask(params, var); if (max == 0 && openmax) { - snd_mask_none(mask); + snd_mask_none(mask); changed = -EINVAL; } else { c1 = snd_mask_refine_min(mask, min + !!openmin); @@ -735,11 +759,12 @@ int snd_pcm_hw_param_set_mask(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, SND_PCM_HW_PARAM_FORMAT, SND_PCM_HW_PARAM_SUBFORMAT. Return the value found. */ -unsigned int snd_pcm_hw_param_set_near(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, - snd_pcm_hw_param_t var, unsigned int best, int *dir) +int snd_pcm_hw_param_set_near(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, + snd_pcm_hw_param_t var, unsigned int best, + int *dir, unsigned int *val) { snd_pcm_hw_params_t save; - int v, err; + int err; unsigned int saved_min; int last = 0; int min, max; @@ -778,16 +803,16 @@ unsigned int snd_pcm_hw_param_set_near(snd_pcm_t *pcm, snd_pcm_hw_params_t *para } else { *params = save; err = snd_pcm_hw_param_set_max(pcm, params, SND_CHANGE, var, &max, &maxdir); - assert(err >= 0); + if (err < 0) + return err; last = 1; } _end: if (last) - v = snd_pcm_hw_param_set_last(pcm, params, var, dir); + err = snd_pcm_hw_param_set_last(pcm, params, var, dir, val); else - v = snd_pcm_hw_param_set_first(pcm, params, var, dir); - assert(v >= 0); - return v; + err = snd_pcm_hw_param_set_first(pcm, params, var, dir, val); + return err; } #if 0 @@ -863,23 +888,23 @@ int snd_pcm_hw_param_set_next(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, } #endif -static void snd_pcm_hw_param_set_near_minmax(snd_pcm_t *pcm, - snd_pcm_hw_params_t *params, - snd_pcm_hw_param_t var, - unsigned int min, int *mindir, - unsigned int max, int *maxdir) +static int snd_pcm_hw_param_set_near_minmax(snd_pcm_t *pcm, + snd_pcm_hw_params_t *params, + snd_pcm_hw_param_t var, + unsigned int min, int *mindir, + unsigned int max, int *maxdir) { snd_pcm_hw_params_t tmp; int err; - if (!boundary_lt(min, *mindir, max, *maxdir)) { - snd_pcm_hw_param_set_near(pcm, params, var, min, mindir); - return; - } + if (!boundary_lt(min, *mindir, max, *maxdir)) + return snd_pcm_hw_param_set_near(pcm, params, var, min, mindir, NULL); tmp = *params; - min = snd_pcm_hw_param_set_near(pcm, &tmp, var, min, mindir); + err = snd_pcm_hw_param_set_near(pcm, &tmp, var, min, mindir, &min); + if (err < 0) + return err; if (boundary_lt(min, *mindir, max, *maxdir)) { tmp = *params; - max = snd_pcm_hw_param_set_near(pcm, &tmp, var, max, maxdir); + err = snd_pcm_hw_param_set_near(pcm, &tmp, var, max, maxdir, &max); } else { max = min; *maxdir = *mindir; @@ -887,6 +912,7 @@ static void snd_pcm_hw_param_set_near_minmax(snd_pcm_t *pcm, err = snd_pcm_hw_param_set_minmax(pcm, params, SND_CHANGE, var, &min, mindir, &max, maxdir); assert(err >= 0); + return 0; } void snd_pcm_hw_param_refine_near(snd_pcm_t *pcm, @@ -904,9 +930,8 @@ void snd_pcm_hw_param_refine_near(snd_pcm_t *pcm, /* ---- end of refinement functions ---- */ -#if 0 -static int snd_pcm_hw_param_empty(const snd_pcm_hw_params_t *params, - snd_pcm_hw_param_t var) +int snd_pcm_hw_param_empty(const snd_pcm_hw_params_t *params, + snd_pcm_hw_param_t var) { if (hw_is_mask(var)) return snd_mask_empty(hw_param_mask_c(params, var)); @@ -915,7 +940,6 @@ static int snd_pcm_hw_param_empty(const snd_pcm_hw_params_t *params, assert(0); return -EINVAL; } -#endif int snd_pcm_hw_param_always_eq(const snd_pcm_hw_params_t *params, snd_pcm_hw_param_t var, @@ -957,17 +981,38 @@ int snd_pcm_hw_param_never_eq(const snd_pcm_hw_params_t *params, max buffer size min tick time */ -static void snd_pcm_hw_params_choose(snd_pcm_t *pcm, snd_pcm_hw_params_t *params) +static int snd_pcm_hw_params_choose(snd_pcm_t *pcm, snd_pcm_hw_params_t *params) { - snd_pcm_hw_param_set_first(pcm, params, SND_PCM_HW_PARAM_ACCESS, 0); - snd_pcm_hw_param_set_first(pcm, params, SND_PCM_HW_PARAM_FORMAT, 0); - snd_pcm_hw_param_set_first(pcm, params, SND_PCM_HW_PARAM_SUBFORMAT, 0); - snd_pcm_hw_param_set_first(pcm, params, SND_PCM_HW_PARAM_CHANNELS, 0); - snd_pcm_hw_param_set_first(pcm, params, SND_PCM_HW_PARAM_RATE, 0); - snd_pcm_hw_param_set_first(pcm, params, SND_PCM_HW_PARAM_PERIOD_TIME, 0); - snd_pcm_hw_param_set_first(pcm, params, SND_PCM_HW_PARAM_PERIOD_SIZE, 0); - snd_pcm_hw_param_set_last(pcm, params, SND_PCM_HW_PARAM_BUFFER_SIZE, 0); - snd_pcm_hw_param_set_first(pcm, params, SND_PCM_HW_PARAM_TICK_TIME, 0); + int err; + + err = snd_pcm_hw_param_set_first(pcm, params, SND_PCM_HW_PARAM_ACCESS, 0, NULL); + if (err < 0) + return err; + snd_pcm_hw_param_set_first(pcm, params, SND_PCM_HW_PARAM_FORMAT, 0, NULL); + if (err < 0) + return err; + snd_pcm_hw_param_set_first(pcm, params, SND_PCM_HW_PARAM_SUBFORMAT, 0, NULL); + if (err < 0) + return err; + snd_pcm_hw_param_set_first(pcm, params, SND_PCM_HW_PARAM_CHANNELS, 0, NULL); + if (err < 0) + return err; + snd_pcm_hw_param_set_first(pcm, params, SND_PCM_HW_PARAM_RATE, 0, NULL); + if (err < 0) + return err; + snd_pcm_hw_param_set_first(pcm, params, SND_PCM_HW_PARAM_PERIOD_TIME, 0, NULL); + if (err < 0) + return err; + snd_pcm_hw_param_set_first(pcm, params, SND_PCM_HW_PARAM_PERIOD_SIZE, 0, NULL); + if (err < 0) + return err; + snd_pcm_hw_param_set_last(pcm, params, SND_PCM_HW_PARAM_BUFFER_SIZE, 0, NULL); + if (err < 0) + return err; + snd_pcm_hw_param_set_first(pcm, params, SND_PCM_HW_PARAM_TICK_TIME, 0, NULL); + if (err < 0) + return err; + return 0; } #if 0 @@ -1989,13 +2034,20 @@ int snd_pcm_hw_refine_slave(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, if (err >= 0) { #ifdef RULES_DEBUG snd_output_printf(log, "srefine '%s'\n", pcm->name); - snd_pcm_hw_params_dump(params, log); + snd_pcm_hw_params_dump(&sparams, log); #endif err = srefine(pcm, &sparams); - } - if (err < 0) { + if (err < 0) { +#ifdef RULES_DEBUG + snd_output_printf(log, "srefine '%s', err < 0 (%i)\n", pcm->name, err); + snd_pcm_hw_params_dump(&sparams, log); +#endif + cchange(pcm, params, &sparams); + return err; + } + } else { #ifdef RULES_DEBUG - snd_output_printf(log, "cchange '%s', (schange || srefine) < 0\n", pcm->name); + snd_output_printf(log, "schange '%s', err < 0 (%i)\n", pcm->name, err); snd_pcm_hw_params_dump(params, log); #endif cchange(pcm, params, &sparams); diff --git a/src/pcm/pcm_plug.c b/src/pcm/pcm_plug.c index 656c742a..2abe79a2 100644 --- a/src/pcm/pcm_plug.c +++ b/src/pcm/pcm_plug.c @@ -530,12 +530,18 @@ static int snd_pcm_plug_hw_refine_cprepare(snd_pcm_t *pcm ATTRIBUTE_UNUSED, snd_ /* HACK: to avoid overflow in PARTBIT_RATE code */ rate_min = snd_pcm_hw_param_get_min(params, SND_PCM_HW_PARAM_RATE, NULL); - if (rate_min < 4000) + if (rate_min < 4000) { _snd_pcm_hw_param_set_min(params, SND_PCM_HW_PARAM_RATE, 4000, 0); + if (snd_pcm_hw_param_empty(params, SND_PCM_HW_PARAM_RATE)) + return -EINVAL; + } /* HACK: to avoid overflow in PERIOD_SIZE code */ channels_max = snd_pcm_hw_param_get_max(params, SND_PCM_HW_PARAM_CHANNELS, NULL); - if (channels_max > 10000) + if (channels_max > 10000) { _snd_pcm_hw_param_set_max(params, SND_PCM_HW_PARAM_CHANNELS, 10000, 0); + if (snd_pcm_hw_param_empty(params, SND_PCM_HW_PARAM_CHANNELS)) + return -EINVAL; + } return 0; } @@ -574,6 +580,7 @@ static int snd_pcm_plug_hw_refine_schange(snd_pcm_t *pcm, snd_pcm_hw_params_t *p snd_pcm_format_t format; snd_interval_t t, buffer_size; const snd_interval_t *srate, *crate; + if (plug->srate == -2) links |= SND_PCM_HW_PARBIT_RATE; else { @@ -609,7 +616,7 @@ static int snd_pcm_plug_hw_refine_schange(snd_pcm_t *pcm, snd_pcm_hw_params_t *p } if (snd_pcm_format_mask_empty(&sfmt_mask)) { - SNDERR("Unable to find an useable slave format"); + SNDERR("Unable to find an useable slave format for '%s'", pcm->name); for (format = 0; format <= SND_PCM_FORMAT_LAST; format++) { if (!snd_pcm_format_mask_test(format_mask, format)) continue; @@ -624,7 +631,8 @@ static int snd_pcm_plug_hw_refine_schange(snd_pcm_t *pcm, snd_pcm_hw_params_t *p } err = snd_pcm_hw_param_set_mask(slave, sparams, SND_CHANGE, SND_PCM_HW_PARAM_FORMAT, &sfmt_mask); - assert(err >= 0); + if (err < 0) + return -EINVAL; } if (snd_pcm_hw_param_never_eq(params, SND_PCM_HW_PARAM_FORMAT, sparams) || @@ -634,6 +642,10 @@ static int snd_pcm_plug_hw_refine_schange(snd_pcm_t *pcm, snd_pcm_hw_params_t *p snd_pcm_access_mask_t access_mask = { SND_PCM_ACCBIT_MMAP }; _snd_pcm_hw_param_set_mask(sparams, SND_PCM_HW_PARAM_ACCESS, &access_mask); + if (snd_pcm_access_mask_empty(snd_pcm_hw_param_get_mask(sparams, SND_PCM_HW_PARAM_ACCESS))) { + SNDERR("Unable to find an useable access for '%s'", pcm->name); + return -EINVAL; + } } if ((links & SND_PCM_HW_PARBIT_RATE) || snd_pcm_hw_param_always_eq(params, SND_PCM_HW_PARAM_RATE, sparams)) -- 2.47.1