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