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;
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);

View file

@ -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