Add config knob for mixer channel name (ALSA/Linux only)

In some complex ALSA setups, using PCM or Master is not the right thing
to do, so allow a custom mixer element name to be specified in the config
file for this use case.

Request and initial patch by Kurt Vanderlinden <kurt.vanderlinden@skynet.be>.
This commit is contained in:
Julien BLACHE 2011-07-08 11:18:20 +02:00
parent 77cb2d403b
commit f08c18a5ed
3 changed files with 26 additions and 2 deletions

View File

@ -45,6 +45,9 @@ audio {
nickname = "Computer" nickname = "Computer"
# Audio device name for local audio output # Audio device name for local audio output
# card = "default" # card = "default"
# Mixer channel to use for volume control - ALSA/Linux only
# If not set, PCM will be used if available, otherwise Master.
# mixer = ""
} }
# Airport Express device # Airport Express device

View File

@ -76,6 +76,7 @@ static cfg_opt_t sec_audio[] =
#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) #elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
CFG_STR("card", "/dev/dsp", CFGF_NONE), CFG_STR("card", "/dev/dsp", CFGF_NONE),
#endif #endif
CFG_STR("mixer", NULL, CFGF_NONE),
CFG_END() CFG_END()
}; };

View File

@ -57,6 +57,7 @@ static struct pcm_packet *pcm_pkt_head;
static struct pcm_packet *pcm_pkt_tail; static struct pcm_packet *pcm_pkt_tail;
static char *card_name; static char *card_name;
static char *mixer_name;
static snd_pcm_t *hdl; static snd_pcm_t *hdl;
static snd_mixer_t *mixer_hdl; static snd_mixer_t *mixer_hdl;
static snd_mixer_elem_t *vol_elem; static snd_mixer_elem_t *vol_elem;
@ -412,6 +413,7 @@ mixer_open(void)
snd_mixer_elem_t *elem; snd_mixer_elem_t *elem;
snd_mixer_elem_t *master; snd_mixer_elem_t *master;
snd_mixer_elem_t *pcm; snd_mixer_elem_t *pcm;
snd_mixer_elem_t *custom;
snd_mixer_selem_id_t *sid; snd_mixer_selem_id_t *sid;
int ret; int ret;
@ -453,17 +455,34 @@ mixer_open(void)
pcm = NULL; pcm = NULL;
master = NULL; master = NULL;
custom = NULL;
for (elem = snd_mixer_first_elem(mixer_hdl); elem; elem = snd_mixer_elem_next(elem)) for (elem = snd_mixer_first_elem(mixer_hdl); elem; elem = snd_mixer_elem_next(elem))
{ {
snd_mixer_selem_get_id(elem, sid); snd_mixer_selem_get_id(elem, sid);
if (strcmp(snd_mixer_selem_id_get_name(sid), "PCM") == 0) if (mixer_name && (strcmp(snd_mixer_selem_id_get_name(sid), mixer_name) == 0))
{
custom = elem;
break;
}
else if (strcmp(snd_mixer_selem_id_get_name(sid), "PCM") == 0)
pcm = elem; pcm = elem;
else if (strcmp(snd_mixer_selem_id_get_name(sid), "Master") == 0) else if (strcmp(snd_mixer_selem_id_get_name(sid), "Master") == 0)
master = elem; master = elem;
} }
if (pcm) if (mixer_name)
{
if (custom)
vol_elem = custom;
else
{
DPRINTF(E_LOG, L_LAUDIO, "Failed to open configured mixer element '%s'\n", mixer_name);
goto out_detach;
}
}
else if (pcm)
vol_elem = pcm; vol_elem = pcm;
else if (master) else if (master)
vol_elem = master; vol_elem = master;
@ -652,6 +671,7 @@ laudio_init(laudio_status_cb cb)
status_cb = cb; status_cb = cb;
card_name = cfg_getstr(cfg_getsec(cfg, "audio"), "card"); card_name = cfg_getstr(cfg_getsec(cfg, "audio"), "card");
mixer_name = cfg_getstr(cfg_getsec(cfg, "audio"), "mixer");
hdl = NULL; hdl = NULL;
mixer_hdl = NULL; mixer_hdl = NULL;