]> git.alsa-project.org Git - alsa-gobject.git/commitdiff
ctl: card: add a API to retrieve list of element ID
authorTakashi Sakamoto <o-takashi@sakamocchi.jp>
Mon, 18 Nov 2019 04:22:44 +0000 (13:22 +0900)
committerTakashi Sakamoto <o-takashi@sakamocchi.jp>
Sun, 1 Dec 2019 05:38:54 +0000 (14:38 +0900)
src/ctl/alsactl.map
src/ctl/card.c
src/ctl/card.h
src/ctl/elem-id.c
src/ctl/privates.h
tests/alsactl-card

index df95f633da9d25ccc863e73e189bed1ae0c989a8..cb1ed2b83ab24e1143877cbec3d432f3d2cd6a09 100644 (file)
@@ -15,6 +15,7 @@ ALSA_GOBJECT_0_0_0 {
     "alsactl_card_new";
     "alsactl_card_open";
     "alsactl_card_get_info";
+    "alsactl_card_get_elem_id_list";
 
     "alsactl_card_info_get_type";
 
index fa505a31799cc60df909bf96503af40071cbae6a..065d6e171ec3e9b05476f92cffaabf737e064d33 100644 (file)
@@ -140,3 +140,88 @@ void alsactl_card_get_info(ALSACtlCard *self, ALSACtlCardInfo **card_info,
         g_object_unref(*card_info);
     }
 }
+
+static void allocate_elem_ids(int fd, struct snd_ctl_elem_list *list,
+                              GError **error)
+{
+    struct snd_ctl_elem_id *ids;
+
+    // Help for deallocation.
+    memset(list, 0, sizeof(*list));
+
+    // Get the number of elements in this control device.
+    if (ioctl(fd, SNDRV_CTL_IOCTL_ELEM_LIST, list) < 0) {
+        generate_error(error, errno);
+        return;
+    }
+
+    // No elements found.
+    if (list->count == 0)
+        return;
+
+    // Allocate spaces for these elements.
+    ids = calloc(list->count, sizeof(*ids));
+    if (!ids) {
+        generate_error(error, ENOMEM);
+        return;
+    }
+
+    list->offset = 0;
+    while (list->offset < list->count) {
+        // ALSA middleware has limitation of one operation.
+        // 1000 is enought less than the limitation.
+        list->space = MIN(list->count - list->offset, 1000);
+        list->pids = ids + list->offset;
+
+        // Get the IDs of elements in this control device.
+        if (ioctl(fd, SNDRV_CTL_IOCTL_ELEM_LIST, list) < 0) {
+            generate_error(error, errno);
+            free(ids);
+            list->pids = NULL;
+            return;
+        }
+
+        list->offset += list->space;
+    }
+    list->pids = ids;
+    list->space = list->count;
+}
+
+static inline void deallocate_elem_ids(struct snd_ctl_elem_list *list)
+{
+    if (list->pids!= NULL)
+        free(list->pids);
+}
+
+/**
+ * alsactl_card_get_elem_id_list:
+ * @self: A #ALSACtlCard.
+ * @entries: (element-type ALSACtl.ElemId)(out): The list of entries for
+ *           ALSACtlElemId.
+ * @error: A #GError.
+ *
+ * Generate a list of ALSACtlElemId for ALSA control character device
+ * associated to the sound card.
+ */
+void alsactl_card_get_elem_id_list(ALSACtlCard *self, GList **entries,
+                                   GError **error)
+{
+    ALSACtlCardPrivate *priv;
+    struct snd_ctl_elem_list list = {0};
+    int i;
+
+    g_return_if_fail(ALSACTL_IS_CARD(self));
+    priv = alsactl_card_get_instance_private(self);
+
+    allocate_elem_ids(priv->fd, &list, error);
+    if (*error != NULL)
+        return;
+
+    for (i = 0; i < list.count; ++i) {
+        struct snd_ctl_elem_id *id = list.pids + i;
+        ALSACtlElemId *elem_id = g_boxed_copy(ALSACTL_TYPE_ELEM_ID, id);
+        *entries = g_list_append(*entries, (gpointer)elem_id);
+    }
+
+    deallocate_elem_ids(&list);
+}
index 0ead57e9a1f67792a9d9150d759f4c476b3cb7b5..cd1397e677fef4cb7b76e484896b7ad9c72b0260 100644 (file)
@@ -6,6 +6,7 @@
 #include <glib-object.h>
 
 #include <ctl/card-info.h>
+#include <ctl/elem-id.h>
 
 G_BEGIN_DECLS
 
@@ -54,6 +55,9 @@ void alsactl_card_open(ALSACtlCard *self, guint card_id, GError **error);
 void alsactl_card_get_info(ALSACtlCard *self, ALSACtlCardInfo **card_info,
                            GError **error);
 
+void alsactl_card_get_elem_id_list(ALSACtlCard *self, GList **entries,
+                                   GError **error);
+
 G_END_DECLS
 
 #endif
index 3ff99696a0c2cc99c664963746d7791e71175c9d..b598e917fa9cbf1158add95ed04f653c6a08d2f2 100644 (file)
@@ -1,5 +1,4 @@
 // SPDX-License-Identifier: LGPL-3.0-or-later
-#include "elem-id.h"
 #include "privates.h"
 
 ALSACtlElemId *ctl_elem_id_copy(const ALSACtlElemId *self)
index 69aeb2bffec2a5a880bcbbd1a3a90c3c8437bb67..986c7de299f1cfd1bc3c278f8b8823b4e3681de4 100644 (file)
@@ -8,6 +8,7 @@
 #include <glib-object.h>
 
 #include "card-info.h"
+#include "elem-id.h"
 
 #include <sound/asound.h>
 
index 05127ee8db7f3a0420f5b1bbd0765a6542a6e44d..12f51de4215743cf4633a17ef532d0aadb4394a4 100644 (file)
@@ -17,6 +17,7 @@ methods = (
     'new',
     'open',
     'get_info',
+    'get_elem_id_list',
 )
 signals = ()