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 | |
| 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')
| -rw-r--r-- | src/modules/alsa-util.c | 252 | ||||
| -rw-r--r-- | src/modules/alsa-util.h | 29 | ||||
| -rw-r--r-- | src/modules/module-alsa-sink.c | 85 | ||||
| -rw-r--r-- | src/modules/module-alsa-source.c | 69 | ||||
| -rw-r--r-- | src/modules/module-bt-proximity.c | 2 | ||||
| -rw-r--r-- | src/modules/module-cli.c | 2 | ||||
| -rw-r--r-- | src/modules/module-detect.c | 3 | ||||
| -rw-r--r-- | src/modules/module-hal-detect.c | 4 | ||||
| -rw-r--r-- | src/modules/module-oss.c | 2 | ||||
| -rw-r--r-- | src/modules/rtp/module-rtp-send.c | 9 | ||||
| -rw-r--r-- | src/pulsecore/modargs.c | 2 | ||||
| -rw-r--r-- | src/pulsecore/modargs.h | 3 | ||||
| -rw-r--r-- | src/pulsecore/protocol-esound.c | 2 | ||||
| -rw-r--r-- | src/pulsecore/protocol-native.c | 4 | ||||
| -rw-r--r-- | src/pulsecore/protocol-simple.c | 4 | 
15 files changed, 350 insertions, 122 deletions
diff --git a/src/modules/alsa-util.c b/src/modules/alsa-util.c index 15ae1fc6..5b74c98c 100644 --- a/src/modules/alsa-util.c +++ b/src/modules/alsa-util.c @@ -34,6 +34,7 @@  #include <pulsecore/log.h>  #include <pulsecore/macro.h> +#include <pulsecore/core-util.h>  #include "alsa-util.h" @@ -284,13 +285,21 @@ try_auto:  /* Set the hardware parameters of the given ALSA device. Returns the   * selected fragment settings in *period and *period_size */ -int pa_alsa_set_hw_params(snd_pcm_t *pcm_handle, pa_sample_spec *ss, uint32_t *periods, snd_pcm_uframes_t *period_size, int *use_mmap) { +int pa_alsa_set_hw_params( +        snd_pcm_t *pcm_handle, +        pa_sample_spec *ss, +        uint32_t *periods, +        snd_pcm_uframes_t *period_size, +        pa_bool_t *use_mmap, +        pa_bool_t require_exact_channel_number) { +      int ret = -1;      snd_pcm_uframes_t buffer_size;      unsigned int r = ss->rate;      unsigned int c = ss->channels;      pa_sample_format_t f = ss->format;      snd_pcm_hw_params_t *hwparams; +    pa_bool_t _use_mmap = use_mmap && *use_mmap;      pa_assert(pcm_handle);      pa_assert(ss); @@ -305,7 +314,7 @@ int pa_alsa_set_hw_params(snd_pcm_t *pcm_handle, pa_sample_spec *ss, uint32_t *p          (ret = snd_pcm_hw_params_set_rate_resample(pcm_handle, hwparams, 0)) < 0)          goto finish; -    if (use_mmap && *use_mmap) { +    if (_use_mmap) {          if ((ret = snd_pcm_hw_params_set_access(pcm_handle, hwparams, SND_PCM_ACCESS_MMAP_INTERLEAVED)) < 0) {              /* mmap() didn't work, fall back to interleaved */ @@ -313,8 +322,7 @@ int pa_alsa_set_hw_params(snd_pcm_t *pcm_handle, pa_sample_spec *ss, uint32_t *p              if ((ret = snd_pcm_hw_params_set_access(pcm_handle, hwparams, SND_PCM_ACCESS_RW_INTERLEAVED)) < 0)                  goto finish; -            if (use_mmap) -                *use_mmap = 0; +            _use_mmap = FALSE;          }      } else if ((ret = snd_pcm_hw_params_set_access(pcm_handle, hwparams, SND_PCM_ACCESS_RW_INTERLEAVED)) < 0) @@ -326,8 +334,13 @@ int pa_alsa_set_hw_params(snd_pcm_t *pcm_handle, pa_sample_spec *ss, uint32_t *p      if ((ret = snd_pcm_hw_params_set_rate_near(pcm_handle, hwparams, &r, NULL)) < 0)          goto finish; -    if ((ret = snd_pcm_hw_params_set_channels_near(pcm_handle, hwparams, &c)) < 0) -        goto finish; +    if (require_exact_channel_number) { +        if ((ret = snd_pcm_hw_params_set_channels(pcm_handle, hwparams, c)) < 0) +            goto finish; +    } else { +        if ((ret = snd_pcm_hw_params_set_channels_near(pcm_handle, hwparams, &c)) < 0) +            goto finish; +    }      if ((*period_size > 0 && (ret = snd_pcm_hw_params_set_period_size_near(pcm_handle, hwparams, period_size, NULL)) < 0) ||          (*periods > 0 && (ret = snd_pcm_hw_params_set_buffer_size_near(pcm_handle, hwparams, &buffer_size)) < 0)) @@ -336,23 +349,14 @@ int pa_alsa_set_hw_params(snd_pcm_t *pcm_handle, pa_sample_spec *ss, uint32_t *p      if  ((ret = snd_pcm_hw_params(pcm_handle, hwparams)) < 0)          goto finish; -    if (ss->rate != r) { +    if (ss->rate != r)          pa_log_warn("Device %s doesn't support %u Hz, changed to %u Hz.", snd_pcm_name(pcm_handle), ss->rate, r); -        /* If the sample rate deviates too much, we need to resample */ -        if (r < ss->rate*.95 || r > ss->rate*1.05) -            ss->rate = r; -    } - -    if (ss->channels != c) { +    if (ss->channels != c)          pa_log_warn("Device %s doesn't support %u channels, changed to %u.", snd_pcm_name(pcm_handle), ss->channels, c); -        ss->channels = c; -    } -    if (ss->format != f) { +    if (ss->format != f)          pa_log_warn("Device %s doesn't support sample format %s, changed to %s.", snd_pcm_name(pcm_handle), pa_sample_format_to_string(ss->format), pa_sample_format_to_string(f)); -        ss->format = f; -    }      if ((ret = snd_pcm_prepare(pcm_handle)) < 0)          goto finish; @@ -361,11 +365,20 @@ int pa_alsa_set_hw_params(snd_pcm_t *pcm_handle, pa_sample_spec *ss, uint32_t *p          (ret = snd_pcm_hw_params_get_period_size(hwparams, period_size, NULL)) < 0)          goto finish; +    /* If the sample rate deviates too much, we need to resample */ +    if (r < ss->rate*.95 || r > ss->rate*1.05) +        ss->rate = r; +    ss->channels = c; +    ss->format = f; +      pa_assert(buffer_size > 0);      pa_assert(*period_size > 0);      *periods = buffer_size / *period_size;      pa_assert(*periods > 0); +    if (use_mmap) +        *use_mmap = _use_mmap; +      ret = 0;  finish: @@ -404,6 +417,209 @@ int pa_alsa_set_sw_params(snd_pcm_t *pcm) {      return 0;  } +struct device_info { +    pa_channel_map map; +    const char *name; +}; + +static const struct device_info device_table[] = { +    {{ 2, { PA_CHANNEL_POSITION_LEFT, PA_CHANNEL_POSITION_RIGHT } }, "front" }, + +    {{ 4, { PA_CHANNEL_POSITION_FRONT_LEFT, PA_CHANNEL_POSITION_FRONT_RIGHT, +            PA_CHANNEL_POSITION_REAR_LEFT, PA_CHANNEL_POSITION_REAR_RIGHT }}, "surround40" }, + +    {{ 5, { PA_CHANNEL_POSITION_FRONT_LEFT, PA_CHANNEL_POSITION_FRONT_RIGHT, +            PA_CHANNEL_POSITION_REAR_LEFT, PA_CHANNEL_POSITION_REAR_RIGHT, +            PA_CHANNEL_POSITION_LFE }}, "surround41" }, + +    {{ 5, { PA_CHANNEL_POSITION_FRONT_LEFT, PA_CHANNEL_POSITION_FRONT_RIGHT, +            PA_CHANNEL_POSITION_REAR_LEFT, PA_CHANNEL_POSITION_REAR_RIGHT, +            PA_CHANNEL_POSITION_CENTER }}, "surround50" }, + +    {{ 6, { PA_CHANNEL_POSITION_FRONT_LEFT, PA_CHANNEL_POSITION_FRONT_RIGHT, +            PA_CHANNEL_POSITION_REAR_LEFT, PA_CHANNEL_POSITION_REAR_RIGHT, +            PA_CHANNEL_POSITION_CENTER, PA_CHANNEL_POSITION_LFE }}, "surround51" }, + +    {{ 8, { PA_CHANNEL_POSITION_FRONT_LEFT, PA_CHANNEL_POSITION_FRONT_RIGHT, +            PA_CHANNEL_POSITION_REAR_LEFT, PA_CHANNEL_POSITION_REAR_RIGHT, +            PA_CHANNEL_POSITION_CENTER, PA_CHANNEL_POSITION_LFE, +            PA_CHANNEL_POSITION_SIDE_LEFT, PA_CHANNEL_POSITION_SIDE_RIGHT }} , "surround71" }, + +    {{ 0, { 0 }}, NULL } +}; + +static pa_bool_t channel_map_superset(const pa_channel_map *a, const pa_channel_map *b) { +    pa_bool_t in_a[PA_CHANNEL_POSITION_MAX]; +    unsigned i; + +    pa_assert(a); +    pa_assert(b); + +    memset(in_a, 0, sizeof(in_a)); + +    for (i = 0; i < a->channels; i++) +        in_a[a->map[i]] = TRUE; + +    for (i = 0; i < b->channels; i++) +        if (!in_a[b->map[i]]) +            return FALSE; + +    return TRUE; +} + +snd_pcm_t *pa_alsa_open_by_device_id( +        const char *dev_id, +        char **dev, +        pa_sample_spec *ss, +        pa_channel_map* map, +        int mode, +        uint32_t *nfrags, +        snd_pcm_uframes_t *period_size, +        pa_bool_t *use_mmap) { + +    int i; +    int direction = 1; +    int err; +    char *d; +    snd_pcm_t *pcm_handle; + +    pa_assert(dev_id); +    pa_assert(dev); +    pa_assert(ss); +    pa_assert(map); +    pa_assert(nfrags); +    pa_assert(period_size); + +    /* First we try to find a device string with a superset of the +     * requested channel map and open it without the plug: prefix. We +     * iterate through our device table from top to bottom and take +     * the first that matches. If we didn't find a working device that +     * way, we iterate backwards, and check all devices that do not +     * provide a superset of the requested channel map.*/ + +    for (i = 0;; i += direction) { +        pa_sample_spec try_ss; + +        if (i < 0) { +            pa_assert(direction == -1); + +            /* OK, so we iterated backwards, and now are at the +             * beginning of our list. */ + +            break; + +        } else if (!device_table[i].name) { +            pa_assert(direction == 1); + +            /* OK, so we are at the end of our list. at iterated +             * forwards. */ + +            i--; +            direction = -1; +        } + +        if ((direction > 0) == !channel_map_superset(&device_table[i].map, map)) +            continue; + +        d = pa_sprintf_malloc("%s:%s", device_table[i].name, dev_id); +        pa_log_debug("Trying %s...", d); + +        if ((err = snd_pcm_open(&pcm_handle, d, mode, SND_PCM_NONBLOCK)) < 0) { +            pa_log_info("Couldn't open PCM device %s: %s", d, snd_strerror(err)); +            pa_xfree(d); +            continue; +        } + +        try_ss.channels = device_table[i].map.channels; +        try_ss.rate = ss->rate; +        try_ss.format = ss->format; + +        if ((err = pa_alsa_set_hw_params(pcm_handle, &try_ss, nfrags, period_size, use_mmap, TRUE)) < 0) { +            pa_log_info("PCM device %s refused our hw parameters: %s", d, snd_strerror(err)); +            pa_xfree(d); +            snd_pcm_close(pcm_handle); +            continue; +        } + +        *ss = try_ss; +        *map = device_table[i].map; +        pa_assert(map->channels == ss->channels); +        *dev = d; +        return pcm_handle; +    } + +    /* OK, we didn't find any good device, so let's try the raw hw: stuff */ + +    d = pa_sprintf_malloc("hw:%s", dev_id); +    pa_log_debug("Trying %s as last resort...", d); +    pcm_handle = pa_alsa_open_by_device_string(d, dev, ss, map, mode, nfrags, period_size, use_mmap); +    pa_xfree(d); + +    return pcm_handle; +} + +snd_pcm_t *pa_alsa_open_by_device_string( +        const char *device, +        char **dev, +        pa_sample_spec *ss, +        pa_channel_map* map, +        int mode, +        uint32_t *nfrags, +        snd_pcm_uframes_t *period_size, +        pa_bool_t *use_mmap) { + +    int err; +    char *d; +    snd_pcm_t *pcm_handle; + +    pa_assert(device); +    pa_assert(dev); +    pa_assert(ss); +    pa_assert(map); +    pa_assert(nfrags); +    pa_assert(period_size); + +    d = pa_xstrdup(device); + +    for (;;) { + +        if ((err = snd_pcm_open(&pcm_handle, d, mode, SND_PCM_NONBLOCK)) < 0) { +            pa_log("Error opening PCM device %s: %s", d, snd_strerror(err)); +            pa_xfree(d); +            return NULL; +        } + +        if ((err = pa_alsa_set_hw_params(pcm_handle, ss, nfrags, period_size, use_mmap, FALSE)) < 0) { + +            if (err == -EPERM) { +                /* Hmm, some hw is very exotic, so we retry with plug, if without it didn't work */ + +                if (pa_startswith(d, "hw:")) { +                    char *t = pa_sprintf_malloc("plughw:%s", d+3); +                    pa_log_debug("Opening the device as '%s' didn't work, retrying with '%s'.", d, t); +                    pa_xfree(d); +                    d = t; + +                    snd_pcm_close(pcm_handle); +                    continue; +                } + +                pa_log("Failed to set hardware parameters on %s: %s", d, snd_strerror(err)); +                pa_xfree(d); +                snd_pcm_close(pcm_handle); +                return NULL; +            } +        } + +        *dev = d; + +        if (ss->channels != map->channels) +            pa_channel_map_init_auto(map, ss->channels, PA_CHANNEL_MAP_ALSA); + +        return pcm_handle; +    } +} +  int pa_alsa_prepare_mixer(snd_mixer_t *mixer, const char *dev) {      int err; diff --git a/src/modules/alsa-util.h b/src/modules/alsa-util.h index 6f1f927e..36720b03 100644 --- a/src/modules/alsa-util.h +++ b/src/modules/alsa-util.h @@ -38,10 +38,37 @@ struct pa_alsa_fdlist *pa_alsa_fdlist_new(void);  void pa_alsa_fdlist_free(struct pa_alsa_fdlist *fdl);  int pa_alsa_fdlist_set_mixer(struct pa_alsa_fdlist *fdl, snd_mixer_t *mixer_handle, pa_mainloop_api* m); -int pa_alsa_set_hw_params(snd_pcm_t *pcm_handle, pa_sample_spec *ss, uint32_t *periods, snd_pcm_uframes_t *period_size, int *use_mmap); +int pa_alsa_set_hw_params( +        snd_pcm_t *pcm_handle, +        pa_sample_spec *ss, +        uint32_t *periods, +        snd_pcm_uframes_t *period_size, +        pa_bool_t *use_mmap, +        pa_bool_t require_exact_channel_number); +  int pa_alsa_set_sw_params(snd_pcm_t *pcm);  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); +snd_pcm_t *pa_alsa_open_by_device_id( +        const char *dev_id, +        char **dev, +        pa_sample_spec *ss, +        pa_channel_map* map, +        int mode, +        uint32_t *nfrags, +        snd_pcm_uframes_t *period_size, +        pa_bool_t *use_mmap); + +snd_pcm_t *pa_alsa_open_by_device_string( +        const char *device, +        char **dev, +        pa_sample_spec *ss, +        pa_channel_map* map, +        int mode, +        uint32_t *nfrags, +        snd_pcm_uframes_t *period_size, +        pa_bool_t *use_mmap); +  #endif diff --git a/src/modules/module-alsa-sink.c b/src/modules/module-alsa-sink.c index 636b413c..e62b8a06 100644 --- a/src/modules/module-alsa-sink.c +++ b/src/modules/module-alsa-sink.c @@ -57,6 +57,7 @@ PA_MODULE_LOAD_ONCE(FALSE);  PA_MODULE_USAGE(          "sink_name=<name for the sink> "          "device=<ALSA device> " +        "device_id=<ALSA device id> "          "format=<sample format> "          "channels=<number of channels> "          "rate=<sample rate> " @@ -89,15 +90,16 @@ struct userdata {      char *device_name; -    int use_mmap; +    pa_bool_t use_mmap; -    int first; +    pa_bool_t first;      pa_rtpoll_item *alsa_rtpoll_item;  };  static const char* const valid_modargs[] = {      "device", +    "device_id",      "sink_name",      "format",      "channels", @@ -127,7 +129,7 @@ static int mmap_write(struct userdata *u) {              if (n == -EPIPE) {                  pa_log_debug("snd_pcm_avail_update: Buffer underrun!"); -                u->first = 1; +                u->first = TRUE;              }              if ((err = snd_pcm_recover(u->pcm_handle, n, 1)) == 0) @@ -151,7 +153,7 @@ static int mmap_write(struct userdata *u) {              if (err == -EPIPE) {                  pa_log_debug("snd_pcm_mmap_begin: Buffer underrun!"); -                u->first = 1; +                u->first = TRUE;              }              if ((err = snd_pcm_recover(u->pcm_handle, err, 1)) == 0) @@ -188,7 +190,7 @@ static int mmap_write(struct userdata *u) {              if (err == -EPIPE) {                  pa_log_debug("snd_pcm_mmap_commit: Buffer underrun!"); -                u->first = 1; +                u->first = TRUE;              }              if ((err = snd_pcm_recover(u->pcm_handle, err, 1)) == 0) @@ -355,7 +357,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; @@ -375,7 +378,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;      } @@ -405,7 +408,7 @@ static int unsuspend(struct userdata *u) {      /* FIXME: We need to reload the volume somehow */ -    u->first = 1; +    u->first = TRUE;      pa_log_info("Resumed successfully..."); @@ -628,7 +631,7 @@ static void thread_func(void *userdata) {              if (work_done && u->first) {                  pa_log_info("Starting playback.");                  snd_pcm_start(u->pcm_handle); -                u->first = 0; +                u->first = FALSE;                  continue;              }          } @@ -709,7 +712,7 @@ 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;      uint32_t nfrags, frag_size; @@ -721,7 +724,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); @@ -761,7 +764,7 @@ int pa__init(pa_module*m) {      u->module = m;      m->userdata = u;      u->use_mmap = use_mmap; -    u->first = 1; +    u->first = TRUE;      pa_thread_mq_init(&u->thread_mq, m->core->mainloop);      u->rtpoll = pa_rtpoll_new();      u->alsa_rtpoll_item = NULL; @@ -769,43 +772,35 @@ int pa__init(pa_module*m) {      snd_config_update_free_global(); -    dev = pa_xstrdup(pa_modargs_get_value(ma, "device", DEFAULT_DEVICE)); - -    for (;;) { - -        if ((err = snd_pcm_open(&u->pcm_handle, dev, SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK)) < 0) { -            pa_log("Error opening PCM device %s: %s", dev, snd_strerror(err)); -            pa_xfree(dev); -            goto fail; -        } +    b = use_mmap; -        b = use_mmap; -        if ((err = pa_alsa_set_hw_params(u->pcm_handle, &ss, &nfrags, &period_size, &b)) < 0) { +    if ((dev_id = pa_modargs_get_value(ma, "device_id", NULL))) { -            if (err == -EPERM) { -                /* Hmm, some hw is very exotic, so we retry with plughw, if hw didn't work */ +        if (!(u->pcm_handle = pa_alsa_open_by_device_id( +                      dev_id, +                      &u->device_name, +                      &ss, &map, +                      SND_PCM_STREAM_PLAYBACK, +                      &nfrags, &period_size, +                      &b))) -                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; +            goto fail; -                    snd_pcm_close(u->pcm_handle); -                    u->pcm_handle = NULL; -                    continue; -                } -            } +    } else { -            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_PLAYBACK, +                      &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."); @@ -828,15 +823,11 @@ int pa__init(pa_module*m) {      /* ALSA might tweak the sample spec, so recalculate the frame size */      frame_size = pa_frame_size(&ss); -    if (ss.channels != map.channels) -        /* Seems ALSA didn't like the channel number, so let's fix the channel map */ -        pa_channel_map_init_auto(&map, ss.channels, PA_CHANNEL_MAP_ALSA); -      if ((err = snd_mixer_open(&u->mixer_handle, 0)) < 0)          pa_log_warn("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, "Master", "PCM"))) {              snd_mixer_close(u->mixer_handle); @@ -847,7 +838,7 @@ int pa__init(pa_module*m) {      if ((name = pa_modargs_get_value(ma, "sink_name", NULL)))          namereg_fail = 1;      else { -        name = name_buf = pa_sprintf_malloc("alsa_output.%s", dev); +        name = name_buf = pa_sprintf_malloc("alsa_output.%s", u->device_name);          namereg_fail = 0;      } @@ -867,7 +858,7 @@ int pa__init(pa_module*m) {      pa_sink_set_rtpoll(u->sink, u->rtpoll);      pa_sink_set_description(u->sink, 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); 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); diff --git a/src/modules/module-bt-proximity.c b/src/modules/module-bt-proximity.c index f6125233..62d530d4 100644 --- a/src/modules/module-bt-proximity.c +++ b/src/modules/module-bt-proximity.c @@ -261,7 +261,7 @@ static struct bonding* bonding_new(struct userdata *u, const char *a) {      dbus_message_unref(m);      dbus_message_unref(r); -    pa_hashmap_put(u->bondings, a, b); +    pa_hashmap_put(u->bondings, b->address, b);      return b; diff --git a/src/modules/module-cli.c b/src/modules/module-cli.c index 71df5a0f..ab311a82 100644 --- a/src/modules/module-cli.c +++ b/src/modules/module-cli.c @@ -70,7 +70,7 @@ static void eof_and_exit_cb(pa_cli*c, void *userdata) {  int pa__init(pa_module*m) {      pa_iochannel *io;      pa_modargs *ma; -    int exit_on_eof = 0; +    pa_bool_t exit_on_eof = FALSE;      pa_assert(m); diff --git a/src/modules/module-detect.c b/src/modules/module-detect.c index 95665931..ee650dfd 100644 --- a/src/modules/module-detect.c +++ b/src/modules/module-detect.c @@ -222,7 +222,8 @@ static int detect_waveout(pa_core *c, int just_one) {  #endif  int pa__init(pa_module*m) { -    int just_one = 0, n = 0; +    pa_bool_t just_one = FALSE; +    int n = 0;      pa_modargs *ma;      pa_assert(m); diff --git a/src/modules/module-hal-detect.c b/src/modules/module-hal-detect.c index 00b66c16..832bc73e 100644 --- a/src/modules/module-hal-detect.c +++ b/src/modules/module-hal-detect.c @@ -191,12 +191,12 @@ static pa_module* hal_device_load_alsa(struct userdata *u, const char *udi, char          *sink_name = pa_sprintf_malloc("alsa_output.%s", strip_udi(udi));          module_name = "module-alsa-sink"; -        args = pa_sprintf_malloc("device=hw:%u sink_name=%s", card, *sink_name); +        args = pa_sprintf_malloc("device_id=%u sink_name=%s", card, *sink_name);      } else {          *source_name = pa_sprintf_malloc("alsa_input.%s", strip_udi(udi));          module_name = "module-alsa-source"; -        args = pa_sprintf_malloc("device=hw:%u source_name=%s", card, *source_name); +        args = pa_sprintf_malloc("device_id=%u source_name=%s", card, *source_name);      }      pa_log_debug("Loading %s with arguments '%s'", module_name, args); diff --git a/src/modules/module-oss.c b/src/modules/module-oss.c index a44ad083..8352a790 100644 --- a/src/modules/module-oss.c +++ b/src/modules/module-oss.c @@ -1139,7 +1139,7 @@ int pa__init(pa_module*m) {      int fd = -1;      int nfrags, frag_size;      int mode, caps; -    int record = 1, playback = 1, use_mmap = 1; +    pa_bool_t record = TRUE, playback = TRUE, use_mmap = TRUE;      pa_sample_spec ss;      pa_channel_map map;      pa_modargs *ma = NULL; diff --git a/src/modules/rtp/module-rtp-send.c b/src/modules/rtp/module-rtp-send.c index d7c50578..95ff15de 100644 --- a/src/modules/rtp/module-rtp-send.c +++ b/src/modules/rtp/module-rtp-send.c @@ -179,11 +179,11 @@ int pa__init(pa_module*m) {      pa_source_output *o = NULL;      uint8_t payload;      char *p; -    int r; +    int r, j;      socklen_t k;      struct timeval tv;      char hn[128], *n; -    int loop = 0; +    pa_bool_t loop = FALSE;      pa_source_output_new_data data;      pa_assert(m); @@ -274,8 +274,9 @@ int pa__init(pa_module*m) {          goto fail;      } -    if (setsockopt(fd, IPPROTO_IP, IP_MULTICAST_LOOP, &loop, sizeof(loop)) < 0 || -        setsockopt(sap_fd, IPPROTO_IP, IP_MULTICAST_LOOP, &loop, sizeof(loop)) < 0) { +    j = !!loop; +    if (setsockopt(fd, IPPROTO_IP, IP_MULTICAST_LOOP, &j, sizeof(j)) < 0 || +        setsockopt(sap_fd, IPPROTO_IP, IP_MULTICAST_LOOP, &j, sizeof(j)) < 0) {          pa_log("IP_MULTICAST_LOOP failed: %s", pa_cstrerror(errno));          goto fail;      } diff --git a/src/pulsecore/modargs.c b/src/pulsecore/modargs.c index 1311af3c..0dab254b 100644 --- a/src/pulsecore/modargs.c +++ b/src/pulsecore/modargs.c @@ -225,7 +225,7 @@ int pa_modargs_get_value_s32(pa_modargs *ma, const char *key, int32_t *value) {      return 0;  } -int pa_modargs_get_value_boolean(pa_modargs *ma, const char *key, int *value) { +int pa_modargs_get_value_boolean(pa_modargs *ma, const char *key, pa_bool_t *value) {      const char *v;      int r; diff --git a/src/pulsecore/modargs.h b/src/pulsecore/modargs.h index aa175885..504b9cd7 100644 --- a/src/pulsecore/modargs.h +++ b/src/pulsecore/modargs.h @@ -28,6 +28,7 @@  #include <pulse/sample.h>  #include <pulse/channelmap.h>  #include <pulsecore/core.h> +#include <pulsecore/macro.h>  typedef struct pa_modargs pa_modargs; @@ -44,7 +45,7 @@ const char *pa_modargs_get_value(pa_modargs *ma, const char *key, const char *de  /* Return a module argument as unsigned 32bit value in *value */  int pa_modargs_get_value_u32(pa_modargs *ma, const char *key, uint32_t *value);  int pa_modargs_get_value_s32(pa_modargs *ma, const char *key, int32_t *value); -int pa_modargs_get_value_boolean(pa_modargs *ma, const char *key, int *value); +int pa_modargs_get_value_boolean(pa_modargs *ma, const char *key, pa_bool_t *value);  /* Return sample spec data from the three arguments "rate", "format" and "channels" */  int pa_modargs_get_sample_spec(pa_modargs *ma, pa_sample_spec *ss); diff --git a/src/pulsecore/protocol-esound.c b/src/pulsecore/protocol-esound.c index 76ba9dd0..004e535e 100644 --- a/src/pulsecore/protocol-esound.c +++ b/src/pulsecore/protocol-esound.c @@ -1406,7 +1406,7 @@ static void on_connection(pa_socket_server*s, pa_iochannel *io, void *userdata)  pa_protocol_esound* pa_protocol_esound_new(pa_core*core, pa_socket_server *server, pa_module *m, pa_modargs *ma) {      pa_protocol_esound *p = NULL; -    int public = 0; +    pa_bool_t public = FALSE;      const char *acl;      pa_assert(core); diff --git a/src/pulsecore/protocol-native.c b/src/pulsecore/protocol-native.c index 9ae0f083..1d294746 100644 --- a/src/pulsecore/protocol-native.c +++ b/src/pulsecore/protocol-native.c @@ -2956,7 +2956,7 @@ static int load_key(pa_protocol_native*p, const char*fn) {  static pa_protocol_native* protocol_new_internal(pa_core *c, pa_module *m, pa_modargs *ma) {      pa_protocol_native *p; -    int public = 0; +    pa_bool_t public = FALSE;      const char *acl;      pa_assert(c); @@ -2976,7 +2976,7 @@ static pa_protocol_native* protocol_new_internal(pa_core *c, pa_module *m, pa_mo  #ifdef HAVE_CREDS      { -        int a = 1; +        pa_bool_t a = 1;          if (pa_modargs_get_value_boolean(ma, "auth-group-enabled", &a) < 0) {              pa_log("auth-group-enabled= expects a boolean argument.");              return NULL; diff --git a/src/pulsecore/protocol-simple.c b/src/pulsecore/protocol-simple.c index 64e2a81c..777def30 100644 --- a/src/pulsecore/protocol-simple.c +++ b/src/pulsecore/protocol-simple.c @@ -566,7 +566,7 @@ fail:  pa_protocol_simple* pa_protocol_simple_new(pa_core *core, pa_socket_server *server, pa_module *m, pa_modargs *ma) {      pa_protocol_simple* p = NULL; -    int enable; +    pa_bool_t enable;      pa_assert(core);      pa_assert(server); @@ -587,7 +587,7 @@ pa_protocol_simple* pa_protocol_simple_new(pa_core *core, pa_socket_server *serv      p->source_name = pa_xstrdup(pa_modargs_get_value(ma, "source", NULL));      p->sink_name = pa_xstrdup(pa_modargs_get_value(ma, "sink", NULL)); -    enable = 0; +    enable = FALSE;      if (pa_modargs_get_value_boolean(ma, "record", &enable) < 0) {          pa_log("record= expects a numeric argument.");          goto fail;  | 
