From a25f1a6a1d1814997be575d44182ca169f1b9987 Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Fri, 18 Dec 2020 17:18:53 +0100 Subject: [PATCH] acp: pass channelmap around so that we can use it as a default in channelmix --- spa/plugins/alsa/alsa-acp-device.c | 16 ++++++++++++---- spa/plugins/audioconvert/channelmix.c | 25 ++++++++++++++++++++++++- 2 files changed, 36 insertions(+), 5 deletions(-) diff --git a/spa/plugins/alsa/alsa-acp-device.c b/spa/plugins/alsa/alsa-acp-device.c index c04ebd179..f432dbedc 100644 --- a/spa/plugins/alsa/alsa-acp-device.c +++ b/spa/plugins/alsa/alsa-acp-device.c @@ -141,9 +141,10 @@ static int emit_node(struct impl *this, struct acp_device *dev) { struct spa_dict_item *items; const struct acp_dict_item *it; - uint32_t n_items; + uint32_t n_items, i; char device_name[128], path[180], channels[16]; char card_id[16], *p; + char positions[SPA_AUDIO_MAX_CHANNELS * 6]; struct spa_device_object_info info; struct acp_card *card = this->card; const char *stream, *devstr;; @@ -161,7 +162,7 @@ static int emit_node(struct impl *this, struct acp_device *dev) info.change_mask = SPA_DEVICE_OBJECT_CHANGE_MASK_PROPS; - n_items = dev->props.n_items + 5; + n_items = dev->props.n_items + 6; items = alloca(n_items * sizeof(*items)); snprintf(card_id, sizeof(card), "%d", card->index); @@ -181,9 +182,16 @@ static int emit_node(struct impl *this, struct acp_device *dev) items[2] = SPA_DICT_ITEM_INIT(SPA_KEY_API_ALSA_PCM_CARD, card_id); items[3] = SPA_DICT_ITEM_INIT(SPA_KEY_API_ALSA_PCM_STREAM, stream); - snprintf(channels, sizeof(channels), "%d", dev->format.channels); + snprintf(channels, sizeof(channels)-1, "%d", dev->format.channels); items[4] = SPA_DICT_ITEM_INIT(SPA_KEY_AUDIO_CHANNELS, channels); - n_items = 5; + + p = positions; + for (i = 0; i < dev->format.channels; i++) + p += snprintf(p, 6, "%s%s", i == 0 ? "" : ",", + spa_debug_type_short_name(spa_type_audio_channel[dev->format.map[i]].name)); + + items[5] = SPA_DICT_ITEM_INIT(SPA_KEY_AUDIO_POSITION, positions); + n_items = 6; acp_dict_for_each(it, &dev->props) items[n_items++] = SPA_DICT_ITEM_INIT(it->key, it->value); diff --git a/spa/plugins/audioconvert/channelmix.c b/spa/plugins/audioconvert/channelmix.c index ce3692783..30c94ef67 100644 --- a/spa/plugins/audioconvert/channelmix.c +++ b/spa/plugins/audioconvert/channelmix.c @@ -1199,6 +1199,16 @@ impl_get_size(const struct spa_handle_factory *factory, return sizeof(struct impl); } +static uint32_t channel_from_name(const char *name, size_t len) +{ + int i; + for (i = 0; spa_type_audio_channel[i].name; i++) { + if (strncmp(name, spa_debug_type_short_name(spa_type_audio_channel[i].name), len) == 0) + return spa_type_audio_channel[i].type; + } + return SPA_AUDIO_CHANNEL_UNKNOWN; +} + static int impl_init(const struct spa_handle_factory *factory, struct spa_handle *handle, @@ -1226,6 +1236,8 @@ impl_init(const struct spa_handle_factory *factory, spa_hook_list_init(&this->hooks); + props_reset(&this->props); + if (info != NULL) { if ((str = spa_dict_lookup(info, "channelmix.normalize")) != NULL && (strcmp(str, "true") == 0 || atoi(str) != 0)) @@ -1233,7 +1245,19 @@ impl_init(const struct spa_handle_factory *factory, if ((str = spa_dict_lookup(info, "channelmix.mix-lfe")) != NULL && (strcmp(str, "true") == 0 || atoi(str) != 0)) this->mix.options |= CHANNELMIX_OPTION_MIX_LFE; + if ((str = spa_dict_lookup(info, SPA_KEY_AUDIO_POSITION)) != NULL) { + size_t len; + const char *p = str; + while (*p && this->props.n_channels < SPA_AUDIO_MAX_CHANNELS) { + if ((len = strcspn(p, ",")) == 0) + break; + this->props.channel_map[this->props.n_channels++] = + channel_from_name(p, len); + p += len + strspn(p+len, ","); + } + } } + this->props.n_channel_volumes = this->props.n_channels; this->node.iface = SPA_INTERFACE_INIT( SPA_TYPE_INTERFACE_Node, @@ -1249,7 +1273,6 @@ impl_init(const struct spa_handle_factory *factory, this->params[1] = SPA_PARAM_INFO(SPA_PARAM_Props, SPA_PARAM_INFO_READWRITE); this->info.params = this->params; this->info.n_params = 2; - props_reset(&this->props); port = GET_OUT_PORT(this, 0); port->direction = SPA_DIRECTION_OUTPUT;