]> git.alsa-project.org Git - alsa-lib.git/commitdiff
pcm: partially revert "pcm: softvol - make snd_pcm_parse_control_id private"
authorJaroslav Kysela <perex@perex.cz>
Tue, 2 Nov 2021 09:55:45 +0000 (10:55 +0100)
committerJaroslav Kysela <perex@perex.cz>
Tue, 2 Nov 2021 10:00:35 +0000 (11:00 +0100)
This reverts partially commit b9a4997e92e4c16147fcf96453a4c3e08080ac66.

It seems that we have have some users for this very specific function.
Mark it deprecated and keep the softvol implementation separate,
so we can remove this function easily in future.

Fixes: https://github.com/alsa-project/alsa-lib/issues/186
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
include/pcm_external.h
src/pcm/pcm_misc.c

index 204a450c7d12b72f7c7ad00be9b93c0b44b9eb3e..a6005b34ca210dc97354e6c96297a2744e989ae7 100644 (file)
@@ -59,7 +59,7 @@ int SND_PCM_PLUGIN_ENTRY(plugin) (snd_pcm_t **pcmp, const char *name,\
 #include "pcm_extplug.h"
 
 int snd_pcm_parse_control_id(snd_config_t *conf, snd_ctl_elem_id_t *ctl_id, int *cardp,
-                            int *cchannelsp, int *hwctlp);
+                            int *cchannelsp, int *hwctlp) __attribute__((deprecated));
 
 /** \} */
 
index 34ea438c5e9722c86d1cdcc839ca8df76b55e25d..ce8d8189aee278031951ac910c9f39c388e31f70 100644 (file)
@@ -753,3 +753,136 @@ snd_pcm_format_t snd_pcm_build_linear_format(int width, int pwidth, int unsignd,
                return linear_formats[width][!!unsignd][!!big_endian];
        }
 }
+
+/**
+ * \brief Parse control element id from the config
+ * \param conf the config tree to parse
+ * \param ctl_id the pointer to store the resultant control element id
+ * \param cardp the pointer to store the card index
+ * \param cchannelsp the pointer to store the number of channels (optional)
+ * \param hwctlp the pointer to store the h/w control flag (optional)
+ * \return 0 if successful, or a negative error code
+ *
+ * \deprecated Since 1.2.5
+ * This function parses the given config tree to retrieve the control element id
+ * and the card index.  It's used by softvol.  External PCM plugins can use this
+ * function for creating or assigining their controls.
+ *
+ * cchannelsp and hwctlp arguments are optional.  Set NULL if not necessary.
+ */
+int snd_pcm_parse_control_id(snd_config_t *conf, snd_ctl_elem_id_t *ctl_id, int *cardp,
+                            int *cchannelsp, int *hwctlp)
+{
+       snd_config_iterator_t i, next;
+       int iface = SND_CTL_ELEM_IFACE_MIXER;
+       const char *name = NULL;
+       long index = 0;
+       long device = -1;
+       long subdevice = -1;
+       int err;
+
+       assert(ctl_id && cardp);
+
+       *cardp = -1;
+       if (cchannelsp)
+               *cchannelsp = 2;
+       snd_config_for_each(i, next, conf) {
+               snd_config_t *n = snd_config_iterator_entry(i);
+               const char *id;
+               if (snd_config_get_id(n, &id) < 0)
+                       continue;
+               if (strcmp(id, "comment") == 0)
+                       continue;
+               if (strcmp(id, "card") == 0) {
+                       err = snd_config_get_card(n);
+                       if (err < 0)
+                               goto _err;
+                       *cardp = err;
+                       continue;
+               }
+               if (strcmp(id, "iface") == 0 || strcmp(id, "interface") == 0) {
+                       const char *ptr;
+                       if ((err = snd_config_get_string(n, &ptr)) < 0) {
+                               SNDERR("field %s is not a string", id);
+                               goto _err;
+                       }
+                       if ((err = snd_config_get_ctl_iface_ascii(ptr)) < 0) {
+                               SNDERR("Invalid value for '%s'", id);
+                               goto _err;
+                       }
+                       iface = err;
+                       continue;
+               }
+               if (strcmp(id, "name") == 0) {
+                       if ((err = snd_config_get_string(n, &name)) < 0) {
+                               SNDERR("field %s is not a string", id);
+                               goto _err;
+                       }
+                       continue;
+               }
+               if (strcmp(id, "index") == 0) {
+                       if ((err = snd_config_get_integer(n, &index)) < 0) {
+                               SNDERR("field %s is not an integer", id);
+                               goto _err;
+                       }
+                       continue;
+               }
+               if (strcmp(id, "device") == 0) {
+                       if ((err = snd_config_get_integer(n, &device)) < 0) {
+                               SNDERR("field %s is not an integer", id);
+                               goto _err;
+                       }
+                       continue;
+               }
+               if (strcmp(id, "subdevice") == 0) {
+                       if ((err = snd_config_get_integer(n, &subdevice)) < 0) {
+                               SNDERR("field %s is not an integer", id);
+                               goto _err;
+                       }
+                       continue;
+               }
+               if (cchannelsp && strcmp(id, "count") == 0) {
+                       long v;
+                       if ((err = snd_config_get_integer(n, &v)) < 0) {
+                               SNDERR("field %s is not an integer", id);
+                               goto _err;
+                       }
+                       if (v < 1 || v > 2) {
+                               SNDERR("Invalid count %ld", v);
+                               goto _err;
+                       }
+                       *cchannelsp = v;
+                       continue;
+               }
+               if (hwctlp && strcmp(id, "hwctl") == 0) {
+                       if ((err = snd_config_get_bool(n)) < 0) {
+                               SNDERR("The field %s must be a boolean type", id);
+                               return err;
+                       }
+                       *hwctlp = err;
+                       continue;
+               }
+               SNDERR("Unknown field %s", id);
+               return -EINVAL;
+       }
+       if (name == NULL) {
+               SNDERR("Missing control name");
+               err = -EINVAL;
+               goto _err;
+       }
+       if (device < 0)
+               device = 0;
+       if (subdevice < 0)
+               subdevice = 0;
+
+       snd_ctl_elem_id_set_interface(ctl_id, iface);
+       snd_ctl_elem_id_set_name(ctl_id, name);
+       snd_ctl_elem_id_set_index(ctl_id, index);
+       snd_ctl_elem_id_set_device(ctl_id, device);
+       snd_ctl_elem_id_set_subdevice(ctl_id, subdevice);
+
+       return 0;
+
+ _err:
+       return err;
+}