diff options
| author | Lennart Poettering <lennart@poettering.net> | 2009-02-14 00:21:36 +0100 | 
|---|---|---|
| committer | Lennart Poettering <lennart@poettering.net> | 2009-02-14 00:21:36 +0100 | 
| commit | 6790c03f91708540da284c80d0cb72cacf41c83d (patch) | |
| tree | da625b3e5cc69b3d3712a8c488ca2e7348312913 /src/modules | |
| parent | 023998e3c84c3158ab9f02e26949dbcd3e048886 (diff) | |
unify ALSA mixer initialization
Diffstat (limited to 'src/modules')
| -rw-r--r-- | src/modules/alsa/alsa-sink.c | 38 | ||||
| -rw-r--r-- | src/modules/alsa/alsa-source.c | 38 | ||||
| -rw-r--r-- | src/modules/alsa/alsa-util.c | 80 | ||||
| -rw-r--r-- | src/modules/alsa/alsa-util.h | 1 | 
4 files changed, 83 insertions, 74 deletions
| diff --git a/src/modules/alsa/alsa-sink.c b/src/modules/alsa/alsa-sink.c index c56614c8..1474cfee 100644 --- a/src/modules/alsa/alsa-sink.c +++ b/src/modules/alsa/alsa-sink.c @@ -1386,43 +1386,7 @@ pa_sink *pa_alsa_sink_new(pa_module *m, pa_modargs *ma, const char*driver, pa_ca      /* ALSA might tweak the sample spec, so recalculate the frame size */      frame_size = pa_frame_size(&ss); -    if ((err = snd_mixer_open(&u->mixer_handle, 0)) < 0) -        pa_log_warn("Error opening mixer: %s", snd_strerror(err)); -    else { -        pa_bool_t found = FALSE; - -        if (pa_alsa_prepare_mixer(u->mixer_handle, u->device_name) >= 0) -            found = TRUE; -        else { -            snd_pcm_info_t *info; - -            snd_pcm_info_alloca(&info); - -            if (snd_pcm_info(u->pcm_handle, 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 (strcmp(u->device_name, md)) -                        if (pa_alsa_prepare_mixer(u->mixer_handle, md) >= 0) -                            found = TRUE; -                    pa_xfree(md); -                } -            } -        } - -        if (found) -            if (!(u->mixer_elem = pa_alsa_find_elem(u->mixer_handle, "Master", "PCM", TRUE))) -                found = FALSE; - -        if (!found) { -            snd_mixer_close(u->mixer_handle); -            u->mixer_handle = NULL; -        } -    } +    pa_alsa_find_mixer_and_elem(u->pcm_handle, &u->mixer_handle, &u->mixer_elem);      pa_sink_new_data_init(&data);      data.driver = driver; diff --git a/src/modules/alsa/alsa-source.c b/src/modules/alsa/alsa-source.c index 2b42d3f9..192645d0 100644 --- a/src/modules/alsa/alsa-source.c +++ b/src/modules/alsa/alsa-source.c @@ -1211,43 +1211,7 @@ pa_source *pa_alsa_source_new(pa_module *m, pa_modargs *ma, const char*driver, p      /* ALSA might tweak the sample spec, so recalculate the frame size */      frame_size = pa_frame_size(&ss); -    if ((err = snd_mixer_open(&u->mixer_handle, 0)) < 0) -        pa_log("Error opening mixer: %s", snd_strerror(err)); -    else { -        pa_bool_t found = FALSE; - -        if (pa_alsa_prepare_mixer(u->mixer_handle, u->device_name) >= 0) -            found = TRUE; -        else { -            snd_pcm_info_t* info; - -            snd_pcm_info_alloca(&info); - -            if (snd_pcm_info(u->pcm_handle, 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 (strcmp(u->device_name, md)) -                        if (pa_alsa_prepare_mixer(u->mixer_handle, md) >= 0) -                            found = TRUE; -                    pa_xfree(md); -                } -            } -        } - -        if (found) -            if (!(u->mixer_elem = pa_alsa_find_elem(u->mixer_handle, "Capture", "Mic", FALSE))) -                found = FALSE; - -        if (!found) { -            snd_mixer_close(u->mixer_handle); -            u->mixer_handle = NULL; -        } -    } +    pa_alsa_find_mixer_and_elem(u->pcm_handle, &u->mixer_handle, &u->mixer_elem);      pa_source_new_data_init(&data);      data.driver = driver; diff --git a/src/modules/alsa/alsa-util.c b/src/modules/alsa/alsa-util.c index 5236d02f..d7caa0f0 100644 --- a/src/modules/alsa/alsa-util.c +++ b/src/modules/alsa/alsa-util.c @@ -1057,6 +1057,86 @@ success:      return elem;  } + +int pa_alsa_find_mixer_and_elem( +        snd_pcm_t *pcm, +        snd_mixer_t **_m, +        snd_mixer_elem_t **_e) { + +    int err; +    snd_mixer_t *m; +    snd_mixer_elem_t *e; +    pa_bool_t found = FALSE; +    const char *dev; + +    pa_assert(pcm); +    pa_assert(_m); +    pa_assert(_e); + +    if ((err = snd_mixer_open(&m, 0)) < 0) { +        pa_log("Error opening mixer: %s", snd_strerror(err)); +        return -1; +    } + +    /* First, try by name */ +    if ((dev = snd_pcm_name(pcm))) +        if (pa_alsa_prepare_mixer(m, dev) >= 0) +            found = TRUE; + +    /* Then, try by card index */ +    if (!found) { +        snd_pcm_info_t* info; +        snd_pcm_info_alloca(&info); + +        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 (pa_alsa_prepare_mixer(m, md) >= 0) +                        found = TRUE; + +                pa_xfree(md); +            } +        } +    } + +    if (!found) { +        snd_mixer_close(m); +        return -1; +    } + +    switch (snd_pcm_stream(pcm)) { + +        case SND_PCM_STREAM_PLAYBACK: +            e = pa_alsa_find_elem(m, "Master", "PCM", TRUE); +            break; + +        case SND_PCM_STREAM_CAPTURE: +            e = pa_alsa_find_elem(m, "Capture", "Mic", FALSE); +            break; + +        default: +            pa_assert_not_reached(); +    } + +    if (!e) { +        snd_mixer_close(m); +        return -1; +    } + +    pa_assert(e && m); + +    *_m = m; +    *_e = e; + +    return 0; +} +  static const snd_mixer_selem_channel_id_t alsa_channel_ids[PA_CHANNEL_POSITION_MAX] = {      [PA_CHANNEL_POSITION_MONO] = SND_MIXER_SCHN_MONO, /* The ALSA name is just an alias! */ diff --git a/src/modules/alsa/alsa-util.h b/src/modules/alsa/alsa-util.h index 8a209348..8b083392 100644 --- a/src/modules/alsa/alsa-util.h +++ b/src/modules/alsa/alsa-util.h @@ -54,6 +54,7 @@ int pa_alsa_set_sw_params(snd_pcm_t *pcm, snd_pcm_uframes_t avail_min);  int pa_alsa_prepare_mixer(snd_mixer_t *mixer, const char *dev);  snd_mixer_elem_t *pa_alsa_find_elem(snd_mixer_t *mixer, const char *name, const char *fallback, pa_bool_t playback); +int pa_alsa_find_mixer_and_elem(snd_pcm_t *pcm, snd_mixer_t **_m, snd_mixer_elem_t **_e);  typedef struct pa_alsa_profile_info {      pa_channel_map map; | 
