]> code.delx.au - pulseaudio/commitdiff
add new call pa_alsa_open_by_device_id_profile()
authorLennart Poettering <lennart@poettering.net>
Tue, 20 Jan 2009 20:36:57 +0000 (21:36 +0100)
committerLennart Poettering <lennart@poettering.net>
Tue, 20 Jan 2009 20:37:30 +0000 (21:37 +0100)
src/modules/alsa/alsa-util.c
src/modules/alsa/alsa-util.h
src/modules/alsa/module-alsa-sink.c
src/modules/alsa/module-alsa-source.c

index b7f44b8535432025dc4b4354dc036849e85ae0ec..e154f6ea895de38d38ed099e90851d3fc02dc1cd 100644 (file)
@@ -574,7 +574,7 @@ static const struct pa_alsa_profile_info device_table[] = {
     {{ 0, { 0 }}, NULL, NULL, NULL, 0 }
 };
 
-snd_pcm_t *pa_alsa_open_by_device_id(
+snd_pcm_t *pa_alsa_open_by_device_id_auto(
         const char *dev_id,
         char **dev,
         pa_sample_spec *ss,
@@ -585,8 +585,7 @@ snd_pcm_t *pa_alsa_open_by_device_id(
         snd_pcm_uframes_t tsched_size,
         pa_bool_t *use_mmap,
         pa_bool_t *use_tsched,
-        const char**config_description,
-        const char **config_name) {
+        const pa_alsa_profile_info **profile) {
 
     int i;
     int direction = 1;
@@ -642,11 +641,8 @@ snd_pcm_t *pa_alsa_open_by_device_id(
                 *map = device_table[i].map;
                 pa_assert(map->channels == ss->channels);
 
-                if (config_description)
-                    *config_description = device_table[i].description;
-                if (config_name)
-                    *config_name = device_table[i].name;
-
+                if (profile)
+                    *profile = &device_table[i];
 
                 return pcm_handle;
             }
@@ -703,10 +699,64 @@ snd_pcm_t *pa_alsa_open_by_device_id(
     pcm_handle = pa_alsa_open_by_device_string(d, dev, ss, map, mode, nfrags, period_size, tsched_size, use_mmap, use_tsched, FALSE);
     pa_xfree(d);
 
-    if (pcm_handle) {
-        *config_description = NULL;
-        *config_name = NULL;
-    }
+    if (pcm_handle && profile)
+        *profile = NULL;
+
+    return pcm_handle;
+}
+
+snd_pcm_t *pa_alsa_open_by_device_id_profile(
+        const char *dev_id,
+        char **dev,
+        pa_sample_spec *ss,
+        pa_channel_map* map,
+        int mode,
+        uint32_t *nfrags,
+        snd_pcm_uframes_t *period_size,
+        snd_pcm_uframes_t tsched_size,
+        pa_bool_t *use_mmap,
+        pa_bool_t *use_tsched,
+        const pa_alsa_profile_info *profile) {
+
+    char *d;
+    snd_pcm_t *pcm_handle;
+    pa_sample_spec try_ss;
+
+    pa_assert(dev_id);
+    pa_assert(dev);
+    pa_assert(ss);
+    pa_assert(map);
+    pa_assert(nfrags);
+    pa_assert(period_size);
+    pa_assert(profile);
+
+    d = pa_sprintf_malloc("%s:%s", profile->alsa_name, dev_id);
+
+    try_ss.channels = profile->map.channels;
+    try_ss.rate = ss->rate;
+    try_ss.format = ss->format;
+
+    pcm_handle = pa_alsa_open_by_device_string(
+            d,
+            dev,
+            &try_ss,
+            map,
+            mode,
+            nfrags,
+            period_size,
+            tsched_size,
+            use_mmap,
+            use_tsched,
+            TRUE);
+
+    pa_xfree(d);
+
+    if (!pcm_handle)
+        return NULL;
+
+    *ss = try_ss;
+    *map = profile->map;
+    pa_assert(map->channels == ss->channels);
 
     return pcm_handle;
 }
index 59656252529e193aebecb9cc8cd9485d3db8467c..18b04028188dcf66d48f3fa2533a65d0695dcc11 100644 (file)
@@ -54,7 +54,16 @@ int pa_alsa_set_sw_params(snd_pcm_t *pcm, snd_pcm_uframes_t avail_min);
 int pa_alsa_prepare_mixer(snd_mixer_t *mixer, const char *dev);
 snd_mixer_elem_t *pa_alsa_find_elem(snd_mixer_t *mixer, const char *name, const char *fallback, pa_bool_t playback);
 
-snd_pcm_t *pa_alsa_open_by_device_id(
+typedef struct pa_alsa_profile_info {
+    pa_channel_map map;
+    const char *alsa_name;
+    const char *description;
+    const char *name;
+    unsigned priority;
+} pa_alsa_profile_info;
+
+/* Picks a working profile based on the specified ss/map */
+snd_pcm_t *pa_alsa_open_by_device_id_auto(
         const char *dev_id,
         char **dev,
         pa_sample_spec *ss,
@@ -65,9 +74,23 @@ snd_pcm_t *pa_alsa_open_by_device_id(
         snd_pcm_uframes_t tsched_size,
         pa_bool_t *use_mmap,
         pa_bool_t *use_tsched,
-        const char **config_name,
-        const char **config_description);
+        const pa_alsa_profile_info **profile);
 
+/* Uses the specified profile */
+snd_pcm_t *pa_alsa_open_by_device_id_profile(
+        const char *dev_id,
+        char **dev,
+        pa_sample_spec *ss,
+        pa_channel_map* map,
+        int mode,
+        uint32_t *nfrags,
+        snd_pcm_uframes_t *period_size,
+        snd_pcm_uframes_t tsched_size,
+        pa_bool_t *use_mmap,
+        pa_bool_t *use_tsched,
+        const pa_alsa_profile_info *profile);
+
+/* Opens the explicit ALSA device */
 snd_pcm_t *pa_alsa_open_by_device_string(
         const char *device,
         char **dev,
@@ -81,14 +104,6 @@ snd_pcm_t *pa_alsa_open_by_device_string(
         pa_bool_t *use_tsched,
         pa_bool_t require_exact_channel_number);
 
-typedef struct pa_alsa_profile_info {
-    pa_channel_map map;
-    const char *alsa_name;
-    const char *description;
-    const char *name;
-    unsigned priority;
-} pa_alsa_profile_info;
-
 int pa_alsa_probe_profiles(
         const char *dev_id,
         const pa_sample_spec *ss,
index 62ce89cbbd34b736f7e343a0b6757f8f175442b9..12d340775a54954f50bbfaaf32a2d8e783cb5ab7 100644 (file)
@@ -1253,7 +1253,7 @@ int pa__init(pa_module*m) {
     pa_bool_t use_mmap = TRUE, b, use_tsched = TRUE, d;
     pa_usec_t usec;
     pa_sink_new_data data;
-    const char *profile_description = NULL, *profile_name = NULL;
+    const pa_alsa_profile_info *profile = NULL;
 
     snd_pcm_info_alloca(&pcm_info);
 
@@ -1332,13 +1332,13 @@ int pa__init(pa_module*m) {
 
     if ((dev_id = pa_modargs_get_value(ma, "device_id", NULL))) {
 
-        if (!(u->pcm_handle = pa_alsa_open_by_device_id(
+        if (!(u->pcm_handle = pa_alsa_open_by_device_id_auto(
                       dev_id,
                       &u->device_name,
                       &ss, &map,
                       SND_PCM_STREAM_PLAYBACK,
                       &nfrags, &period_frames, tsched_frames,
-                      &b, &d, &profile_description, &profile_name)))
+                      &b, &d, &profile)))
 
             goto fail;
 
@@ -1358,8 +1358,8 @@ int pa__init(pa_module*m) {
     pa_assert(u->device_name);
     pa_log_info("Successfully opened device %s.", u->device_name);
 
-    if (profile_description)
-        pa_log_info("Selected configuration '%s' (%s).", profile_description, profile_name);
+    if (profile)
+        pa_log_info("Selected configuration '%s' (%s).", profile->description, profile->name);
 
     if (use_mmap && !b) {
         pa_log_info("Device doesn't support mmap(), falling back to UNIX read/write mode.");
@@ -1444,10 +1444,10 @@ int pa__init(pa_module*m) {
     pa_proplist_setf(data.proplist, PA_PROP_DEVICE_BUFFERING_FRAGMENT_SIZE, "%lu", (unsigned long) (period_frames * frame_size));
     pa_proplist_sets(data.proplist, PA_PROP_DEVICE_ACCESS_MODE, u->use_tsched ? "mmap+timer" : (u->use_mmap ? "mmap" : "serial"));
 
-    if (profile_name)
-        pa_proplist_sets(data.proplist, PA_PROP_DEVICE_PROFILE_NAME, profile_name);
-    if (profile_description)
-        pa_proplist_sets(data.proplist, PA_PROP_DEVICE_PROFILE_DESCRIPTION, profile_description);
+    if (profile) {
+        pa_proplist_sets(data.proplist, PA_PROP_DEVICE_PROFILE_NAME, profile->name);
+        pa_proplist_sets(data.proplist, PA_PROP_DEVICE_PROFILE_DESCRIPTION, profile->description);
+    }
 
     u->sink = pa_sink_new(m->core, &data, PA_SINK_HARDWARE|PA_SINK_LATENCY);
     pa_sink_new_data_done(&data);
index 7ca305f58ce2d33303dad0bd2893d3ccf5ac36de..08ef12fa72fcc46352cbd43f5a9737f4cf8b983a 100644 (file)
@@ -1087,7 +1087,7 @@ int pa__init(pa_module*m) {
     pa_bool_t namereg_fail;
     pa_bool_t use_mmap = TRUE, b, use_tsched = TRUE, d;
     pa_source_new_data data;
-    const char *profile_description = NULL, *profile_name = NULL;
+    const pa_alsa_profile_info *profile = NULL;
 
     snd_pcm_info_alloca(&pcm_info);
 
@@ -1161,13 +1161,13 @@ int pa__init(pa_module*m) {
 
     if ((dev_id = pa_modargs_get_value(ma, "device_id", NULL))) {
 
-        if (!(u->pcm_handle = pa_alsa_open_by_device_id(
+        if (!(u->pcm_handle = pa_alsa_open_by_device_id_auto(
                       dev_id,
                       &u->device_name,
                       &ss, &map,
                       SND_PCM_STREAM_CAPTURE,
                       &nfrags, &period_frames, tsched_frames,
-                      &b, &d, &profile_description, &profile_name)))
+                      &b, &d, &profile)))
             goto fail;
 
     } else {
@@ -1185,8 +1185,8 @@ int pa__init(pa_module*m) {
     pa_assert(u->device_name);
     pa_log_info("Successfully opened device %s.", u->device_name);
 
-    if (profile_description)
-        pa_log_info("Selected configuration '%s' (%s).", profile_description, profile_name);
+    if (profile)
+        pa_log_info("Selected configuration '%s' (%s).", profile->description, profile->name);
 
     if (use_mmap && !b) {
         pa_log_info("Device doesn't support mmap(), falling back to UNIX read/write mode.");
@@ -1271,10 +1271,10 @@ int pa__init(pa_module*m) {
     pa_proplist_setf(data.proplist, PA_PROP_DEVICE_BUFFERING_FRAGMENT_SIZE, "%lu", (unsigned long) (period_frames * frame_size));
     pa_proplist_sets(data.proplist, PA_PROP_DEVICE_ACCESS_MODE, u->use_tsched ? "mmap+timer" : (u->use_mmap ? "mmap" : "serial"));
 
-    if (profile_name)
-        pa_proplist_sets(data.proplist, PA_PROP_DEVICE_PROFILE_NAME, profile_name);
-    if (profile_description)
-        pa_proplist_sets(data.proplist, PA_PROP_DEVICE_PROFILE_DESCRIPTION, profile_description);
+    if (profile) {
+        pa_proplist_sets(data.proplist, PA_PROP_DEVICE_PROFILE_NAME, profile->name);
+        pa_proplist_sets(data.proplist, PA_PROP_DEVICE_PROFILE_DESCRIPTION, profile->description);
+    }
 
     u->source = pa_source_new(m->core, &data, PA_SOURCE_HARDWARE|PA_SOURCE_LATENCY);
     pa_source_new_data_done(&data);