winealsa: Add support for alsa cards without a PCM mixer (only Line).
This commit is contained in:
parent
fcfbb46d2e
commit
254b8f85b5
|
@ -421,6 +421,8 @@ int ALSA_CheckSetVolume(snd_hctl_t *hctl, int *out_left, int *out_right,
|
||||||
snd_ctl_elem_info_t * eleminfop = NULL;
|
snd_ctl_elem_info_t * eleminfop = NULL;
|
||||||
snd_ctl_elem_value_t * elemvaluep = NULL;
|
snd_ctl_elem_value_t * elemvaluep = NULL;
|
||||||
snd_ctl_elem_id_t * elemidp = NULL;
|
snd_ctl_elem_id_t * elemidp = NULL;
|
||||||
|
const char *names[] = {"PCM Playback Volume", "Line Playback Volume", NULL};
|
||||||
|
const char **name;
|
||||||
|
|
||||||
|
|
||||||
#define EXIT_ON_ERROR(f,txt,exitcode) do \
|
#define EXIT_ON_ERROR(f,txt,exitcode) do \
|
||||||
|
@ -447,81 +449,88 @@ int ALSA_CheckSetVolume(snd_hctl_t *hctl, int *out_left, int *out_right,
|
||||||
|
|
||||||
/* Setup and find an element id that exactly matches the characteristic we want
|
/* Setup and find an element id that exactly matches the characteristic we want
|
||||||
** FIXME: It is probably short sighted to hard code and fixate on PCM Playback Volume */
|
** FIXME: It is probably short sighted to hard code and fixate on PCM Playback Volume */
|
||||||
snd_ctl_elem_id_set_name(elemidp, "PCM Playback Volume");
|
|
||||||
snd_ctl_elem_id_set_interface(elemidp, SND_CTL_ELEM_IFACE_MIXER);
|
for( name = names; *name; name++ )
|
||||||
elem = snd_hctl_find_elem(hctl, elemidp);
|
|
||||||
if (elem)
|
|
||||||
{
|
{
|
||||||
/* Read and return volume information */
|
snd_ctl_elem_id_set_name(elemidp, *name);
|
||||||
EXIT_ON_ERROR(snd_hctl_elem_info(elem, eleminfop), "snd_hctl_elem_info", MMSYSERR_NOTSUPPORTED);
|
snd_ctl_elem_id_set_interface(elemidp, SND_CTL_ELEM_IFACE_MIXER);
|
||||||
value_count = snd_ctl_elem_info_get_count(eleminfop);
|
elem = snd_hctl_find_elem(hctl, elemidp);
|
||||||
if (out_min || out_max || out_step)
|
if (elem)
|
||||||
{
|
{
|
||||||
if (!snd_ctl_elem_info_is_readable(eleminfop))
|
/* Read and return volume information */
|
||||||
{
|
EXIT_ON_ERROR(snd_hctl_elem_info(elem, eleminfop), "snd_hctl_elem_info", MMSYSERR_NOTSUPPORTED);
|
||||||
ERR("snd_ctl_elem_info_is_readable returned false; cannot return info\n");
|
value_count = snd_ctl_elem_info_get_count(eleminfop);
|
||||||
rc = MMSYSERR_NOTSUPPORTED;
|
if (out_min || out_max || out_step)
|
||||||
goto out;
|
{
|
||||||
}
|
if (!snd_ctl_elem_info_is_readable(eleminfop))
|
||||||
|
{
|
||||||
|
ERR("snd_ctl_elem_info_is_readable returned false; cannot return info\n");
|
||||||
|
rc = MMSYSERR_NOTSUPPORTED;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
if (out_min)
|
if (out_min)
|
||||||
*out_min = snd_ctl_elem_info_get_min(eleminfop);
|
*out_min = snd_ctl_elem_info_get_min(eleminfop);
|
||||||
|
|
||||||
if (out_max)
|
if (out_max)
|
||||||
*out_max = snd_ctl_elem_info_get_max(eleminfop);
|
*out_max = snd_ctl_elem_info_get_max(eleminfop);
|
||||||
|
|
||||||
if (out_step)
|
if (out_step)
|
||||||
*out_step = snd_ctl_elem_info_get_step(eleminfop);
|
*out_step = snd_ctl_elem_info_get_step(eleminfop);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (out_left || out_right)
|
if (out_left || out_right)
|
||||||
{
|
{
|
||||||
EXIT_ON_ERROR(snd_hctl_elem_read(elem, elemvaluep), "snd_hctl_elem_read", MMSYSERR_NOTSUPPORTED);
|
EXIT_ON_ERROR(snd_hctl_elem_read(elem, elemvaluep), "snd_hctl_elem_read", MMSYSERR_NOTSUPPORTED);
|
||||||
|
|
||||||
if (out_left)
|
if (out_left)
|
||||||
*out_left = snd_ctl_elem_value_get_integer(elemvaluep, 0);
|
*out_left = snd_ctl_elem_value_get_integer(elemvaluep, 0);
|
||||||
|
|
||||||
if (out_right)
|
if (out_right)
|
||||||
{
|
{
|
||||||
if (value_count == 1)
|
if (value_count == 1)
|
||||||
*out_right = snd_ctl_elem_value_get_integer(elemvaluep, 0);
|
*out_right = snd_ctl_elem_value_get_integer(elemvaluep, 0);
|
||||||
else if (value_count == 2)
|
else if (value_count == 2)
|
||||||
*out_right = snd_ctl_elem_value_get_integer(elemvaluep, 1);
|
*out_right = snd_ctl_elem_value_get_integer(elemvaluep, 1);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ERR("Unexpected value count %d from snd_ctl_elem_info_get_count while getting volume info\n", value_count);
|
ERR("Unexpected value count %d from snd_ctl_elem_info_get_count while getting volume info\n", value_count);
|
||||||
rc = -1;
|
rc = -1;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set the volume */
|
/* Set the volume */
|
||||||
if (new_left || new_right)
|
if (new_left || new_right)
|
||||||
{
|
{
|
||||||
EXIT_ON_ERROR(snd_hctl_elem_read(elem, elemvaluep), "snd_hctl_elem_read", MMSYSERR_NOTSUPPORTED);
|
EXIT_ON_ERROR(snd_hctl_elem_read(elem, elemvaluep), "snd_hctl_elem_read", MMSYSERR_NOTSUPPORTED);
|
||||||
if (new_left)
|
if (new_left)
|
||||||
snd_ctl_elem_value_set_integer(elemvaluep, 0, *new_left);
|
snd_ctl_elem_value_set_integer(elemvaluep, 0, *new_left);
|
||||||
if (new_right)
|
if (new_right)
|
||||||
{
|
{
|
||||||
if (value_count == 1)
|
if (value_count == 1)
|
||||||
snd_ctl_elem_value_set_integer(elemvaluep, 0, *new_right);
|
snd_ctl_elem_value_set_integer(elemvaluep, 0, *new_right);
|
||||||
else if (value_count == 2)
|
else if (value_count == 2)
|
||||||
snd_ctl_elem_value_set_integer(elemvaluep, 1, *new_right);
|
snd_ctl_elem_value_set_integer(elemvaluep, 1, *new_right);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ERR("Unexpected value count %d from snd_ctl_elem_info_get_count while setting volume info\n", value_count);
|
ERR("Unexpected value count %d from snd_ctl_elem_info_get_count while setting volume info\n", value_count);
|
||||||
rc = -1;
|
rc = -1;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
EXIT_ON_ERROR(snd_hctl_elem_write(elem, elemvaluep), "snd_hctl_elem_write", MMSYSERR_NOTSUPPORTED);
|
EXIT_ON_ERROR(snd_hctl_elem_write(elem, elemvaluep), "snd_hctl_elem_write", MMSYSERR_NOTSUPPORTED);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
|
||||||
|
if( !*name )
|
||||||
{
|
{
|
||||||
ERR("Could not find 'PCM Playback Volume' element\n");
|
ERR("Could not find '{PCM,Line} Playback Volume' element\n");
|
||||||
rc = MMSYSERR_NOTSUPPORTED;
|
rc = MMSYSERR_NOTSUPPORTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -435,7 +435,7 @@ static void ALSA_MixerInit(void)
|
||||||
char cardind[6], cardname[10];
|
char cardind[6], cardname[10];
|
||||||
|
|
||||||
snd_ctl_t *ctl;
|
snd_ctl_t *ctl;
|
||||||
snd_mixer_elem_t *elem, *mastelem = NULL, *headelem = NULL, *captelem = NULL, *pcmelem = NULL, *micelem = NULL;
|
snd_mixer_elem_t *elem, *mastelem = NULL, *headelem = NULL, *captelem = NULL, *pcmelem = NULL, *lineelem = NULL, *micelem = NULL;
|
||||||
|
|
||||||
memset(info, 0, snd_ctl_card_info_sizeof());
|
memset(info, 0, snd_ctl_card_info_sizeof());
|
||||||
memset(&mixdev[mixnum], 0, sizeof(*mixdev));
|
memset(&mixdev[mixnum], 0, sizeof(*mixdev));
|
||||||
|
@ -520,6 +520,8 @@ static void ALSA_MixerInit(void)
|
||||||
headelem = elem;
|
headelem = elem;
|
||||||
else if (!strcasecmp(snd_mixer_selem_get_name(elem), "PCM") && !pcmelem)
|
else if (!strcasecmp(snd_mixer_selem_get_name(elem), "PCM") && !pcmelem)
|
||||||
pcmelem = elem;
|
pcmelem = elem;
|
||||||
|
else if (!strcasecmp(snd_mixer_selem_get_name(elem), "Line") && !lineelem)
|
||||||
|
lineelem = elem;
|
||||||
++(mixdev[mixnum].chans);
|
++(mixdev[mixnum].chans);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -548,6 +550,12 @@ static void ALSA_MixerInit(void)
|
||||||
mastelem = pcmelem;
|
mastelem = pcmelem;
|
||||||
capcontrols -= !!snd_mixer_selem_has_capture_switch(mastelem);
|
capcontrols -= !!snd_mixer_selem_has_capture_switch(mastelem);
|
||||||
}
|
}
|
||||||
|
else if (lineelem && !mastelem)
|
||||||
|
{
|
||||||
|
/* Use 'Line' as master device */
|
||||||
|
mastelem = lineelem;
|
||||||
|
capcontrols -= !!snd_mixer_selem_has_capture_switch(mastelem);
|
||||||
|
}
|
||||||
else if (!mastelem && !captelem && !micelem)
|
else if (!mastelem && !captelem && !micelem)
|
||||||
{
|
{
|
||||||
/* If there is nothing sensible that can act as 'Master' control, something is wrong */
|
/* If there is nothing sensible that can act as 'Master' control, something is wrong */
|
||||||
|
|
Loading…
Reference in New Issue