-static int prepare_mixer(snd_mixer_t *mixer, const char *dev) {
- int err;
-
- pa_assert(mixer);
- pa_assert(dev);
-
- if ((err = snd_mixer_attach(mixer, dev)) < 0) {
- pa_log_info("Unable to attach to mixer %s: %s", dev, pa_alsa_strerror(err));
- return -1;
- }
-
- if ((err = snd_mixer_selem_register(mixer, NULL, NULL)) < 0) {
- pa_log_warn("Unable to register mixer: %s", pa_alsa_strerror(err));
- return -1;
- }
-
- if ((err = snd_mixer_load(mixer)) < 0) {
- pa_log_warn("Unable to load mixer: %s", pa_alsa_strerror(err));
- return -1;
- }
-
- pa_log_info("Successfully attached to mixer '%s'", dev);
- return 0;
-}
-
-snd_mixer_t *pa_alsa_open_mixer_for_pcm(snd_pcm_t *pcm, char **ctl_device) {
- int err;
- snd_mixer_t *m;
- const char *dev;
- snd_pcm_info_t* info;
- snd_pcm_info_alloca(&info);
-
- pa_assert(pcm);
-
- if ((err = snd_mixer_open(&m, 0)) < 0) {
- pa_log("Error opening mixer: %s", pa_alsa_strerror(err));
- return NULL;
- }
-
- /* First, try by name */
- if ((dev = snd_pcm_name(pcm)))
- if (prepare_mixer(m, dev) >= 0) {
- if (ctl_device)
- *ctl_device = pa_xstrdup(dev);
-
- return m;
- }
-
- /* Then, try by card index */
- if (snd_pcm_info(pcm, info) >= 0) {
- char *md;
- int card_idx;
-
- if ((card_idx = snd_pcm_info_get_card(info)) >= 0) {
-
- md = pa_sprintf_malloc("hw:%i", card_idx);
-
- if (!dev || !pa_streq(dev, md))
- if (prepare_mixer(m, md) >= 0) {
-
- if (ctl_device)
- *ctl_device = md;
- else
- pa_xfree(md);
-
- return m;
- }
-
- pa_xfree(md);
- }
- }
-
- snd_mixer_close(m);
- return NULL;
-}
-