mirror of
https://github.com/alsa-project/alsa-lib.git
synced 2025-10-29 05:40:25 -04:00
More pcm params functions returns an error rather than do assert().
Some cleanups in refine. Added more debug code to refine. Improved dmix refine method.
This commit is contained in:
parent
c7d58f398e
commit
3b6638e8ce
4 changed files with 182 additions and 89 deletions
|
|
@ -498,6 +498,26 @@ static inline snd_interval_t *hw_param_interval(snd_pcm_hw_params_t *params,
|
|||
return ¶ms->intervals[var - SND_PCM_HW_PARAM_FIRST_INTERVAL];
|
||||
}
|
||||
|
||||
static int hw_param_interval_refine_one(snd_pcm_hw_params_t *params,
|
||||
snd_pcm_hw_param_t var,
|
||||
snd_pcm_hw_params_t *src)
|
||||
{
|
||||
snd_interval_t *i;
|
||||
|
||||
if (!(params->rmask & (1<<var))) /* nothing to do? */
|
||||
return 0;
|
||||
i = hw_param_interval(params, var);
|
||||
if (snd_interval_empty(i)) {
|
||||
SNDERR("dmix interval %i empty?\n", (int)var);
|
||||
return -EINVAL;
|
||||
}
|
||||
if (snd_interval_refine(i, hw_param_interval(src, var)))
|
||||
params->cmask |= 1<<var;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#undef REFINE_DEBUG
|
||||
|
||||
static int snd_pcm_dmix_hw_refine(snd_pcm_t *pcm, snd_pcm_hw_params_t *params)
|
||||
{
|
||||
snd_pcm_dmix_t *dmix = pcm->private_data;
|
||||
|
|
@ -508,25 +528,59 @@ static int snd_pcm_dmix_hw_refine(snd_pcm_t *pcm, snd_pcm_hw_params_t *params)
|
|||
(1<<SNDRV_PCM_ACCESS_RW_INTERLEAVED) |
|
||||
(1<<SNDRV_PCM_ACCESS_RW_NONINTERLEAVED),
|
||||
0, 0, 0 } };
|
||||
int err;
|
||||
|
||||
snd_mask_refine(hw_param_mask(params, SND_PCM_HW_PARAM_ACCESS), &access);
|
||||
snd_mask_refine_set(hw_param_mask(params, SND_PCM_HW_PARAM_FORMAT),
|
||||
snd_mask_value(hw_param_mask(hw_params, SND_PCM_HW_PARAM_FORMAT)));
|
||||
#ifdef REFINE_DEBUG
|
||||
snd_output_t *log;
|
||||
snd_output_stdio_attach(&log, stderr, 0);
|
||||
snd_output_puts(log, "DMIX REFINE (begin):\n");
|
||||
snd_pcm_hw_params_dump(params, log);
|
||||
#endif
|
||||
|
||||
if (params->rmask & (1<<SND_PCM_HW_PARAM_ACCESS)) {
|
||||
if (snd_mask_empty(hw_param_mask(params, SND_PCM_HW_PARAM_ACCESS))) {
|
||||
SNDERR("dmix access mask empty?\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
if (snd_mask_refine(hw_param_mask(params, SND_PCM_HW_PARAM_ACCESS), &access))
|
||||
params->cmask |= 1<<SND_PCM_HW_PARAM_ACCESS;
|
||||
}
|
||||
if (params->rmask & (1<<SND_PCM_HW_PARAM_FORMAT)) {
|
||||
if (snd_mask_empty(hw_param_mask(params, SND_PCM_HW_PARAM_FORMAT))) {
|
||||
SNDERR("dmix format mask empty?\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
if (snd_mask_refine_set(hw_param_mask(params, SND_PCM_HW_PARAM_FORMAT),
|
||||
snd_mask_value(hw_param_mask(hw_params, SND_PCM_HW_PARAM_FORMAT))))
|
||||
params->cmask |= 1<<SND_PCM_HW_PARAM_FORMAT;
|
||||
}
|
||||
//snd_mask_none(hw_param_mask(params, SND_PCM_HW_PARAM_SUBFORMAT));
|
||||
snd_interval_refine_set(hw_param_interval(params, SND_PCM_HW_PARAM_CHANNELS),
|
||||
snd_interval_value(hw_param_interval(hw_params, SND_PCM_HW_PARAM_CHANNELS)));
|
||||
snd_interval_refine_set(hw_param_interval(params, SND_PCM_HW_PARAM_RATE),
|
||||
snd_interval_value(hw_param_interval(hw_params, SND_PCM_HW_PARAM_RATE)));
|
||||
snd_interval_refine_set(hw_param_interval(params, SND_PCM_HW_PARAM_BUFFER_SIZE),
|
||||
snd_interval_value(hw_param_interval(hw_params, SND_PCM_HW_PARAM_BUFFER_SIZE)));
|
||||
snd_interval_refine_set(hw_param_interval(params, SND_PCM_HW_PARAM_BUFFER_TIME),
|
||||
snd_interval_value(hw_param_interval(hw_params, SND_PCM_HW_PARAM_BUFFER_TIME)));
|
||||
snd_interval_refine_set(hw_param_interval(params, SND_PCM_HW_PARAM_PERIOD_SIZE),
|
||||
snd_interval_value(hw_param_interval(hw_params, SND_PCM_HW_PARAM_PERIOD_SIZE)));
|
||||
snd_interval_refine_set(hw_param_interval(params, SND_PCM_HW_PARAM_PERIOD_TIME),
|
||||
snd_interval_value(hw_param_interval(hw_params, SND_PCM_HW_PARAM_PERIOD_TIME)));
|
||||
snd_interval_refine_set(hw_param_interval(params, SND_PCM_HW_PARAM_PERIODS),
|
||||
snd_interval_value(hw_param_interval(hw_params, SND_PCM_HW_PARAM_PERIODS)));
|
||||
err = hw_param_interval_refine_one(params, SND_PCM_HW_PARAM_CHANNELS, hw_params);
|
||||
if (err < 0)
|
||||
return err;
|
||||
err = hw_param_interval_refine_one(params, SND_PCM_HW_PARAM_RATE, hw_params);
|
||||
if (err < 0)
|
||||
return err;
|
||||
err = hw_param_interval_refine_one(params, SND_PCM_HW_PARAM_BUFFER_SIZE, hw_params);
|
||||
if (err < 0)
|
||||
return err;
|
||||
err = hw_param_interval_refine_one(params, SND_PCM_HW_PARAM_BUFFER_TIME, hw_params);
|
||||
if (err < 0)
|
||||
return err;
|
||||
err = hw_param_interval_refine_one(params, SND_PCM_HW_PARAM_PERIOD_SIZE, hw_params);
|
||||
if (err < 0)
|
||||
return err;
|
||||
err = hw_param_interval_refine_one(params, SND_PCM_HW_PARAM_PERIOD_TIME, hw_params);
|
||||
if (err < 0)
|
||||
return err;
|
||||
err = hw_param_interval_refine_one(params, SND_PCM_HW_PARAM_PERIODS, hw_params);
|
||||
if (err < 0)
|
||||
return err;
|
||||
#ifdef REFINE_DEBUG
|
||||
snd_output_puts(log, "DMIX REFINE (end):\n");
|
||||
snd_pcm_hw_params_dump(params, log);
|
||||
snd_output_close(log);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -625,20 +679,6 @@ static int snd_pcm_dmix_resume(snd_pcm_t *pcm)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static snd_pcm_sframes_t snd_pcm_dmix_writei(snd_pcm_t *pcm, const void *buffer, snd_pcm_uframes_t size)
|
||||
{
|
||||
int res = snd_pcm_mmap_writei(pcm, buffer, size);
|
||||
snd_pcm_dmix_sync_ptr(pcm, size);
|
||||
return res;
|
||||
}
|
||||
|
||||
static snd_pcm_sframes_t snd_pcm_dmix_writen(snd_pcm_t *pcm, void **bufs, snd_pcm_uframes_t size)
|
||||
{
|
||||
int res = snd_pcm_mmap_writen(pcm, bufs, size);
|
||||
snd_pcm_dmix_sync_ptr(pcm, size);
|
||||
return res;
|
||||
}
|
||||
|
||||
static snd_pcm_sframes_t snd_pcm_dmix_readi(snd_pcm_t *pcm ATTRIBUTE_UNUSED, void *buffer ATTRIBUTE_UNUSED, snd_pcm_uframes_t size ATTRIBUTE_UNUSED)
|
||||
{
|
||||
return -ENODEV;
|
||||
|
|
@ -734,8 +774,8 @@ static snd_pcm_fast_ops_t snd_pcm_dmix_fast_ops = {
|
|||
pause: snd_pcm_dmix_pause,
|
||||
rewind: snd_pcm_dmix_rewind,
|
||||
resume: snd_pcm_dmix_resume,
|
||||
writei: snd_pcm_dmix_writei,
|
||||
writen: snd_pcm_dmix_writen,
|
||||
writei: snd_pcm_mmap_writei,
|
||||
writen: snd_pcm_mmap_writen,
|
||||
readi: snd_pcm_dmix_readi,
|
||||
readn: snd_pcm_dmix_readn,
|
||||
avail_update: snd_pcm_dmix_avail_update,
|
||||
|
|
|
|||
|
|
@ -486,14 +486,14 @@ int _snd_pcm_hw_param_refine(snd_pcm_hw_params_t *params,
|
|||
int _snd_pcm_hw_params_refine(snd_pcm_hw_params_t *params,
|
||||
unsigned int vars,
|
||||
const snd_pcm_hw_params_t *src);
|
||||
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);
|
||||
void snd_pcm_hw_param_refine_multiple(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_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_refine_multiple(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,
|
||||
|
|
|
|||
|
|
@ -95,6 +95,8 @@ void _snd_pcm_hw_params_any(snd_pcm_hw_params_t *params)
|
|||
_snd_pcm_hw_param_any(params, k);
|
||||
for (k = SND_PCM_HW_PARAM_FIRST_INTERVAL; k <= SND_PCM_HW_PARAM_LAST_INTERVAL; k++)
|
||||
_snd_pcm_hw_param_any(params, k);
|
||||
params->rmask = ~0U;
|
||||
params->cmask = 0;
|
||||
params->info = ~0U;
|
||||
}
|
||||
|
||||
|
|
@ -132,13 +134,16 @@ int snd_pcm_hw_param_get_min(const snd_pcm_hw_params_t *params, snd_pcm_hw_param
|
|||
unsigned int *val, int *dir)
|
||||
{
|
||||
if (hw_is_mask(var)) {
|
||||
const snd_mask_t *m = hw_param_mask_c(params, var);
|
||||
assert(!snd_mask_empty(m));
|
||||
if (dir)
|
||||
*dir = 0;
|
||||
if (val)
|
||||
*val = snd_mask_min(hw_param_mask_c(params, var));
|
||||
*val = snd_mask_min(m);
|
||||
return 0;
|
||||
} else if (hw_is_interval(var)) {
|
||||
const snd_interval_t *i = hw_param_interval_c(params, var);
|
||||
assert(!snd_interval_empty(i));
|
||||
if (dir)
|
||||
*dir = i->openmin;
|
||||
if (val)
|
||||
|
|
@ -154,13 +159,16 @@ int snd_pcm_hw_param_get_max(const snd_pcm_hw_params_t *params, snd_pcm_hw_param
|
|||
unsigned int *val, int *dir)
|
||||
{
|
||||
if (hw_is_mask(var)) {
|
||||
const snd_mask_t *m = hw_param_mask_c(params, var);
|
||||
assert(!snd_mask_empty(m));
|
||||
if (dir)
|
||||
*dir = 0;
|
||||
if (val)
|
||||
*val = snd_mask_max(hw_param_mask_c(params, var));
|
||||
*val = snd_mask_max(m);
|
||||
return 0;
|
||||
} else if (hw_is_interval(var)) {
|
||||
const snd_interval_t *i = hw_param_interval_c(params, var);
|
||||
assert(!snd_interval_empty(i));
|
||||
if (dir)
|
||||
*dir = - (int) i->openmax;
|
||||
if (val)
|
||||
|
|
@ -211,7 +219,7 @@ void _snd_pcm_hw_param_set_empty(snd_pcm_hw_params_t *params,
|
|||
snd_pcm_hw_param_t var)
|
||||
{
|
||||
if (hw_is_mask(var)) {
|
||||
snd_mask_none(hw_param_mask(params, var));
|
||||
snd_mask_none(hw_param_mask(params, var));
|
||||
params->cmask |= 1 << var;
|
||||
params->rmask |= 1 << var;
|
||||
} else if (hw_is_interval(var)) {
|
||||
|
|
@ -421,6 +429,10 @@ int snd_pcm_hw_param_set_min(snd_pcm_t *pcm, snd_pcm_hw_params_t *params,
|
|||
err = snd_pcm_hw_refine(pcm, params);
|
||||
if (err < 0)
|
||||
goto _fail;
|
||||
if (snd_pcm_hw_param_empty(params, var)) {
|
||||
err = -ENOENT;
|
||||
goto _fail;
|
||||
}
|
||||
}
|
||||
return snd_pcm_hw_param_get_min(params, var, val, dir);
|
||||
_fail:
|
||||
|
|
@ -492,6 +504,10 @@ int snd_pcm_hw_param_set_max(snd_pcm_t *pcm, snd_pcm_hw_params_t *params,
|
|||
err = snd_pcm_hw_refine(pcm, params);
|
||||
if (err < 0)
|
||||
goto _fail;
|
||||
if (snd_pcm_hw_param_empty(params, var)) {
|
||||
err = -ENOENT;
|
||||
goto _fail;
|
||||
}
|
||||
}
|
||||
return snd_pcm_hw_param_get_max(params, var, val, dir);
|
||||
_fail:
|
||||
|
|
@ -772,6 +788,7 @@ int snd_pcm_hw_param_set_near(snd_pcm_t *pcm, snd_pcm_hw_params_t *params,
|
|||
int min, max;
|
||||
int mindir, maxdir;
|
||||
int valdir = dir ? *dir : 0;
|
||||
snd_interval_t *i;
|
||||
/* FIXME */
|
||||
if (best > INT_MAX)
|
||||
best = INT_MAX;
|
||||
|
|
@ -788,6 +805,11 @@ int snd_pcm_hw_param_set_near(snd_pcm_t *pcm, snd_pcm_hw_params_t *params,
|
|||
save = *params;
|
||||
saved_min = min;
|
||||
err = snd_pcm_hw_param_set_min(pcm, params, SND_CHANGE, var, &min, &mindir);
|
||||
|
||||
i = hw_param_interval(params, var);
|
||||
if (!snd_interval_empty(i) && snd_interval_single(i))
|
||||
return snd_pcm_hw_param_get_min(params, var, val, dir);
|
||||
|
||||
if (err >= 0) {
|
||||
snd_pcm_hw_params_t params1;
|
||||
if (max < 0)
|
||||
|
|
@ -913,28 +935,33 @@ static int 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);
|
||||
if (err < 0)
|
||||
return err;
|
||||
return 0;
|
||||
}
|
||||
|
||||
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_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)
|
||||
{
|
||||
unsigned int min, max;
|
||||
int mindir, maxdir;
|
||||
int mindir, maxdir, err;
|
||||
|
||||
snd_pcm_hw_param_get_min(src, var, &min, &mindir);
|
||||
snd_pcm_hw_param_get_max(src, var, &max, &maxdir);
|
||||
snd_pcm_hw_param_set_near_minmax(pcm, params, var,
|
||||
min, &mindir, max, &maxdir);
|
||||
if ((err = snd_pcm_hw_param_get_min(src, var, &min, &mindir)) < 0)
|
||||
return err;
|
||||
if ((err = snd_pcm_hw_param_get_max(src, var, &max, &maxdir)) < 0)
|
||||
return err;
|
||||
if ((err = snd_pcm_hw_param_set_near_minmax(pcm, params, var,
|
||||
min, &mindir, max, &maxdir)) < 0)
|
||||
return err;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void snd_pcm_hw_param_refine_multiple(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_refine_multiple(snd_pcm_t *pcm,
|
||||
snd_pcm_hw_params_t *params,
|
||||
snd_pcm_hw_param_t var,
|
||||
const snd_pcm_hw_params_t *src)
|
||||
{
|
||||
const snd_interval_t *it = hw_param_interval_c(src, var);
|
||||
const snd_interval_t *st = hw_param_interval_c(params, var);
|
||||
|
|
@ -945,11 +972,11 @@ void snd_pcm_hw_param_refine_multiple(snd_pcm_t *pcm,
|
|||
break;
|
||||
if (it->min > cur || (it->min == cur && st->openmin))
|
||||
continue;
|
||||
if (! snd_pcm_hw_param_set(pcm, params, SND_TRY, var, cur, 0))
|
||||
return; /* ok */
|
||||
if (snd_pcm_hw_param_set(pcm, params, SND_TRY, var, cur, 0) == 0)
|
||||
return 0; /* ok */
|
||||
}
|
||||
}
|
||||
snd_pcm_hw_param_refine_near(pcm, params, var, src);
|
||||
return snd_pcm_hw_param_refine_near(pcm, params, var, src);
|
||||
}
|
||||
|
||||
/* ---- end of refinement functions ---- */
|
||||
|
|
@ -971,10 +998,10 @@ int snd_pcm_hw_param_always_eq(const snd_pcm_hw_params_t *params,
|
|||
{
|
||||
if (hw_is_mask(var))
|
||||
return snd_mask_always_eq(hw_param_mask_c(params, var),
|
||||
hw_param_mask_c(params1, var));
|
||||
hw_param_mask_c(params1, var));
|
||||
if (hw_is_interval(var))
|
||||
return snd_interval_always_eq(hw_param_interval_c(params, var),
|
||||
hw_param_interval_c(params1, var));
|
||||
hw_param_interval_c(params1, var));
|
||||
assert(0);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
|
@ -985,10 +1012,10 @@ int snd_pcm_hw_param_never_eq(const snd_pcm_hw_params_t *params,
|
|||
{
|
||||
if (hw_is_mask(var))
|
||||
return snd_mask_never_eq(hw_param_mask_c(params, var),
|
||||
hw_param_mask_c(params1, var));
|
||||
hw_param_mask_c(params1, var));
|
||||
if (hw_is_interval(var))
|
||||
return snd_interval_never_eq(hw_param_interval_c(params, var),
|
||||
hw_param_interval_c(params1, var));
|
||||
hw_param_interval_c(params1, var));
|
||||
assert(0);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
|
@ -1903,6 +1930,8 @@ int snd_pcm_hw_refine_soft(snd_pcm_t *pcm ATTRIBUTE_UNUSED, snd_pcm_hw_params_t
|
|||
#ifdef RULES_DEBUG
|
||||
snd_output_t *log;
|
||||
snd_output_stdio_attach(&log, stderr, 0);
|
||||
snd_output_printf(log, "refine_soft '%s' (begin)\n", pcm->name);
|
||||
snd_pcm_hw_params_dump(params, log);
|
||||
#endif
|
||||
|
||||
for (k = SND_PCM_HW_PARAM_FIRST_MASK; k <= SND_PCM_HW_PARAM_LAST_MASK; k++) {
|
||||
|
|
@ -1991,6 +2020,8 @@ int snd_pcm_hw_refine_soft(snd_pcm_t *pcm ATTRIBUTE_UNUSED, snd_pcm_hw_params_t
|
|||
return 0;
|
||||
_err:
|
||||
#ifdef RULES_DEBUG
|
||||
snd_output_printf(log, "refine_soft '%s' (end-%i)\n", pcm->name, changed);
|
||||
snd_pcm_hw_params_dump(params, log);
|
||||
snd_output_close(log);
|
||||
#endif
|
||||
return changed;
|
||||
|
|
@ -2051,19 +2082,25 @@ int snd_pcm_hw_refine_slave(snd_pcm_t *pcm, snd_pcm_hw_params_t *params,
|
|||
cmask = params->cmask;
|
||||
params->cmask = 0;
|
||||
#ifdef RULES_DEBUG
|
||||
snd_output_printf(log, "schange '%s'\n", pcm->name);
|
||||
snd_output_printf(log, "schange '%s' (client)\n", pcm->name);
|
||||
snd_pcm_hw_params_dump(params, log);
|
||||
snd_output_printf(log, "schange '%s' (slave)\n", pcm->name);
|
||||
snd_pcm_hw_params_dump(&sparams, log);
|
||||
#endif
|
||||
err = schange(pcm, params, &sparams);
|
||||
if (err >= 0) {
|
||||
#ifdef RULES_DEBUG
|
||||
snd_output_printf(log, "srefine '%s'\n", pcm->name);
|
||||
snd_output_printf(log, "srefine '%s' (client)\n", pcm->name);
|
||||
snd_pcm_hw_params_dump(params, log);
|
||||
snd_output_printf(log, "srefine '%s' (slave)\n", pcm->name);
|
||||
snd_pcm_hw_params_dump(&sparams, log);
|
||||
#endif
|
||||
err = srefine(pcm, &sparams);
|
||||
if (err < 0) {
|
||||
#ifdef RULES_DEBUG
|
||||
snd_output_printf(log, "srefine '%s', err < 0 (%i)\n", pcm->name, err);
|
||||
snd_output_printf(log, "srefine '%s', err < 0 (%i) (client)\n", pcm->name, err);
|
||||
snd_pcm_hw_params_dump(params, log);
|
||||
snd_output_printf(log, "srefine '%s', err < 0 (%i) (slave)\n", pcm->name, err);
|
||||
snd_pcm_hw_params_dump(&sparams, log);
|
||||
#endif
|
||||
cchange(pcm, params, &sparams);
|
||||
|
|
@ -2071,8 +2108,10 @@ int snd_pcm_hw_refine_slave(snd_pcm_t *pcm, snd_pcm_hw_params_t *params,
|
|||
}
|
||||
} else {
|
||||
#ifdef RULES_DEBUG
|
||||
snd_output_printf(log, "schange '%s', err < 0 (%i)\n", pcm->name, err);
|
||||
snd_output_printf(log, "schange '%s', err < 0 (%i) (client)\n", pcm->name, err);
|
||||
snd_pcm_hw_params_dump(params, log);
|
||||
snd_output_printf(log, "schange '%s', err < 0 (%i) (slave)\n", pcm->name, err);
|
||||
snd_pcm_hw_params_dump(&sparams, log);
|
||||
#endif
|
||||
cchange(pcm, params, &sparams);
|
||||
return err;
|
||||
|
|
|
|||
|
|
@ -595,16 +595,21 @@ static int snd_pcm_plug_insert_plugins(snd_pcm_t *pcm,
|
|||
static int snd_pcm_plug_hw_refine_cprepare(snd_pcm_t *pcm ATTRIBUTE_UNUSED, snd_pcm_hw_params_t *params)
|
||||
{
|
||||
unsigned int rate_min, channels_max;
|
||||
int err;
|
||||
|
||||
/* HACK: to avoid overflow in PARTBIT_RATE code */
|
||||
snd_pcm_hw_param_get_min(params, SND_PCM_HW_PARAM_RATE, &rate_min, NULL);
|
||||
err = snd_pcm_hw_param_get_min(params, SND_PCM_HW_PARAM_RATE, &rate_min, NULL);
|
||||
if (err < 0)
|
||||
return err;
|
||||
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 */
|
||||
snd_pcm_hw_param_get_max(params, SND_PCM_HW_PARAM_CHANNELS, &channels_max, NULL);
|
||||
err = snd_pcm_hw_param_get_max(params, SND_PCM_HW_PARAM_CHANNELS, &channels_max, NULL);
|
||||
if (err < 0)
|
||||
return err;
|
||||
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))
|
||||
|
|
@ -617,6 +622,8 @@ static int snd_pcm_plug_hw_refine_sprepare(snd_pcm_t *pcm, snd_pcm_hw_params_t *
|
|||
{
|
||||
snd_pcm_plug_t *plug = pcm->private_data;
|
||||
_snd_pcm_hw_params_any(sparams);
|
||||
int err;
|
||||
|
||||
if (plug->sformat >= 0) {
|
||||
_snd_pcm_hw_params_set_format(sparams, plug->sformat);
|
||||
_snd_pcm_hw_params_set_subformat(sparams, SND_PCM_SUBFORMAT_STD);
|
||||
|
|
@ -627,11 +634,10 @@ static int snd_pcm_plug_hw_refine_sprepare(snd_pcm_t *pcm, snd_pcm_hw_params_t *
|
|||
if (plug->srate > 0)
|
||||
_snd_pcm_hw_param_set_minmax(sparams, SND_PCM_HW_PARAM_RATE,
|
||||
plug->srate, 0, plug->srate + 1, -1);
|
||||
if (plug->sformat >= 0 || plug->schannels > 0 || plug->srate > 0) {
|
||||
int err = snd_pcm_hw_refine(plug->req_slave, sparams);
|
||||
if (err < 0)
|
||||
return err;
|
||||
}
|
||||
/* reduce the available configurations */
|
||||
err = snd_pcm_hw_refine(plug->req_slave, sparams);
|
||||
if (err < 0)
|
||||
return err;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -652,22 +658,23 @@ static int snd_pcm_plug_hw_refine_schange(snd_pcm_t *pcm, snd_pcm_hw_params_t *p
|
|||
if (plug->srate == -2)
|
||||
links |= SND_PCM_HW_PARBIT_RATE;
|
||||
else {
|
||||
snd_pcm_hw_param_refine_multiple(slave, sparams, SND_PCM_HW_PARAM_RATE,
|
||||
params);
|
||||
err = snd_pcm_hw_param_refine_multiple(slave, sparams, SND_PCM_HW_PARAM_RATE, params);
|
||||
if (err < 0)
|
||||
return err;
|
||||
}
|
||||
|
||||
if (plug->schannels == -2)
|
||||
links |= SND_PCM_HW_PARBIT_CHANNELS;
|
||||
else
|
||||
snd_pcm_hw_param_refine_near(slave, sparams, SND_PCM_HW_PARAM_CHANNELS,
|
||||
params);
|
||||
else {
|
||||
err = snd_pcm_hw_param_refine_near(slave, sparams, SND_PCM_HW_PARAM_CHANNELS, params);
|
||||
if (err < 0)
|
||||
return err;
|
||||
}
|
||||
if (plug->sformat == -2)
|
||||
links |= SND_PCM_HW_PARBIT_FORMAT;
|
||||
else {
|
||||
format_mask = snd_pcm_hw_param_get_mask(params,
|
||||
SND_PCM_HW_PARAM_FORMAT);
|
||||
sformat_mask = snd_pcm_hw_param_get_mask(sparams,
|
||||
SND_PCM_HW_PARAM_FORMAT);
|
||||
format_mask = snd_pcm_hw_param_get_mask(params, SND_PCM_HW_PARAM_FORMAT);
|
||||
sformat_mask = snd_pcm_hw_param_get_mask(sparams, SND_PCM_HW_PARAM_FORMAT);
|
||||
snd_mask_none(&sfmt_mask);
|
||||
for (format = 0; format <= SND_PCM_FORMAT_LAST; format++) {
|
||||
snd_pcm_format_t f;
|
||||
|
|
@ -749,8 +756,6 @@ static int snd_pcm_plug_hw_refine_cchange(snd_pcm_t *pcm ATTRIBUTE_UNUSED,
|
|||
snd_interval_t t;
|
||||
const snd_interval_t *sbuffer_size;
|
||||
const snd_interval_t *srate, *crate;
|
||||
unsigned int rate_min, srate_min;
|
||||
int rate_mindir, srate_mindir;
|
||||
|
||||
if (plug->schannels == -2)
|
||||
links |= SND_PCM_HW_PARBIT_CHANNELS;
|
||||
|
|
@ -801,9 +806,16 @@ static int snd_pcm_plug_hw_refine_cchange(snd_pcm_t *pcm ATTRIBUTE_UNUSED,
|
|||
if (plug->srate == -2)
|
||||
links |= SND_PCM_HW_PARBIT_RATE;
|
||||
else {
|
||||
unsigned int rate_min, srate_min;
|
||||
int rate_mindir, srate_mindir;
|
||||
|
||||
/* This is a temporary hack, waiting for a better solution */
|
||||
snd_pcm_hw_param_get_min(params, SND_PCM_HW_PARAM_RATE, &rate_min, &rate_mindir);
|
||||
snd_pcm_hw_param_get_min(sparams, SND_PCM_HW_PARAM_RATE, &srate_min, &srate_mindir);
|
||||
err = snd_pcm_hw_param_get_min(params, SND_PCM_HW_PARAM_RATE, &rate_min, &rate_mindir);
|
||||
if (err < 0)
|
||||
return err;
|
||||
err = snd_pcm_hw_param_get_min(sparams, SND_PCM_HW_PARAM_RATE, &srate_min, &srate_mindir);
|
||||
if (err < 0)
|
||||
return err;
|
||||
if (rate_min == srate_min && srate_mindir > rate_mindir) {
|
||||
err = _snd_pcm_hw_param_set_min(params, SND_PCM_HW_PARAM_RATE, srate_min, srate_mindir);
|
||||
if (err < 0)
|
||||
|
|
@ -820,6 +832,8 @@ static int snd_pcm_plug_hw_refine_cchange(snd_pcm_t *pcm ATTRIBUTE_UNUSED,
|
|||
srate = snd_pcm_hw_param_get_interval(sparams, SND_PCM_HW_PARAM_RATE);
|
||||
snd_interval_muldiv(sbuffer_size, crate, srate, &t);
|
||||
snd_interval_floor(&t);
|
||||
if (snd_interval_empty(&t))
|
||||
return -EINVAL;
|
||||
err = _snd_pcm_hw_param_set_interval(params, SND_PCM_HW_PARAM_BUFFER_SIZE, &t);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue