diff options
| author | Lennart Poettering <lennart@poettering.net> | 2007-11-13 17:37:44 +0000 | 
|---|---|---|
| committer | Lennart Poettering <lennart@poettering.net> | 2007-11-13 17:37:44 +0000 | 
| commit | d17bb53d3ebfbd7046719400264bd87830c140d8 (patch) | |
| tree | 1109700c79559f391d0edfb2f9db82252f5010f4 /src/modules/module-alsa-source.c | |
| parent | f7528825257d5d4b056268da3c82181f520a8ff6 (diff) | |
Completely rework ALSA device selection code: choose the device to open depending on the requested number of channels and channel map. In most cases it will now suffice to set default-channels=6 to enable 5.1 sound for all devices that support it
git-svn-id: file:///home/lennart/svn/public/pulseaudio/trunk@2050 fefdeb5f-60dc-0310-8127-8f9354f1896f
Diffstat (limited to 'src/modules/module-alsa-source.c')
| -rw-r--r-- | src/modules/module-alsa-source.c | 69 | 
1 files changed, 30 insertions, 39 deletions
diff --git a/src/modules/module-alsa-source.c b/src/modules/module-alsa-source.c index 1a6113a7..2d2bfa07 100644 --- a/src/modules/module-alsa-source.c +++ b/src/modules/module-alsa-source.c @@ -58,6 +58,7 @@ PA_MODULE_LOAD_ONCE(FALSE);  PA_MODULE_USAGE(          "source_name=<name for the source> "          "device=<ALSA device> " +        "device_id=<ALSA device id> "          "format=<sample format> "          "channels=<number of channels> "          "rate=<sample rate> " @@ -89,13 +90,14 @@ struct userdata {      char *device_name; -    int use_mmap; +    pa_bool_t use_mmap;      pa_rtpoll_item *alsa_rtpoll_item;  };  static const char* const valid_modargs[] = {      "device", +    "device_id",      "source_name",      "channels",      "rate", @@ -342,7 +344,8 @@ static int suspend(struct userdata *u) {  static int unsuspend(struct userdata *u) {      pa_sample_spec ss; -    int err, b; +    int err; +    pa_bool_t b;      unsigned nfrags;      snd_pcm_uframes_t period_size; @@ -362,7 +365,7 @@ static int unsuspend(struct userdata *u) {      period_size = u->fragment_size / u->frame_size;      b = u->use_mmap; -    if ((err = pa_alsa_set_hw_params(u->pcm_handle, &ss, &nfrags, &period_size, &b)) < 0) { +    if ((err = pa_alsa_set_hw_params(u->pcm_handle, &ss, &nfrags, &period_size, &b, TRUE)) < 0) {          pa_log("Failed to set hardware parameters: %s", snd_strerror(err));          goto fail;      } @@ -691,10 +694,10 @@ int pa__init(pa_module*m) {      pa_modargs *ma = NULL;      struct userdata *u = NULL; -    char *dev; +    const char *dev_id;      pa_sample_spec ss;      pa_channel_map map; -    unsigned nfrags, frag_size; +    uint32_t nfrags, frag_size;      snd_pcm_uframes_t period_size;      size_t frame_size;      snd_pcm_info_t *pcm_info = NULL; @@ -703,7 +706,7 @@ int pa__init(pa_module*m) {      const char *name;      char *name_buf = NULL;      int namereg_fail; -    int use_mmap = 1, b; +    pa_bool_t use_mmap = TRUE, b;      snd_pcm_info_alloca(&pcm_info); @@ -750,43 +753,31 @@ int pa__init(pa_module*m) {      snd_config_update_free_global(); -    dev = pa_xstrdup(pa_modargs_get_value(ma, "device", DEFAULT_DEVICE)); - -    for (;;) { +    if ((dev_id = pa_modargs_get_value(ma, "device_id", NULL))) { -        if ((err = snd_pcm_open(&u->pcm_handle, dev, SND_PCM_STREAM_CAPTURE, SND_PCM_NONBLOCK)) < 0) { -            pa_log("Error opening PCM device %s: %s", dev, snd_strerror(err)); -            pa_xfree(dev); +        if (!(u->pcm_handle = pa_alsa_open_by_device_id( +                      dev_id, +                      &u->device_name, +                      &ss, &map, +                      SND_PCM_STREAM_CAPTURE, +                      &nfrags, &period_size, +                      &b)))              goto fail; -        } - -        b = use_mmap; -        if ((err = pa_alsa_set_hw_params(u->pcm_handle, &ss, &nfrags, &period_size, &b)) < 0) { - -            if (err == -EPERM) { -                /* Hmm, some hw is very exotic, so we retry with plughw, if hw didn't work */ -                if (pa_startswith(dev, "hw:")) { -                    char *d = pa_sprintf_malloc("plughw:%s", dev+3); -                    pa_log_debug("Opening the device as '%s' didn't work, retrying with '%s'.", dev, d); -                    pa_xfree(dev); -                    dev = d; +    } else { -                    snd_pcm_close(u->pcm_handle); -                    u->pcm_handle = NULL; -                    continue; -                } -            } - -            pa_log("Failed to set hardware parameters: %s", snd_strerror(err)); -            pa_xfree(dev); +        if (!(u->pcm_handle = pa_alsa_open_by_device_string( +                      pa_modargs_get_value(ma, "device", DEFAULT_DEVICE), +                      &u->device_name, +                      &ss, &map, +                      SND_PCM_STREAM_CAPTURE, +                      &nfrags, &period_size, +                      &b)))              goto fail; -        } - -        break;      } -    u->device_name = dev; +    pa_assert(u->device_name); +    pa_log_info("Successfully opened device %s.", u->device_name);      if (use_mmap && !b) {          pa_log_info("Device doesn't support mmap(), falling back to UNIX read/write mode."); @@ -817,7 +808,7 @@ int pa__init(pa_module*m) {          pa_log("Error opening mixer: %s", snd_strerror(err));      else { -        if ((pa_alsa_prepare_mixer(u->mixer_handle, dev) < 0) || +        if ((pa_alsa_prepare_mixer(u->mixer_handle, u->device_name) < 0) ||              !(u->mixer_elem = pa_alsa_find_elem(u->mixer_handle, "Capture", NULL))) {              snd_mixer_close(u->mixer_handle);              u->mixer_handle = NULL; @@ -827,7 +818,7 @@ int pa__init(pa_module*m) {      if ((name = pa_modargs_get_value(ma, "source_name", NULL)))          namereg_fail = 1;      else { -        name = name_buf = pa_sprintf_malloc("alsa_input.%s", dev); +        name = name_buf = pa_sprintf_malloc("alsa_input.%s", u->device_name);          namereg_fail = 0;      } @@ -847,7 +838,7 @@ int pa__init(pa_module*m) {      pa_source_set_rtpoll(u->source, u->rtpoll);      pa_source_set_description(u->source, t = pa_sprintf_malloc(                                        "ALSA PCM on %s (%s)%s", -                                      dev, +                                      u->device_name,                                        snd_pcm_info_get_name(pcm_info),                                        use_mmap ? " via DMA" : ""));      pa_xfree(t);  | 
