[pulseaudio-discuss] [PATCH 3/3] alsa-ucm: Support Playback/CaptureVolume

David Henningsson david.henningsson at canonical.com
Mon Sep 30 05:06:48 PDT 2013


On 09/20/2013 01:57 PM, Arun Raghavan wrote:
> This allows us to support the PlaybackVolume and CaptureVolume commands
> in UCM, specifying a mixer control to use for hardware volume control.
> 
> This only works with ports corresponding to single devices at the
> moment, and doesn't support stacking controls for combination ports.
> 
> On the UCM side, this also requires that when disabling the device for
> the port, the volume should be reset to some default.

Overall, this seems to be a very well written patch, good work! Just two
comments further down.

> When enabling/disabling combination devices, things are a bit iffy since
> we have no way to reset the volume before switching to a combination
> device. It would be nice to have a combination-transition-sequence
> command in UCM to handle this and other similar cases.
> ---
>  src/modules/alsa/alsa-sink.c        |  69 +++++++++++++++-----
>  src/modules/alsa/alsa-source.c      |  34 ++++++----
>  src/modules/alsa/alsa-ucm.c         | 126 ++++++++++++++++++++++++++++++++++--
>  src/modules/alsa/alsa-ucm.h         |  19 +++++-
>  src/modules/alsa/module-alsa-card.c |   4 +-
>  5 files changed, 215 insertions(+), 37 deletions(-)
> 
> diff --git a/src/modules/alsa/alsa-sink.c b/src/modules/alsa/alsa-sink.c
> index d3d5b19..3b64448 100644
> --- a/src/modules/alsa/alsa-sink.c
> +++ b/src/modules/alsa/alsa-sink.c
> @@ -1422,7 +1422,7 @@ static void sink_set_mute_cb(pa_sink *s) {
>  static void mixer_volume_init(struct userdata *u) {
>      pa_assert(u);
>  
> -    if (!u->mixer_path->has_volume) {
> +    if (!u->mixer_path || !u->mixer_path->has_volume) {
>          pa_sink_set_write_volume_callback(u->sink, NULL);
>          pa_sink_set_get_volume_callback(u->sink, NULL);
>          pa_sink_set_set_volume_callback(u->sink, NULL);
> @@ -1457,7 +1457,7 @@ static void mixer_volume_init(struct userdata *u) {
>          pa_log_info("Using hardware volume control. Hardware dB scale %s.", u->mixer_path->has_dB ? "supported" : "not supported");
>      }
>  
> -    if (!u->mixer_path->has_mute) {
> +    if (!u->mixer_path || !u->mixer_path->has_mute) {
>          pa_sink_set_get_mute_callback(u->sink, NULL);
>          pa_sink_set_set_mute_callback(u->sink, NULL);
>          pa_log_info("Driver does not support hardware mute control, falling back to software mute control.");
> @@ -1470,10 +1470,31 @@ static void mixer_volume_init(struct userdata *u) {
>  
>  static int sink_set_port_ucm_cb(pa_sink *s, pa_device_port *p) {
>      struct userdata *u = s->userdata;
> +    pa_alsa_ucm_port_data *data;
> +
> +    data = PA_DEVICE_PORT_DATA(p);
>  
>      pa_assert(u);
>      pa_assert(p);
>      pa_assert(u->ucm_context);
> +    pa_assert(u->mixer_handle);
> +
> +    u->mixer_path = data->path;
> +    mixer_volume_init(u);
> +
> +    if (data->path) {
> +        pa_alsa_path_select(u->mixer_path, NULL, u->mixer_handle, s->muted);
> +
> +        if (s->set_mute)
> +            s->set_mute(s);
> +        if (s->flags & PA_SINK_DEFERRED_VOLUME) {
> +            if (s->write_volume)
> +                s->write_volume(s);
> +        } else {
> +            if (s->set_volume)
> +                s->set_volume(s);
> +        }
> +    }
>  
>      return pa_alsa_ucm_set_port(u->ucm_context, p, true);
>  }
> @@ -1896,7 +1917,7 @@ static void set_sink_name(pa_sink_new_data *data, pa_modargs *ma, const char *de
>  static void find_mixer(struct userdata *u, pa_alsa_mapping *mapping, const char *element, bool ignore_dB) {
>      snd_hctl_t *hctl;
>  
> -    if (!mapping && !element)
> +    if (!u->ucm_context && (!mapping && !element))
>          return;
>  
>      if (!(u->mixer_handle = pa_alsa_open_mixer_for_pcm(u->pcm_handle, &u->control_device, &hctl))) {
> @@ -1904,6 +1925,11 @@ static void find_mixer(struct userdata *u, pa_alsa_mapping *mapping, const char
>          return;
>      }
>  
> +    if (u->ucm_context) {
> +        /* We just want to open the device */
> +        return;
> +    }
> +
>      if (element) {
>  
>          if (!(u->mixer_path = pa_alsa_path_synthesize(element, PA_ALSA_DIRECTION_OUTPUT)))
> @@ -1941,16 +1967,31 @@ static int setup_mixer(struct userdata *u, bool ignore_dB) {
>          return 0;
>  
>      if (u->sink->active_port) {
> -        pa_alsa_port_data *data;
> +        if (!u->ucm_context) {
> +            pa_alsa_port_data *data;
>  
> -        /* We have a list of supported paths, so let's activate the
> -         * one that has been chosen as active */
> +            /* We have a list of supported paths, so let's activate the
> +             * one that has been chosen as active */
>  
> -        data = PA_DEVICE_PORT_DATA(u->sink->active_port);
> -        u->mixer_path = data->path;
> +            data = PA_DEVICE_PORT_DATA(u->sink->active_port);
> +            u->mixer_path = data->path;
>  
> -        pa_alsa_path_select(data->path, data->setting, u->mixer_handle, u->sink->muted);
> +            pa_alsa_path_select(data->path, data->setting, u->mixer_handle, u->sink->muted);
> +        } else {
> +            pa_alsa_ucm_port_data *data;
> +
> +            /* First activate the port on the UCM side */
> +            if (pa_alsa_ucm_set_port(u->ucm_context, u->sink->active_port, true) < 0)
> +                return -1;
>  
> +            data = PA_DEVICE_PORT_DATA(u->sink->active_port);
> +
> +            /* Now activate volume controls, if any */
> +            if (data->path) {
> +                u->mixer_path = data->path;
> +                pa_alsa_path_select(data->path, NULL, u->mixer_handle, u->sink->muted);
> +            }
> +        }
>      } else {
>  
>          if (!u->mixer_path && u->mixer_path_set)
> @@ -2244,8 +2285,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 (!u->ucm_context)
> -        find_mixer(u, mapping, pa_modargs_get_value(ma, "control", NULL), ignore_dB);
> +    find_mixer(u, mapping, pa_modargs_get_value(ma, "control", NULL), ignore_dB);
>  
>      pa_sink_new_data_init(&data);
>      data.driver = driver;
> @@ -2295,7 +2335,7 @@ pa_sink *pa_alsa_sink_new(pa_module *m, pa_modargs *ma, const char*driver, pa_ca
>      }
>  
>      if (u->ucm_context)
> -        pa_alsa_ucm_add_ports(&data.ports, data.proplist, u->ucm_context, true, card);
> +        pa_alsa_ucm_add_ports(&data.ports, data.proplist, u->ucm_context, true, card, u->pcm_handle, ignore_dB);
>      else if (u->mixer_path_set)
>          pa_alsa_add_ports(&data, u->mixer_path_set, card);
>  
> @@ -2366,10 +2406,7 @@ pa_sink *pa_alsa_sink_new(pa_module *m, pa_modargs *ma, const char*driver, pa_ca
>      if (update_sw_params(u) < 0)
>          goto fail;
>  
> -    if (u->ucm_context) {
> -        if (u->sink->active_port && pa_alsa_ucm_set_port(u->ucm_context, u->sink->active_port, true) < 0)
> -            goto fail;
> -    } else if (setup_mixer(u, ignore_dB) < 0)
> +    if (setup_mixer(u, ignore_dB) < 0)
>          goto fail;
>  
>      pa_alsa_dump(PA_LOG_DEBUG, u->pcm_handle);
> diff --git a/src/modules/alsa/alsa-source.c b/src/modules/alsa/alsa-source.c
> index 8416ba8..9b80b9e 100644
> --- a/src/modules/alsa/alsa-source.c
> +++ b/src/modules/alsa/alsa-source.c
> @@ -1652,16 +1652,31 @@ static int setup_mixer(struct userdata *u, bool ignore_dB) {
>          return 0;
>  
>      if (u->source->active_port) {
> -        pa_alsa_port_data *data;
> +        if (!u->ucm_context) {
> +            pa_alsa_port_data *data;
>  
> -        /* We have a list of supported paths, so let's activate the
> -         * one that has been chosen as active */
> +            /* We have a list of supported paths, so let's activate the
> +             * one that has been chosen as active */
>  
> -        data = PA_DEVICE_PORT_DATA(u->source->active_port);
> -        u->mixer_path = data->path;
> +            data = PA_DEVICE_PORT_DATA(u->source->active_port);
> +            u->mixer_path = data->path;
>  
> -        pa_alsa_path_select(data->path, data->setting, u->mixer_handle, u->source->muted);
> +            pa_alsa_path_select(data->path, data->setting, u->mixer_handle, u->source->muted);
> +        } else {
> +            pa_alsa_ucm_port_data *data;
> +
> +            /* First activate the port on the UCM side */
> +            if (pa_alsa_ucm_set_port(u->ucm_context, u->source->active_port, true) < 0)
> +                return -1;
> +
> +            data = PA_DEVICE_PORT_DATA(u->source->active_port);
>  
> +            /* Now activate volume controls, if any */
> +            if (data->path) {
> +                u->mixer_path = data->path;
> +                pa_alsa_path_select(data->path, NULL, u->mixer_handle, u->source->muted);
> +            }
> +        }
>      } else {
>  
>          if (!u->mixer_path && u->mixer_path_set)
> @@ -1994,7 +2009,7 @@ pa_source *pa_alsa_source_new(pa_module *m, pa_modargs *ma, const char*driver, p
>      }
>  
>      if (u->ucm_context)
> -        pa_alsa_ucm_add_ports(&data.ports, data.proplist, u->ucm_context, false, card);
> +        pa_alsa_ucm_add_ports(&data.ports, data.proplist, u->ucm_context, false, card, u->pcm_handle, ignore_dB);
>      else if (u->mixer_path_set)
>          pa_alsa_add_ports(&data, u->mixer_path_set, card);
>  
> @@ -2057,10 +2072,7 @@ pa_source *pa_alsa_source_new(pa_module *m, pa_modargs *ma, const char*driver, p
>      if (update_sw_params(u) < 0)
>          goto fail;
>  
> -    if (u->ucm_context) {
> -        if (u->source->active_port && pa_alsa_ucm_set_port(u->ucm_context, u->source->active_port, false) < 0)
> -            goto fail;
> -    } else if (setup_mixer(u, ignore_dB) < 0)
> +    if (setup_mixer(u, ignore_dB) < 0)
>          goto fail;
>  
>      pa_alsa_dump(PA_LOG_DEBUG, u->pcm_handle);
> diff --git a/src/modules/alsa/alsa-ucm.c b/src/modules/alsa/alsa-ucm.c
> index 47ff926..822f760 100644
> --- a/src/modules/alsa/alsa-ucm.c
> +++ b/src/modules/alsa/alsa-ucm.c
> @@ -278,6 +278,17 @@ static int ucm_get_device_property(
>              else
>                  pa_log_debug("UCM playback priority %s for device %s error", value, device_name);
>          }
> +
> +        /* Volume control element */
> +        if (!device->playback_volume)
> +            device->playback_volume = pa_hashmap_new_full(pa_idxset_string_hash_func, pa_idxset_string_compare_func, pa_xfree,
> +                                                          pa_xfree);
> +
> +        value = pa_proplist_gets(device->proplist, PA_ALSA_PROP_UCM_PLAYBACK_VOLUME);
> +        if (value) {
> +            pa_hashmap_put(device->playback_volume, pa_xstrdup(pa_proplist_gets(verb->proplist, PA_ALSA_PROP_UCM_NAME)),
> +                           pa_xstrdup(value));
> +        }
>      }
>  
>      if (device->capture_channels) { /* source device */
> @@ -299,6 +310,17 @@ static int ucm_get_device_property(
>              else
>                  pa_log_debug("UCM capture priority %s for device %s error", value, device_name);
>          }
> +
> +        /* Volume control element */
> +        if (!device->capture_volume)
> +            device->capture_volume = pa_hashmap_new_full(pa_idxset_string_hash_func, pa_idxset_string_compare_func, pa_xfree,
> +                                                         pa_xfree);
> +
> +        value = pa_proplist_gets(device->proplist, PA_ALSA_PROP_UCM_CAPTURE_VOLUME);
> +        if (value) {
> +            pa_hashmap_put(device->capture_volume, pa_xstrdup(pa_proplist_gets(verb->proplist, PA_ALSA_PROP_UCM_NAME)),
> +                           pa_xstrdup(value));
> +        }
>      }
>  
>      if (PA_UCM_PLAYBACK_PRIORITY_UNSET(device) || PA_UCM_CAPTURE_PRIORITY_UNSET(device)) {
> @@ -671,6 +693,57 @@ static int pa_alsa_ucm_device_cmp(const void *a, const void *b) {
>      return strcmp(pa_proplist_gets(d1->proplist, PA_ALSA_PROP_UCM_NAME), pa_proplist_gets(d2->proplist, PA_ALSA_PROP_UCM_NAME));
>  }
>  
> +static void ucm_port_data_free(pa_device_port *port) {
> +    pa_alsa_ucm_port_data *data = PA_DEVICE_PORT_DATA(port);
> +
> +    if (data->paths) {
> +        pa_hashmap_free(data->paths);
> +    }
> +
> +    data->path = NULL;

Any reason why you set data->path to null but not data->paths?

> +}
> +
> +static void probe_volumes(pa_hashmap *hash, snd_pcm_t *pcm_handle, bool ignore_dB) {
> +    pa_device_port *port;
> +    pa_alsa_path *path;
> +    pa_alsa_ucm_port_data *data;
> +    snd_mixer_t *mixer_handle;
> +    snd_hctl_t *hctl;
> +    const char *profile;
> +    void *state, *state2;
> +
> +    if (!(mixer_handle = pa_alsa_open_mixer_for_pcm(pcm_handle, NULL, &hctl))) {
> +        pa_log_error("Failed to find a working mixer device.");
> +        goto fail;
> +    }


You probably want to not do "pa_alsa_open_mixer_for_pcm" here, but
instead try to use whatever the ucm file specifies in "cset" - in most
cases there wouldn't be a difference, but who knows...

(This might also apply to more places)

> +
> +    PA_HASHMAP_FOREACH(port, hash, state) {
> +        data = PA_DEVICE_PORT_DATA(port);
> +
> +        PA_HASHMAP_FOREACH_KV(profile, path, data->paths, state2) {
> +            if (pa_alsa_path_probe(path, mixer_handle, hctl, ignore_dB) < 0) {
> +                pa_log_warn("Could not probe path: %s, using s/w volume", data->path->name);
> +                pa_hashmap_remove(data->paths, profile);
> +                pa_alsa_path_free(path);
> +            } else
> +                pa_log_debug("Set up h/w volume using '%s' for %s:%s", path->name, profile, port->name);
> +        }
> +    }
> +
> +    return;
> +
> +fail:
> +    /* We could not probe the paths we created. Free them and rever to software volumes. */
> +    PA_HASHMAP_FOREACH(port, hash, state) {
> +        data = PA_DEVICE_PORT_DATA(port);
> +
> +        if (data->path) {
> +            pa_alsa_path_free(data->path);
> +            data->path = NULL;
> +        }
> +    }
> +}
> +
>  static void ucm_add_port_combination(
>          pa_hashmap *hash,
>          pa_alsa_ucm_mapping_context *context,
> @@ -688,7 +761,10 @@ static void ucm_add_port_combination(
>      char *name, *desc;
>      const char *dev_name;
>      const char *direction;
> +    const char *profile, *volume;
>      pa_alsa_ucm_device *sorted[num], *dev;
> +    pa_alsa_ucm_port_data *data;
> +    void *state;
>  
>      for (i = 0; i < num; i++)
>          sorted[i] = pdevices[i];
> @@ -743,15 +819,35 @@ static void ucm_add_port_combination(
>          pa_device_port_new_data_set_description(&port_data, desc);
>          pa_device_port_new_data_set_direction(&port_data, is_sink ? PA_DIRECTION_OUTPUT : PA_DIRECTION_INPUT);
>  
> -        port = pa_device_port_new(core, &port_data, 0);
> +        port = pa_device_port_new(core, &port_data, sizeof(pa_alsa_ucm_port_data));
>          pa_device_port_new_data_done(&port_data);
> -        pa_assert(port);
> +
> +        data = PA_DEVICE_PORT_DATA(port);
> +        data->paths = pa_hashmap_new_full(pa_idxset_string_hash_func, pa_idxset_string_compare_func, pa_xfree,
> +                                          (pa_free_cb_t) pa_alsa_path_free);
> +        port->impl_free = ucm_port_data_free;
>  
>          pa_hashmap_put(ports, port->name, port);
>          pa_log_debug("Add port %s: %s", port->name, port->description);
>          port->profiles = pa_hashmap_new(pa_idxset_string_hash_func, pa_idxset_string_compare_func);
>      }
>  
> +    if (num == 1) {
> +        /* To keep things simple and not worry about stacking controls, we only support hardware volumes on non-combination
> +         * ports. */
> +        data = PA_DEVICE_PORT_DATA(port);
> +
> +        PA_HASHMAP_FOREACH_KV(profile, volume, is_sink ? dev->playback_volume : dev->capture_volume, state) {
> +            pa_alsa_path *path = pa_alsa_path_synthesize(volume,
> +                    is_sink ? PA_ALSA_DIRECTION_OUTPUT : PA_ALSA_DIRECTION_INPUT);
> +
> +            if (!path)
> +                pa_log_warn("Failed to set up volume control: %s", volume);
> +            else
> +                pa_hashmap_put(data->paths, pa_xstrdup(profile), path);
> +        }
> +    }
> +
>      port->priority = priority;
>  
>      pa_xfree(name);
> @@ -931,7 +1027,9 @@ void pa_alsa_ucm_add_ports(
>          pa_proplist *proplist,
>          pa_alsa_ucm_mapping_context *context,
>          bool is_sink,
> -        pa_card *card) {
> +        pa_card *card,
> +        snd_pcm_t *pcm_handle,
> +        bool ignore_dB) {
>  
>      uint32_t idx;
>      char *merged_roles;
> @@ -946,6 +1044,9 @@ void pa_alsa_ucm_add_ports(
>      /* add ports first */
>      pa_alsa_ucm_add_ports_combination(*p, context, is_sink, card->ports, NULL, card->core);
>  
> +    /* now set up volume paths if any */
> +    probe_volumes(*p, pcm_handle, ignore_dB);
> +
>      /* then set property PA_PROP_DEVICE_INTENDED_ROLES */
>      merged_roles = pa_xstrdup(pa_proplist_gets(proplist, PA_PROP_DEVICE_INTENDED_ROLES));
>      PA_IDXSET_FOREACH(dev, context->ucm_devices, idx) {
> @@ -970,10 +1071,13 @@ void pa_alsa_ucm_add_ports(
>  }
>  
>  /* Change UCM verb and device to match selected card profile */
> -int pa_alsa_ucm_set_profile(pa_alsa_ucm_config *ucm, const char *new_profile, const char *old_profile) {
> +int pa_alsa_ucm_set_profile(pa_alsa_ucm_config *ucm, pa_card *card, const char *new_profile, const char *old_profile) {
>      int ret = 0;
>      const char *profile;
>      pa_alsa_ucm_verb *verb;
> +    pa_device_port *port;
> +    pa_alsa_ucm_port_data *data;
> +    void *state;
>  
>      if (new_profile == old_profile)
>          return ret;
> @@ -1002,6 +1106,12 @@ int pa_alsa_ucm_set_profile(pa_alsa_ucm_config *ucm, const char *new_profile, co
>          }
>      }
>  
> +    /* select volume controls on ports */
> +    PA_HASHMAP_FOREACH(port, card->ports, state) {
> +        data = PA_DEVICE_PORT_DATA(port);
> +        data->path = pa_hashmap_get(data->paths, new_profile);
> +    }
> +
>      return ret;
>  }
>  
> @@ -1551,6 +1661,8 @@ static void free_verb(pa_alsa_ucm_verb *verb) {
>  
>      PA_LLIST_FOREACH_SAFE(di, dn, verb->devices) {
>          PA_LLIST_REMOVE(pa_alsa_ucm_device, verb->devices, di);
> +        pa_hashmap_free(di->playback_volume);
> +        pa_hashmap_free(di->capture_volume);
>          pa_proplist_free(di->proplist);
>          if (di->conflicting_devices)
>              pa_idxset_free(di->conflicting_devices, NULL);
> @@ -1684,7 +1796,7 @@ pa_alsa_profile_set* pa_alsa_ucm_add_profile_set(pa_alsa_ucm_config *ucm, pa_cha
>      return NULL;
>  }
>  
> -int pa_alsa_ucm_set_profile(pa_alsa_ucm_config *ucm, const char *new_profile, const char *old_profile) {
> +int pa_alsa_ucm_set_profile(pa_alsa_ucm_config *ucm, pa_card *card, const char *new_profile, const char *old_profile) {
>      return -1;
>  }
>  
> @@ -1697,7 +1809,9 @@ void pa_alsa_ucm_add_ports(
>          pa_proplist *proplist,
>          pa_alsa_ucm_mapping_context *context,
>          bool is_sink,
> -        pa_card *card) {
> +        pa_card *card,
> +        snd_pcm_t *pcm_handle,
> +        bool ignore_dB) {
>  }
>  
>  void pa_alsa_ucm_add_ports_combination(
> diff --git a/src/modules/alsa/alsa-ucm.h b/src/modules/alsa/alsa-ucm.h
> index 2fae6c4..36a491f 100644
> --- a/src/modules/alsa/alsa-ucm.h
> +++ b/src/modules/alsa/alsa-ucm.h
> @@ -91,10 +91,11 @@ typedef struct pa_alsa_ucm_modifier pa_alsa_ucm_modifier;
>  typedef struct pa_alsa_ucm_device pa_alsa_ucm_device;
>  typedef struct pa_alsa_ucm_config pa_alsa_ucm_config;
>  typedef struct pa_alsa_ucm_mapping_context pa_alsa_ucm_mapping_context;
> +typedef struct pa_alsa_ucm_port_data pa_alsa_ucm_port_data;
>  
>  int pa_alsa_ucm_query_profiles(pa_alsa_ucm_config *ucm, int card_index);
>  pa_alsa_profile_set* pa_alsa_ucm_add_profile_set(pa_alsa_ucm_config *ucm, pa_channel_map *default_channel_map);
> -int pa_alsa_ucm_set_profile(pa_alsa_ucm_config *ucm, const char *new_profile, const char *old_profile);
> +int pa_alsa_ucm_set_profile(pa_alsa_ucm_config *ucm, pa_card *card, const char *new_profile, const char *old_profile);
>  
>  int pa_alsa_ucm_get_verb(snd_use_case_mgr_t *uc_mgr, const char *verb_name, const char *verb_desc, pa_alsa_ucm_verb **p_verb);
>  
> @@ -103,7 +104,9 @@ void pa_alsa_ucm_add_ports(
>          pa_proplist *proplist,
>          pa_alsa_ucm_mapping_context *context,
>          bool is_sink,
> -        pa_card *card);
> +        pa_card *card,
> +        snd_pcm_t *pcm_handle,
> +        bool ignore_dB);
>  void pa_alsa_ucm_add_ports_combination(
>          pa_hashmap *hash,
>          pa_alsa_ucm_mapping_context *context,
> @@ -135,6 +138,11 @@ struct pa_alsa_ucm_device {
>      unsigned playback_channels;
>      unsigned capture_channels;
>  
> +    /* These may be different per verb, so we store this as a hashmap of verb -> volume_control. We might eventually want to
> +     * make this a hashmap of verb -> per-verb-device-properties-struct. */
> +    pa_hashmap *playback_volume;
> +    pa_hashmap *capture_volume;
> +
>      pa_alsa_mapping *playback_mapping;
>      pa_alsa_mapping *capture_mapping;
>  
> @@ -194,4 +202,11 @@ struct pa_alsa_ucm_mapping_context {
>      pa_idxset *ucm_modifiers;
>  };
>  
> +struct pa_alsa_ucm_port_data {
> +    /* profile -> pa_alsa_path for volume control */
> +    pa_hashmap *paths;
> +    /* Current path, set when activating profile */
> +    pa_alsa_path *path;
> +};
> +
>  #endif
> diff --git a/src/modules/alsa/module-alsa-card.c b/src/modules/alsa/module-alsa-card.c
> index 96e88e5..970344a 100644
> --- a/src/modules/alsa/module-alsa-card.c
> +++ b/src/modules/alsa/module-alsa-card.c
> @@ -244,7 +244,7 @@ static int card_set_profile(pa_card *c, pa_card_profile *new_profile) {
>  
>      /* if UCM is available for this card then update the verb */
>      if (u->use_ucm) {
> -        if (pa_alsa_ucm_set_profile(&u->ucm, nd->profile ? nd->profile->name : NULL,
> +        if (pa_alsa_ucm_set_profile(&u->ucm, c, nd->profile ? nd->profile->name : NULL,
>                      od->profile ? od->profile->name : NULL) < 0)
>              return -1;
>      }
> @@ -294,7 +294,7 @@ static void init_profile(struct userdata *u) {
>  
>      if (d->profile && u->use_ucm) {
>          /* Set initial verb */
> -        if (pa_alsa_ucm_set_profile(ucm, d->profile->name, NULL) < 0) {
> +        if (pa_alsa_ucm_set_profile(ucm, u->card, d->profile->name, NULL) < 0) {
>              pa_log("Failed to set ucm profile %s", d->profile->name);
>              return;
>          }
> 



-- 
David Henningsson, Canonical Ltd.
https://launchpad.net/~diwic


More information about the pulseaudio-discuss mailing list