From ff1820f1ad1496ccb60f6ecce048f6a474ceba79 Mon Sep 17 00:00:00 2001 From: Jaroslav Kysela Date: Mon, 23 Jul 2001 13:07:47 +0000 Subject: [PATCH] Added snd_mixer_selem_is_active function. Changed behaviour for CTL_SINGLE. Function snd_mixer_handle_events is no longer called from simple mixer code. --- include/mixer.h | 1 + src/mixer/simple.c | 108 +++++++++++++++++++++++---------------------- 2 files changed, 57 insertions(+), 52 deletions(-) diff --git a/include/mixer.h b/include/mixer.h index aa9785e2..d9b18b3c 100644 --- a/include/mixer.h +++ b/include/mixer.h @@ -129,6 +129,7 @@ unsigned int snd_mixer_selem_get_index(snd_mixer_elem_t *elem); snd_mixer_elem_t *snd_mixer_find_selem(snd_mixer_t *mixer, const snd_mixer_selem_id_t *id); +int snd_mixer_selem_is_active(snd_mixer_elem_t *elem); int snd_mixer_selem_is_playback_mono(snd_mixer_elem_t *elem); int snd_mixer_selem_has_playback_channel(snd_mixer_elem_t *obj, snd_mixer_selem_channel_id_t channel); int snd_mixer_selem_is_capture_mono(snd_mixer_elem_t *elem); diff --git a/src/mixer/simple.c b/src/mixer/simple.c index 727da83e..68b82d0b 100644 --- a/src/mixer/simple.c +++ b/src/mixer/simple.c @@ -75,6 +75,7 @@ typedef enum _selem_ctl_type { typedef struct _selem_ctl { snd_hctl_elem_t *elem; snd_ctl_elem_type_t type; + unsigned int access; unsigned int values; long min, max; } selem_ctl_t; @@ -524,13 +525,13 @@ static int simple_update(snd_mixer_elem_t *melem) simple = melem->private_data; ctl = &simple->ctls[CTL_SINGLE]; if (ctl->elem) { - pchannels = ctl->values; + pchannels = cchannels = ctl->values; if (ctl->type == SNDRV_CTL_ELEM_TYPE_INTEGER) { - caps |= CAP_GVOLUME | CAP_PVOLUME; - pmin = ctl->min; - pmax = ctl->max; + caps |= CAP_GVOLUME; + pmin = cmin = ctl->min; + pmax = cmax = ctl->max; } else - caps |= CAP_GSWITCH | CAP_PSWITCH; + caps |= CAP_GSWITCH; } ctl = &simple->ctls[CTL_GLOBAL_SWITCH]; if (ctl->elem) { @@ -538,7 +539,7 @@ static int simple_update(snd_mixer_elem_t *melem) pchannels = ctl->values; if (cchannels < ctl->values) cchannels = ctl->values; - caps |= CAP_GSWITCH | CAP_PSWITCH; + caps |= CAP_GSWITCH; } ctl = &simple->ctls[CTL_GLOBAL_ROUTE]; if (ctl->elem) { @@ -546,7 +547,7 @@ static int simple_update(snd_mixer_elem_t *melem) pchannels = ctl->values; if (cchannels < ctl->values) cchannels = ctl->values; - caps |= CAP_GSWITCH | CAP_PSWITCH; + caps |= CAP_GSWITCH; } ctl = &simple->ctls[CTL_GLOBAL_VOLUME]; if (ctl->elem) { @@ -562,19 +563,21 @@ static int simple_update(snd_mixer_elem_t *melem) cmin = ctl->min; if (cmax < ctl->max) cmax = ctl->max; - caps |= CAP_GVOLUME | CAP_PVOLUME; + caps |= CAP_GVOLUME; } ctl = &simple->ctls[CTL_PLAYBACK_SWITCH]; if (ctl->elem) { if (pchannels < ctl->values) pchannels = ctl->values; caps |= CAP_PSWITCH; + caps &= ~CAP_GSWITCH; } ctl = &simple->ctls[CTL_PLAYBACK_ROUTE]; if (ctl->elem) { if (pchannels < ctl->values) pchannels = ctl->values; caps |= CAP_PSWITCH; + caps &= ~CAP_GSWITCH; } ctl = &simple->ctls[CTL_CAPTURE_SWITCH]; if (ctl->elem) { @@ -599,6 +602,7 @@ static int simple_update(snd_mixer_elem_t *melem) if (pmax < ctl->max) pmax = ctl->max; caps |= CAP_PVOLUME; + caps &= ~CAP_GVOLUME; } ctl = &simple->ctls[CTL_CAPTURE_VOLUME]; if (ctl->elem) { @@ -622,9 +626,9 @@ static int simple_update(snd_mixer_elem_t *melem) pchannels = 32; if (cchannels > 32) cchannels = 32; - if (caps & CAP_PSWITCH) + if (caps & (CAP_GSWITCH|CAP_PSWITCH)) caps |= CAP_PSWITCH_JOIN | CAP_PVOLUME_JOIN; - if (caps & CAP_CSWITCH) + if (caps & (CAP_GSWITCH|CAP_CSWITCH)) caps |= CAP_CSWITCH_JOIN | CAP_PVOLUME_JOIN; if (pchannels > 1 || cchannels > 1) { if (simple->ctls[CTL_SINGLE].elem && @@ -637,11 +641,11 @@ static int simple_update(snd_mixer_elem_t *melem) if (simple->ctls[CTL_GLOBAL_ROUTE].elem || (simple->ctls[CTL_GLOBAL_SWITCH].elem && simple->ctls[CTL_GLOBAL_SWITCH].values > 1)) { - caps &= ~CAP_PSWITCH_JOIN; + caps &= ~(CAP_PSWITCH_JOIN|CAP_CSWITCH_JOIN); } if (simple->ctls[CTL_GLOBAL_VOLUME].elem && simple->ctls[CTL_GLOBAL_VOLUME].values > 1) { - caps &= ~CAP_PVOLUME_JOIN; + caps &= ~(CAP_PVOLUME_JOIN|CAP_CVOLUME_JOIN); } } if (pchannels > 1) { @@ -799,6 +803,7 @@ static int simple_add1(snd_mixer_class_t *class, const char *name, assert(!simple->ctls[type].elem); simple->ctls[type].elem = helem; simple->ctls[type].type = info.type; + simple->ctls[type].access = info.access; simple->ctls[type].values = info.count; simple->ctls[type].min = info.value.integer.min; simple->ctls[type].max = info.value.integer.max; @@ -890,13 +895,6 @@ static int simple_event_remove(snd_hctl_elem_t *helem, return snd_mixer_elem_info(melem); } -static int simple_event_info(snd_mixer_elem_t *melem) -{ - int err = simple_update(melem); - assert(err >= 0); - return snd_mixer_elem_info(melem); -} - static int simple_event(snd_mixer_class_t *class, unsigned int mask, snd_hctl_elem_t *helem, snd_mixer_elem_t *melem) { @@ -909,9 +907,13 @@ static int simple_event(snd_mixer_class_t *class, unsigned int mask, return err; } if (mask & SND_CTL_EVENT_MASK_INFO) { - err = simple_event_info(melem); + err = simple_event_remove(helem, melem); + if (err < 0) + return err; + err = simple_event_add(class, helem); if (err < 0) return err; + return 0; } if (mask & SND_CTL_EVENT_MASK_VALUE) { err = selem_read(melem); @@ -1148,6 +1150,24 @@ const char *snd_mixer_selem_channel_name(snd_mixer_selem_channel_id_t channel) return p; } +/** + * \brief Get info about the active state of a mixer simple element + * \param elem Mixer simple element handle + * \return 0 if not active, 1 if active + */ +int snd_mixer_selem_is_active(snd_mixer_elem_t *elem) +{ + selem_t *s; + selem_ctl_type_t ctl; + assert(elem); + assert(elem->type == SND_MIXER_ELEM_SIMPLE); + s = elem->private_data; + for (ctl = CTL_SINGLE; ctl <= CTL_LAST; ctl++) + if (s->ctls[ctl].elem != NULL && (s->ctls[ctl].access & SNDRV_CTL_ELEM_ACCESS_INACTIVE) != 0) + return 0; + return 1; +} + /** * \brief Get info about channels of playback stream of a mixer simple element * \param elem Mixer simple element handle @@ -1224,7 +1244,7 @@ int snd_mixer_selem_has_playback_volume(snd_mixer_elem_t *elem) assert(elem); assert(elem->type == SND_MIXER_ELEM_SIMPLE); s = elem->private_data; - return !!(s->caps & CAP_PVOLUME); + return !!(s->caps & CAP_PVOLUME) || !!(s->caps & CAP_GVOLUME); } /** @@ -1252,7 +1272,7 @@ int snd_mixer_selem_has_playback_switch(snd_mixer_elem_t *elem) assert(elem); assert(elem->type == SND_MIXER_ELEM_SIMPLE); s = elem->private_data; - return !!(s->caps & CAP_PSWITCH); + return !!(s->caps & CAP_PSWITCH) && !!(s->caps & CAP_GSWITCH); } /** @@ -1278,16 +1298,12 @@ int snd_mixer_selem_has_playback_switch_joined(snd_mixer_elem_t *elem) */ int snd_mixer_selem_get_playback_volume(snd_mixer_elem_t *elem, snd_mixer_selem_channel_id_t channel, long *value) { - int err; selem_t *s; assert(elem); assert(elem->type == SND_MIXER_ELEM_SIMPLE); s = elem->private_data; assert((unsigned int) channel < s->str[PLAY].channels); - assert(s->caps & CAP_PVOLUME); - err = snd_mixer_handle_events(elem->class->mixer); - if (err < 0) - return err; + assert(s->caps & (CAP_PVOLUME|CAP_GVOLUME)); if (s->caps & CAP_PVOLUME_JOIN) channel = 0; *value = s->str[PLAY].vol[channel]; @@ -1303,16 +1319,12 @@ int snd_mixer_selem_get_playback_volume(snd_mixer_elem_t *elem, snd_mixer_selem_ */ int snd_mixer_selem_get_playback_switch(snd_mixer_elem_t *elem, snd_mixer_selem_channel_id_t channel, int *value) { - int err; selem_t *s; assert(elem); assert(elem->type == SND_MIXER_ELEM_SIMPLE); s = elem->private_data; assert((unsigned int) channel < s->str[PLAY].channels); - assert(s->caps & CAP_PSWITCH); - err = snd_mixer_handle_events(elem->class->mixer); - if (err < 0) - return err; + assert(s->caps & (CAP_PSWITCH|CAP_GSWITCH)); if (s->caps & CAP_PSWITCH_JOIN) channel = 0; *value = !!(s->str[PLAY].sw & (1 << channel)); @@ -1333,7 +1345,7 @@ int snd_mixer_selem_set_playback_volume(snd_mixer_elem_t *elem, snd_mixer_selem_ assert(elem); assert(elem->type == SND_MIXER_ELEM_SIMPLE); s = elem->private_data; - assert(s->caps & CAP_PVOLUME); + assert(s->caps & (CAP_GVOLUME|CAP_PVOLUME)); changed = _snd_mixer_selem_set_volume(elem, PLAY, channel, value); if (changed < 0) return changed; @@ -1355,7 +1367,7 @@ int snd_mixer_selem_set_playback_volume_all(snd_mixer_elem_t *elem, long value) assert(elem); assert(elem->type == SND_MIXER_ELEM_SIMPLE); s = elem->private_data; - assert(s->caps & CAP_PVOLUME); + assert(s->caps & (CAP_GVOLUME|CAP_PVOLUME)); changed = _snd_mixer_selem_set_volume_all(elem, PLAY, value); if (changed < 0) return changed; @@ -1378,7 +1390,7 @@ int snd_mixer_selem_set_playback_switch(snd_mixer_elem_t *elem, snd_mixer_selem_ assert(elem); assert(elem->type == SND_MIXER_ELEM_SIMPLE); s = elem->private_data; - assert(s->caps & CAP_PSWITCH); + assert(s->caps & (CAP_GSWITCH|CAP_PSWITCH)); changed = _snd_mixer_selem_set_switch(elem, PLAY, channel, value); if (changed < 0) return changed; @@ -1400,7 +1412,7 @@ int snd_mixer_selem_set_playback_switch_all(snd_mixer_elem_t *elem, int value) assert(elem); assert(elem->type == SND_MIXER_ELEM_SIMPLE); s = elem->private_data; - assert(s->caps & CAP_PSWITCH); + assert(s->caps & (CAP_GSWITCH|CAP_PSWITCH)); changed = _snd_mixer_selem_set_switch_all(elem, PLAY, value); if (changed < 0) return changed; @@ -1485,7 +1497,7 @@ int snd_mixer_selem_has_capture_volume(snd_mixer_elem_t *elem) assert(elem); assert(elem->type == SND_MIXER_ELEM_SIMPLE); s = elem->private_data; - return !!(s->caps & CAP_CVOLUME); + return !!(s->caps & CAP_CVOLUME) || !!(s->caps & CAP_GVOLUME); } /** @@ -1513,7 +1525,7 @@ int snd_mixer_selem_has_capture_switch(snd_mixer_elem_t *elem) assert(elem); assert(elem->type == SND_MIXER_ELEM_SIMPLE); s = elem->private_data; - return !!(s->caps & CAP_CSWITCH); + return !!(s->caps & CAP_CSWITCH) || !!(s->caps & CAP_GSWITCH); } /** @@ -1568,16 +1580,12 @@ int snd_mixer_selem_get_capture_group(snd_mixer_elem_t *elem) */ int snd_mixer_selem_get_capture_volume(snd_mixer_elem_t *elem, snd_mixer_selem_channel_id_t channel, long *value) { - int err; selem_t *s; assert(elem); assert(elem->type == SND_MIXER_ELEM_SIMPLE); s = elem->private_data; assert((unsigned int) channel < s->str[CAPT].channels); - assert(s->caps & CAP_CVOLUME); - err = snd_mixer_handle_events(elem->class->mixer); - if (err < 0) - return err; + assert(s->caps & (CAP_GVOLUME|CAP_CVOLUME)); if (s->caps & CAP_CVOLUME_JOIN) channel = 0; *value = s->str[CAPT].vol[channel]; @@ -1593,16 +1601,12 @@ int snd_mixer_selem_get_capture_volume(snd_mixer_elem_t *elem, snd_mixer_selem_c */ int snd_mixer_selem_get_capture_switch(snd_mixer_elem_t *elem, snd_mixer_selem_channel_id_t channel, int *value) { - int err; selem_t *s; assert(elem); assert(elem->type == SND_MIXER_ELEM_SIMPLE); s = elem->private_data; assert((unsigned int) channel < s->str[CAPT].channels); - assert(s->caps & CAP_CSWITCH); - err = snd_mixer_handle_events(elem->class->mixer); - if (err < 0) - return err; + assert(s->caps & (CAP_GSWITCH | CAP_CSWITCH)); if (s->caps & CAP_CSWITCH_JOIN) channel = 0; *value = !!(s->str[CAPT].sw & (1 << channel)); @@ -1623,7 +1627,7 @@ int snd_mixer_selem_set_capture_volume(snd_mixer_elem_t *elem, snd_mixer_selem_c assert(elem); assert(elem->type == SND_MIXER_ELEM_SIMPLE); s = elem->private_data; - assert(s->caps & CAP_CVOLUME); + assert(s->caps & (CAP_GVOLUME | CAP_CVOLUME)); changed = _snd_mixer_selem_set_volume(elem, CAPT, channel, value); if (changed < 0) return changed; @@ -1645,7 +1649,7 @@ int snd_mixer_selem_set_capture_volume_all(snd_mixer_elem_t *elem, long value) assert(elem); assert(elem->type == SND_MIXER_ELEM_SIMPLE); s = elem->private_data; - assert(s->caps & CAP_CVOLUME); + assert(s->caps & (CAP_GVOLUME | CAP_CVOLUME)); changed = _snd_mixer_selem_set_volume_all(elem, CAPT, value); if (changed < 0) return changed; @@ -1668,7 +1672,7 @@ int snd_mixer_selem_set_capture_switch(snd_mixer_elem_t *elem, snd_mixer_selem_c assert(elem); assert(elem->type == SND_MIXER_ELEM_SIMPLE); s = elem->private_data; - assert(s->caps & CAP_CSWITCH); + assert(s->caps & (CAP_GSWITCH | CAP_CSWITCH)); changed = _snd_mixer_selem_set_switch(elem, CAPT, channel, value); if (changed < 0) return changed; @@ -1690,7 +1694,7 @@ int snd_mixer_selem_set_capture_switch_all(snd_mixer_elem_t *elem, int value) assert(elem); assert(elem->type == SND_MIXER_ELEM_SIMPLE); s = elem->private_data; - assert(s->caps & CAP_CSWITCH); + assert(s->caps & (CAP_GSWITCH | CAP_CSWITCH)); changed = _snd_mixer_selem_set_switch_all(elem, CAPT, value); if (changed < 0) return changed; -- 2.47.3