spa: alsa: fix multiple %f in node device strings of nodes

ACP allows multiple %f in device strings (cf pa_alsa_open_by_template),
but we replace only one of them when emitting the nodes. The a52
profiles in default.conf use multiple %f and probably don't work.

Fix to replace also multiple %f when emitting ACP device nodes.
This commit is contained in:
Pauli Virtanen 2024-07-04 22:36:47 +03:00 committed by Wim Taymans
parent daef48b0eb
commit 677f3a152c

View file

@ -126,6 +126,29 @@ static int setup_sources(struct impl *this)
return 0;
}
static int replace_string(const char *str, const char *val, const char *rep,
char *buf, size_t size)
{
struct spa_strbuf s;
const char *p;
size_t len = strlen(val);
spa_assert(len > 0);
spa_strbuf_init(&s, buf, size);
while (1) {
p = strstr(str, val);
if (!p)
break;
spa_strbuf_append(&s, "%.*s%s", (int)SPA_PTRDIFF(p, str), str, rep);
str = p + len;
}
spa_strbuf_append(&s, "%s", str);
return 0;
}
static int emit_node(struct impl *this, struct acp_device *dev)
{
struct spa_dict_item *items;
@ -136,7 +159,7 @@ static int emit_node(struct impl *this, struct acp_device *dev)
char positions[SPA_AUDIO_MAX_CHANNELS * 12];
struct spa_device_object_info info;
struct acp_card *card = this->card;
const char *stream, *devstr, *card_id;
const char *stream, *card_id;
info = SPA_DEVICE_OBJECT_INFO_INIT();
info.type = SPA_TYPE_INTERFACE_Node;
@ -158,15 +181,7 @@ static int emit_node(struct impl *this, struct acp_device *dev)
card_id = acp_dict_lookup(&card->props, "alsa.id");
snprintf(card_name, sizeof(card_name), "%s", card_id ? card_id : card_index);
devstr = dev->device_strings[0];
p = strstr(devstr, "%f");
if (p) {
snprintf(device_name, sizeof(device_name), "%.*s%d%s",
(int)SPA_PTRDIFF(p, devstr), devstr,
card->index, p+2);
} else {
snprintf(device_name, sizeof(device_name), "%s", devstr);
}
replace_string(dev->device_strings[0], "%f", card_index, device_name, sizeof(device_name));
snprintf(path, sizeof(path), "alsa:acp:%s:%d:%s", card_name, dev->index, stream);
items[n_items++] = SPA_DICT_ITEM_INIT(SPA_KEY_OBJECT_PATH, path);