mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2026-04-04 07:15:35 -04:00
alsa: Use hw:X for accessing card ctl
In ACP mode, we might be accessing front:0 as the PCM, and using that string to generate the ctl device name does not make sense. In PulseAudio, we used the card index to generate a hw:X string, and we replicate that here. Fixes: https://gitlab.freedesktop.org/pipewire/pipewire/-/issues/4028
This commit is contained in:
parent
5be2f5e096
commit
2f9a5e0694
1 changed files with 27 additions and 39 deletions
|
|
@ -657,21 +657,6 @@ static void fill_device_name(struct state *state, const char *params, char devic
|
||||||
state->props.device, params ? params : "");
|
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)
|
static void bind_ctl_event(struct spa_source *source)
|
||||||
{
|
{
|
||||||
struct state *state = source->data;
|
struct state *state = source->data;
|
||||||
|
|
@ -830,6 +815,23 @@ cleanup:
|
||||||
snd_ctl_elem_list_free_space(element_list);
|
snd_ctl_elem_list_free_space(element_list);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int open_card_ctl(struct state *state)
|
||||||
|
{
|
||||||
|
int err;
|
||||||
|
char card_name[256];
|
||||||
|
|
||||||
|
snprintf(card_name, sizeof(card_name), "hw:%d", state->card_index);
|
||||||
|
|
||||||
|
err = snd_ctl_open(&state->ctl, card_name, SND_CTL_NONBLOCK);
|
||||||
|
if (err < 0) {
|
||||||
|
spa_log_info(state->log, "%s could not find ctl card: %s",
|
||||||
|
card_name, snd_strerror(err));
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static void bind_ctls_for_params(struct state *state)
|
static void bind_ctls_for_params(struct state *state)
|
||||||
{
|
{
|
||||||
int err;
|
int err;
|
||||||
|
|
@ -838,17 +840,9 @@ static void bind_ctls_for_params(struct state *state)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!state->ctl) {
|
if (!state->ctl) {
|
||||||
char card_name[256];
|
err = open_card_ctl(state);
|
||||||
|
if (err < 0)
|
||||||
fill_card_name(state, NULL, 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 card: %s",
|
|
||||||
card_name, snd_strerror(err));
|
|
||||||
state->ctl = NULL;
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
state->ctl_n_fds = snd_ctl_poll_descriptors_count(state->ctl);
|
state->ctl_n_fds = snd_ctl_poll_descriptors_count(state->ctl);
|
||||||
|
|
@ -1003,7 +997,7 @@ int spa_alsa_clear(struct state *state)
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int probe_pitch_ctl(struct state *state, const char* device_name)
|
static int probe_pitch_ctl(struct state *state)
|
||||||
{
|
{
|
||||||
snd_ctl_elem_id_t *id;
|
snd_ctl_elem_id_t *id;
|
||||||
/* TODO: Add configuration params for the control name and units */
|
/* TODO: Add configuration params for the control name and units */
|
||||||
|
|
@ -1017,16 +1011,10 @@ static int probe_pitch_ctl(struct state *state, const char* device_name)
|
||||||
snd_lib_error_set_handler(silence_error_handler);
|
snd_lib_error_set_handler(silence_error_handler);
|
||||||
|
|
||||||
if (!state->ctl) {
|
if (!state->ctl) {
|
||||||
char card_name[256];
|
err = open_card_ctl(state);
|
||||||
device_name_to_card_name(device_name, card_name, sizeof(card_name));
|
if (err < 0)
|
||||||
|
|
||||||
err = snd_ctl_open(&state->ctl, card_name, SND_CTL_NONBLOCK);
|
|
||||||
if (err < 0) {
|
|
||||||
spa_log_info(state->log, "%s could not find ctl card: %s",
|
|
||||||
card_name, snd_strerror(err));
|
|
||||||
state->ctl = NULL;
|
|
||||||
goto error;
|
goto error;
|
||||||
}
|
|
||||||
opened = true;
|
opened = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1039,8 +1027,8 @@ static int probe_pitch_ctl(struct state *state, const char* device_name)
|
||||||
|
|
||||||
err = snd_ctl_elem_read(state->ctl, state->pitch_elem);
|
err = snd_ctl_elem_read(state->ctl, state->pitch_elem);
|
||||||
if (err < 0) {
|
if (err < 0) {
|
||||||
spa_log_debug(state->log, "%s: did not find ctl %s: %s",
|
spa_log_debug(state->log, "%s: did not find ctl: %s",
|
||||||
device_name, elem_name, snd_strerror(err));
|
elem_name, snd_strerror(err));
|
||||||
|
|
||||||
snd_ctl_elem_value_free(state->pitch_elem);
|
snd_ctl_elem_value_free(state->pitch_elem);
|
||||||
state->pitch_elem = NULL;
|
state->pitch_elem = NULL;
|
||||||
|
|
@ -1057,7 +1045,7 @@ static int probe_pitch_ctl(struct state *state, const char* device_name)
|
||||||
CHECK(snd_ctl_elem_write(state->ctl, state->pitch_elem), "snd_ctl_elem_write");
|
CHECK(snd_ctl_elem_write(state->ctl, state->pitch_elem), "snd_ctl_elem_write");
|
||||||
state->last_rate = 1.0;
|
state->last_rate = 1.0;
|
||||||
|
|
||||||
spa_log_info(state->log, "%s: found ctl %s", device_name, elem_name);
|
spa_log_info(state->log, "found ctl %s", elem_name);
|
||||||
err = 0;
|
err = 0;
|
||||||
error:
|
error:
|
||||||
snd_lib_error_set_handler(NULL);
|
snd_lib_error_set_handler(NULL);
|
||||||
|
|
@ -1124,7 +1112,7 @@ int spa_alsa_open(struct state *state, const char *params)
|
||||||
state->sample_count = 0;
|
state->sample_count = 0;
|
||||||
state->sample_time = 0;
|
state->sample_time = 0;
|
||||||
|
|
||||||
probe_pitch_ctl(state, device_name);
|
probe_pitch_ctl(state);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue