Mercurial > mplayer.hg
comparison libao2/ao_alsa.c @ 37089:86893b300a45
alsa: Better volume control handling, especially for S/PDIF.
If no mixer channel was specified and PCM does not exist, just
pick the first.
If no volume control is available, at least support mute and full
volume switching if a playback switch exists.
This is also useful for being able to unmute S/PDIF devices.
Especially useful since there seem to be several driver/ALSA bugs
that mean these devices often start as muted after every boot.
author | reimar |
---|---|
date | Tue, 06 May 2014 19:02:03 +0000 |
parents | 36820f219892 |
children |
comparison
equal
deleted
inserted
replaced
37088:3a9a804e488b | 37089:86893b300a45 |
---|---|
167 snd_mixer_close(handle); | 167 snd_mixer_close(handle); |
168 return CONTROL_ERROR; | 168 return CONTROL_ERROR; |
169 } | 169 } |
170 | 170 |
171 elem = snd_mixer_find_selem(handle, sid); | 171 elem = snd_mixer_find_selem(handle, sid); |
172 if (!elem && !mixer_channel) { | |
173 // if nothing specified just try picking the first | |
174 elem = snd_mixer_first_elem(handle); | |
175 if (elem) | |
176 mp_msg(MSGT_AO, MSGL_V, "[AO_ALSA] Auto-selected element %s\n", snd_mixer_selem_get_name(elem)); | |
177 } | |
172 if (!elem) { | 178 if (!elem) { |
173 mp_msg(MSGT_AO,MSGL_ERR,MSGTR_AO_ALSA_UnableToFindSimpleControl, | 179 mp_msg(MSGT_AO,MSGL_ERR,MSGTR_AO_ALSA_UnableToFindSimpleControl, |
174 snd_mixer_selem_id_get_name(sid), snd_mixer_selem_id_get_index(sid)); | 180 snd_mixer_selem_id_get_name(sid), snd_mixer_selem_id_get_index(sid)); |
181 mp_msg(MSGT_AO, MSGL_INFO, "[AO_ALSA] Available elements for device:\n"); | |
182 for (elem = snd_mixer_first_elem(handle); elem; elem = snd_mixer_elem_next(elem)) | |
183 mp_msg(MSGT_AO, MSGL_INFO, "[AO_ALSA] %s\n", snd_mixer_selem_get_name(elem)); | |
184 mp_msg(MSGT_AO, MSGL_INFO, "\n"); | |
175 snd_mixer_close(handle); | 185 snd_mixer_close(handle); |
176 return CONTROL_ERROR; | 186 return CONTROL_ERROR; |
177 } | 187 } |
188 | |
189 if (!snd_mixer_selem_has_playback_volume(elem) && | |
190 !snd_mixer_selem_has_playback_volume_joined(elem)) | |
191 { | |
192 if (!snd_mixer_selem_has_playback_switch(elem)) | |
193 return CONTROL_FALSE; | |
194 if (cmd == AOCONTROL_GET_VOLUME) { | |
195 int v; | |
196 snd_mixer_selem_get_playback_switch(elem, SND_MIXER_SCHN_FRONT_LEFT, &v); | |
197 vol->left = v ? 100 : 0; | |
198 snd_mixer_selem_get_playback_switch(elem, SND_MIXER_SCHN_FRONT_RIGHT, &v); | |
199 vol->right = v ? 100 : 0; | |
200 return CONTROL_TRUE; | |
201 } | |
202 // special case: only mute supported | |
203 if (vol->left != 0 && vol->left != 100 || | |
204 vol->right != 0 && vol->right != 100) | |
205 return CONTROL_FALSE; | |
206 if (snd_mixer_selem_has_playback_switch_joined(elem)) { | |
207 if (vol->left != vol->right) | |
208 return CONTROL_FALSE; | |
209 } else { | |
210 snd_mixer_selem_set_playback_switch(elem, SND_MIXER_SCHN_FRONT_RIGHT, vol->right != 0); | |
211 } | |
212 snd_mixer_selem_set_playback_switch(elem, SND_MIXER_SCHN_FRONT_LEFT, vol->left != 0); | |
213 return CONTROL_TRUE; | |
214 } | |
178 | 215 |
179 snd_mixer_selem_get_playback_volume_range(elem,&pmin,&pmax); | 216 snd_mixer_selem_get_playback_volume_range(elem,&pmin,&pmax); |
180 f_multi = (100 / (float)(pmax - pmin)); | 217 f_multi = (100 / (float)(pmax - pmin)); |
181 | 218 |
182 if (cmd == AOCONTROL_SET_VOLUME) { | 219 if (cmd == AOCONTROL_SET_VOLUME) { |