Mixer behaviour fixes

This commit is contained in:
Jaroslav Kysela 2001-07-26 10:52:42 +00:00
parent 78156e8f16
commit 5b41fff0be

View file

@ -297,11 +297,11 @@ static int selem_read(snd_mixer_elem_t *elem)
memcpy(pvol, s->str[PLAY].vol, sizeof(pvol)); memcpy(pvol, s->str[PLAY].vol, sizeof(pvol));
memset(&s->str[PLAY].vol, 0, sizeof(s->str[PLAY].vol)); memset(&s->str[PLAY].vol, 0, sizeof(s->str[PLAY].vol));
psw = s->str[PLAY].sw; psw = s->str[PLAY].sw;
s->str[PLAY].sw = 0; s->str[PLAY].sw = ~0U;
memcpy(cvol, s->str[CAPT].vol, sizeof(cvol)); memcpy(cvol, s->str[CAPT].vol, sizeof(cvol));
memset(&s->str[CAPT].vol, 0, sizeof(s->str[CAPT].vol)); memset(&s->str[CAPT].vol, 0, sizeof(s->str[CAPT].vol));
csw = s->str[CAPT].sw; csw = s->str[CAPT].sw;
s->str[CAPT].sw = 0; s->str[CAPT].sw = ~0U;
if (s->ctls[CTL_PLAYBACK_VOLUME].elem) if (s->ctls[CTL_PLAYBACK_VOLUME].elem)
err = elem_read_volume(s, PLAY, CTL_PLAYBACK_VOLUME); err = elem_read_volume(s, PLAY, CTL_PLAYBACK_VOLUME);
@ -313,20 +313,37 @@ static int selem_read(snd_mixer_elem_t *elem)
if (err < 0) if (err < 0)
return err; return err;
s->str[PLAY].sw = ~0; if ((s->caps & (CAP_GSWITCH|CAP_PSWITCH)) == 0) {
if (s->ctls[CTL_PLAYBACK_SWITCH].elem) s->str[CAPT].sw = 0;
goto __skip_pswitch;
}
if (s->ctls[CTL_PLAYBACK_SWITCH].elem) {
err = elem_read_switch(s, PLAY, CTL_PLAYBACK_SWITCH); err = elem_read_switch(s, PLAY, CTL_PLAYBACK_SWITCH);
if (s->ctls[CTL_GLOBAL_SWITCH].elem) if (err < 0)
return err;
}
if (s->ctls[CTL_GLOBAL_SWITCH].elem) {
err = elem_read_switch(s, PLAY, CTL_GLOBAL_SWITCH); err = elem_read_switch(s, PLAY, CTL_GLOBAL_SWITCH);
if (err < 0)
return err;
}
if (s->ctls[CTL_SINGLE].elem && if (s->ctls[CTL_SINGLE].elem &&
s->ctls[CTL_SINGLE].type == SND_CTL_ELEM_TYPE_BOOLEAN) s->ctls[CTL_SINGLE].type == SND_CTL_ELEM_TYPE_BOOLEAN) {
err = elem_read_switch(s, PLAY, CTL_SINGLE); err = elem_read_switch(s, PLAY, CTL_SINGLE);
if (s->ctls[CTL_PLAYBACK_ROUTE].elem) if (err < 0)
return err;
}
if (s->ctls[CTL_PLAYBACK_ROUTE].elem) {
err = elem_read_route(s, PLAY, CTL_PLAYBACK_ROUTE); err = elem_read_route(s, PLAY, CTL_PLAYBACK_ROUTE);
if (s->ctls[CTL_GLOBAL_ROUTE].elem) if (err < 0)
return err;
}
if (s->ctls[CTL_GLOBAL_ROUTE].elem) {
err = elem_read_route(s, PLAY, CTL_GLOBAL_ROUTE); err = elem_read_route(s, PLAY, CTL_GLOBAL_ROUTE);
if (err < 0) if (err < 0)
return err; return err;
}
__skip_pswitch:
if (s->ctls[CTL_CAPTURE_VOLUME].elem) if (s->ctls[CTL_CAPTURE_VOLUME].elem)
err = elem_read_volume(s, CAPT, CTL_CAPTURE_VOLUME); err = elem_read_volume(s, CAPT, CTL_CAPTURE_VOLUME);
@ -338,35 +355,53 @@ static int selem_read(snd_mixer_elem_t *elem)
if (err < 0) if (err < 0)
return err; return err;
s->str[CAPT].sw = ~0; if ((s->caps & (CAP_GSWITCH|CAP_CSWITCH)) == 0) {
if (s->ctls[CTL_CAPTURE_SWITCH].elem) s->str[CAPT].sw = 0;
goto __skip_cswitch;
}
if (s->ctls[CTL_CAPTURE_SWITCH].elem) {
err = elem_read_switch(s, CAPT, CTL_CAPTURE_SWITCH); err = elem_read_switch(s, CAPT, CTL_CAPTURE_SWITCH);
if (s->ctls[CTL_GLOBAL_SWITCH].elem) if (err < 0)
return err;
}
if (s->ctls[CTL_GLOBAL_SWITCH].elem) {
err = elem_read_switch(s, CAPT, CTL_GLOBAL_SWITCH); err = elem_read_switch(s, CAPT, CTL_GLOBAL_SWITCH);
if (err < 0)
return err;
}
if (s->ctls[CTL_SINGLE].elem && if (s->ctls[CTL_SINGLE].elem &&
s->ctls[CTL_SINGLE].type == SND_CTL_ELEM_TYPE_BOOLEAN) s->ctls[CTL_SINGLE].type == SND_CTL_ELEM_TYPE_BOOLEAN) {
err = elem_read_switch(s, CAPT, CTL_SINGLE); err = elem_read_switch(s, CAPT, CTL_SINGLE);
if (s->ctls[CTL_CAPTURE_ROUTE].elem) if (err < 0)
return err;
}
if (s->ctls[CTL_CAPTURE_ROUTE].elem) {
err = elem_read_route(s, CAPT, CTL_CAPTURE_ROUTE); err = elem_read_route(s, CAPT, CTL_CAPTURE_ROUTE);
if (s->ctls[CTL_GLOBAL_ROUTE].elem) if (err < 0)
return err;
}
if (s->ctls[CTL_GLOBAL_ROUTE].elem) {
err = elem_read_route(s, CAPT, CTL_GLOBAL_ROUTE); err = elem_read_route(s, CAPT, CTL_GLOBAL_ROUTE);
if (err < 0)
return err;
}
if (s->ctls[CTL_CAPTURE_SOURCE].elem) { if (s->ctls[CTL_CAPTURE_SOURCE].elem) {
snd_ctl_elem_value_t ctl; snd_ctl_elem_value_t ctl;
selem_ctl_t *c = &s->ctls[CTL_CAPTURE_SOURCE]; selem_ctl_t *c = &s->ctls[CTL_CAPTURE_SOURCE];
memset(&ctl, 0, sizeof(ctl)); memset(&ctl, 0, sizeof(ctl));
err = snd_hctl_elem_read(c->elem, &ctl); err = snd_hctl_elem_read(c->elem, &ctl);
if (err >= 0) { if (err < 0)
for (idx = 0; idx < s->str[CAPT].channels; idx++) { return err;
unsigned int idx1 = idx; for (idx = 0; idx < s->str[CAPT].channels; idx++) {
if (idx >= c->values) unsigned int idx1 = idx;
idx1 = 0; if (idx >= c->values)
if (snd_ctl_elem_value_get_enumerated(&ctl, idx1) == s->capture_item) idx1 = 0;
s->str[CAPT].sw |= 1 << idx; if (snd_ctl_elem_value_get_enumerated(&ctl, idx1) != s->capture_item)
} s->str[CAPT].sw &= ~(1 << idx);
} }
} }
if (err < 0) __skip_cswitch:
return err;
if (memcmp(pvol, s->str[PLAY].vol, sizeof(pvol)) || if (memcmp(pvol, s->str[PLAY].vol, sizeof(pvol)) ||
psw != s->str[PLAY].sw || psw != s->str[PLAY].sw ||
memcmp(cvol, s->str[CAPT].vol, sizeof(cvol)) || memcmp(cvol, s->str[CAPT].vol, sizeof(cvol)) ||
@ -627,9 +662,13 @@ static int simple_update(snd_mixer_elem_t *melem)
if (cchannels > 32) if (cchannels > 32)
cchannels = 32; cchannels = 32;
if (caps & (CAP_GSWITCH|CAP_PSWITCH)) if (caps & (CAP_GSWITCH|CAP_PSWITCH))
caps |= CAP_PSWITCH_JOIN | CAP_PVOLUME_JOIN; caps |= CAP_PSWITCH_JOIN;
if (caps & (CAP_GVOLUME|CAP_PVOLUME))
caps |= CAP_PVOLUME_JOIN;
if (caps & (CAP_GSWITCH|CAP_CSWITCH)) if (caps & (CAP_GSWITCH|CAP_CSWITCH))
caps |= CAP_CSWITCH_JOIN | CAP_PVOLUME_JOIN; caps |= CAP_CSWITCH_JOIN;
if (caps & (CAP_GVOLUME|CAP_CVOLUME))
caps |= CAP_PVOLUME_JOIN;
if (pchannels > 1 || cchannels > 1) { if (pchannels > 1 || cchannels > 1) {
if (simple->ctls[CTL_SINGLE].elem && if (simple->ctls[CTL_SINGLE].elem &&
simple->ctls[CTL_SINGLE].values > 1) { simple->ctls[CTL_SINGLE].values > 1) {
@ -670,6 +709,13 @@ static int simple_update(snd_mixer_elem_t *melem)
caps &= ~CAP_CVOLUME_JOIN; caps &= ~CAP_CVOLUME_JOIN;
} }
} }
/* exceptions */
if ((caps & (CAP_GSWITCH|CAP_PSWITCH|CAP_CSWITCH)) == (caps & CAP_GSWITCH)) {
caps &= ~(CAP_GSWITCH|CAP_CSWITCH_JOIN|CAP_CSWITCH_EXCL);
caps |= CAP_PSWITCH;
}
simple->caps = caps; simple->caps = caps;
simple->str[PLAY].channels = pchannels; simple->str[PLAY].channels = pchannels;
if (!simple->str[PLAY].range) { if (!simple->str[PLAY].range) {