MixerElem *lamixer_volelem_new(snd_mixer_elem_t *elem) { MixerElem *mixer_elem; guint voltype=0, elemidx=0, mono; long minrange=0,maxrange=0,rangevalue_left=0,rangevalue_right=0; const char* selem_name = NULL; char elem_name[64]; mixer_elem = g_malloc(sizeof(MixerElem)); mixer_elem->elem = elem; mixer_elem->playback = NULL; mixer_elem->capture = NULL; mixer_elem->pswitch = NULL; mixer_elem->cswitch = NULL; mixer_elem->penum = NULL; mixer_elem->cenum = NULL; elemidx = snd_mixer_selem_get_index(elem); selem_name = snd_mixer_selem_id_get_name(sid); strcpy(elem_name, selem_name); if(elemidx > 0) { sprintf(elem_name,"%s %i",elem_name, elemidx); } if (!snd_mixer_selem_is_enumerated(elem)) { if (snd_mixer_selem_has_playback_volume(elem)) { voltype = 1; snd_mixer_selem_get_playback_volume_range (elem, &minrange, &maxrange); mono = snd_mixer_selem_is_playback_mono(elem); snd_mixer_selem_get_playback_volume (elem, SND_MIXER_SCHN_FRONT_LEFT, &rangevalue_left); if(!mono) snd_mixer_selem_get_playback_volume (elem, SND_MIXER_SCHN_FRONT_RIGHT, &rangevalue_right); mixer_elem->playback = lamixer_volbox_new(elem_name,mono, \ (snd_mixer_selem_has_playback_switch(elem) || snd_mixer_selem_has_playback_switch_joined(elem)), minrange, maxrange, elem, voltype); } else if (snd_mixer_selem_has_playback_switch(elem)) { voltype = 1; mixer_elem->pswitch = lamixer_switchbox_add(elem_name, elem, voltype); } if (snd_mixer_selem_has_capture_volume(elem)) { voltype = 2; snd_mixer_selem_get_capture_volume_range (elem, &minrange, &maxrange); mono = snd_mixer_selem_is_capture_mono(elem); snd_mixer_selem_get_capture_volume (elem, SND_MIXER_SCHN_FRONT_LEFT, &rangevalue_left); if(!mono) snd_mixer_selem_get_capture_volume (elem, SND_MIXER_SCHN_FRONT_RIGHT, &rangevalue_right); mixer_elem->capture = lamixer_volbox_new(elem_name,mono, \ (snd_mixer_selem_has_capture_switch(elem) || snd_mixer_selem_has_capture_switch_joined(elem)), minrange, maxrange, elem, voltype); } else if (snd_mixer_selem_has_capture_switch(elem)) { voltype = 2; mixer_elem->cswitch = lamixer_switchbox_add(elem_name, elem, voltype); } } else { if (snd_mixer_selem_is_enum_playback(elem)) { voltype = 1; mixer_elem->penum = lamixer_enumbox_add(elem_name, elem, voltype); } else if (snd_mixer_selem_is_enum_capture(elem)) { voltype = 2; mixer_elem->cenum = lamixer_enumbox_add(elem_name, elem, voltype); } } return mixer_elem; }
static bool alsa_mixer_open(struct mixer *data, GError **error_r) { struct alsa_mixer *am = (struct alsa_mixer *)data; int err; snd_mixer_elem_t *elem; am->volume_set = -1; err = snd_mixer_open(&am->handle, 0); if (err < 0) { g_set_error(error_r, alsa_mixer_quark(), err, "snd_mixer_open() failed: %s", snd_strerror(err)); return false; } if ((err = snd_mixer_attach(am->handle, am->device)) < 0) { alsa_mixer_close(data); g_set_error(error_r, alsa_mixer_quark(), err, "failed to attach to %s: %s", am->device, snd_strerror(err)); return false; } if ((err = snd_mixer_selem_register(am->handle, NULL, NULL)) < 0) { alsa_mixer_close(data); g_set_error(error_r, alsa_mixer_quark(), err, "snd_mixer_selem_register() failed: %s", snd_strerror(err)); return false; } if ((err = snd_mixer_load(am->handle)) < 0) { alsa_mixer_close(data); g_set_error(error_r, alsa_mixer_quark(), err, "snd_mixer_load() failed: %s\n", snd_strerror(err)); return false; } elem = snd_mixer_first_elem(am->handle); while (elem) { if (snd_mixer_elem_get_type(elem) == SND_MIXER_ELEM_SIMPLE) { if ((g_ascii_strcasecmp(am->control, snd_mixer_selem_get_name(elem)) == 0) && (am->index == snd_mixer_selem_get_index(elem))) { break; } } elem = snd_mixer_elem_next(elem); } if (elem) { am->elem = elem; snd_mixer_selem_get_playback_volume_range(am->elem, &am->volume_min, &am->volume_max); return true; } alsa_mixer_close(data); g_set_error(error_r, alsa_mixer_quark(), 0, "no such mixer control: %s", am->control); return false; }