The structure for control element ID is hybrid. It has two ways to check equality; e.g. equality of numid field, and equality of the other fields. Just checking equality according to numid field, current alsa-lib take userspace applications to call snd_ctl_elem_id_get_numid() twice. It's better to add optimized version of the equality check.
This commit adds API to check equality of numid field for a pair of control element IDs.
Signed-off-by: Takashi Sakamoto o-takashi@sakamocchi.jp --- include/control.h | 1 + src/control/control.c | 19 ++++++++++++++++ test/lsb/ctl-elem-id.c | 50 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 70 insertions(+)
diff --git a/include/control.h b/include/control.h index 40ac2e97..260d7f30 100644 --- a/include/control.h +++ b/include/control.h @@ -424,6 +424,7 @@ int snd_ctl_elem_id_malloc(snd_ctl_elem_id_t **ptr); void snd_ctl_elem_id_free(snd_ctl_elem_id_t *obj); void snd_ctl_elem_id_clear(snd_ctl_elem_id_t *obj); void snd_ctl_elem_id_copy(snd_ctl_elem_id_t *dst, const snd_ctl_elem_id_t *src); +int snd_ctl_elem_id_equal_by_numid(snd_ctl_elem_id_t *l, snd_ctl_elem_id_t *r); int snd_ctl_elem_id_compare(snd_ctl_elem_id_t *id1, const snd_ctl_elem_id_t *id2); unsigned int snd_ctl_elem_id_get_numid(const snd_ctl_elem_id_t *obj); snd_ctl_elem_iface_t snd_ctl_elem_id_get_interface(const snd_ctl_elem_id_t *obj); diff --git a/src/control/control.c b/src/control/control.c index 197d4f52..6d1eda15 100644 --- a/src/control/control.c +++ b/src/control/control.c @@ -83,6 +83,8 @@ the same (driver updates can change it, but in practice this is rare). The numid can change on each boot. In case of an USB sound card, the numid can also change when it is reconnected.
+For equality check between a pair of #snd_ctl_elem_id_t according to the numid, +snd_ctl_elem_id_equal_by_numid() is available.
\section element_lists Element Lists
@@ -1818,6 +1820,23 @@ void snd_ctl_elem_id_copy(snd_ctl_elem_id_t *dst, const snd_ctl_elem_id_t *src) *dst = *src; }
+/** + * \brief check equality between two arguments according to numid. + * \param l opaque pointer to element ID structure. + * \param r opaque pointer to another element ID structure. + * \retval zero if they equal, else zero. + * + * The structure underlying #snd_ctl_elem_id_t is hybrid one. It has two ways to + * check equality. The API implements one of the ways, according to the value of + * numid field. + */ +int snd_ctl_elem_id_equal_by_numid(snd_ctl_elem_id_t *l, snd_ctl_elem_id_t *r) +{ + assert(l && r); + + return l->numid == r->numid; +} + /** * \brief compare one #snd_ctl_elem_id_t to another * \param id1 pointer to first id diff --git a/test/lsb/ctl-elem-id.c b/test/lsb/ctl-elem-id.c index ae416698..f499b268 100644 --- a/test/lsb/ctl-elem-id.c +++ b/test/lsb/ctl-elem-id.c @@ -18,9 +18,59 @@
#include "../include/asoundlib.h"
+static void set_elem_id_by_tuple(snd_ctl_elem_id_t *elem_id, + snd_ctl_elem_iface_t iface, + unsigned int device_id, + unsigned int subdevice_id, + const char *name, + unsigned int index) +{ + snd_ctl_elem_id_set_interface(elem_id, iface); + snd_ctl_elem_id_set_device(elem_id, device_id); + snd_ctl_elem_id_set_subdevice(elem_id, subdevice_id); + snd_ctl_elem_id_set_name(elem_id, name); + snd_ctl_elem_id_set_index(elem_id, index); +} + +// Case 0.0. The same value of numid field should result in true positive. +static void equality_by_numid_0(snd_ctl_elem_id_t *l, snd_ctl_elem_id_t *r) +{ + snd_ctl_elem_id_set_numid(l, 33); + snd_ctl_elem_id_set_numid(r, 33); + assert(snd_ctl_elem_id_equal_by_numid(l, r)); +} + +// Case 0.1. The different value of numid field should result in false positive. +static void equality_by_numid_1(snd_ctl_elem_id_t *l, snd_ctl_elem_id_t *r) +{ + snd_ctl_elem_id_set_numid(l, 333); + snd_ctl_elem_id_set_numid(r, 444); + assert(!snd_ctl_elem_id_equal_by_numid(l, r)); +} + +// Case 0.2. The same tuple should result in false positive. +static void equality_by_numid_2(snd_ctl_elem_id_t *l, snd_ctl_elem_id_t *r) +{ + set_elem_id_by_tuple(l, SND_CTL_ELEM_IFACE_CARD, 0, 1, "something", 2); + set_elem_id_by_tuple(r, SND_CTL_ELEM_IFACE_CARD, 0, 1, "something", 2); + assert(!snd_ctl_elem_id_equal_by_numid(l, r)); +} + +// Case 0.3. The tuple should result in false positive. +static void equality_by_numid_3(snd_ctl_elem_id_t *l, snd_ctl_elem_id_t *r) +{ + set_elem_id_by_tuple(l, SND_CTL_ELEM_IFACE_CARD, 300, 400, "something", 500); + set_elem_id_by_tuple(r, SND_CTL_ELEM_IFACE_MIXER, 600, 700, "something", 800); + assert(!snd_ctl_elem_id_equal_by_numid(l, r)); +} + int main() { void (*entries[])(snd_ctl_elem_id_t *l, snd_ctl_elem_id_t *r) = { + equality_by_numid_0, + equality_by_numid_1, + equality_by_numid_2, + equality_by_numid_3, }; int count = sizeof(entries) / sizeof(*entries); int fd;