From 99e6c77525253ca55a2b0a5282f64ff7cdddc570 Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Thu, 2 Sep 2021 12:33:44 +0200 Subject: [PATCH] alsa: improve device name construction Get the ucm prefix only once, when we open the UCM card and then use it for all devices using the card. Construct the device name right before we open it with the ucm prefix and possibly the AES flags instead of messing with the property. --- spa/plugins/alsa/alsa-pcm.c | 51 +++++++++++++++++++------------------ spa/plugins/alsa/alsa-pcm.h | 2 +- 2 files changed, 27 insertions(+), 26 deletions(-) diff --git a/spa/plugins/alsa/alsa-pcm.c b/spa/plugins/alsa/alsa-pcm.c index 8451b458c..15f2152dc 100644 --- a/spa/plugins/alsa/alsa-pcm.c +++ b/spa/plugins/alsa/alsa-pcm.c @@ -23,6 +23,7 @@ struct card { int ref; uint32_t index; snd_use_case_mgr_t *ucm; + char *ucm_prefix; }; static struct card *find_card(uint32_t index) @@ -41,6 +42,7 @@ static struct card *ensure_card(uint32_t index) { struct card *c; char card_name[64]; + const char *alibpref = NULL; int err; if ((c = find_card(index)) != NULL) @@ -68,6 +70,10 @@ static struct card *ensure_card(uint32_t index) return NULL; } } + if ((snd_use_case_get(c->ucm, "_alibpref", &alibpref) != 0)) + alibpref = NULL; + c->ucm_prefix = (char*)alibpref; + spa_list_append(&cards, &c->link); return c; @@ -82,8 +88,9 @@ static void release_card(uint32_t index) if (--c->ref > 0) return; - snd_use_case_mgr_close(c->ucm); spa_list_remove(&c->link); + free(c->ucm_prefix); + snd_use_case_mgr_close(c->ucm); free(c); } @@ -99,36 +106,20 @@ int spa_alsa_init(struct state *state) if (state->open_ucm) { struct card *c; - const char *alibpref = NULL; c = ensure_card(state->card_index); if (c == NULL) { spa_log_error(state->log, "UCM not available for card %d", state->card_index); return -errno; } - - if ((snd_use_case_get(c->ucm, "_alibpref", &alibpref) != 0)) - alibpref = NULL; - if (alibpref != NULL) { - char name[sizeof(state->props.device)]; - state->ucm_prefix_len = strlen(alibpref); - spa_scnprintf(name, sizeof(name), "%s%s", alibpref, - state->props.device); - strcpy(state->props.device, name); - free((void*)alibpref); - } + state->ucm_prefix = c->ucm_prefix; } return 0; } int spa_alsa_clear(struct state *state) { - if (state->ucm_prefix_len > 0) { - memmove(state->props.device, - state->props.device + state->ucm_prefix_len, - sizeof(state->props.device) - state->ucm_prefix_len); - state->ucm_prefix_len = 0; - } + state->ucm_prefix = NULL; release_card(state->card_index); return 0; } @@ -140,21 +131,27 @@ int spa_alsa_open(struct state *state) int err; struct props *props = &state->props; snd_pcm_info_t *pcminfo; + char device_name[128]; if (state->opened) return 0; CHECK(snd_output_stdio_attach(&state->output, stderr, 0), "attach failed"); - spa_log_info(state->log, NAME" %p: ALSA device open '%s' %s", state, props->device, + spa_scnprintf(device_name, sizeof(device_name), "%s%s%s", + state->ucm_prefix ? state->ucm_prefix : "", + props->device, + (state->is_iec958 || state->is_hdmi) ? ",AES0=6": ""); + + spa_log_info(state->log, NAME" %p: ALSA device open '%s' %s", state, device_name, state->stream == SND_PCM_STREAM_CAPTURE ? "capture" : "playback"); CHECK(snd_pcm_open(&state->hndl, - props->device, + device_name, state->stream, SND_PCM_NONBLOCK | SND_PCM_NO_AUTO_RESAMPLE | SND_PCM_NO_AUTO_CHANNELS | SND_PCM_NO_AUTO_FORMAT), "'%s': %s open failed", - props->device, + device_name, state->stream == SND_PCM_STREAM_CAPTURE ? "capture" : "playback"); if ((err = spa_system_timerfd_create(state->data_system, @@ -751,7 +748,7 @@ spa_alsa_enum_format(struct state *state, int seq, uint32_t start, uint32_t num, return res; } -static int set_pcm_format(struct state *state, struct spa_audio_info_raw *info, uint32_t flags) +static int set_pcm_format(struct state *state, struct spa_audio_info_raw *info, uint32_t flags, bool spdif) { unsigned int rrate, rchannels; snd_pcm_uframes_t period_size; @@ -904,6 +901,10 @@ static int set_iec958_format(struct state *state, struct spa_audio_info_iec958 * { struct spa_audio_info_raw fmt; + spa_log_info(state->log, "using IEC958 Codec:%s rate:%d", + spa_debug_type_find_short_name(spa_type_audio_iec958_codec, info->codec), + info->rate); + fmt.format = SPA_AUDIO_FORMAT_S16_LE; fmt.channels = 2; fmt.rate = info->rate; @@ -925,7 +926,7 @@ static int set_iec958_format(struct state *state, struct spa_audio_info_iec958 * default: return -ENOTSUP; } - return set_pcm_format(state, &fmt, flags); + return set_pcm_format(state, &fmt, flags, true); } int spa_alsa_set_format(struct state *state, struct spa_audio_info *fmt, uint32_t flags) @@ -934,7 +935,7 @@ int spa_alsa_set_format(struct state *state, struct spa_audio_info *fmt, uint32_ switch (fmt->media_subtype) { case SPA_MEDIA_SUBTYPE_raw: - res = set_pcm_format(state, &fmt->info.raw, flags); + res = set_pcm_format(state, &fmt->info.raw, flags, false); break; case SPA_MEDIA_SUBTYPE_iec958: res = set_iec958_format(state, &fmt->info.iec958, flags); diff --git a/spa/plugins/alsa/alsa-pcm.h b/spa/plugins/alsa/alsa-pcm.h index 2dac2f1ab..3072c98e2 100644 --- a/spa/plugins/alsa/alsa-pcm.h +++ b/spa/plugins/alsa/alsa-pcm.h @@ -205,7 +205,7 @@ struct state { struct spa_latency_info latency[2]; struct spa_process_latency_info process_latency; - uint32_t ucm_prefix_len; + const char *ucm_prefix; }; int