From 8168dfdbc1bca47b7a77f2e1f04425057c767ad5 Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Wed, 1 Jul 2020 12:54:27 +0200 Subject: [PATCH] alsa-pcm: allow setting number of channels Allow passing the number of channels when creating a device to restrict the negotiated channels. --- spa/include/spa/param/audio/raw.h | 2 ++ spa/plugins/alsa/alsa-pcm-sink.c | 2 ++ spa/plugins/alsa/alsa-pcm-source.c | 2 ++ spa/plugins/alsa/alsa-pcm.c | 7 +++++++ spa/plugins/alsa/alsa-pcm.h | 2 ++ 5 files changed, 15 insertions(+) diff --git a/spa/include/spa/param/audio/raw.h b/spa/include/spa/param/audio/raw.h index 5f63d8187..18debcce4 100644 --- a/spa/include/spa/param/audio/raw.h +++ b/spa/include/spa/param/audio/raw.h @@ -221,6 +221,8 @@ struct spa_audio_info_raw { #define SPA_KEY_AUDIO_CHANNEL "audio.channel" /**< an audio channel as string, * Ex. "FL" */ +#define SPA_KEY_AUDIO_CHANNELS "audio.channels" /**< an audio channel count as int */ + struct spa_audio_info_dsp { enum spa_audio_format format; /*< format, one of the DSP formats in enum spa_audio_format_dsp */ }; diff --git a/spa/plugins/alsa/alsa-pcm-sink.c b/spa/plugins/alsa/alsa-pcm-sink.c index 2766a7042..f6acb3fdc 100644 --- a/spa/plugins/alsa/alsa-pcm-sink.c +++ b/spa/plugins/alsa/alsa-pcm-sink.c @@ -751,6 +751,8 @@ impl_init(const struct spa_handle_factory *factory, for (i = 0; info && i < info->n_items; i++) { if (!strcmp(info->items[i].key, SPA_KEY_API_ALSA_PATH)) { snprintf(this->props.device, 63, "%s", info->items[i].value); + } else if (!strcmp(info->items[i].key, SPA_KEY_AUDIO_CHANNELS)) { + this->default_channels = atoi(info->items[i].value); } } diff --git a/spa/plugins/alsa/alsa-pcm-source.c b/spa/plugins/alsa/alsa-pcm-source.c index 297fb089f..6bb244e35 100644 --- a/spa/plugins/alsa/alsa-pcm-source.c +++ b/spa/plugins/alsa/alsa-pcm-source.c @@ -770,6 +770,8 @@ impl_init(const struct spa_handle_factory *factory, for (i = 0; info && i < info->n_items; i++) { if (!strcmp(info->items[i].key, SPA_KEY_API_ALSA_PATH)) { snprintf(this->props.device, 63, "%s", info->items[i].value); + } else if (!strcmp(info->items[i].key, SPA_KEY_AUDIO_CHANNELS)) { + this->default_channels = atoi(info->items[i].value); } } return 0; diff --git a/spa/plugins/alsa/alsa-pcm.c b/spa/plugins/alsa/alsa-pcm.c index e009f2564..404e0bdfb 100644 --- a/spa/plugins/alsa/alsa-pcm.c +++ b/spa/plugins/alsa/alsa-pcm.c @@ -357,6 +357,13 @@ spa_alsa_enum_format(struct state *state, int seq, uint32_t start, uint32_t num, CHECK(snd_pcm_hw_params_get_channels_min(params, &min), "get_channels_min"); CHECK(snd_pcm_hw_params_get_channels_max(params, &max), "get_channels_max"); + if (state->default_channels != 0) { + if (min < state->default_channels) + min = state->default_channels; + if (max > state->default_channels) + max = state->default_channels; + } + spa_pod_builder_prop(&b, SPA_FORMAT_AUDIO_channels, 0); if ((maps = snd_pcm_query_chmaps(hndl)) != NULL) { diff --git a/spa/plugins/alsa/alsa-pcm.h b/spa/plugins/alsa/alsa-pcm.h index f8f9cb7bc..e71221fd2 100644 --- a/spa/plugins/alsa/alsa-pcm.h +++ b/spa/plugins/alsa/alsa-pcm.h @@ -101,6 +101,8 @@ struct state { bool have_format; struct spa_audio_info current_format; + unsigned int default_channels; + snd_pcm_uframes_t buffer_frames; snd_pcm_uframes_t period_frames; snd_pcm_format_t format;