2 * \file control/control.c
3 * \brief CTL interface - primitive controls
4 * \author Abramo Bagnara <abramo@alsa-project.org>
7 * CTL interface is designed to access primitive controls.
8 * See \ref control page for more details.
11 * Control Interface - main file
12 * Copyright (c) 2000 by Abramo Bagnara <abramo@alsa-project.org>
15 * This library is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU Lesser General Public License as
17 * published by the Free Software Foundation; either version 2.1 of
18 * the License, or (at your option) any later version.
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU Lesser General Public License for more details.
25 * You should have received a copy of the GNU Lesser General Public
26 * License along with this library; if not, write to the Free Software
27 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
31 /*! \page control Control interface
33 <P>Control interface is designed to access primitive controls. There is
34 also interface notifying about control and structure changes.
36 \section control_general_overview General overview
38 The primitive controls can be integer, boolean, enumerators, bytes
51 #include "control_local.h"
54 * \brief get identifier of CTL handle
55 * \param ctl CTL handle
56 * \return ascii identifier of CTL handle
58 * Returns the ASCII identifier of given CTL handle. It's the same
59 * identifier specified in snd_ctl_open().
61 const char *snd_ctl_name(snd_ctl_t *ctl)
68 * \brief get type of CTL handle
69 * \param ctl CTL handle
70 * \return type of CTL handle
72 * Returns the type #snd_ctl_type_t of given CTL handle.
74 snd_ctl_type_t snd_ctl_type(snd_ctl_t *ctl)
81 * \brief close CTL handle
82 * \param ctl CTL handle
83 * \return 0 on success otherwise a negative error code
85 * Closes the specified CTL handle and frees all associated
88 int snd_ctl_close(snd_ctl_t *ctl)
91 while (!list_empty(&ctl->async_handlers)) {
92 snd_async_handler_t *h = list_entry(&ctl->async_handlers.next, snd_async_handler_t, hlist);
93 snd_async_del_handler(h);
95 err = ctl->ops->close(ctl);
98 snd_dlclose(ctl->dl_handle);
104 * \brief set nonblock mode
105 * \param ctl CTL handle
106 * \param nonblock 0 = block, 1 = nonblock mode
107 * \return 0 on success otherwise a negative error code
109 int snd_ctl_nonblock(snd_ctl_t *ctl, int nonblock)
113 err = ctl->ops->nonblock(ctl, nonblock);
116 ctl->nonblock = nonblock;
121 int snd_ctl_new(snd_ctl_t **ctlp, snd_ctl_type_t type, const char *name)
124 ctl = calloc(1, sizeof(*ctl));
129 ctl->name = strdup(name);
130 INIT_LIST_HEAD(&ctl->async_handlers);
137 * \brief set async mode
138 * \param ctl CTL handle
139 * \param sig Signal to raise: < 0 disable, 0 default (SIGIO)
140 * \param pid Process ID to signal: 0 current
141 * \return 0 on success otherwise a negative error code
143 * A signal is raised when a change happens.
145 int snd_ctl_async(snd_ctl_t *ctl, int sig, pid_t pid)
152 return ctl->ops->async(ctl, sig, pid);
157 * \brief get count of poll descriptors for CTL handle
158 * \param ctl CTL handle
159 * \return count of poll descriptors
161 int snd_ctl_poll_descriptors_count(snd_ctl_t *ctl)
164 if (ctl->ops->poll_descriptors_count)
165 return ctl->ops->poll_descriptors_count(ctl);
166 if (ctl->poll_fd < 0)
172 * \brief get poll descriptors
173 * \param ctl CTL handle
174 * \param pfds array of poll descriptors
175 * \param space space in the poll descriptor array
176 * \return count of filled descriptors
178 int snd_ctl_poll_descriptors(snd_ctl_t *ctl, struct pollfd *pfds, unsigned int space)
181 if (ctl->ops->poll_descriptors)
182 return ctl->ops->poll_descriptors(ctl, pfds, space);
183 if (ctl->poll_fd < 0)
186 pfds->fd = ctl->poll_fd;
187 pfds->events = POLLIN|POLLERR|POLLNVAL;
194 * \brief get returned events from poll descriptors
195 * \param ctl CTL handle
196 * \param pfds array of poll descriptors
197 * \param nfds count of poll descriptors
198 * \param revents returned events
199 * \return zero if success, otherwise a negative error code
201 int snd_ctl_poll_descriptors_revents(snd_ctl_t *ctl, struct pollfd *pfds, unsigned int nfds, unsigned short *revents)
203 assert(ctl && pfds && revents);
204 if (ctl->ops->poll_revents)
205 return ctl->ops->poll_revents(ctl, pfds, nfds, revents);
207 *revents = pfds->revents;
214 * \brief Ask to be informed about events (poll, #snd_async_add_ctl_handler, #snd_ctl_read)
215 * \param ctl CTL handle
216 * \param subscribe 0 = unsubscribe, 1 = subscribe
217 * \return 0 on success otherwise a negative error code
219 int snd_ctl_subscribe_events(snd_ctl_t *ctl, int subscribe)
222 return ctl->ops->subscribe_events(ctl, subscribe);
227 * \brief Get card related information
228 * \param ctl CTL handle
229 * \param info Card info pointer
230 * \return 0 on success otherwise a negative error code
232 int snd_ctl_card_info(snd_ctl_t *ctl, snd_ctl_card_info_t *info)
235 return ctl->ops->card_info(ctl, info);
239 * \brief Get a list of element identifiers
240 * \param ctl CTL handle
241 * \param list CTL element identifiers list pointer
242 * \return 0 on success otherwise a negative error code
244 int snd_ctl_elem_list(snd_ctl_t *ctl, snd_ctl_elem_list_t *list)
247 assert(list->space == 0 || list->pids);
248 return ctl->ops->element_list(ctl, list);
252 * \brief Get CTL element information
253 * \param ctl CTL handle
254 * \param info CTL element id/information pointer
255 * \return 0 on success otherwise a negative error code
257 int snd_ctl_elem_info(snd_ctl_t *ctl, snd_ctl_elem_info_t *info)
259 assert(ctl && info && (info->id.name[0] || info->id.numid));
260 return ctl->ops->element_info(ctl, info);
264 * \brief Create and add an user INTEGER CTL element
265 * \param ctl CTL handle
266 * \param id CTL element id to add
267 * \param count number of elements
268 * \param min minimum value
269 * \param max maximum value
270 * \param step value step
271 * \return 0 on success otherwise a negative error code
273 int snd_ctl_elem_add_integer(snd_ctl_t *ctl, const snd_ctl_elem_id_t *id,
274 unsigned int count, long min, long max, long step)
276 snd_ctl_elem_info_t *info;
277 snd_ctl_elem_value_t *val;
281 assert(ctl && id && id->name[0]);
282 snd_ctl_elem_info_alloca(&info);
284 info->type = SND_CTL_ELEM_TYPE_INTEGER;
285 info->access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
286 SNDRV_CTL_ELEM_ACCESS_TLV_READWRITE;
288 info->value.integer.min = min;
289 info->value.integer.max = max;
290 info->value.integer.step = step;
291 err = ctl->ops->element_add(ctl, info);
294 snd_ctl_elem_value_alloca(&val);
296 for (i = 0; i < count; i++)
297 val->value.integer.value[i] = min;
298 err = ctl->ops->element_write(ctl, val);
303 * \brief Create and add an user INTEGER64 CTL element
304 * \param ctl CTL handle
305 * \param id CTL element id to add
306 * \param count number of elements
307 * \param min minimum value
308 * \param max maximum value
309 * \param step value step
310 * \return 0 on success otherwise a negative error code
312 int snd_ctl_elem_add_integer64(snd_ctl_t *ctl, const snd_ctl_elem_id_t *id,
313 unsigned int count, long long min, long long max,
316 snd_ctl_elem_info_t *info;
317 snd_ctl_elem_value_t *val;
321 assert(ctl && id && id->name[0]);
322 snd_ctl_elem_info_alloca(&info);
324 info->type = SND_CTL_ELEM_TYPE_INTEGER64;
326 info->value.integer64.min = min;
327 info->value.integer64.max = max;
328 info->value.integer64.step = step;
329 err = ctl->ops->element_add(ctl, info);
332 snd_ctl_elem_value_alloca(&val);
334 for (i = 0; i < count; i++)
335 val->value.integer64.value[i] = min;
336 err = ctl->ops->element_write(ctl, val);
341 * \brief Create and add an user BOOLEAN CTL element
342 * \param ctl CTL handle
343 * \param id CTL element id to add
344 * \param count number of elements
345 * \return 0 on success otherwise a negative error code
347 int snd_ctl_elem_add_boolean(snd_ctl_t *ctl, const snd_ctl_elem_id_t *id,
350 snd_ctl_elem_info_t *info;
352 assert(ctl && id && id->name[0]);
353 snd_ctl_elem_info_alloca(&info);
355 info->type = SND_CTL_ELEM_TYPE_BOOLEAN;
357 info->value.integer.min = 0;
358 info->value.integer.max = 1;
359 return ctl->ops->element_add(ctl, info);
363 * \brief Create and add an user IEC958 CTL element
364 * \param ctl CTL handle
365 * \param id CTL element info to add
366 * \return 0 on success otherwise a negative error code
368 int snd_ctl_elem_add_iec958(snd_ctl_t *ctl, const snd_ctl_elem_id_t *id)
370 snd_ctl_elem_info_t *info;
372 assert(ctl && id && id->name[0]);
373 snd_ctl_elem_info_alloca(&info);
375 info->type = SND_CTL_ELEM_TYPE_IEC958;
377 return ctl->ops->element_add(ctl, info);
381 * \brief Remove an user CTL element
382 * \param ctl CTL handle
383 * \param id CTL element identification
384 * \return 0 on success otherwise a negative error code
386 int snd_ctl_elem_remove(snd_ctl_t *ctl, snd_ctl_elem_id_t *id)
388 assert(ctl && id && (id->name[0] || id->numid));
389 return ctl->ops->element_remove(ctl, id);
393 * \brief Get CTL element value
394 * \param ctl CTL handle
395 * \param control CTL element id/value pointer
396 * \return 0 on success otherwise a negative error code
398 int snd_ctl_elem_read(snd_ctl_t *ctl, snd_ctl_elem_value_t *control)
400 assert(ctl && control && (control->id.name[0] || control->id.numid));
401 return ctl->ops->element_read(ctl, control);
405 * \brief Set CTL element value
406 * \param ctl CTL handle
407 * \param control CTL element id/value pointer
408 * \retval 0 on success
409 * \retval >0 on success when value was changed
410 * \retval <0 a negative error code
412 int snd_ctl_elem_write(snd_ctl_t *ctl, snd_ctl_elem_value_t *control)
414 assert(ctl && control && (control->id.name[0] || control->id.numid));
415 return ctl->ops->element_write(ctl, control);
418 static int snd_ctl_tlv_do(snd_ctl_t *ctl, int op_flag,
419 const snd_ctl_elem_id_t *id,
420 unsigned int *tlv, unsigned int tlv_size)
422 snd_ctl_elem_info_t *info = NULL;
425 if (id->numid == 0) {
426 info = calloc(1, sizeof(*info));
431 err = snd_ctl_elem_info(ctl, info);
434 if (id->numid == 0) {
439 err = ctl->ops->element_tlv(ctl, op_flag, id->numid, tlv, tlv_size);
449 * \brief Get CTL element TLV value
450 * \param ctl CTL handle
451 * \param id CTL element id pointer
452 * \param tlv TLV array pointer to store
453 * \param tlv_size TLV array size in bytes
454 * \return 0 on success otherwise a negative error code
456 int snd_ctl_elem_tlv_read(snd_ctl_t *ctl, const snd_ctl_elem_id_t *id,
457 unsigned int *tlv, unsigned int tlv_size)
460 assert(ctl && id && (id->name[0] || id->numid) && tlv);
461 if (tlv_size < 2 * sizeof(int))
463 /* 1.0.12 driver doesn't return the error even if the user TLV
464 * is empty. So, initialize TLV here with an invalid type
465 * and compare the returned value after ioctl for checking
466 * the validity of TLV.
470 err = snd_ctl_tlv_do(ctl, 0, id, tlv, tlv_size);
471 if (err >= 0 && tlv[0] == (unsigned int)-1)
477 * \brief Set CTL element TLV value
478 * \param ctl CTL handle
479 * \param id CTL element id pointer
480 * \param tlv TLV array pointer to store
481 * \retval 0 on success
482 * \retval >0 on success when value was changed
483 * \retval <0 a negative error code
485 int snd_ctl_elem_tlv_write(snd_ctl_t *ctl, const snd_ctl_elem_id_t *id,
486 const unsigned int *tlv)
488 assert(ctl && id && (id->name[0] || id->numid) && tlv);
489 return snd_ctl_tlv_do(ctl, 1, id, (unsigned int *)tlv, tlv[1] + 2 * sizeof(unsigned int));
493 * \brief Process CTL element TLV command
494 * \param ctl CTL handle
495 * \param id CTL element id pointer
496 * \param tlv TLV array pointer to process
497 * \retval 0 on success
498 * \retval >0 on success when value was changed
499 * \retval <0 a negative error code
501 int snd_ctl_elem_tlv_command(snd_ctl_t *ctl, const snd_ctl_elem_id_t *id,
502 const unsigned int *tlv)
504 assert(ctl && id && (id->name[0] || id->numid) && tlv);
505 return snd_ctl_tlv_do(ctl, -1, id, (unsigned int *)tlv, tlv[1] + 2 * sizeof(unsigned int));
509 * \brief Lock CTL element
510 * \param ctl CTL handle
511 * \param id CTL element id pointer
512 * \return 0 on success otherwise a negative error code
514 int snd_ctl_elem_lock(snd_ctl_t *ctl, snd_ctl_elem_id_t *id)
517 return ctl->ops->element_lock(ctl, id);
521 * \brief Unlock CTL element
522 * \param ctl CTL handle
523 * \param id CTL element id pointer
524 * \return 0 on success otherwise a negative error code
526 int snd_ctl_elem_unlock(snd_ctl_t *ctl, snd_ctl_elem_id_t *id)
529 return ctl->ops->element_unlock(ctl, id);
533 * \brief Get next hardware dependent device number
534 * \param ctl CTL handle
535 * \param device current device on entry and next device on return
536 * \return 0 on success otherwise a negative error code
538 int snd_ctl_hwdep_next_device(snd_ctl_t *ctl, int *device)
540 assert(ctl && device);
541 return ctl->ops->hwdep_next_device(ctl, device);
545 * \brief Get info about a hardware dependent device
546 * \param ctl CTL handle
547 * \param info Hardware dependent device id/info pointer
548 * \return 0 on success otherwise a negative error code
550 int snd_ctl_hwdep_info(snd_ctl_t *ctl, snd_hwdep_info_t * info)
553 return ctl->ops->hwdep_info(ctl, info);
557 * \brief Get next PCM device number
558 * \param ctl CTL handle
559 * \param device current device on entry and next device on return
560 * \return 0 on success otherwise a negative error code
562 int snd_ctl_pcm_next_device(snd_ctl_t *ctl, int * device)
564 assert(ctl && device);
565 return ctl->ops->pcm_next_device(ctl, device);
569 * \brief Get info about a PCM device
570 * \param ctl CTL handle
571 * \param info PCM device id/info pointer
572 * \return 0 on success otherwise a negative error code
574 int snd_ctl_pcm_info(snd_ctl_t *ctl, snd_pcm_info_t * info)
577 return ctl->ops->pcm_info(ctl, info);
581 * \brief Set preferred PCM subdevice number of successive PCM open
582 * \param ctl CTL handle
583 * \param subdev Preferred PCM subdevice number
584 * \return 0 on success otherwise a negative error code
586 int snd_ctl_pcm_prefer_subdevice(snd_ctl_t *ctl, int subdev)
589 return ctl->ops->pcm_prefer_subdevice(ctl, subdev);
593 * \brief Get next RawMidi device number
594 * \param ctl CTL handle
595 * \param device current device on entry and next device on return
596 * \return 0 on success otherwise a negative error code
598 int snd_ctl_rawmidi_next_device(snd_ctl_t *ctl, int * device)
600 assert(ctl && device);
601 return ctl->ops->rawmidi_next_device(ctl, device);
605 * \brief Get info about a RawMidi device
606 * \param ctl CTL handle
607 * \param info RawMidi device id/info pointer
608 * \return 0 on success otherwise a negative error code
610 int snd_ctl_rawmidi_info(snd_ctl_t *ctl, snd_rawmidi_info_t * info)
613 return ctl->ops->rawmidi_info(ctl, info);
617 * \brief Set preferred RawMidi subdevice number of successive RawMidi open
618 * \param ctl CTL handle
619 * \param subdev Preferred RawMidi subdevice number
620 * \return 0 on success otherwise a negative error code
622 int snd_ctl_rawmidi_prefer_subdevice(snd_ctl_t *ctl, int subdev)
625 return ctl->ops->rawmidi_prefer_subdevice(ctl, subdev);
629 * \brief Set Power State to given SND_CTL_POWER_* value and do the power management
630 * \param ctl CTL handle
631 * \param state Desired Power State
632 * \return 0 on success otherwise a negative error code
634 int snd_ctl_set_power_state(snd_ctl_t *ctl, unsigned int state)
637 if (ctl->ops->set_power_state)
638 return ctl->ops->set_power_state(ctl, state);
643 * \brief Get actual Power State
644 * \param ctl CTL handle
645 * \param state Destination value
646 * \return 0 on success otherwise a negative error code
648 int snd_ctl_get_power_state(snd_ctl_t *ctl, unsigned int *state)
651 if (ctl->ops->get_power_state)
652 return ctl->ops->get_power_state(ctl, state);
657 * \brief Read an event
658 * \param ctl CTL handle
659 * \param event Event pointer
660 * \return number of events read otherwise a negative error code on failure
662 int snd_ctl_read(snd_ctl_t *ctl, snd_ctl_event_t *event)
664 assert(ctl && event);
665 return (ctl->ops->read)(ctl, event);
669 * \brief Wait for a CTL to become ready (i.e. at least one event pending)
670 * \param ctl CTL handle
671 * \param timeout maximum time in milliseconds to wait
672 * \return 0 otherwise a negative error code on failure
674 int snd_ctl_wait(snd_ctl_t *ctl, int timeout)
677 unsigned short *revents;
678 int i, npfds, pollio, err, err_poll;
680 npfds = snd_ctl_poll_descriptors_count(ctl);
681 if (npfds <= 0 || npfds >= 16) {
682 SNDERR("Invalid poll_fds %d\n", npfds);
685 pfd = alloca(sizeof(*pfd) * npfds);
686 revents = alloca(sizeof(*revents) * npfds);
687 err = snd_ctl_poll_descriptors(ctl, pfd, npfds);
691 SNDMSG("invalid poll descriptors %d\n", err);
695 err_poll = poll(pfd, npfds, timeout);
700 err = snd_ctl_poll_descriptors_revents(ctl, pfd, npfds, revents);
704 for (i = 0; i < npfds; i++) {
705 if (revents[i] & (POLLERR | POLLNVAL))
707 if ((revents[i] & (POLLIN | POLLOUT)) == 0)
713 return err_poll > 0 ? 1 : 0;
717 * \brief Add an async handler for a CTL
718 * \param handler Returned handler handle
719 * \param ctl CTL handle
720 * \param callback Callback function
721 * \param private_data Callback private data
722 * \return 0 otherwise a negative error code on failure
724 int snd_async_add_ctl_handler(snd_async_handler_t **handler, snd_ctl_t *ctl,
725 snd_async_callback_t callback, void *private_data)
729 snd_async_handler_t *h;
730 err = snd_async_add_handler(&h, _snd_ctl_async_descriptor(ctl),
731 callback, private_data);
734 h->type = SND_ASYNC_HANDLER_CTL;
736 was_empty = list_empty(&ctl->async_handlers);
737 list_add_tail(&h->hlist, &ctl->async_handlers);
739 err = snd_ctl_async(ctl, snd_async_handler_get_signo(h), getpid());
741 snd_async_del_handler(h);
750 * \brief Return CTL handle related to an async handler
751 * \param handler Async handler handle
754 snd_ctl_t *snd_async_handler_get_ctl(snd_async_handler_t *handler)
756 assert(handler->type == SND_ASYNC_HANDLER_CTL);
757 return handler->u.ctl;
760 static const char *const build_in_ctls[] = {
764 static int snd_ctl_open_conf(snd_ctl_t **ctlp, const char *name,
765 snd_config_t *ctl_root, snd_config_t *ctl_conf, int mode)
768 char *buf = NULL, *buf1 = NULL;
770 snd_config_t *conf, *type_conf = NULL;
771 snd_config_iterator_t i, next;
772 const char *lib = NULL, *open_name = NULL;
774 int (*open_func)(snd_ctl_t **, const char *, snd_config_t *, snd_config_t *, int) = NULL;
776 extern void *snd_control_open_symbols(void);
779 if (snd_config_get_type(ctl_conf) != SND_CONFIG_TYPE_COMPOUND) {
781 SNDERR("Invalid type for CTL %s definition", name);
783 SNDERR("Invalid type for CTL definition");
786 err = snd_config_search(ctl_conf, "type", &conf);
788 SNDERR("type is not defined");
791 err = snd_config_get_id(conf, &id);
793 SNDERR("unable to get id");
796 err = snd_config_get_string(conf, &str);
798 SNDERR("Invalid type for %s", id);
801 err = snd_config_search_definition(ctl_root, "ctl_type", str, &type_conf);
803 if (snd_config_get_type(type_conf) != SND_CONFIG_TYPE_COMPOUND) {
804 SNDERR("Invalid type for CTL type %s definition", str);
807 snd_config_for_each(i, next, type_conf) {
808 snd_config_t *n = snd_config_iterator_entry(i);
810 if (snd_config_get_id(n, &id) < 0)
812 if (strcmp(id, "comment") == 0)
814 if (strcmp(id, "lib") == 0) {
815 err = snd_config_get_string(n, &lib);
817 SNDERR("Invalid type for %s", id);
822 if (strcmp(id, "open") == 0) {
823 err = snd_config_get_string(n, &open_name);
825 SNDERR("Invalid type for %s", id);
830 SNDERR("Unknown field %s", id);
836 buf = malloc(strlen(str) + 32);
842 sprintf(buf, "_snd_ctl_%s_open", str);
845 const char *const *build_in = build_in_ctls;
847 if (!strcmp(*build_in, str))
851 if (*build_in == NULL) {
852 buf1 = malloc(strlen(str) + sizeof(ALSA_PLUGIN_DIR) + 32);
858 sprintf(buf1, "%s/libasound_module_ctl_%s.so", ALSA_PLUGIN_DIR, str);
862 snd_control_open_symbols();
864 open_func = snd_dlobj_cache_lookup(open_name);
869 h = snd_dlopen(lib, RTLD_NOW);
871 open_func = snd_dlsym(h, open_name, SND_DLSYM_VERSION(SND_CONTROL_DLSYM_VERSION));
874 SNDERR("Cannot open shared library %s", lib);
876 } else if (!open_func) {
877 SNDERR("symbol %s is not defined inside %s", open_name, lib);
883 snd_config_delete(type_conf);
885 err = open_func(ctlp, name, ctl_root, ctl_conf, mode);
887 if (h /*&& (mode & SND_CTL_KEEP_ALIVE)*/) {
888 snd_dlobj_cache_add(open_name, h, open_func);
891 (*ctlp)->dl_handle = h;
903 static int snd_ctl_open_noupdate(snd_ctl_t **ctlp, snd_config_t *root, const char *name, int mode)
906 snd_config_t *ctl_conf;
907 err = snd_config_search_definition(root, "ctl", name, &ctl_conf);
909 SNDERR("Invalid CTL %s", name);
912 err = snd_ctl_open_conf(ctlp, name, root, ctl_conf, mode);
913 snd_config_delete(ctl_conf);
919 * \param ctlp Returned CTL handle
920 * \param name ASCII identifier of the CTL handle
921 * \param mode Open mode (see #SND_CTL_NONBLOCK, #SND_CTL_ASYNC)
922 * \return 0 on success otherwise a negative error code
924 int snd_ctl_open(snd_ctl_t **ctlp, const char *name, int mode)
927 assert(ctlp && name);
928 err = snd_config_update();
931 return snd_ctl_open_noupdate(ctlp, snd_config, name, mode);
935 * \brief Opens a CTL using local configuration
936 * \param ctlp Returned CTL handle
937 * \param name ASCII identifier of the CTL handle
938 * \param mode Open mode (see #SND_CTL_NONBLOCK, #SND_CTL_ASYNC)
939 * \param lconf Local configuration
940 * \return 0 on success otherwise a negative error code
942 int snd_ctl_open_lconf(snd_ctl_t **ctlp, const char *name,
943 int mode, snd_config_t *lconf)
945 assert(ctlp && name && lconf);
946 return snd_ctl_open_noupdate(ctlp, lconf, name, mode);
950 #define TYPE(v) [SND_CTL_ELEM_TYPE_##v] = #v
951 #define IFACE(v) [SND_CTL_ELEM_IFACE_##v] = #v
952 #define IFACE1(v, n) [SND_CTL_ELEM_IFACE_##v] = #n
953 #define EVENT(v) [SND_CTL_EVENT_##v] = #v
955 static const char *const snd_ctl_elem_type_names[] = {
965 static const char *const snd_ctl_elem_iface_names[] = {
975 static const char *const snd_ctl_event_type_names[] = {
981 * \brief get name of a CTL element type
982 * \param type CTL element type
983 * \return ascii name of CTL element type
985 const char *snd_ctl_elem_type_name(snd_ctl_elem_type_t type)
987 assert(type <= SND_CTL_ELEM_TYPE_LAST);
988 return snd_ctl_elem_type_names[type];
992 * \brief get name of a CTL element related interface
993 * \param iface CTL element related interface
994 * \return ascii name of CTL element related interface
996 const char *snd_ctl_elem_iface_name(snd_ctl_elem_iface_t iface)
998 assert(iface <= SND_CTL_ELEM_IFACE_LAST);
999 return snd_ctl_elem_iface_names[iface];
1003 * \brief get name of a CTL event type
1004 * \param type CTL event type
1005 * \return ascii name of CTL event type
1007 const char *snd_ctl_event_type_name(snd_ctl_event_type_t type)
1009 assert(type <= SND_CTL_EVENT_LAST);
1010 return snd_ctl_event_type_names[type];
1014 * \brief allocate space for CTL element identifiers list
1015 * \param obj CTL element identifiers list
1016 * \param entries Entries to allocate
1017 * \return 0 on success otherwise a negative error code
1019 int snd_ctl_elem_list_alloc_space(snd_ctl_elem_list_t *obj, unsigned int entries)
1022 obj->pids = calloc(entries, sizeof(*obj->pids));
1027 obj->space = entries;
1032 * \brief free previously allocated space for CTL element identifiers list
1033 * \param obj CTL element identifiers list
1035 void snd_ctl_elem_list_free_space(snd_ctl_elem_list_t *obj)
1043 * \brief Get event mask for an element related event
1044 * \param obj CTL event
1045 * \return event mask for element related event
1047 unsigned int snd_ctl_event_elem_get_mask(const snd_ctl_event_t *obj)
1050 assert(obj->type == SND_CTL_EVENT_ELEM);
1051 return obj->data.elem.mask;
1055 * \brief Get CTL element identifier for an element related event
1056 * \param obj CTL event
1057 * \param ptr Pointer to returned CTL element identifier
1059 void snd_ctl_event_elem_get_id(const snd_ctl_event_t *obj, snd_ctl_elem_id_t *ptr)
1062 assert(obj->type == SND_CTL_EVENT_ELEM);
1063 *ptr = obj->data.elem.id;
1067 * \brief Get element numeric identifier for an element related event
1068 * \param obj CTL event
1069 * \return element numeric identifier
1071 unsigned int snd_ctl_event_elem_get_numid(const snd_ctl_event_t *obj)
1074 assert(obj->type == SND_CTL_EVENT_ELEM);
1075 return obj->data.elem.id.numid;
1079 * \brief Get interface part of CTL element identifier for an element related event
1080 * \param obj CTL event
1081 * \return interface part of element identifier
1083 snd_ctl_elem_iface_t snd_ctl_event_elem_get_interface(const snd_ctl_event_t *obj)
1086 assert(obj->type == SND_CTL_EVENT_ELEM);
1087 return obj->data.elem.id.iface;
1091 * \brief Get device part of CTL element identifier for an element related event
1092 * \param obj CTL event
1093 * \return device part of element identifier
1095 unsigned int snd_ctl_event_elem_get_device(const snd_ctl_event_t *obj)
1098 assert(obj->type == SND_CTL_EVENT_ELEM);
1099 return obj->data.elem.id.device;
1103 * \brief Get subdevice part of CTL element identifier for an element related event
1104 * \param obj CTL event
1105 * \return subdevice part of element identifier
1107 unsigned int snd_ctl_event_elem_get_subdevice(const snd_ctl_event_t *obj)
1110 assert(obj->type == SND_CTL_EVENT_ELEM);
1111 return obj->data.elem.id.subdevice;
1115 * \brief Get name part of CTL element identifier for an element related event
1116 * \param obj CTL event
1117 * \return name part of element identifier
1119 const char *snd_ctl_event_elem_get_name(const snd_ctl_event_t *obj)
1122 assert(obj->type == SND_CTL_EVENT_ELEM);
1123 return (const char *)obj->data.elem.id.name;
1127 * \brief Get index part of CTL element identifier for an element related event
1128 * \param obj CTL event
1129 * \return index part of element identifier
1131 unsigned int snd_ctl_event_elem_get_index(const snd_ctl_event_t *obj)
1134 assert(obj->type == SND_CTL_EVENT_ELEM);
1135 return obj->data.elem.id.index;
1139 int _snd_ctl_poll_descriptor(snd_ctl_t *ctl)
1142 return ctl->poll_fd;
1147 * \brief get size of #snd_ctl_elem_id_t
1148 * \return size in bytes
1150 size_t snd_ctl_elem_id_sizeof()
1152 return sizeof(snd_ctl_elem_id_t);
1156 * \brief allocate an invalid #snd_ctl_elem_id_t using standard malloc
1157 * \param ptr returned pointer
1158 * \return 0 on success otherwise negative error code
1160 int snd_ctl_elem_id_malloc(snd_ctl_elem_id_t **ptr)
1163 *ptr = calloc(1, sizeof(snd_ctl_elem_id_t));
1170 * \brief frees a previously allocated #snd_ctl_elem_id_t
1171 * \param obj pointer to object to free
1173 void snd_ctl_elem_id_free(snd_ctl_elem_id_t *obj)
1179 * \brief clear given #snd_ctl_elem_id_t object
1180 * \param obj pointer to object to clear
1182 void snd_ctl_elem_id_clear(snd_ctl_elem_id_t *obj)
1184 memset(obj, 0, sizeof(snd_ctl_elem_id_t));
1188 * \brief copy one #snd_ctl_elem_id_t to another
1189 * \param dst pointer to destination
1190 * \param src pointer to source
1192 void snd_ctl_elem_id_copy(snd_ctl_elem_id_t *dst, const snd_ctl_elem_id_t *src)
1199 * \brief Get numeric identifier from a CTL element identifier
1200 * \param obj CTL element identifier
1201 * \return CTL element numeric identifier
1203 unsigned int snd_ctl_elem_id_get_numid(const snd_ctl_elem_id_t *obj)
1210 * \brief Get interface part of a CTL element identifier
1211 * \param obj CTL element identifier
1212 * \return CTL element related interface
1214 snd_ctl_elem_iface_t snd_ctl_elem_id_get_interface(const snd_ctl_elem_id_t *obj)
1221 * \brief Get device part of a CTL element identifier
1222 * \param obj CTL element identifier
1223 * \return CTL element related device
1225 unsigned int snd_ctl_elem_id_get_device(const snd_ctl_elem_id_t *obj)
1232 * \brief Get subdevice part of a CTL element identifier
1233 * \param obj CTL element identifier
1234 * \return CTL element related subdevice
1236 unsigned int snd_ctl_elem_id_get_subdevice(const snd_ctl_elem_id_t *obj)
1239 return obj->subdevice;
1243 * \brief Get name part of a CTL element identifier
1244 * \param obj CTL element identifier
1245 * \return CTL element name
1247 const char *snd_ctl_elem_id_get_name(const snd_ctl_elem_id_t *obj)
1250 return (const char *)obj->name;
1254 * \brief Get index part of a CTL element identifier
1255 * \param obj CTL element identifier
1256 * \return CTL element index
1258 unsigned int snd_ctl_elem_id_get_index(const snd_ctl_elem_id_t *obj)
1265 * \brief Set numeric identifier for a CTL element identifier
1266 * \param obj CTL element identifier
1267 * \param val CTL element numeric identifier
1269 void snd_ctl_elem_id_set_numid(snd_ctl_elem_id_t *obj, unsigned int val)
1276 * \brief Set interface part for a CTL element identifier
1277 * \param obj CTL element identifier
1278 * \param val CTL element related interface
1280 void snd_ctl_elem_id_set_interface(snd_ctl_elem_id_t *obj, snd_ctl_elem_iface_t val)
1287 * \brief Set device part for a CTL element identifier
1288 * \param obj CTL element identifier
1289 * \param val CTL element related device
1291 void snd_ctl_elem_id_set_device(snd_ctl_elem_id_t *obj, unsigned int val)
1298 * \brief Set subdevice part for a CTL element identifier
1299 * \param obj CTL element identifier
1300 * \param val CTL element related subdevice
1302 void snd_ctl_elem_id_set_subdevice(snd_ctl_elem_id_t *obj, unsigned int val)
1305 obj->subdevice = val;
1309 * \brief Set name part for a CTL element identifier
1310 * \param obj CTL element identifier
1311 * \param val CTL element name
1313 void snd_ctl_elem_id_set_name(snd_ctl_elem_id_t *obj, const char *val)
1316 strncpy((char *)obj->name, val, sizeof(obj->name));
1320 * \brief Set index part for a CTL element identifier
1321 * \param obj CTL element identifier
1322 * \param val CTL element index
1324 void snd_ctl_elem_id_set_index(snd_ctl_elem_id_t *obj, unsigned int val)
1331 * \brief get size of #snd_ctl_card_info_t
1332 * \return size in bytes
1334 size_t snd_ctl_card_info_sizeof()
1336 return sizeof(snd_ctl_card_info_t);
1340 * \brief allocate an invalid #snd_ctl_card_info_t using standard malloc
1341 * \param ptr returned pointer
1342 * \return 0 on success otherwise negative error code
1344 int snd_ctl_card_info_malloc(snd_ctl_card_info_t **ptr)
1347 *ptr = calloc(1, sizeof(snd_ctl_card_info_t));
1354 * \brief frees a previously allocated #snd_ctl_card_info_t
1355 * \param obj pointer to object to free
1357 void snd_ctl_card_info_free(snd_ctl_card_info_t *obj)
1363 * \brief clear given #snd_ctl_card_info_t object
1364 * \param obj pointer to object to clear
1366 void snd_ctl_card_info_clear(snd_ctl_card_info_t *obj)
1368 memset(obj, 0, sizeof(snd_ctl_card_info_t));
1372 * \brief copy one #snd_ctl_card_info_t to another
1373 * \param dst pointer to destination
1374 * \param src pointer to source
1376 void snd_ctl_card_info_copy(snd_ctl_card_info_t *dst, const snd_ctl_card_info_t *src)
1383 * \brief Get card number from a CTL card info
1384 * \param obj CTL card info
1385 * \return card number
1387 int snd_ctl_card_info_get_card(const snd_ctl_card_info_t *obj)
1394 * \brief Get card identifier from a CTL card info
1395 * \param obj CTL card info
1396 * \return card identifier
1398 const char *snd_ctl_card_info_get_id(const snd_ctl_card_info_t *obj)
1401 return (const char *)obj->id;
1405 * \brief Get card driver name from a CTL card info
1406 * \param obj CTL card info
1407 * \return card driver name
1409 const char *snd_ctl_card_info_get_driver(const snd_ctl_card_info_t *obj)
1412 return (const char *)obj->driver;
1416 * \brief Get card name from a CTL card info
1417 * \param obj CTL card info
1420 const char *snd_ctl_card_info_get_name(const snd_ctl_card_info_t *obj)
1423 return (const char *)obj->name;
1427 * \brief Get card long name from a CTL card info
1428 * \param obj CTL card info
1429 * \return card long name
1431 const char *snd_ctl_card_info_get_longname(const snd_ctl_card_info_t *obj)
1434 return (const char *)obj->longname;
1438 * \brief Get card mixer name from a CTL card info
1439 * \param obj CTL card info
1440 * \return card mixer name
1442 const char *snd_ctl_card_info_get_mixername(const snd_ctl_card_info_t *obj)
1445 return (const char *)obj->mixername;
1449 * \brief Get card component list from a CTL card info
1450 * \param obj CTL card info
1451 * \return card mixer identifier
1453 const char *snd_ctl_card_info_get_components(const snd_ctl_card_info_t *obj)
1456 return (const char *)obj->components;
1460 * \brief get size of #snd_ctl_event_t
1461 * \return size in bytes
1463 size_t snd_ctl_event_sizeof()
1465 return sizeof(snd_ctl_event_t);
1469 * \brief allocate an invalid #snd_ctl_event_t using standard malloc
1470 * \param ptr returned pointer
1471 * \return 0 on success otherwise negative error code
1473 int snd_ctl_event_malloc(snd_ctl_event_t **ptr)
1476 *ptr = calloc(1, sizeof(snd_ctl_event_t));
1483 * \brief frees a previously allocated #snd_ctl_event_t
1484 * \param obj pointer to object to free
1486 void snd_ctl_event_free(snd_ctl_event_t *obj)
1492 * \brief clear given #snd_ctl_event_t object
1493 * \param obj pointer to object to clear
1495 void snd_ctl_event_clear(snd_ctl_event_t *obj)
1497 memset(obj, 0, sizeof(snd_ctl_event_t));
1501 * \brief copy one #snd_ctl_event_t to another
1502 * \param dst pointer to destination
1503 * \param src pointer to source
1505 void snd_ctl_event_copy(snd_ctl_event_t *dst, const snd_ctl_event_t *src)
1512 * \brief Get type of a CTL event
1513 * \param obj CTL event
1514 * \return CTL event type
1516 snd_ctl_event_type_t snd_ctl_event_get_type(const snd_ctl_event_t *obj)
1523 * \brief get size of #snd_ctl_elem_list_t
1524 * \return size in bytes
1526 size_t snd_ctl_elem_list_sizeof()
1528 return sizeof(snd_ctl_elem_list_t);
1532 * \brief allocate an invalid #snd_ctl_elem_list_t using standard malloc
1533 * \param ptr returned pointer
1534 * \return 0 on success otherwise negative error code
1536 int snd_ctl_elem_list_malloc(snd_ctl_elem_list_t **ptr)
1539 *ptr = calloc(1, sizeof(snd_ctl_elem_list_t));
1546 * \brief frees a previously allocated #snd_ctl_elem_list_t
1547 * \param obj pointer to object to free
1549 void snd_ctl_elem_list_free(snd_ctl_elem_list_t *obj)
1555 * \brief clear given #snd_ctl_elem_list_t object
1556 * \param obj pointer to object to clear
1558 void snd_ctl_elem_list_clear(snd_ctl_elem_list_t *obj)
1560 memset(obj, 0, sizeof(snd_ctl_elem_list_t));
1564 * \brief copy one #snd_ctl_elem_list_t to another
1565 * \param dst pointer to destination
1566 * \param src pointer to source
1568 void snd_ctl_elem_list_copy(snd_ctl_elem_list_t *dst, const snd_ctl_elem_list_t *src)
1575 * \brief Set index of first wanted CTL element identifier in a CTL element identifiers list
1576 * \param obj CTL element identifiers list
1577 * \param val index of CTL element to put at position 0 of list
1579 void snd_ctl_elem_list_set_offset(snd_ctl_elem_list_t *obj, unsigned int val)
1586 * \brief Get number of used entries in CTL element identifiers list
1587 * \param obj CTL element identifier list
1588 * \return number of used entries
1590 unsigned int snd_ctl_elem_list_get_used(const snd_ctl_elem_list_t *obj)
1597 * \brief Get total count of elements present in CTL device (information present in every filled CTL element identifiers list)
1598 * \param obj CTL element identifier list
1599 * \return total number of elements
1601 unsigned int snd_ctl_elem_list_get_count(const snd_ctl_elem_list_t *obj)
1608 * \brief Get CTL element identifier for an entry of a CTL element identifiers list
1609 * \param obj CTL element identifier list
1610 * \param idx Index of entry
1611 * \param ptr Pointer to returned CTL element identifier
1613 void snd_ctl_elem_list_get_id(const snd_ctl_elem_list_t *obj, unsigned int idx, snd_ctl_elem_id_t *ptr)
1616 assert(idx < obj->used);
1617 *ptr = obj->pids[idx];
1621 * \brief Get CTL element numeric identifier for an entry of a CTL element identifiers list
1622 * \param obj CTL element identifier list
1623 * \param idx Index of entry
1624 * \return CTL element numeric identifier
1626 unsigned int snd_ctl_elem_list_get_numid(const snd_ctl_elem_list_t *obj, unsigned int idx)
1629 assert(idx < obj->used);
1630 return obj->pids[idx].numid;
1634 * \brief Get interface part of CTL element identifier for an entry of a CTL element identifiers list
1635 * \param obj CTL element identifier list
1636 * \param idx Index of entry
1637 * \return CTL element related interface
1639 snd_ctl_elem_iface_t snd_ctl_elem_list_get_interface(const snd_ctl_elem_list_t *obj, unsigned int idx)
1642 assert(idx < obj->used);
1643 return obj->pids[idx].iface;
1647 * \brief Get device part of CTL element identifier for an entry of a CTL element identifiers list
1648 * \param obj CTL element identifier list
1649 * \param idx Index of entry
1650 * \return CTL element related device
1652 unsigned int snd_ctl_elem_list_get_device(const snd_ctl_elem_list_t *obj, unsigned int idx)
1655 assert(idx < obj->used);
1656 return obj->pids[idx].device;
1660 * \brief Get subdevice part of CTL element identifier for an entry of a CTL element identifiers list
1661 * \param obj CTL element identifier list
1662 * \param idx Index of entry
1663 * \return CTL element related subdevice
1665 unsigned int snd_ctl_elem_list_get_subdevice(const snd_ctl_elem_list_t *obj, unsigned int idx)
1668 assert(idx < obj->used);
1669 return obj->pids[idx].subdevice;
1673 * \brief Get name part of CTL element identifier for an entry of a CTL element identifiers list
1674 * \param obj CTL element identifier list
1675 * \param idx Index of entry
1676 * \return CTL element name
1678 const char *snd_ctl_elem_list_get_name(const snd_ctl_elem_list_t *obj, unsigned int idx)
1681 assert(idx < obj->used);
1682 return (const char *)obj->pids[idx].name;
1686 * \brief Get index part of CTL element identifier for an entry of a CTL element identifiers list
1687 * \param obj CTL element identifier list
1688 * \param idx Index of entry
1689 * \return CTL element index
1691 unsigned int snd_ctl_elem_list_get_index(const snd_ctl_elem_list_t *obj, unsigned int idx)
1694 assert(idx < obj->used);
1695 return obj->pids[idx].index;
1699 * \brief get size of #snd_ctl_elem_info_t
1700 * \return size in bytes
1702 size_t snd_ctl_elem_info_sizeof()
1704 return sizeof(snd_ctl_elem_info_t);
1708 * \brief allocate an invalid #snd_ctl_elem_info_t using standard malloc
1709 * \param ptr returned pointer
1710 * \return 0 on success otherwise negative error code
1712 int snd_ctl_elem_info_malloc(snd_ctl_elem_info_t **ptr)
1715 *ptr = calloc(1, sizeof(snd_ctl_elem_info_t));
1722 * \brief frees a previously allocated #snd_ctl_elem_info_t
1723 * \param obj pointer to object to free
1725 void snd_ctl_elem_info_free(snd_ctl_elem_info_t *obj)
1731 * \brief clear given #snd_ctl_elem_info_t object
1732 * \param obj pointer to object to clear
1734 void snd_ctl_elem_info_clear(snd_ctl_elem_info_t *obj)
1736 memset(obj, 0, sizeof(snd_ctl_elem_info_t));
1740 * \brief copy one #snd_ctl_elem_info_t to another
1741 * \param dst pointer to destination
1742 * \param src pointer to source
1744 void snd_ctl_elem_info_copy(snd_ctl_elem_info_t *dst, const snd_ctl_elem_info_t *src)
1751 * \brief Get type from a CTL element id/info
1752 * \param obj CTL element id/info
1753 * \return CTL element content type
1755 snd_ctl_elem_type_t snd_ctl_elem_info_get_type(const snd_ctl_elem_info_t *obj)
1762 * \brief Get info about readability from a CTL element id/info
1763 * \param obj CTL element id/info
1764 * \return 0 if element is not readable, 1 if element is readable
1766 int snd_ctl_elem_info_is_readable(const snd_ctl_elem_info_t *obj)
1769 return !!(obj->access & SNDRV_CTL_ELEM_ACCESS_READ);
1773 * \brief Get info about writability from a CTL element id/info
1774 * \param obj CTL element id/info
1775 * \return 0 if element is not writable, 1 if element is not writable
1777 int snd_ctl_elem_info_is_writable(const snd_ctl_elem_info_t *obj)
1780 return !!(obj->access & SNDRV_CTL_ELEM_ACCESS_WRITE);
1784 * \brief Get info about notification feasibility from a CTL element id/info
1785 * \param obj CTL element id/info
1786 * \return 0 if all element value changes are notified to subscribed applications, 1 otherwise
1788 int snd_ctl_elem_info_is_volatile(const snd_ctl_elem_info_t *obj)
1791 return !!(obj->access & SNDRV_CTL_ELEM_ACCESS_VOLATILE);
1795 * \brief Get info about status from a CTL element id/info
1796 * \param obj CTL element id/info
1797 * \return 0 if element value is not active, 1 if is active
1799 int snd_ctl_elem_info_is_inactive(const snd_ctl_elem_info_t *obj)
1802 return !!(obj->access & SNDRV_CTL_ELEM_ACCESS_INACTIVE);
1806 * \brief Get info whether an element is locked
1807 * \param obj CTL element id/info
1808 * \return 0 if element value is currently changeable, 1 if it's locked by another application
1810 int snd_ctl_elem_info_is_locked(const snd_ctl_elem_info_t *obj)
1813 return !!(obj->access & SNDRV_CTL_ELEM_ACCESS_LOCK);
1817 * \brief Get info if I own an element
1818 * \param obj CTL element id/info
1819 * \return 0 if element value is currently changeable, 1 if it's locked by another application
1821 int snd_ctl_elem_info_is_owner(const snd_ctl_elem_info_t *obj)
1824 return !!(obj->access & SNDRV_CTL_ELEM_ACCESS_OWNER);
1828 * \brief Get info if it's a user element
1829 * \param obj CTL element id/info
1830 * \return 0 if element value is a system element, 1 if it's a user-created element
1832 int snd_ctl_elem_info_is_user(const snd_ctl_elem_info_t *obj)
1835 return !!(obj->access & SNDRV_CTL_ELEM_ACCESS_USER);
1839 * \brief Get info about TLV readability from a CTL element id/info
1840 * \param obj CTL element id/info
1841 * \return 0 if element's TLV is not readable, 1 if element's TLV is readable
1843 int snd_ctl_elem_info_is_tlv_readable(const snd_ctl_elem_info_t *obj)
1846 return !!(obj->access & SNDRV_CTL_ELEM_ACCESS_TLV_READ);
1850 * \brief Get info about TLV writeability from a CTL element id/info
1851 * \param obj CTL element id/info
1852 * \return 0 if element's TLV is not writable, 1 if element's TLV is writable
1854 int snd_ctl_elem_info_is_tlv_writable(const snd_ctl_elem_info_t *obj)
1857 return !!(obj->access & SNDRV_CTL_ELEM_ACCESS_TLV_WRITE);
1861 * \brief Get info about TLV command possibility from a CTL element id/info
1862 * \param obj CTL element id/info
1863 * \return 0 if element's TLV command is not possible, 1 if element's TLV command is supported
1865 int snd_ctl_elem_info_is_tlv_commandable(const snd_ctl_elem_info_t *obj)
1868 return !!(obj->access & SNDRV_CTL_ELEM_ACCESS_TLV_COMMAND);
1872 * \brief (DEPRECATED) Get info about values passing policy from a CTL element value
1873 * \param obj CTL element id/info
1874 * \return 0 if element value need to be passed by contents, 1 if need to be passed with a pointer
1876 int snd_ctl_elem_info_is_indirect(const snd_ctl_elem_info_t *obj)
1881 link_warning(snd_ctl_elem_info_is_indirect, "Warning: snd_ctl_elem_info_is_indirect is deprecated, do not use it");
1884 * \brief Get owner of a locked element
1885 * \param obj CTL element id/info
1886 * \return value entries count
1888 pid_t snd_ctl_elem_info_get_owner(const snd_ctl_elem_info_t *obj)
1895 * \brief Get number of value entries from a CTL element id/info
1896 * \param obj CTL element id/info
1897 * \return value entries count
1899 unsigned int snd_ctl_elem_info_get_count(const snd_ctl_elem_info_t *obj)
1906 * \brief Get minimum value from a #SND_CTL_ELEM_TYPE_INTEGER CTL element id/info
1907 * \param obj CTL element id/info
1908 * \return Minimum value
1910 long snd_ctl_elem_info_get_min(const snd_ctl_elem_info_t *obj)
1913 assert(obj->type == SND_CTL_ELEM_TYPE_INTEGER);
1914 return obj->value.integer.min;
1918 * \brief Get maximum value from a #SND_CTL_ELEM_TYPE_INTEGER CTL element id/info
1919 * \param obj CTL element id/info
1920 * \return Maximum value
1922 long snd_ctl_elem_info_get_max(const snd_ctl_elem_info_t *obj)
1925 assert(obj->type == SND_CTL_ELEM_TYPE_INTEGER);
1926 return obj->value.integer.max;
1930 * \brief Get value step from a #SND_CTL_ELEM_TYPE_INTEGER CTL element id/info
1931 * \param obj CTL element id/info
1934 long snd_ctl_elem_info_get_step(const snd_ctl_elem_info_t *obj)
1937 assert(obj->type == SND_CTL_ELEM_TYPE_INTEGER);
1938 return obj->value.integer.step;
1942 * \brief Get minimum value from a #SND_CTL_ELEM_TYPE_INTEGER64 CTL element id/info
1943 * \param obj CTL element id/info
1944 * \return Minimum value
1946 long long snd_ctl_elem_info_get_min64(const snd_ctl_elem_info_t *obj)
1949 assert(obj->type == SND_CTL_ELEM_TYPE_INTEGER64);
1950 return obj->value.integer64.min;
1954 * \brief Get maximum value from a #SND_CTL_ELEM_TYPE_INTEGER64 CTL element id/info
1955 * \param obj CTL element id/info
1956 * \return Maximum value
1958 long long snd_ctl_elem_info_get_max64(const snd_ctl_elem_info_t *obj)
1961 assert(obj->type == SND_CTL_ELEM_TYPE_INTEGER64);
1962 return obj->value.integer64.max;
1966 * \brief Get value step from a #SND_CTL_ELEM_TYPE_INTEGER64 CTL element id/info
1967 * \param obj CTL element id/info
1970 long long snd_ctl_elem_info_get_step64(const snd_ctl_elem_info_t *obj)
1973 assert(obj->type == SND_CTL_ELEM_TYPE_INTEGER64);
1974 return obj->value.integer64.step;
1978 * \brief Get number of items available from a #SND_CTL_ELEM_TYPE_ENUMERATED CTL element id/info
1979 * \param obj CTL element id/info
1980 * \return items count
1982 unsigned int snd_ctl_elem_info_get_items(const snd_ctl_elem_info_t *obj)
1985 assert(obj->type == SND_CTL_ELEM_TYPE_ENUMERATED);
1986 return obj->value.enumerated.items;
1990 * \brief Select item in a #SND_CTL_ELEM_TYPE_ENUMERATED CTL element id/info
1991 * \param obj CTL element id/info
1992 * \param val item number
1994 void snd_ctl_elem_info_set_item(snd_ctl_elem_info_t *obj, unsigned int val)
1997 obj->value.enumerated.item = val;
2001 * \brief Get name for selected item in a #SND_CTL_ELEM_TYPE_ENUMERATED CTL element id/info
2002 * \param obj CTL element id/info
2003 * \return name of chosen item
2005 const char *snd_ctl_elem_info_get_item_name(const snd_ctl_elem_info_t *obj)
2008 assert(obj->type == SND_CTL_ELEM_TYPE_ENUMERATED);
2009 return obj->value.enumerated.name;
2013 * \brief Get count of dimensions for given element
2014 * \param obj CTL element id/info
2015 * \return zero value if no dimensions are defined, otherwise positive value with count of dimensions
2018 int INTERNAL(snd_ctl_elem_info_get_dimensions)(const snd_ctl_elem_info_t *obj)
2020 int snd_ctl_elem_info_get_dimensions(const snd_ctl_elem_info_t *obj)
2026 for (i = 3; i >= 0; i--)
2027 if (obj->dimen.d[i])
2031 use_default_symbol_version(__snd_ctl_elem_info_get_dimensions, snd_ctl_elem_info_get_dimensions, ALSA_0.9.3);
2034 * \brief Get specified of dimension width for given element
2035 * \param obj CTL element id/info
2036 * \param idx The dimension index
2037 * \return zero value if no dimension width is defined, otherwise positive value with with of specified dimension
2040 int INTERNAL(snd_ctl_elem_info_get_dimension)(const snd_ctl_elem_info_t *obj, unsigned int idx)
2042 int snd_ctl_elem_info_get_dimension(const snd_ctl_elem_info_t *obj, unsigned int idx)
2048 return obj->dimen.d[idx];
2050 use_default_symbol_version(__snd_ctl_elem_info_get_dimension, snd_ctl_elem_info_get_dimension, ALSA_0.9.3);
2053 * \brief Get CTL element identifier of a CTL element id/info
2054 * \param obj CTL element id/info
2055 * \param ptr Pointer to returned CTL element identifier
2057 void snd_ctl_elem_info_get_id(const snd_ctl_elem_info_t *obj, snd_ctl_elem_id_t *ptr)
2064 * \brief Get element numeric identifier of a CTL element id/info
2065 * \param obj CTL element id/info
2066 * \return element numeric identifier
2068 unsigned int snd_ctl_elem_info_get_numid(const snd_ctl_elem_info_t *obj)
2071 return obj->id.numid;
2075 * \brief Get interface part of CTL element identifier of a CTL element id/info
2076 * \param obj CTL element id/info
2077 * \return interface part of element identifier
2079 snd_ctl_elem_iface_t snd_ctl_elem_info_get_interface(const snd_ctl_elem_info_t *obj)
2082 return obj->id.iface;
2086 * \brief Get device part of CTL element identifier of a CTL element id/info
2087 * \param obj CTL element id/info
2088 * \return device part of element identifier
2090 unsigned int snd_ctl_elem_info_get_device(const snd_ctl_elem_info_t *obj)
2093 return obj->id.device;
2097 * \brief Get subdevice part of CTL element identifier of a CTL element id/info
2098 * \param obj CTL element id/info
2099 * \return subdevice part of element identifier
2101 unsigned int snd_ctl_elem_info_get_subdevice(const snd_ctl_elem_info_t *obj)
2104 return obj->id.subdevice;
2108 * \brief Get name part of CTL element identifier of a CTL element id/info
2109 * \param obj CTL element id/info
2110 * \return name part of element identifier
2112 const char *snd_ctl_elem_info_get_name(const snd_ctl_elem_info_t *obj)
2115 return (const char *)obj->id.name;
2119 * \brief Get index part of CTL element identifier of a CTL element id/info
2120 * \param obj CTL element id/info
2121 * \return index part of element identifier
2123 unsigned int snd_ctl_elem_info_get_index(const snd_ctl_elem_info_t *obj)
2126 return obj->id.index;
2130 * \brief Set CTL element identifier of a CTL element id/info
2131 * \param obj CTL element id/info
2132 * \param ptr CTL element identifier
2134 void snd_ctl_elem_info_set_id(snd_ctl_elem_info_t *obj, const snd_ctl_elem_id_t *ptr)
2141 * \brief Set element numeric identifier of a CTL element id/info
2142 * \param obj CTL element id/info
2143 * \param val element numeric identifier
2145 void snd_ctl_elem_info_set_numid(snd_ctl_elem_info_t *obj, unsigned int val)
2148 obj->id.numid = val;
2152 * \brief Set interface part of CTL element identifier of a CTL element id/info
2153 * \param obj CTL element id/info
2154 * \param val interface part of element identifier
2156 void snd_ctl_elem_info_set_interface(snd_ctl_elem_info_t *obj, snd_ctl_elem_iface_t val)
2159 obj->id.iface = val;
2163 * \brief Set device part of CTL element identifier of a CTL element id/info
2164 * \param obj CTL element id/info
2165 * \param val device part of element identifier
2167 void snd_ctl_elem_info_set_device(snd_ctl_elem_info_t *obj, unsigned int val)
2170 obj->id.device = val;
2174 * \brief Set subdevice part of CTL element identifier of a CTL element id/info
2175 * \param obj CTL element id/info
2176 * \param val subdevice part of element identifier
2178 void snd_ctl_elem_info_set_subdevice(snd_ctl_elem_info_t *obj, unsigned int val)
2181 obj->id.subdevice = val;
2185 * \brief Set name part of CTL element identifier of a CTL element id/info
2186 * \param obj CTL element id/info
2187 * \param val name part of element identifier
2189 void snd_ctl_elem_info_set_name(snd_ctl_elem_info_t *obj, const char *val)
2192 strncpy((char *)obj->id.name, val, sizeof(obj->id.name));
2196 * \brief Set index part of CTL element identifier of a CTL element id/info
2197 * \param obj CTL element id/info
2198 * \param val index part of element identifier
2200 void snd_ctl_elem_info_set_index(snd_ctl_elem_info_t *obj, unsigned int val)
2203 obj->id.index = val;
2207 * \brief get size of #snd_ctl_elem_value_t
2208 * \return size in bytes
2210 size_t snd_ctl_elem_value_sizeof()
2212 return sizeof(snd_ctl_elem_value_t);
2216 * \brief allocate an invalid #snd_ctl_elem_value_t using standard malloc
2217 * \param ptr returned pointer
2218 * \return 0 on success otherwise negative error code
2220 int snd_ctl_elem_value_malloc(snd_ctl_elem_value_t **ptr)
2223 *ptr = calloc(1, sizeof(snd_ctl_elem_value_t));
2230 * \brief frees a previously allocated #snd_ctl_elem_value_t
2231 * \param obj pointer to object to free
2233 void snd_ctl_elem_value_free(snd_ctl_elem_value_t *obj)
2239 * \brief clear given #snd_ctl_elem_value_t object
2240 * \param obj pointer to object to clear
2242 void snd_ctl_elem_value_clear(snd_ctl_elem_value_t *obj)
2244 memset(obj, 0, sizeof(snd_ctl_elem_value_t));
2248 * \brief copy one #snd_ctl_elem_value_t to another
2249 * \param dst pointer to destination
2250 * \param src pointer to source
2252 void snd_ctl_elem_value_copy(snd_ctl_elem_value_t *dst, const snd_ctl_elem_value_t *src)
2259 * \brief Get CTL element identifier of a CTL element id/value
2260 * \param obj CTL element id/value
2261 * \param ptr Pointer to returned CTL element identifier
2263 void snd_ctl_elem_value_get_id(const snd_ctl_elem_value_t *obj, snd_ctl_elem_id_t *ptr)
2270 * \brief Get element numeric identifier of a CTL element id/value
2271 * \param obj CTL element id/value
2272 * \return element numeric identifier
2274 unsigned int snd_ctl_elem_value_get_numid(const snd_ctl_elem_value_t *obj)
2277 return obj->id.numid;
2281 * \brief Get interface part of CTL element identifier of a CTL element id/value
2282 * \param obj CTL element id/value
2283 * \return interface part of element identifier
2285 snd_ctl_elem_iface_t snd_ctl_elem_value_get_interface(const snd_ctl_elem_value_t *obj)
2288 return obj->id.iface;
2292 * \brief Get device part of CTL element identifier of a CTL element id/value
2293 * \param obj CTL element id/value
2294 * \return device part of element identifier
2296 unsigned int snd_ctl_elem_value_get_device(const snd_ctl_elem_value_t *obj)
2299 return obj->id.device;
2303 * \brief Get subdevice part of CTL element identifier of a CTL element id/value
2304 * \param obj CTL element id/value
2305 * \return subdevice part of element identifier
2307 unsigned int snd_ctl_elem_value_get_subdevice(const snd_ctl_elem_value_t *obj)
2310 return obj->id.subdevice;
2314 * \brief Get name part of CTL element identifier of a CTL element id/value
2315 * \param obj CTL element id/value
2316 * \return name part of element identifier
2318 const char *snd_ctl_elem_value_get_name(const snd_ctl_elem_value_t *obj)
2321 return (const char *)obj->id.name;
2325 * \brief Get index part of CTL element identifier of a CTL element id/value
2326 * \param obj CTL element id/value
2327 * \return index part of element identifier
2329 unsigned int snd_ctl_elem_value_get_index(const snd_ctl_elem_value_t *obj)
2332 return obj->id.index;
2336 * \brief Set CTL element identifier of a CTL element id/value
2337 * \param obj CTL element id/value
2338 * \param ptr CTL element identifier
2340 void snd_ctl_elem_value_set_id(snd_ctl_elem_value_t *obj, const snd_ctl_elem_id_t *ptr)
2347 * \brief Set element numeric identifier of a CTL element id/value
2348 * \param obj CTL element id/value
2349 * \param val element numeric identifier
2351 void snd_ctl_elem_value_set_numid(snd_ctl_elem_value_t *obj, unsigned int val)
2354 obj->id.numid = val;
2358 * \brief Set interface part of CTL element identifier of a CTL element id/value
2359 * \param obj CTL element id/value
2360 * \param val interface part of element identifier
2362 void snd_ctl_elem_value_set_interface(snd_ctl_elem_value_t *obj, snd_ctl_elem_iface_t val)
2365 obj->id.iface = val;
2369 * \brief Set device part of CTL element identifier of a CTL element id/value
2370 * \param obj CTL element id/value
2371 * \param val device part of element identifier
2373 void snd_ctl_elem_value_set_device(snd_ctl_elem_value_t *obj, unsigned int val)
2376 obj->id.device = val;
2380 * \brief Set subdevice part of CTL element identifier of a CTL element id/value
2381 * \param obj CTL element id/value
2382 * \param val subdevice part of element identifier
2384 void snd_ctl_elem_value_set_subdevice(snd_ctl_elem_value_t *obj, unsigned int val)
2387 obj->id.subdevice = val;
2391 * \brief Set name part of CTL element identifier of a CTL element id/value
2392 * \param obj CTL element id/value
2393 * \param val name part of element identifier
2395 void snd_ctl_elem_value_set_name(snd_ctl_elem_value_t *obj, const char *val)
2398 strncpy((char *)obj->id.name, val, sizeof(obj->id.name));
2402 * \brief Set index part of CTL element identifier of a CTL element id/value
2403 * \param obj CTL element id/value
2404 * \param val index part of element identifier
2406 void snd_ctl_elem_value_set_index(snd_ctl_elem_value_t *obj, unsigned int val)
2409 obj->id.index = val;
2413 * \brief Get value for an entry of a #SND_CTL_ELEM_TYPE_BOOLEAN CTL element id/value
2414 * \param obj CTL element id/value
2415 * \param idx Entry index
2416 * \return value for the entry
2418 int snd_ctl_elem_value_get_boolean(const snd_ctl_elem_value_t *obj, unsigned int idx)
2421 assert(idx < sizeof(obj->value.integer.value) / sizeof(obj->value.integer.value[0]));
2422 return obj->value.integer.value[idx];
2426 * \brief Get value for an entry of a #SND_CTL_ELEM_TYPE_INTEGER CTL element id/value
2427 * \param obj CTL element id/value
2428 * \param idx Entry index
2429 * \return value for the entry
2431 long snd_ctl_elem_value_get_integer(const snd_ctl_elem_value_t *obj, unsigned int idx)
2434 assert(idx < sizeof(obj->value.integer.value) / sizeof(obj->value.integer.value[0]));
2435 return obj->value.integer.value[idx];
2439 * \brief Get value for an entry of a #SND_CTL_ELEM_TYPE_INTEGER64 CTL element id/value
2440 * \param obj CTL element id/value
2441 * \param idx Entry index
2442 * \return value for the entry
2444 long long snd_ctl_elem_value_get_integer64(const snd_ctl_elem_value_t *obj, unsigned int idx)
2447 assert(idx < sizeof(obj->value.integer64.value) / sizeof(obj->value.integer64.value[0]));
2448 return obj->value.integer64.value[idx];
2452 * \brief Get value for an entry of a #SND_CTL_ELEM_TYPE_ENUMERATED CTL element id/value
2453 * \param obj CTL element id/value
2454 * \param idx Entry index
2455 * \return value for the entry
2457 unsigned int snd_ctl_elem_value_get_enumerated(const snd_ctl_elem_value_t *obj, unsigned int idx)
2460 assert(idx < sizeof(obj->value.enumerated.item) / sizeof(obj->value.enumerated.item[0]));
2461 return obj->value.enumerated.item[idx];
2465 * \brief Get value for an entry of a #SND_CTL_ELEM_TYPE_BYTES CTL element id/value
2466 * \param obj CTL element id/value
2467 * \param idx Entry index
2468 * \return value for the entry
2470 unsigned char snd_ctl_elem_value_get_byte(const snd_ctl_elem_value_t *obj, unsigned int idx)
2473 assert(idx < sizeof(obj->value.bytes.data));
2474 return obj->value.bytes.data[idx];
2478 * \brief Set value for an entry of a #SND_CTL_ELEM_TYPE_BOOLEAN CTL element id/value
2479 * \param obj CTL element id/value
2480 * \param idx Entry index
2481 * \param val value for the entry
2483 void snd_ctl_elem_value_set_boolean(snd_ctl_elem_value_t *obj, unsigned int idx, long val)
2486 obj->value.integer.value[idx] = val;
2490 * \brief Set value for an entry of a #SND_CTL_ELEM_TYPE_INTEGER CTL element id/value
2491 * \param obj CTL element id/value
2492 * \param idx Entry index
2493 * \param val value for the entry
2495 void snd_ctl_elem_value_set_integer(snd_ctl_elem_value_t *obj, unsigned int idx, long val)
2498 obj->value.integer.value[idx] = val;
2502 * \brief Set value for an entry of a #SND_CTL_ELEM_TYPE_INTEGER64 CTL element id/value
2503 * \param obj CTL element id/value
2504 * \param idx Entry index
2505 * \param val value for the entry
2507 void snd_ctl_elem_value_set_integer64(snd_ctl_elem_value_t *obj, unsigned int idx, long long val)
2510 obj->value.integer64.value[idx] = val;
2514 * \brief Set value for an entry of a #SND_CTL_ELEM_TYPE_ENUMERATED CTL element id/value
2515 * \param obj CTL element id/value
2516 * \param idx Entry index
2517 * \param val value for the entry
2519 void snd_ctl_elem_value_set_enumerated(snd_ctl_elem_value_t *obj, unsigned int idx, unsigned int val)
2522 obj->value.enumerated.item[idx] = val;
2526 * \brief Set value for an entry of a #SND_CTL_ELEM_TYPE_BYTES CTL element id/value
2527 * \param obj CTL element id/value
2528 * \param idx Entry index
2529 * \param val value for the entry
2531 void snd_ctl_elem_value_set_byte(snd_ctl_elem_value_t *obj, unsigned int idx, unsigned char val)
2534 obj->value.bytes.data[idx] = val;
2538 * \brief Set CTL element #SND_CTL_ELEM_TYPE_BYTES value
2539 * \param obj CTL handle
2540 * \param data Bytes value
2541 * \param size Size in bytes
2543 void snd_ctl_elem_set_bytes(snd_ctl_elem_value_t *obj, void *data, size_t size)
2546 if (size >= sizeof(obj->value.bytes.data)) {
2550 memcpy(obj->value.bytes.data, data, size);
2554 * \brief Get value for a #SND_CTL_ELEM_TYPE_BYTES CTL element id/value
2555 * \param obj CTL element id/value
2556 * \return Pointer to CTL element value
2558 const void * snd_ctl_elem_value_get_bytes(const snd_ctl_elem_value_t *obj)
2561 return obj->value.bytes.data;
2565 * \brief Get value for a #SND_CTL_ELEM_TYPE_IEC958 CTL element id/value
2566 * \param obj CTL element id/value
2567 * \param ptr Pointer to returned CTL element value
2569 void snd_ctl_elem_value_get_iec958(const snd_ctl_elem_value_t *obj, snd_aes_iec958_t *ptr)
2572 memcpy(ptr, &obj->value.iec958, sizeof(*ptr));
2576 * \brief Set value for a #SND_CTL_ELEM_TYPE_IEC958 CTL element id/value
2577 * \param obj CTL element id/value
2578 * \param ptr Pointer to CTL element value
2580 void snd_ctl_elem_value_set_iec958(snd_ctl_elem_value_t *obj, const snd_aes_iec958_t *ptr)
2583 memcpy(&obj->value.iec958, ptr, sizeof(obj->value.iec958));