From 6538fe70644a80fc4a9c62daa2b97a95704a02b0 Mon Sep 17 00:00:00 2001 From: Sangchul Lee Date: Tue, 5 Jun 2018 17:10:34 +0900 Subject: [PATCH] alsa-util/sink/source: Add infrastructure for supported sample formats There has been a function to get supported sample rates from alsa and an array for it in userdata of each module-alsa-sink/source. Similarly, this patch adds a function to get supported sample formats(bitdepth) from alsa and an array for it to each userdata of the modules. [Version] 11.1-41 [Issue Type] New feature Change-Id: I80397d47324de0b80a24eaa619cd03da8417f746 Signed-off-by: Sangchul Lee --- packaging/pulseaudio.spec | 2 +- src/modules/alsa/alsa-sink.c | 16 +++++++++ src/modules/alsa/alsa-source.c | 16 +++++++++ src/modules/alsa/alsa-util.c | 80 ++++++++++++++++++++++++++++++++++++++++++ src/modules/alsa/alsa-util.h | 3 ++ 5 files changed, 116 insertions(+), 1 deletion(-) diff --git a/packaging/pulseaudio.spec b/packaging/pulseaudio.spec index e784b2a..6a5b800 100644 --- a/packaging/pulseaudio.spec +++ b/packaging/pulseaudio.spec @@ -3,7 +3,7 @@ Name: pulseaudio Summary: Improved Linux sound server Version: 11.1 -Release: 40 +Release: 41 Group: Multimedia/Audio License: LGPL-2.1 URL: http://pulseaudio.org diff --git a/src/modules/alsa/alsa-sink.c b/src/modules/alsa/alsa-sink.c index 402b441..45b460d 100644 --- a/src/modules/alsa/alsa-sink.c +++ b/src/modules/alsa/alsa-sink.c @@ -110,6 +110,9 @@ struct userdata { pa_cvolume hardware_volume; +#ifdef __TIZEN__ + pa_sample_format_t *supported_formats; +#endif unsigned int *rates; size_t @@ -2286,6 +2289,14 @@ pa_sink *pa_alsa_sink_new(pa_module *m, pa_modargs *ma, const char*driver, pa_ca if ((is_iec958(u) || is_hdmi(u)) && ss.channels == 2) set_formats = true; +#ifdef __TIZEN__ + u->supported_formats = pa_alsa_get_supported_formats(u->pcm_handle, ss.format); + if (!u->supported_formats) { + pa_log_error("Failed to find any supported sample formats."); + goto fail; + } + +#endif u->rates = pa_alsa_get_supported_rates(u->pcm_handle, ss.rate); if (!u->rates) { pa_log_error("Failed to find any supported sample rates."); @@ -2569,6 +2580,11 @@ static void userdata_free(struct userdata *u) { if (u->formats) pa_idxset_free(u->formats, (pa_free_cb_t) pa_format_info_free); +#ifdef __TIZEN__ + if (u->supported_formats) + pa_xfree(u->supported_formats); + +#endif if (u->rates) pa_xfree(u->rates); diff --git a/src/modules/alsa/alsa-source.c b/src/modules/alsa/alsa-source.c index 6d85153..443c8a9 100644 --- a/src/modules/alsa/alsa-source.c +++ b/src/modules/alsa/alsa-source.c @@ -98,6 +98,9 @@ struct userdata { pa_cvolume hardware_volume; +#ifdef __TIZEN__ + pa_sample_format_t *supported_formats; +#endif unsigned int *rates; size_t @@ -1963,6 +1966,14 @@ pa_source *pa_alsa_source_new(pa_module *m, pa_modargs *ma, const char*driver, p pa_log_info("Disabling latency range changes on overrun"); } +#ifdef __TIZEN__ + u->supported_formats = pa_alsa_get_supported_formats(u->pcm_handle, ss.format); + if (!u->supported_formats) { + pa_log_error("Failed to find any supported sample formats."); + goto fail; + } + +#endif u->rates = pa_alsa_get_supported_rates(u->pcm_handle, ss.rate); if (!u->rates) { pa_log_error("Failed to find any supported sample rates."); @@ -2197,6 +2208,11 @@ static void userdata_free(struct userdata *u) { if (u->smoother) pa_smoother_free(u->smoother); +#ifdef __TIZEN__ + if (u->supported_formats) + pa_xfree(u->supported_formats); + +#endif if (u->rates) pa_xfree(u->rates); diff --git a/src/modules/alsa/alsa-util.c b/src/modules/alsa/alsa-util.c index 61fb490..b664501 100644 --- a/src/modules/alsa/alsa-util.c +++ b/src/modules/alsa/alsa-util.c @@ -1417,6 +1417,86 @@ unsigned int *pa_alsa_get_supported_rates(snd_pcm_t *pcm, unsigned int fallback_ return rates; } +#ifdef __TIZEN__ +pa_sample_format_t *pa_alsa_get_supported_formats(snd_pcm_t *pcm, pa_sample_format_t fallback_format) { + static const snd_pcm_format_t format_trans_to_pa[] = { + [SND_PCM_FORMAT_U8] = PA_SAMPLE_U8, + [SND_PCM_FORMAT_A_LAW] = PA_SAMPLE_ALAW, + [SND_PCM_FORMAT_MU_LAW] = PA_SAMPLE_ULAW, + [SND_PCM_FORMAT_S16_LE] = PA_SAMPLE_S16LE, + [SND_PCM_FORMAT_S16_BE] = PA_SAMPLE_S16BE, + [SND_PCM_FORMAT_FLOAT_LE] = PA_SAMPLE_FLOAT32LE, + [SND_PCM_FORMAT_FLOAT_BE] = PA_SAMPLE_FLOAT32BE, + [SND_PCM_FORMAT_S32_LE] = PA_SAMPLE_S32LE, + [SND_PCM_FORMAT_S32_BE] = PA_SAMPLE_S32BE, + [SND_PCM_FORMAT_S24_3LE] = PA_SAMPLE_S24LE, + [SND_PCM_FORMAT_S24_3BE] = PA_SAMPLE_S24BE, + [SND_PCM_FORMAT_S24_LE] = PA_SAMPLE_S24_32LE, + [SND_PCM_FORMAT_S24_BE] = PA_SAMPLE_S24_32BE, + }; + static const snd_pcm_format_t all_formats[] = { + SND_PCM_FORMAT_U8, + SND_PCM_FORMAT_A_LAW, + SND_PCM_FORMAT_MU_LAW, + SND_PCM_FORMAT_S16_LE, + SND_PCM_FORMAT_S16_BE, + SND_PCM_FORMAT_FLOAT_LE, + SND_PCM_FORMAT_FLOAT_BE, + SND_PCM_FORMAT_S32_LE, + SND_PCM_FORMAT_S32_BE, + SND_PCM_FORMAT_S24_3LE, + SND_PCM_FORMAT_S24_3BE, + SND_PCM_FORMAT_S24_LE, + SND_PCM_FORMAT_S24_BE, + }; + bool supported[PA_ELEMENTSOF(all_formats)] = { + false, + }; + snd_pcm_hw_params_t *hwparams; + unsigned int i, j, n; + pa_sample_format_t *formats = NULL; + int ret; + + snd_pcm_hw_params_alloca(&hwparams); + + if ((ret = snd_pcm_hw_params_any(pcm, hwparams)) < 0) { + pa_log_debug("snd_pcm_hw_params_any() failed: %s", pa_alsa_strerror(ret)); + return NULL; + } + + for (i = 0, n = 0; i < PA_ELEMENTSOF(all_formats); i++) { + if (snd_pcm_hw_params_test_format(pcm, hwparams, all_formats[i]) == 0) { + supported[i] = true; + n++; + } + } + + if (n > 0) { + formats = pa_xnew(pa_sample_format_t, n + 1); + + for (i = 0, j = 0; i < PA_ELEMENTSOF(all_formats); i++) { + if (supported[i]) + formats[j++] = format_trans_to_pa[all_formats[i]]; + } + + formats[j] = PA_SAMPLE_MAX; + } else { + formats = pa_xnew(pa_sample_format_t, 2); + + formats[0] = fallback_format; + if ((ret = snd_pcm_hw_params_set_format(pcm, hwparams, format_trans_to_pa[formats[0]])) < 0) { + pa_log_debug("snd_pcm_hw_params_set_format() failed: %s", pa_alsa_strerror(ret)); + pa_xfree(formats); + return NULL; + } + + formats[1] = PA_SAMPLE_MAX; + } + + return formats; +} +#endif + bool pa_alsa_pcm_is_hw(snd_pcm_t *pcm) { snd_pcm_info_t* info; snd_pcm_info_alloca(&info); diff --git a/src/modules/alsa/alsa-util.h b/src/modules/alsa/alsa-util.h index 8345a0b..5d4d327 100644 --- a/src/modules/alsa/alsa-util.h +++ b/src/modules/alsa/alsa-util.h @@ -132,6 +132,9 @@ char *pa_alsa_get_driver_name_by_pcm(snd_pcm_t *pcm); char *pa_alsa_get_reserve_name(const char *device); unsigned int *pa_alsa_get_supported_rates(snd_pcm_t *pcm, unsigned int fallback_rate); +#ifdef __TIZEN__ +pa_sample_format_t *pa_alsa_get_supported_formats(snd_pcm_t *pcm, pa_sample_format_t fallback_format); +#endif bool pa_alsa_pcm_is_hw(snd_pcm_t *pcm); bool pa_alsa_pcm_is_modem(snd_pcm_t *pcm); -- 2.7.4