]> git.alsa-project.org Git - alsa-lib.git/commitdiff
Added embedded/anonymous slave PCM definition
authorAbramo Bagnara <abramo@alsa-project.org>
Mon, 14 May 2001 15:44:37 +0000 (15:44 +0000)
committerAbramo Bagnara <abramo@alsa-project.org>
Mon, 14 May 2001 15:44:37 +0000 (15:44 +0000)
15 files changed:
doc/asoundrc.doc
src/pcm/pcm.c
src/pcm/pcm_adpcm.c
src/pcm/pcm_alaw.c
src/pcm/pcm_copy.c
src/pcm/pcm_file.c
src/pcm/pcm_linear.c
src/pcm/pcm_local.h
src/pcm/pcm_meter.c
src/pcm/pcm_mulaw.c
src/pcm/pcm_multi.c
src/pcm/pcm_plug.c
src/pcm/pcm_rate.c
src/pcm/pcm_route.c
src/pcm/pcm_share.c

index 0033b5def1ffe4dcf2f6b8d941e35a34af4b49c2..143a9afc284430ad2e0dfc87ae257db5def97db1 100644 (file)
@@ -21,6 +21,8 @@ pcm_scope_type.NAME {
 # Slave PCM definition
 pcm_slave.NAME {
   pcm STR              # PCM name
+  # or
+  pcm { }              # PCM definition
   format STR           # Format
   channels INT         # Channels
   rate INT             # Rate
@@ -46,6 +48,8 @@ pcm.NAME {
   # or
   slave {              # Slave definition or name
     pcm STR            # Slave PCM name
+    # or
+    pcm { }            # Slave PCM definition
   }
   ttable {             # Transfer table (bidimensional compound of 
                        # cchannels * schannels numbers)
@@ -63,6 +67,8 @@ pcm.NAME {
   # or
   slave {              # Slave definition or name
     pcm STR            # Slave PCM name
+    # or
+    pcm { }            # Slave PCM definition
     format STR         # Slave format
   }
 
@@ -72,6 +78,8 @@ pcm.NAME {
   # or
   slave {              # Slave definition or name
     pcm STR            # Slave PCM name
+    # or
+    pcm { }            # Slave PCM definition
     [format STR]       # Slave format (default client format)
     rate INT           # Slave rate
   }
@@ -82,6 +90,8 @@ pcm.NAME {
   # or
   slave {              # Slave definition or name
     pcm STR            # Slave PCM name
+    # or
+    pcm { }            # Slave PCM definition
     [format STR]       # Slave format (default client format)
     [channels INT]     # Slave channels (default client channels)
   }
@@ -99,6 +109,8 @@ pcm.NAME {
     # or
     N {                        # Slave definition for slave N
       pcm STR          # Slave PCM name
+    # or
+      pcm { }          # Slave PCM definition
       channels INT     # Slave channels
     }
   }
@@ -115,6 +127,8 @@ pcm.NAME {
   # or
   slave {              # Slave definition or name
     pcm STR            # Slave PCM name
+    # or
+    pcm { }            # Slave PCM definition
   }
   file STR             # File name
   # or
@@ -127,6 +141,8 @@ pcm.NAME {
   # or
   slave {              # Slave definition or name
     pcm STR            # Slave PCM name
+    # or
+    pcm { }            # Slave PCM definition
   }
   [frequency INT]      # Updates per second
   scopes {             # Scopes
@@ -142,6 +158,8 @@ pcm.NAME {
   # or
   slave {              # Slave definition or name
     pcm STR            # Slave PCM name
+    # or
+    pcm { }            # Slave PCM definition
     [format STR]       # Slave format (default client format)
     [channels INT]     # Slave channels (default client channels)
   }
@@ -165,6 +183,8 @@ pcm.NAME {
   # or
   slave {              # Slave definition or name
     pcm STR            # Slave PCM name
+    # or
+    pcm { }            # Slave PCM definition
   }
 
 
index 23185aeb62f53520213c2280bb373b6e1b0e260b..9890235a99a7292ceb14c855e071105c06a3fe12 100644 (file)
@@ -909,31 +909,93 @@ ssize_t snd_pcm_samples_to_bytes(snd_pcm_t *pcm, int samples)
        return samples * pcm->sample_bits / 8;
 }
 
-/**
- * \brief Opens a PCM
- * \param pcmp Returned PCM handle
- * \param name ASCII identifier of the PCM handle
- * \param stream Wanted stream
- * \param mode Open mode (see #SND_PCM_NONBLOCK, #SND_PCM_ASYNC)
- * \return 0 on success otherwise a negative error code
- */
-int snd_pcm_open(snd_pcm_t **pcmp, const char *name, 
-                snd_pcm_stream_t stream, int mode)
+static int snd_pcm_open_conf(snd_pcm_t **pcmp, const char *name,
+                            snd_config_t *pcm_conf,
+                            snd_pcm_stream_t stream, int mode)
 {
        const char *str;
        char buf[256];
        int err;
-       snd_config_t *pcm_conf, *conf, *type_conf = NULL;
+       snd_config_t *conf, *type_conf = NULL;
        snd_config_iterator_t i, next;
        const char *lib = NULL, *open_name = NULL;
        int (*open_func)(snd_pcm_t **, const char *, snd_config_t *, 
                         snd_pcm_stream_t, int);
        void *h;
-       const char *name1;
-       assert(pcmp && name);
-       err = snd_config_update();
-       if (err < 0)
+       if (snd_config_get_type(pcm_conf) != SND_CONFIG_TYPE_COMPOUND) {
+               if (name)
+                       SNDERR("Invalid type for PCM %s definition", name);
+               else
+                       SNDERR("Invalid type for PCM definition");
+               return -EINVAL;
+       }
+       err = snd_config_search(pcm_conf, "type", &conf);
+       if (err < 0) {
+               SNDERR("type is not defined");
+               return err;
+       }
+       err = snd_config_get_string(conf, &str);
+       if (err < 0) {
+               SNDERR("Invalid type for %s", snd_config_get_id(conf));
                return err;
+       }
+       err = snd_config_search_alias(snd_config, "pcm_type", str, &type_conf);
+       if (err >= 0) {
+               if (snd_config_get_type(type_conf) != SND_CONFIG_TYPE_COMPOUND) {
+                       SNDERR("Invalid type for PCM type %s definition", str);
+                       return -EINVAL;
+               }
+               snd_config_for_each(i, next, type_conf) {
+                       snd_config_t *n = snd_config_iterator_entry(i);
+                       const char *id = snd_config_get_id(n);
+                       if (strcmp(id, "comment") == 0)
+                               continue;
+                       if (strcmp(id, "lib") == 0) {
+                               err = snd_config_get_string(n, &lib);
+                               if (err < 0) {
+                                       SNDERR("Invalid type for %s", id);
+                                       return -EINVAL;
+                               }
+                               continue;
+                       }
+                       if (strcmp(id, "open") == 0) {
+                               err = snd_config_get_string(n, &open_name);
+                               if (err < 0) {
+                                       SNDERR("Invalid type for %s", id);
+                                       return -EINVAL;
+                               }
+                               continue;
+                       }
+                       SNDERR("Unknown field %s", id);
+                       return -EINVAL;
+               }
+       }
+       if (!open_name) {
+               open_name = buf;
+               snprintf(buf, sizeof(buf), "_snd_pcm_%s_open", str);
+       }
+       if (!lib)
+               lib = "libasound.so";
+       h = dlopen(lib, RTLD_NOW);
+       if (!h) {
+               SNDERR("Cannot open shared library %s", lib);
+               return -ENOENT;
+       }
+       open_func = dlsym(h, open_name);
+       if (!open_func) {
+               SNDERR("symbol %s is not defined inside %s", open_name, lib);
+               dlclose(h);
+               return -ENXIO;
+       }
+       return open_func(pcmp, name, pcm_conf, stream, mode);
+}
+
+static int snd_pcm_open_noupdate(snd_pcm_t **pcmp, const char *name, 
+                                snd_pcm_stream_t stream, int mode)
+{
+       int err;
+       snd_config_t *pcm_conf;
+       const char *name1;
 
        err = snd_config_search_alias(snd_config, "pcm", name, &pcm_conf);
        name1 = name;
@@ -1005,69 +1067,37 @@ int snd_pcm_open(snd_pcm_t **pcmp, const char *name,
                SNDERR("Unknown PCM %s", name1);
                return -ENOENT;
        }
-       if (snd_config_get_type(pcm_conf) != SND_CONFIG_TYPE_COMPOUND) {
-               SNDERR("Invalid type for PCM %s definition", name1);
-               return -EINVAL;
-       }
-       err = snd_config_search(pcm_conf, "type", &conf);
-       if (err < 0) {
-               SNDERR("type is not defined");
-               return err;
-       }
-       err = snd_config_get_string(conf, &str);
-       if (err < 0) {
-               SNDERR("Invalid type for %s", snd_config_get_id(conf));
+       return snd_pcm_open_conf(pcmp, name, pcm_conf, stream, mode);
+}
+
+#ifndef DOC_HIDDEN
+int snd_pcm_open_slave(snd_pcm_t **pcmp, snd_config_t *conf,
+                      snd_pcm_stream_t stream, int mode)
+{
+       const char *str;
+       if (snd_config_get_string(conf, &str) >= 0)
+               return snd_pcm_open_noupdate(pcmp, str, stream, mode);
+       return snd_pcm_open_conf(pcmp, NULL, conf, stream, mode);
+}
+#endif
+
+/**
+ * \brief Opens a PCM
+ * \param pcmp Returned PCM handle
+ * \param name ASCII identifier of the PCM handle
+ * \param stream Wanted stream
+ * \param mode Open mode (see #SND_PCM_NONBLOCK, #SND_PCM_ASYNC)
+ * \return 0 on success otherwise a negative error code
+ */
+int snd_pcm_open(snd_pcm_t **pcmp, const char *name, 
+                snd_pcm_stream_t stream, int mode)
+{
+       int err;
+       assert(pcmp && name);
+       err = snd_config_update();
+       if (err < 0)
                return err;
-       }
-       err = snd_config_search_alias(snd_config, "pcm_type", str, &type_conf);
-       if (err >= 0) {
-               if (snd_config_get_type(type_conf) != SND_CONFIG_TYPE_COMPOUND) {
-                       SNDERR("Invalid type for PCM type %s definition", str);
-                       return -EINVAL;
-               }
-               snd_config_for_each(i, next, type_conf) {
-                       snd_config_t *n = snd_config_iterator_entry(i);
-                       const char *id = snd_config_get_id(n);
-                       if (strcmp(id, "comment") == 0)
-                               continue;
-                       if (strcmp(id, "lib") == 0) {
-                               err = snd_config_get_string(n, &lib);
-                               if (err < 0) {
-                                       SNDERR("Invalid type for %s", id);
-                                       return -EINVAL;
-                               }
-                               continue;
-                       }
-                       if (strcmp(id, "open") == 0) {
-                               err = snd_config_get_string(n, &open_name);
-                               if (err < 0) {
-                                       SNDERR("Invalid type for %s", id);
-                                       return -EINVAL;
-                               }
-                               continue;
-                       }
-                       SNDERR("Unknown field %s", id);
-                       return -EINVAL;
-               }
-       }
-       if (!open_name) {
-               open_name = buf;
-               snprintf(buf, sizeof(buf), "_snd_pcm_%s_open", str);
-       }
-       if (!lib)
-               lib = "libasound.so";
-       h = dlopen(lib, RTLD_NOW);
-       if (!h) {
-               SNDERR("Cannot open shared library %s", lib);
-               return -ENOENT;
-       }
-       open_func = dlsym(h, open_name);
-       if (!open_func) {
-               SNDERR("symbol %s is not defined inside %s", open_name, lib);
-               dlclose(h);
-               return -ENXIO;
-       }
-       return open_func(pcmp, name, pcm_conf, stream, mode);
+       return snd_pcm_open_noupdate(pcmp, name, stream, mode);
 }
 
 /**
@@ -4281,7 +4311,7 @@ static const char *names[SND_PCM_HW_PARAM_LAST + 1] = {
        [SND_PCM_HW_PARAM_BUFFER_TIME] = "buffer_time"
 };
 
-int snd_pcm_slave_conf(snd_config_t *conf, const char **namep
+int snd_pcm_slave_conf(snd_config_t *conf, snd_config_t **pcm_conf
                       unsigned int count, ...)
 {
        snd_config_iterator_t i, next;
@@ -4317,17 +4347,7 @@ int snd_pcm_slave_conf(snd_config_t *conf, const char **namep,
                if (strcmp(id, "comment") == 0)
                        continue;
                if (strcmp(id, "pcm") == 0) {
-                       if (pcm_valid) {
-                       _duplicated:
-                               SNDERR("duplicated %s", id);
-                               return -EINVAL;
-                       }
-                       err = snd_config_get_string(n, namep);
-                       if (err < 0) {
-                       _invalid:
-                               SNDERR("invalid type for %s", id);
-                               return err;
-                       }
+                       *pcm_conf = n;
                        pcm_valid = 1;
                        continue;
                }
@@ -4338,15 +4358,16 @@ int snd_pcm_slave_conf(snd_config_t *conf, const char **namep,
                        assert(names[idx]);
                        if (strcmp(id, names[idx]) != 0)
                                continue;
-                       if (fields[k].valid)
-                               goto _duplicated;
                        switch (idx) {
                        case SND_PCM_HW_PARAM_FORMAT:
                        {
                                snd_pcm_format_t f;
                                err = snd_config_get_string(n, &str);
-                               if (err < 0)
-                                       goto _invalid;
+                               if (err < 0) {
+                               _invalid:
+                                       SNDERR("invalid type for %s", id);
+                                       return err;
+                               }
                                f = snd_pcm_format_value(str);
                                if (f == SND_PCM_FORMAT_UNKNOWN) {
                                        SNDERR("unknown format");
@@ -4370,6 +4391,10 @@ int snd_pcm_slave_conf(snd_config_t *conf, const char **namep,
                SNDERR("Unknown field %s", id);
                return -EINVAL;
        }
+       if (!pcm_valid) {
+               SNDERR("missing field pcm");
+               return -EINVAL;
+       }
        for (k = 0; k < count; ++k) {
                if (fields[k].mandatory && !fields[k].valid) {
                        SNDERR("missing field %s", names[fields[k].index]);
index 672281553a4936404b0c86e6dc8d7e21296f64e7..69e250953088a3bb7b69014d3627eeaa0687909a 100644 (file)
@@ -552,10 +552,9 @@ int _snd_pcm_adpcm_open(snd_pcm_t **pcmp, const char *name,
                         snd_pcm_stream_t stream, int mode)
 {
        snd_config_iterator_t i, next;
-       const char *sname = NULL;
        int err;
        snd_pcm_t *spcm;
-       snd_config_t *slave = NULL;
+       snd_config_t *slave = NULL, *sconf;
        snd_pcm_format_t sformat;
        snd_config_for_each(i, next, conf) {
                snd_config_t *n = snd_config_iterator_entry(i);
@@ -575,7 +574,7 @@ int _snd_pcm_adpcm_open(snd_pcm_t **pcmp, const char *name,
                SNDERR("slave is not defined");
                return -EINVAL;
        }
-       err = snd_pcm_slave_conf(slave, &sname, 1,
+       err = snd_pcm_slave_conf(slave, &sconf, 1,
                                 SND_PCM_HW_PARAM_FORMAT, 1, &sformat);
        if (err < 0)
                return err;
@@ -584,12 +583,7 @@ int _snd_pcm_adpcm_open(snd_pcm_t **pcmp, const char *name,
                SNDERR("invalid slave format");
                return -EINVAL;
        }
-       /* This is needed cause snd_config_update may destroy config */
-       sname = strdup(sname);
-       if (!sname)
-               return  -ENOMEM;
-       err = snd_pcm_open(&spcm, sname, stream, mode);
-       free((void *) sname);
+       err = snd_pcm_open_slave(&spcm, sconf, stream, mode);
        if (err < 0)
                return err;
        err = snd_pcm_adpcm_open(pcmp, name, sformat, spcm, 1);
index aecd52fa705eb6f954b7e8cd4126b4af3b43e5cf..e2d57cfeecdea71bad1104e821d903ec4a5e4756 100644 (file)
@@ -425,10 +425,9 @@ int _snd_pcm_alaw_open(snd_pcm_t **pcmp, const char *name,
                         snd_pcm_stream_t stream, int mode)
 {
        snd_config_iterator_t i, next;
-       const char *sname = NULL;
        int err;
        snd_pcm_t *spcm;
-       snd_config_t *slave = NULL;
+       snd_config_t *slave = NULL, *sconf;
        snd_pcm_format_t sformat;
        snd_config_for_each(i, next, conf) {
                snd_config_t *n = snd_config_iterator_entry(i);
@@ -448,7 +447,7 @@ int _snd_pcm_alaw_open(snd_pcm_t **pcmp, const char *name,
                SNDERR("slave is not defined");
                return -EINVAL;
        }
-       err = snd_pcm_slave_conf(slave, &sname, 1,
+       err = snd_pcm_slave_conf(slave, &sconf, 1,
                                 SND_PCM_HW_PARAM_FORMAT, 1, &sformat);
        if (err < 0)
                return err;
@@ -457,12 +456,7 @@ int _snd_pcm_alaw_open(snd_pcm_t **pcmp, const char *name,
                SNDERR("invalid slave format");
                return -EINVAL;
        }
-       /* This is needed cause snd_config_update may destroy config */
-       sname = strdup(sname);
-       if (!sname)
-               return  -ENOMEM;
-       err = snd_pcm_open(&spcm, sname, stream, mode);
-       free((void *) sname);
+       err = snd_pcm_open_slave(&spcm, sconf, stream, mode);
        if (err < 0)
                return err;
        err = snd_pcm_alaw_open(pcmp, name, sformat, spcm, 1);
index 64f33c78acfd1d5a2ca5f61a05ddfc150b683b97..a9f85b88865d6904e79b48037a653b1581fae6e3 100644 (file)
@@ -191,14 +191,13 @@ int snd_pcm_copy_open(snd_pcm_t **pcmp, const char *name, snd_pcm_t *slave, int
 }
 
 int _snd_pcm_copy_open(snd_pcm_t **pcmp, const char *name,
-                        snd_config_t *conf, 
-                        snd_pcm_stream_t stream, int mode)
+                      snd_config_t *conf, 
+                      snd_pcm_stream_t stream, int mode)
 {
        snd_config_iterator_t i, next;
-       const char *sname = NULL;
        int err;
        snd_pcm_t *spcm;
-       snd_config_t *slave = NULL;
+       snd_config_t *slave = NULL, *sconf;
        snd_config_for_each(i, next, conf) {
                snd_config_t *n = snd_config_iterator_entry(i);
                const char *id = snd_config_get_id(n);
@@ -217,15 +216,10 @@ int _snd_pcm_copy_open(snd_pcm_t **pcmp, const char *name,
                SNDERR("slave is not defined");
                return -EINVAL;
        }
-       err = snd_pcm_slave_conf(slave, &sname, 0);
+       err = snd_pcm_slave_conf(slave, &sconf, 0);
        if (err < 0)
                return err;
-       /* This is needed cause snd_config_update may destroy config */
-       sname = strdup(sname);
-       if (!sname)
-               return  -ENOMEM;
-       err = snd_pcm_open(&spcm, sname, stream, mode);
-       free((void *) sname);
+       err = snd_pcm_open_slave(&spcm, sconf, stream, mode);
        if (err < 0)
                return err;
        err = snd_pcm_copy_open(pcmp, name, spcm, 1);
index a979914c86991cb93bd9c6048a2b9a0b799d7103..9e378e0e7e7d622d72ddb070bdd4a60dce4a7fd3 100644 (file)
@@ -457,10 +457,9 @@ int _snd_pcm_file_open(snd_pcm_t **pcmp, const char *name,
                       snd_pcm_stream_t stream, int mode)
 {
        snd_config_iterator_t i, next;
-       const char *sname = NULL;
        int err;
        snd_pcm_t *spcm;
-       snd_config_t *slave = NULL;
+       snd_config_t *slave = NULL, *sconf;
        const char *fname = NULL;
        const char *format = NULL;
        long fd = -1;
@@ -501,19 +500,14 @@ int _snd_pcm_file_open(snd_pcm_t **pcmp, const char *name,
                SNDERR("slave is not defined");
                return -EINVAL;
        }
-       err = snd_pcm_slave_conf(slave, &sname, 0);
+       err = snd_pcm_slave_conf(slave, &sconf, 0);
        if (err < 0)
                return err;
        if (!fname && fd < 0) {
                SNDERR("file is not defined");
                return -EINVAL;
        }
-       /* This is needed cause snd_config_update may destroy config */
-       sname = strdup(sname);
-       if (!sname)
-               return  -ENOMEM;
-       err = snd_pcm_open(&spcm, sname, stream, mode);
-       free((void *) sname);
+       err = snd_pcm_open_slave(&spcm, sconf, stream, mode);
        if (err < 0)
                return err;
        err = snd_pcm_file_open(pcmp, name, fname, fd, format, spcm, 1);
index 3c25b6ac39a86911e7feb451714a14ca5d4b3d1d..d4f9cb750d2ebee8b2a98257fde8f7c6176d6b1c 100644 (file)
@@ -330,10 +330,9 @@ int _snd_pcm_linear_open(snd_pcm_t **pcmp, const char *name,
                         snd_pcm_stream_t stream, int mode)
 {
        snd_config_iterator_t i, next;
-       const char *sname;
        int err;
        snd_pcm_t *spcm;
-       snd_config_t *slave = NULL;
+       snd_config_t *slave = NULL, *sconf;
        snd_pcm_format_t sformat;
        snd_config_for_each(i, next, conf) {
                snd_config_t *n = snd_config_iterator_entry(i);
@@ -353,7 +352,7 @@ int _snd_pcm_linear_open(snd_pcm_t **pcmp, const char *name,
                SNDERR("slave is not defined");
                return -EINVAL;
        }
-       err = snd_pcm_slave_conf(slave, &sname, 1,
+       err = snd_pcm_slave_conf(slave, &sconf, 1,
                                 SND_PCM_HW_PARAM_FORMAT, 1, &sformat);
        if (err < 0)
                return err;
@@ -361,12 +360,7 @@ int _snd_pcm_linear_open(snd_pcm_t **pcmp, const char *name,
                SNDERR("slave format is not linear");
                return -EINVAL;
        }
-       /* This is needed cause snd_config_update may destroy config */
-       sname = strdup(sname);
-       if (!sname)
-               return  -ENOMEM;
-       err = snd_pcm_open(&spcm, sname, stream, mode);
-       free((void *) sname);
+       err = snd_pcm_open_slave(&spcm, sconf, stream, mode);
        if (err < 0)
                return err;
        err = snd_pcm_linear_open(pcmp, name, sformat, spcm, 1);
index 2a1b5bcdff0ad30ef9278200780da78380a75bf7..af827976039a47e979079dac9c20491e19b98db5 100644 (file)
@@ -527,9 +527,12 @@ int snd_pcm_hw_strategy_simple_choices(snd_pcm_hw_strategy_t *strategy, int orde
                                       snd_pcm_hw_strategy_simple_choices_list_t *choices);
 #endif
 
-int snd_pcm_slave_conf(snd_config_t *conf, const char **namep,
+int snd_pcm_slave_conf(snd_config_t *conf, snd_config_t **pcm_conf,
                       unsigned int count, ...);
 
+int snd_pcm_open_slave(snd_pcm_t **pcmp, snd_config_t *conf,
+                      snd_pcm_stream_t stream, int mode);
+
 #define SND_PCM_HW_PARBIT_ACCESS       (1U << SND_PCM_HW_PARAM_ACCESS)
 #define SND_PCM_HW_PARBIT_FORMAT       (1U << SND_PCM_HW_PARAM_FORMAT)
 #define SND_PCM_HW_PARBIT_SUBFORMAT    (1U << SND_PCM_HW_PARAM_SUBFORMAT)
index 01aefcf1a472ba9be2fcdbea5fd3d3e01c21ccb0..28bbe6679b2ab149cc21e5b1941ca17a629fb4e8 100644 (file)
@@ -716,10 +716,9 @@ int _snd_pcm_meter_open(snd_pcm_t **pcmp, const char *name,
                        snd_pcm_stream_t stream, int mode)
 {
        snd_config_iterator_t i, next;
-       const char *sname = NULL;
        int err;
        snd_pcm_t *spcm;
-       snd_config_t *slave = NULL;
+       snd_config_t *slave = NULL, *sconf;
        long frequency = -1;
        snd_config_t *scopes = NULL;
        snd_config_for_each(i, next, conf) {
@@ -756,15 +755,10 @@ int _snd_pcm_meter_open(snd_pcm_t **pcmp, const char *name,
                SNDERR("slave is not defined");
                return -EINVAL;
        }
-       err = snd_pcm_slave_conf(slave, &sname, 0);
+       err = snd_pcm_slave_conf(slave, &sconf, 0);
        if (err < 0)
                return err;
-       /* This is needed cause snd_config_update may destroy config */
-       sname = strdup(sname);
-       if (!sname)
-               return  -ENOMEM;
-       err = snd_pcm_open(&spcm, sname, stream, mode);
-       free((void *) sname);
+       err = snd_pcm_open_slave(&spcm, sconf, stream, mode);
        if (err < 0)
                return err;
        err = snd_pcm_meter_open(pcmp, name, frequency > 0 ? (unsigned int) frequency : FREQUENCY, spcm, 1);
index 9450faad3d9e6584026c0bd6e5f9dbb928c9d752..9f307937d2a4d1c0d601b155e6fd77067cb36a40 100644 (file)
@@ -440,10 +440,9 @@ int _snd_pcm_mulaw_open(snd_pcm_t **pcmp, const char *name,
                         snd_pcm_stream_t stream, int mode)
 {
        snd_config_iterator_t i, next;
-       const char *sname = NULL;
        int err;
        snd_pcm_t *spcm;
-       snd_config_t *slave = NULL;
+       snd_config_t *slave = NULL, *sconf;
        snd_pcm_format_t sformat;
        snd_config_for_each(i, next, conf) {
                snd_config_t *n = snd_config_iterator_entry(i);
@@ -463,7 +462,7 @@ int _snd_pcm_mulaw_open(snd_pcm_t **pcmp, const char *name,
                SNDERR("slave is not defined");
                return -EINVAL;
        }
-       err = snd_pcm_slave_conf(slave, &sname, 1,
+       err = snd_pcm_slave_conf(slave, &sconf, 1,
                                 SND_PCM_HW_PARAM_FORMAT, 1, &sformat);
        if (err < 0)
                return err;
@@ -472,12 +471,7 @@ int _snd_pcm_mulaw_open(snd_pcm_t **pcmp, const char *name,
                SNDERR("invalid slave format");
                return -EINVAL;
        }
-       /* This is needed cause snd_config_update may destroy config */
-       sname = strdup(sname);
-       if (!sname)
-               return  -ENOMEM;
-       err = snd_pcm_open(&spcm, sname, stream, mode);
-       free((void *) sname);
+       err = snd_pcm_open_slave(&spcm, sconf, stream, mode);
        if (err < 0)
                return err;
        err = snd_pcm_mulaw_open(pcmp, name, sformat, spcm, 1);
index aa6b63262e85254524116b3e253a19690968b0fa..65e0d454766dab552f0a82c4f238398be986e6fa 100644 (file)
@@ -655,7 +655,7 @@ int _snd_pcm_multi_open(snd_pcm_t **pcmp, const char *name, snd_config_t *conf,
        int err;
        unsigned int idx;
        const char **slaves_id = NULL;
-       char **slaves_name = NULL;
+       snd_config_t **slaves_conf = NULL;
        snd_pcm_t **slaves_pcm = NULL;
        unsigned int *slaves_channels = NULL;
        int *channels_sidx = NULL;
@@ -718,7 +718,7 @@ int _snd_pcm_multi_open(snd_pcm_t **pcmp, const char *name, snd_config_t *conf,
                return -EINVAL;
        }
        slaves_id = calloc(slaves_count, sizeof(*slaves_id));
-       slaves_name = calloc(slaves_count, sizeof(*slaves_name));
+       slaves_conf = calloc(slaves_count, sizeof(*slaves_conf));
        slaves_pcm = calloc(slaves_count, sizeof(*slaves_pcm));
        slaves_channels = calloc(slaves_count, sizeof(*slaves_channels));
        channels_sidx = calloc(channels_count, sizeof(*channels_sidx));
@@ -729,14 +729,12 @@ int _snd_pcm_multi_open(snd_pcm_t **pcmp, const char *name, snd_config_t *conf,
        idx = 0;
        snd_config_for_each(i, inext, slaves) {
                snd_config_t *m = snd_config_iterator_entry(i);
-               const char *n;
                int channels;
                slaves_id[idx] = snd_config_get_id(m);
-               err = snd_pcm_slave_conf(m, &n, 1,
+               err = snd_pcm_slave_conf(m, &slaves_conf[idx], 1,
                                         SND_PCM_HW_PARAM_CHANNELS, 1, &channels);
                if (err < 0)
                        goto _free;
-               slaves_name[idx] = strdup(n);
                slaves_channels[idx] = channels;
                ++idx;
        }
@@ -807,7 +805,7 @@ int _snd_pcm_multi_open(snd_pcm_t **pcmp, const char *name, snd_config_t *conf,
        }
        
        for (idx = 0; idx < slaves_count; ++idx) {
-               err = snd_pcm_open(&slaves_pcm[idx], slaves_name[idx], stream, mode);
+               err = snd_pcm_open_slave(&slaves_pcm[idx], slaves_conf[idx], stream, mode);
                if (err < 0)
                        goto _free;
        }
@@ -821,12 +819,10 @@ _free:
                for (idx = 0; idx < slaves_count; ++idx) {
                        if (slaves_pcm[idx])
                                snd_pcm_close(slaves_pcm[idx]);
-                       if (slaves_name[idx])
-                               free(slaves_name[idx]);
                }
        }
-       if (slaves_name)
-               free(slaves_name);
+       if (slaves_conf)
+               free(slaves_conf);
        if (slaves_pcm)
                free(slaves_pcm);
        if (slaves_channels)
index c2454b15bf135099d39f1d97076dd35488822dd8..3c18d7196adeadc0469f248a1e76406505a8bec9 100644 (file)
@@ -715,10 +715,9 @@ int _snd_pcm_plug_open(snd_pcm_t **pcmp, const char *name,
                       snd_pcm_stream_t stream, int mode)
 {
        snd_config_iterator_t i, next;
-       const char *sname = NULL;
        int err;
        snd_pcm_t *spcm;
-       snd_config_t *slave = NULL;
+       snd_config_t *slave = NULL, *sconf;
        snd_config_t *tt = NULL;
        snd_pcm_route_ttable_entry_t *ttable = NULL;
        unsigned int cused, sused;
@@ -748,7 +747,7 @@ int _snd_pcm_plug_open(snd_pcm_t **pcmp, const char *name,
                SNDERR("slave is not defined");
                return -EINVAL;
        }
-       err = snd_pcm_slave_conf(slave, &sname, 0);
+       err = snd_pcm_slave_conf(slave, &sconf, 0);
        if (err < 0)
                return err;
        if (tt) {
@@ -759,12 +758,7 @@ int _snd_pcm_plug_open(snd_pcm_t **pcmp, const char *name,
                        return err;
        }
                
-       /* This is needed cause snd_config_update may destroy config */
-       sname = strdup(sname);
-       if (!sname)
-               return  -ENOMEM;
-       err = snd_pcm_open(&spcm, sname, stream, mode);
-       free((void *) sname);
+       err = snd_pcm_open_slave(&spcm, sconf, stream, mode);
        if (err < 0)
                return err;
        err = snd_pcm_plug_open(pcmp, name, ttable, MAX_CHANNELS, cused, sused, spcm, 1);
index c87589f213dd9b84fa0f0a657d4745b5e1470d0c..236532d8f7c3ee607ff0a502230081545d4bb242 100644 (file)
@@ -539,10 +539,9 @@ int _snd_pcm_rate_open(snd_pcm_t **pcmp, const char *name,
                         snd_pcm_stream_t stream, int mode)
 {
        snd_config_iterator_t i, next;
-       const char *sname = NULL;
        int err;
        snd_pcm_t *spcm;
-       snd_config_t *slave = NULL;
+       snd_config_t *slave = NULL, *sconf;
        snd_pcm_format_t sformat = SND_PCM_FORMAT_UNKNOWN;
        int srate = -1;
        snd_config_for_each(i, next, conf) {
@@ -563,7 +562,7 @@ int _snd_pcm_rate_open(snd_pcm_t **pcmp, const char *name,
                SNDERR("slave is not defined");
                return -EINVAL;
        }
-       err = snd_pcm_slave_conf(slave, &sname, 2,
+       err = snd_pcm_slave_conf(slave, &sconf, 2,
                                 SND_PCM_HW_PARAM_FORMAT, 0, &sformat,
                                 SND_PCM_HW_PARAM_RATE, 1, &srate);
        if (err < 0)
@@ -573,12 +572,7 @@ int _snd_pcm_rate_open(snd_pcm_t **pcmp, const char *name,
                SNDERR("slave format is not linear");
                return -EINVAL;
        }
-       /* This is needed cause snd_config_update may destroy config */
-       sname = strdup(sname);
-       if (!sname)
-               return  -ENOMEM;
-       err = snd_pcm_open(&spcm, sname, stream, mode);
-       free((void *) sname);
+       err = snd_pcm_open_slave(&spcm, sconf, stream, mode);
        if (err < 0)
                return err;
        err = snd_pcm_rate_open(pcmp, name, 
index d4f33e7b2015ea89bc3a8323cec6de44379c9f66..95299f5519ef0e3077d624ebe534b52247f44286 100644 (file)
@@ -843,10 +843,9 @@ int _snd_pcm_route_open(snd_pcm_t **pcmp, const char *name,
                        snd_pcm_stream_t stream, int mode)
 {
        snd_config_iterator_t i, next;
-       const char *sname = NULL;
        int err;
        snd_pcm_t *spcm;
-       snd_config_t *slave = NULL;
+       snd_config_t *slave = NULL, *sconf;
        snd_pcm_format_t sformat = SND_PCM_FORMAT_UNKNOWN;
        int schannels = -1;
        snd_config_t *tt = NULL;
@@ -882,7 +881,7 @@ int _snd_pcm_route_open(snd_pcm_t **pcmp, const char *name,
                SNDERR("ttable is not defined");
                return -EINVAL;
        }
-       err = snd_pcm_slave_conf(slave, &sname, 2,
+       err = snd_pcm_slave_conf(slave, &sconf, 2,
                                 SND_PCM_HW_PARAM_FORMAT, 0, &sformat,
                                 SND_PCM_HW_PARAM_CHANNELS, 0, &schannels);
        if (err < 0)
@@ -898,12 +897,7 @@ int _snd_pcm_route_open(snd_pcm_t **pcmp, const char *name,
        if (err < 0)
                return err;
 
-       /* This is needed cause snd_config_update may destroy config */
-       sname = strdup(sname);
-       if (!sname)
-               return  -ENOMEM;
-       err = snd_pcm_open(&spcm, sname, stream, mode);
-       free((void *) sname);
+       err = snd_pcm_open_slave(&spcm, sconf, stream, mode);
        if (err < 0)
                return err;
        err = snd_pcm_route_open(pcmp, name, sformat, schannels,
index 69e78b716f36becac8aa46e8b4a7c6286bbc087d..c1ca99b26a22ff680ac06d18dcb59e816e502071 100644 (file)
@@ -1371,10 +1371,11 @@ int _snd_pcm_share_open(snd_pcm_t **pcmp, const char *name, snd_config_t *conf,
                        snd_pcm_stream_t stream, int mode)
 {
        snd_config_iterator_t i, next;
-       const char *sname = NULL;
+       const char *slave_name = NULL;
+       const char *sname;
        snd_config_t *bindings = NULL;
        int err;
-       snd_config_t *slave = NULL;
+       snd_config_t *slave = NULL, *sconf;
        unsigned int *channels_map;
        unsigned int channels = 0;
        snd_pcm_format_t sformat = SND_PCM_FORMAT_UNKNOWN;
@@ -1391,7 +1392,7 @@ int _snd_pcm_share_open(snd_pcm_t **pcmp, const char *name, snd_config_t *conf,
                if (strcmp(id, "type") == 0)
                        continue;
                if (strcmp(id, "slave") == 0) {
-                       err = snd_config_get_string(n, &sname);
+                       err = snd_config_get_string(n, &slave_name);
                        if (err < 0) {
                                SNDERR("Invalid type for %s", id);
                                return -EINVAL;
@@ -1414,7 +1415,7 @@ int _snd_pcm_share_open(snd_pcm_t **pcmp, const char *name, snd_config_t *conf,
                SNDERR("slave is not defined");
                return -EINVAL;
        }
-       err = snd_pcm_slave_conf(slave, &sname, 5,
+       err = snd_pcm_slave_conf(slave, &sconf, 5,
                                 SND_PCM_HW_PARAM_CHANNELS, 0, &schannels,
                                 SND_PCM_HW_PARAM_FORMAT, 0, &sformat,
                                 SND_PCM_HW_PARAM_RATE, 0, &srate,
@@ -1422,6 +1423,14 @@ int _snd_pcm_share_open(snd_pcm_t **pcmp, const char *name, snd_config_t *conf,
                                 SND_PCM_HW_PARAM_BUFFER_TIME, 0, &sbuffer_time);
        if (err < 0)
                return err;
+
+       /* FIXME: nothing strictly forces to have named definition */
+       err = snd_config_get_string(sconf, &sname);
+       if (err < 0) {
+               SNDERR("slave.pcm is not a string");
+               return err;
+       }
+
        if (!bindings) {
                SNDERR("bindings is not defined");
                return -EINVAL;
@@ -1463,10 +1472,10 @@ int _snd_pcm_share_open(snd_pcm_t **pcmp, const char *name, snd_config_t *conf,
        }
        if (schannels <= 0)
                schannels = schannel_max + 1;
-           err = snd_pcm_share_open(pcmp, name, sname, sformat, srate, 
-                                    (unsigned int) schannels,
-                                    speriod_time, sbuffer_time,
-                                    channels, channels_map, stream, mode);
+       err = snd_pcm_share_open(pcmp, name, sname, sformat, srate, 
+                                (unsigned int) schannels,
+                                speriod_time, sbuffer_time,
+                                channels, channels_map, stream, mode);
 _free:
        free(channels_map);
        return err;