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.
This commit is contained in:
Wim Taymans 2021-09-02 12:33:44 +02:00
parent 9052b1be33
commit 99e6c77525
2 changed files with 27 additions and 26 deletions

View file

@ -23,6 +23,7 @@ struct card {
int ref; int ref;
uint32_t index; uint32_t index;
snd_use_case_mgr_t *ucm; snd_use_case_mgr_t *ucm;
char *ucm_prefix;
}; };
static struct card *find_card(uint32_t index) static struct card *find_card(uint32_t index)
@ -41,6 +42,7 @@ static struct card *ensure_card(uint32_t index)
{ {
struct card *c; struct card *c;
char card_name[64]; char card_name[64];
const char *alibpref = NULL;
int err; int err;
if ((c = find_card(index)) != NULL) if ((c = find_card(index)) != NULL)
@ -68,6 +70,10 @@ static struct card *ensure_card(uint32_t index)
return NULL; 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); spa_list_append(&cards, &c->link);
return c; return c;
@ -82,8 +88,9 @@ static void release_card(uint32_t index)
if (--c->ref > 0) if (--c->ref > 0)
return; return;
snd_use_case_mgr_close(c->ucm);
spa_list_remove(&c->link); spa_list_remove(&c->link);
free(c->ucm_prefix);
snd_use_case_mgr_close(c->ucm);
free(c); free(c);
} }
@ -99,36 +106,20 @@ int spa_alsa_init(struct state *state)
if (state->open_ucm) { if (state->open_ucm) {
struct card *c; struct card *c;
const char *alibpref = NULL;
c = ensure_card(state->card_index); c = ensure_card(state->card_index);
if (c == NULL) { if (c == NULL) {
spa_log_error(state->log, "UCM not available for card %d", state->card_index); spa_log_error(state->log, "UCM not available for card %d", state->card_index);
return -errno; return -errno;
} }
state->ucm_prefix = c->ucm_prefix;
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);
}
} }
return 0; return 0;
} }
int spa_alsa_clear(struct state *state) int spa_alsa_clear(struct state *state)
{ {
if (state->ucm_prefix_len > 0) { state->ucm_prefix = NULL;
memmove(state->props.device,
state->props.device + state->ucm_prefix_len,
sizeof(state->props.device) - state->ucm_prefix_len);
state->ucm_prefix_len = 0;
}
release_card(state->card_index); release_card(state->card_index);
return 0; return 0;
} }
@ -140,21 +131,27 @@ int spa_alsa_open(struct state *state)
int err; int err;
struct props *props = &state->props; struct props *props = &state->props;
snd_pcm_info_t *pcminfo; snd_pcm_info_t *pcminfo;
char device_name[128];
if (state->opened) if (state->opened)
return 0; return 0;
CHECK(snd_output_stdio_attach(&state->output, stderr, 0), "attach failed"); 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"); state->stream == SND_PCM_STREAM_CAPTURE ? "capture" : "playback");
CHECK(snd_pcm_open(&state->hndl, CHECK(snd_pcm_open(&state->hndl,
props->device, device_name,
state->stream, state->stream,
SND_PCM_NONBLOCK | SND_PCM_NONBLOCK |
SND_PCM_NO_AUTO_RESAMPLE | SND_PCM_NO_AUTO_RESAMPLE |
SND_PCM_NO_AUTO_CHANNELS | SND_PCM_NO_AUTO_FORMAT), "'%s': %s open failed", 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"); state->stream == SND_PCM_STREAM_CAPTURE ? "capture" : "playback");
if ((err = spa_system_timerfd_create(state->data_system, 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; 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; unsigned int rrate, rchannels;
snd_pcm_uframes_t period_size; 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; 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.format = SPA_AUDIO_FORMAT_S16_LE;
fmt.channels = 2; fmt.channels = 2;
fmt.rate = info->rate; fmt.rate = info->rate;
@ -925,7 +926,7 @@ static int set_iec958_format(struct state *state, struct spa_audio_info_iec958 *
default: default:
return -ENOTSUP; 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) 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) { switch (fmt->media_subtype) {
case SPA_MEDIA_SUBTYPE_raw: 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; break;
case SPA_MEDIA_SUBTYPE_iec958: case SPA_MEDIA_SUBTYPE_iec958:
res = set_iec958_format(state, &fmt->info.iec958, flags); res = set_iec958_format(state, &fmt->info.iec958, flags);

View file

@ -205,7 +205,7 @@ struct state {
struct spa_latency_info latency[2]; struct spa_latency_info latency[2];
struct spa_process_latency_info process_latency; struct spa_process_latency_info process_latency;
uint32_t ucm_prefix_len; const char *ucm_prefix;
}; };
int int