From 81d8ecf0dc30554972f7a2a4e4e65a446f877b63 Mon Sep 17 00:00:00 2001 From: Emil Svendsen Date: Sat, 2 Mar 2024 21:23:05 +0100 Subject: [PATCH] alsa-pcm: snd_ctl_open: remove device suffix ALSA controls can only be opened on the card itself and will fail when trying to open controls on the ALSA device. The device name we get may or may not include the device suffix. If no suffix is present the default device is 0 that's why currently it works on most audio cards. But all other devices above 0 needs the suffix [1]. [1] Device 0: hw:cardname Device 0: hw:cardname,0 Device 1: hw:cardname,1 Device 2: hw:cardname,2 Device X: hw:cardname,X --- spa/plugins/alsa/alsa-pcm.c | 34 ++++++++++++++++++++++++++-------- 1 file changed, 26 insertions(+), 8 deletions(-) diff --git a/spa/plugins/alsa/alsa-pcm.c b/spa/plugins/alsa/alsa-pcm.c index 8c8dc2366..4fb1a1ad3 100644 --- a/spa/plugins/alsa/alsa-pcm.c +++ b/spa/plugins/alsa/alsa-pcm.c @@ -640,6 +640,21 @@ static void fill_device_name(struct state *state, const char *params, char devic state->props.device, params ? params : ""); } +static void device_name_to_card_name(const char *device_name, char *card_name, size_t card_len) +{ + size_t card_name_len = strcspn(device_name, ","); + snprintf(card_name, card_len, "%.*s", (int) card_name_len, device_name); +} + +static void fill_card_name(struct state *state, const char *params, char *card_name, size_t len) +{ + char device_name[256]; + size_t max_len = SPA_MIN(len, sizeof(device_name)); + + fill_device_name(state, params, device_name, max_len); + device_name_to_card_name(device_name, card_name, max_len); +} + static void bind_ctl_event(struct spa_source *source) { // We don't know if a bound element changed or not, so let's find out @@ -687,14 +702,14 @@ static void bind_ctls_for_params(struct state *state) return; if (!state->ctl) { - char device_name[256]; + char card_name[256]; - fill_device_name(state, NULL, device_name, sizeof(device_name)); + fill_card_name(state, NULL, card_name, sizeof(card_name)); - err = snd_ctl_open(&state->ctl, device_name, SND_CTL_NONBLOCK); + err = snd_ctl_open(&state->ctl, card_name, SND_CTL_NONBLOCK); if (err < 0) { - spa_log_info(state->log, "%s could not find ctl device: %s", - state->props.device, snd_strerror(err)); + spa_log_info(state->log, "%s could not find ctl card: %s", + card_name, snd_strerror(err)); state->ctl = NULL; return; } @@ -891,10 +906,13 @@ static int probe_pitch_ctl(struct state *state, const char* device_name) snd_lib_error_set_handler(silence_error_handler); if (!state->ctl) { - err = snd_ctl_open(&state->ctl, device_name, SND_CTL_NONBLOCK); + char card_name[256]; + device_name_to_card_name(device_name, card_name, sizeof(card_name)); + + err = snd_ctl_open(&state->ctl, card_name, SND_CTL_NONBLOCK); if (err < 0) { - spa_log_info(state->log, "%s could not find ctl device: %s", - device_name, snd_strerror(err)); + spa_log_info(state->log, "%s could not find ctl card: %s", + card_name, snd_strerror(err)); state->ctl = NULL; goto error; }