alsa-util/sink/source: Add infrastructure for supported sample formats 80/182580/3
authorSangchul Lee <sc11.lee@samsung.com>
Tue, 5 Jun 2018 08:10:34 +0000 (17:10 +0900)
committerSangchul Lee <sc11.lee@samsung.com>
Mon, 9 Jul 2018 01:21:10 +0000 (10:21 +0900)
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 <sc11.lee@samsung.com>
packaging/pulseaudio.spec
src/modules/alsa/alsa-sink.c
src/modules/alsa/alsa-source.c
src/modules/alsa/alsa-util.c
src/modules/alsa/alsa-util.h

index e784b2a..6a5b800 100644 (file)
@@ -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
index 402b441..45b460d 100644 (file)
@@ -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);
 
index 6d85153..443c8a9 100644 (file)
@@ -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);
 
index 61fb490..b664501 100644 (file)
@@ -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);
index 8345a0b..5d4d327 100644 (file)
@@ -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);