winealsa: Add support for alsa cards without a PCM mixer (only Line).

This commit is contained in:
Andy Norris 2011-03-05 16:03:55 -05:00 committed by Alexandre Julliard
parent fcfbb46d2e
commit 254b8f85b5
2 changed files with 82 additions and 65 deletions

View File

@ -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,7 +449,10 @@ 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");
for( name = names; *name; name++ )
{
snd_ctl_elem_id_set_name(elemidp, *name);
snd_ctl_elem_id_set_interface(elemidp, SND_CTL_ELEM_IFACE_MIXER); snd_ctl_elem_id_set_interface(elemidp, SND_CTL_ELEM_IFACE_MIXER);
elem = snd_hctl_find_elem(hctl, elemidp); elem = snd_hctl_find_elem(hctl, elemidp);
if (elem) if (elem)
@ -518,10 +523,14 @@ int ALSA_CheckSetVolume(snd_hctl_t *hctl, int *out_left, int *out_right,
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;
} }

View File

@ -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 */