Commit 99e6c775 authored by Wim Taymans's avatar Wim Taymans
Browse files

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.
parent 9052b1be
Pipeline #393750 passed with stages
in 3 minutes and 3 seconds
......@@ -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);
......
......@@ -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
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment