Fix softvol access refine

The commit a13707da6b

    pcm_softvol plugin: remove access type change for refine

breaks the softvol in the case of RW -> MMAP.  The slave of softvol
must be an mmap although the previous fix forces RW access.

This patch reverts the commit, and the fixed access refine method
to hanle non-interleaved <-> interleaved changes.

Signed-off-by: Takashi Iwai <tiwai@suse.de>
This commit is contained in:
Takashi Iwai 2008-12-04 15:21:40 +01:00
parent c0fd854ff1
commit 48e4d089dc

View file

@ -399,6 +399,7 @@ static int snd_pcm_softvol_hw_refine_cprepare(snd_pcm_t *pcm,
{ {
int err; int err;
snd_pcm_softvol_t *svol = pcm->private_data; snd_pcm_softvol_t *svol = pcm->private_data;
snd_pcm_access_mask_t access_mask = { SND_PCM_ACCBIT_SHM };
snd_pcm_format_mask_t format_mask = { snd_pcm_format_mask_t format_mask = {
{ {
(1ULL << SND_PCM_FORMAT_S16_LE) | (1ULL << SND_PCM_FORMAT_S16_LE) |
@ -412,6 +413,10 @@ static int snd_pcm_softvol_hw_refine_cprepare(snd_pcm_t *pcm,
snd_pcm_format_mask_none(&format_mask); snd_pcm_format_mask_none(&format_mask);
snd_pcm_format_mask_set(&format_mask, svol->sformat); snd_pcm_format_mask_set(&format_mask, svol->sformat);
} }
err = _snd_pcm_hw_param_set_mask(params, SND_PCM_HW_PARAM_ACCESS,
&access_mask);
if (err < 0)
return err;
err = _snd_pcm_hw_param_set_mask(params, SND_PCM_HW_PARAM_FORMAT, err = _snd_pcm_hw_param_set_mask(params, SND_PCM_HW_PARAM_FORMAT,
&format_mask); &format_mask);
if (err < 0) if (err < 0)
@ -429,7 +434,10 @@ static int snd_pcm_softvol_hw_refine_cprepare(snd_pcm_t *pcm,
static int snd_pcm_softvol_hw_refine_sprepare(snd_pcm_t *pcm, snd_pcm_hw_params_t *sparams) static int snd_pcm_softvol_hw_refine_sprepare(snd_pcm_t *pcm, snd_pcm_hw_params_t *sparams)
{ {
snd_pcm_softvol_t *svol = pcm->private_data; snd_pcm_softvol_t *svol = pcm->private_data;
snd_pcm_access_mask_t saccess_mask = { SND_PCM_ACCBIT_MMAP };
_snd_pcm_hw_params_any(sparams); _snd_pcm_hw_params_any(sparams);
_snd_pcm_hw_param_set_mask(sparams, SND_PCM_HW_PARAM_ACCESS,
&saccess_mask);
if (svol->sformat != SND_PCM_FORMAT_UNKNOWN) { if (svol->sformat != SND_PCM_FORMAT_UNKNOWN) {
_snd_pcm_hw_params_set_format(sparams, svol->sformat); _snd_pcm_hw_params_set_format(sparams, svol->sformat);
_snd_pcm_hw_params_set_subformat(sparams, SND_PCM_SUBFORMAT_STD); _snd_pcm_hw_params_set_subformat(sparams, SND_PCM_SUBFORMAT_STD);
@ -437,14 +445,45 @@ static int snd_pcm_softvol_hw_refine_sprepare(snd_pcm_t *pcm, snd_pcm_hw_params_
return 0; return 0;
} }
/*
* refine the access mask
*/
static int check_access_mask(snd_pcm_hw_params_t *src,
snd_pcm_hw_params_t *dst)
{
const snd_pcm_access_mask_t *mask;
snd_pcm_access_mask_t smask;
mask = snd_pcm_hw_param_get_mask(src, SND_PCM_HW_PARAM_ACCESS);
snd_mask_none(&smask);
if (snd_pcm_access_mask_test(mask, SND_PCM_ACCESS_RW_INTERLEAVED) ||
snd_pcm_access_mask_test(mask, SND_PCM_ACCESS_MMAP_INTERLEAVED)) {
snd_pcm_access_mask_set(&smask,
SND_PCM_ACCESS_RW_INTERLEAVED);
snd_pcm_access_mask_set(&smask,
SND_PCM_ACCESS_MMAP_INTERLEAVED);
}
if (snd_pcm_access_mask_test(mask, SND_PCM_ACCESS_RW_NONINTERLEAVED) ||
snd_pcm_access_mask_test(mask, SND_PCM_ACCESS_MMAP_NONINTERLEAVED)) {
snd_pcm_access_mask_set(&smask,
SND_PCM_ACCESS_RW_NONINTERLEAVED);
snd_pcm_access_mask_set(&smask,
SND_PCM_ACCESS_MMAP_NONINTERLEAVED);
}
if (snd_pcm_access_mask_test(mask, SND_PCM_ACCESS_MMAP_COMPLEX))
snd_pcm_access_mask_set(&smask,
SND_PCM_ACCESS_MMAP_COMPLEX);
return _snd_pcm_hw_param_set_mask(dst, SND_PCM_HW_PARAM_ACCESS, &smask);
}
static int snd_pcm_softvol_hw_refine_schange(snd_pcm_t *pcm, static int snd_pcm_softvol_hw_refine_schange(snd_pcm_t *pcm,
snd_pcm_hw_params_t *params, snd_pcm_hw_params_t *params,
snd_pcm_hw_params_t *sparams) snd_pcm_hw_params_t *sparams)
{ {
snd_pcm_softvol_t *svol = pcm->private_data; snd_pcm_softvol_t *svol = pcm->private_data;
int err; int err;
unsigned int links = (SND_PCM_HW_PARBIT_ACCESS | unsigned int links = (SND_PCM_HW_PARBIT_CHANNELS |
SND_PCM_HW_PARBIT_CHANNELS |
SND_PCM_HW_PARBIT_RATE | SND_PCM_HW_PARBIT_RATE |
SND_PCM_HW_PARBIT_PERIODS | SND_PCM_HW_PARBIT_PERIODS |
SND_PCM_HW_PARBIT_PERIOD_SIZE | SND_PCM_HW_PARBIT_PERIOD_SIZE |
@ -459,6 +498,11 @@ static int snd_pcm_softvol_hw_refine_schange(snd_pcm_t *pcm,
err = _snd_pcm_hw_params_refine(sparams, links, params); err = _snd_pcm_hw_params_refine(sparams, links, params);
if (err < 0) if (err < 0)
return err; return err;
err = check_access_mask(params, sparams);
if (err < 0)
return err;
return 0; return 0;
} }
@ -468,8 +512,7 @@ static int snd_pcm_softvol_hw_refine_cchange(snd_pcm_t *pcm,
{ {
snd_pcm_softvol_t *svol = pcm->private_data; snd_pcm_softvol_t *svol = pcm->private_data;
int err; int err;
unsigned int links = (SND_PCM_HW_PARBIT_ACCESS | unsigned int links = (SND_PCM_HW_PARBIT_CHANNELS |
SND_PCM_HW_PARBIT_CHANNELS |
SND_PCM_HW_PARBIT_RATE | SND_PCM_HW_PARBIT_RATE |
SND_PCM_HW_PARBIT_PERIODS | SND_PCM_HW_PARBIT_PERIODS |
SND_PCM_HW_PARBIT_PERIOD_SIZE | SND_PCM_HW_PARBIT_PERIOD_SIZE |
@ -484,6 +527,11 @@ static int snd_pcm_softvol_hw_refine_cchange(snd_pcm_t *pcm,
err = _snd_pcm_hw_params_refine(params, links, sparams); err = _snd_pcm_hw_params_refine(params, links, sparams);
if (err < 0) if (err < 0)
return err; return err;
err = check_access_mask(sparams, params);
if (err < 0)
return err;
return 0; return 0;
} }