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
52 #include "control_local.h"
55 * \brief get identifier of CTL handle
56 * \param ctl CTL handle
57 * \return ascii identifier of CTL handle
59 * Returns the ASCII identifier of given CTL handle. It's the same
60 * identifier specified in snd_ctl_open().
62 const char *snd_ctl_name(snd_ctl_t *ctl)
69 * \brief get type of CTL handle
70 * \param ctl CTL handle
71 * \return type of CTL handle
73 * Returns the type #snd_ctl_type_t of given CTL handle.
75 snd_ctl_type_t snd_ctl_type(snd_ctl_t *ctl)
82 * \brief close CTL handle
83 * \param ctl CTL handle
84 * \return 0 on success otherwise a negative error code
86 * Closes the specified CTL handle and frees all associated
89 int snd_ctl_close(snd_ctl_t *ctl)
92 while (!list_empty(&ctl->async_handlers)) {
93 snd_async_handler_t *h = list_entry(&ctl->async_handlers.next, snd_async_handler_t, hlist);
94 snd_async_del_handler(h);
96 err = ctl->ops->close(ctl);
98 snd_dlobj_cache_put(ctl->open_func);
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 a user-defined control element of type enumerated.
364 * \param[in] ctl Control device handle.
365 * \param[in] id ID of the new control element.
366 * \param[in] count Number of element values.
367 * \param[in] items Range of possible values (0 ... \a items - 1).
368 * \param[in] names An array containing \a items strings.
369 * \return Zero on success, otherwise a negative error code.
371 * This function creates a user element, i.e., a control element that is not
372 * controlled by the control device's driver but that is just stored together
373 * with the other elements of \a ctl.
375 * The fields of \a id, except numid, must be set to unique values that
376 * identify the new element.
378 * The new element is locked; its value is initialized as zero.
382 * <dt>-EBUSY<dd>A control element with ID \a id already exists.
383 * <dt>-EINVAL<dd>\a count is not at least one or greater than 128, or \a items
384 * is not at least one, or a string in \a names is empty or longer than 63
385 * bytes, or the strings in \a names require more than 64 KB storage.
386 * <dt>-ENOMEM<dd>Out of memory, or there are too many user control elements.
387 * <dt>-ENXIO<dd>This driver does not support (enumerated) user controls.
388 * <dt>-ENODEV<dd>Device unplugged.
391 * \par Compatibility:
392 * snd_ctl_elem_add_enumerated() was introduced in ALSA 1.0.25.
394 int snd_ctl_elem_add_enumerated(snd_ctl_t *ctl, const snd_ctl_elem_id_t *id,
395 unsigned int count, unsigned int items,
396 const char *const names[])
398 snd_ctl_elem_info_t *info;
399 unsigned int i, bytes;
403 assert(ctl && id && id->name[0] && names);
405 snd_ctl_elem_info_alloca(&info);
407 info->type = SND_CTL_ELEM_TYPE_ENUMERATED;
409 info->value.enumerated.items = items;
412 for (i = 0; i < items; ++i)
413 bytes += strlen(names[i]) + 1;
417 info->value.enumerated.names_ptr = (uintptr_t)buf;
418 info->value.enumerated.names_length = bytes;
420 for (i = 0; i < items; ++i)
421 p = stpcpy(p, names[i]) + 1;
423 err = ctl->ops->element_add(ctl, info);
431 * \brief Create and add an user IEC958 CTL element
432 * \param ctl CTL handle
433 * \param id CTL element info to add
434 * \return 0 on success otherwise a negative error code
436 int snd_ctl_elem_add_iec958(snd_ctl_t *ctl, const snd_ctl_elem_id_t *id)
438 snd_ctl_elem_info_t *info;
440 assert(ctl && id && id->name[0]);
441 snd_ctl_elem_info_alloca(&info);
443 info->type = SND_CTL_ELEM_TYPE_IEC958;
445 return ctl->ops->element_add(ctl, info);
449 * \brief Remove an user CTL element
450 * \param ctl CTL handle
451 * \param id CTL element identification
452 * \return 0 on success otherwise a negative error code
454 int snd_ctl_elem_remove(snd_ctl_t *ctl, snd_ctl_elem_id_t *id)
456 assert(ctl && id && (id->name[0] || id->numid));
457 return ctl->ops->element_remove(ctl, id);
461 * \brief Get CTL element value
462 * \param ctl CTL handle
463 * \param control CTL element id/value pointer
464 * \return 0 on success otherwise a negative error code
466 int snd_ctl_elem_read(snd_ctl_t *ctl, snd_ctl_elem_value_t *control)
468 assert(ctl && control && (control->id.name[0] || control->id.numid));
469 return ctl->ops->element_read(ctl, control);
473 * \brief Set CTL element value
474 * \param ctl CTL handle
475 * \param control CTL element id/value pointer
476 * \retval 0 on success
477 * \retval >0 on success when value was changed
478 * \retval <0 a negative error code
480 int snd_ctl_elem_write(snd_ctl_t *ctl, snd_ctl_elem_value_t *control)
482 assert(ctl && control && (control->id.name[0] || control->id.numid));
483 return ctl->ops->element_write(ctl, control);
486 static int snd_ctl_tlv_do(snd_ctl_t *ctl, int op_flag,
487 const snd_ctl_elem_id_t *id,
488 unsigned int *tlv, unsigned int tlv_size)
490 snd_ctl_elem_info_t *info = NULL;
493 if (id->numid == 0) {
494 info = calloc(1, sizeof(*info));
499 err = snd_ctl_elem_info(ctl, info);
502 if (id->numid == 0) {
507 err = ctl->ops->element_tlv(ctl, op_flag, id->numid, tlv, tlv_size);
517 * \brief Get CTL element TLV value
518 * \param ctl CTL handle
519 * \param id CTL element id pointer
520 * \param tlv TLV array pointer to store
521 * \param tlv_size TLV array size in bytes
522 * \return 0 on success otherwise a negative error code
524 int snd_ctl_elem_tlv_read(snd_ctl_t *ctl, const snd_ctl_elem_id_t *id,
525 unsigned int *tlv, unsigned int tlv_size)
528 assert(ctl && id && (id->name[0] || id->numid) && tlv);
529 if (tlv_size < 2 * sizeof(int))
531 /* 1.0.12 driver doesn't return the error even if the user TLV
532 * is empty. So, initialize TLV here with an invalid type
533 * and compare the returned value after ioctl for checking
534 * the validity of TLV.
538 err = snd_ctl_tlv_do(ctl, 0, id, tlv, tlv_size);
539 if (err >= 0 && tlv[0] == (unsigned int)-1)
545 * \brief Set CTL element TLV value
546 * \param ctl CTL handle
547 * \param id CTL element id pointer
548 * \param tlv TLV array pointer to store
549 * \retval 0 on success
550 * \retval >0 on success when value was changed
551 * \retval <0 a negative error code
553 int snd_ctl_elem_tlv_write(snd_ctl_t *ctl, const snd_ctl_elem_id_t *id,
554 const unsigned int *tlv)
556 assert(ctl && id && (id->name[0] || id->numid) && tlv);
557 return snd_ctl_tlv_do(ctl, 1, id, (unsigned int *)tlv, tlv[1] + 2 * sizeof(unsigned int));
561 * \brief Process CTL element TLV command
562 * \param ctl CTL handle
563 * \param id CTL element id pointer
564 * \param tlv TLV array pointer to process
565 * \retval 0 on success
566 * \retval >0 on success when value was changed
567 * \retval <0 a negative error code
569 int snd_ctl_elem_tlv_command(snd_ctl_t *ctl, const snd_ctl_elem_id_t *id,
570 const unsigned int *tlv)
572 assert(ctl && id && (id->name[0] || id->numid) && tlv);
573 return snd_ctl_tlv_do(ctl, -1, id, (unsigned int *)tlv, tlv[1] + 2 * sizeof(unsigned int));
577 * \brief Lock CTL element
578 * \param ctl CTL handle
579 * \param id CTL element id pointer
580 * \return 0 on success otherwise a negative error code
582 int snd_ctl_elem_lock(snd_ctl_t *ctl, snd_ctl_elem_id_t *id)
585 return ctl->ops->element_lock(ctl, id);
589 * \brief Unlock CTL element
590 * \param ctl CTL handle
591 * \param id CTL element id pointer
592 * \return 0 on success otherwise a negative error code
594 int snd_ctl_elem_unlock(snd_ctl_t *ctl, snd_ctl_elem_id_t *id)
597 return ctl->ops->element_unlock(ctl, id);
601 * \brief Get next hardware dependent device number
602 * \param ctl CTL handle
603 * \param device current device on entry and next device on return
604 * \return 0 on success otherwise a negative error code
606 int snd_ctl_hwdep_next_device(snd_ctl_t *ctl, int *device)
608 assert(ctl && device);
609 return ctl->ops->hwdep_next_device(ctl, device);
613 * \brief Get info about a hardware dependent device
614 * \param ctl CTL handle
615 * \param info Hardware dependent device id/info pointer
616 * \return 0 on success otherwise a negative error code
618 int snd_ctl_hwdep_info(snd_ctl_t *ctl, snd_hwdep_info_t * info)
621 return ctl->ops->hwdep_info(ctl, info);
625 * \brief Get next PCM device number
626 * \param ctl CTL handle
627 * \param device current device on entry and next device on return
628 * \return 0 on success otherwise a negative error code
630 int snd_ctl_pcm_next_device(snd_ctl_t *ctl, int * device)
632 assert(ctl && device);
633 return ctl->ops->pcm_next_device(ctl, device);
637 * \brief Get info about a PCM device
638 * \param ctl CTL handle
639 * \param info PCM device id/info pointer
640 * \return 0 on success otherwise a negative error code
642 int snd_ctl_pcm_info(snd_ctl_t *ctl, snd_pcm_info_t * info)
645 return ctl->ops->pcm_info(ctl, info);
649 * \brief Set preferred PCM subdevice number of successive PCM open
650 * \param ctl CTL handle
651 * \param subdev Preferred PCM subdevice number
652 * \return 0 on success otherwise a negative error code
654 int snd_ctl_pcm_prefer_subdevice(snd_ctl_t *ctl, int subdev)
657 return ctl->ops->pcm_prefer_subdevice(ctl, subdev);
661 * \brief Get next RawMidi device number
662 * \param ctl CTL handle
663 * \param device current device on entry and next device on return
664 * \return 0 on success otherwise a negative error code
666 int snd_ctl_rawmidi_next_device(snd_ctl_t *ctl, int * device)
668 assert(ctl && device);
669 return ctl->ops->rawmidi_next_device(ctl, device);
673 * \brief Get info about a RawMidi device
674 * \param ctl CTL handle
675 * \param info RawMidi device id/info pointer
676 * \return 0 on success otherwise a negative error code
678 int snd_ctl_rawmidi_info(snd_ctl_t *ctl, snd_rawmidi_info_t * info)
681 return ctl->ops->rawmidi_info(ctl, info);
685 * \brief Set preferred RawMidi subdevice number of successive RawMidi open
686 * \param ctl CTL handle
687 * \param subdev Preferred RawMidi subdevice number
688 * \return 0 on success otherwise a negative error code
690 int snd_ctl_rawmidi_prefer_subdevice(snd_ctl_t *ctl, int subdev)
693 return ctl->ops->rawmidi_prefer_subdevice(ctl, subdev);
697 * \brief Set Power State to given SND_CTL_POWER_* value and do the power management
698 * \param ctl CTL handle
699 * \param state Desired Power State
700 * \return 0 on success otherwise a negative error code
702 int snd_ctl_set_power_state(snd_ctl_t *ctl, unsigned int state)
705 if (ctl->ops->set_power_state)
706 return ctl->ops->set_power_state(ctl, state);
711 * \brief Get actual Power State
712 * \param ctl CTL handle
713 * \param state Destination value
714 * \return 0 on success otherwise a negative error code
716 int snd_ctl_get_power_state(snd_ctl_t *ctl, unsigned int *state)
719 if (ctl->ops->get_power_state)
720 return ctl->ops->get_power_state(ctl, state);
725 * \brief Read an event
726 * \param ctl CTL handle
727 * \param event Event pointer
728 * \return number of events read otherwise a negative error code on failure
730 int snd_ctl_read(snd_ctl_t *ctl, snd_ctl_event_t *event)
732 assert(ctl && event);
733 return (ctl->ops->read)(ctl, event);
737 * \brief Wait for a CTL to become ready (i.e. at least one event pending)
738 * \param ctl CTL handle
739 * \param timeout maximum time in milliseconds to wait
740 * \return 0 otherwise a negative error code on failure
742 int snd_ctl_wait(snd_ctl_t *ctl, int timeout)
745 unsigned short revents;
746 int npfds, err, err_poll;
748 npfds = snd_ctl_poll_descriptors_count(ctl);
749 if (npfds <= 0 || npfds >= 16) {
750 SNDERR("Invalid poll_fds %d\n", npfds);
753 pfd = alloca(sizeof(*pfd) * npfds);
754 err = snd_ctl_poll_descriptors(ctl, pfd, npfds);
758 SNDMSG("invalid poll descriptors %d\n", err);
762 err_poll = poll(pfd, npfds, timeout);
767 err = snd_ctl_poll_descriptors_revents(ctl, pfd, npfds, &revents);
770 if (revents & (POLLERR | POLLNVAL))
772 if (revents & (POLLIN | POLLOUT))
778 * \brief Add an async handler for a CTL
779 * \param handler Returned handler handle
780 * \param ctl CTL handle
781 * \param callback Callback function
782 * \param private_data Callback private data
783 * \return 0 otherwise a negative error code on failure
785 int snd_async_add_ctl_handler(snd_async_handler_t **handler, snd_ctl_t *ctl,
786 snd_async_callback_t callback, void *private_data)
790 snd_async_handler_t *h;
791 err = snd_async_add_handler(&h, _snd_ctl_async_descriptor(ctl),
792 callback, private_data);
795 h->type = SND_ASYNC_HANDLER_CTL;
797 was_empty = list_empty(&ctl->async_handlers);
798 list_add_tail(&h->hlist, &ctl->async_handlers);
800 err = snd_ctl_async(ctl, snd_async_handler_get_signo(h), getpid());
802 snd_async_del_handler(h);
811 * \brief Return CTL handle related to an async handler
812 * \param handler Async handler handle
815 snd_ctl_t *snd_async_handler_get_ctl(snd_async_handler_t *handler)
817 assert(handler->type == SND_ASYNC_HANDLER_CTL);
818 return handler->u.ctl;
821 static const char *const build_in_ctls[] = {
825 static int snd_ctl_open_conf(snd_ctl_t **ctlp, const char *name,
826 snd_config_t *ctl_root, snd_config_t *ctl_conf, int mode)
829 char *buf = NULL, *buf1 = NULL;
831 snd_config_t *conf, *type_conf = NULL;
832 snd_config_iterator_t i, next;
833 const char *lib = NULL, *open_name = NULL;
835 int (*open_func)(snd_ctl_t **, const char *, snd_config_t *, snd_config_t *, int) = NULL;
837 extern void *snd_control_open_symbols(void);
839 if (snd_config_get_type(ctl_conf) != SND_CONFIG_TYPE_COMPOUND) {
841 SNDERR("Invalid type for CTL %s definition", name);
843 SNDERR("Invalid type for CTL definition");
846 err = snd_config_search(ctl_conf, "type", &conf);
848 SNDERR("type is not defined");
851 err = snd_config_get_id(conf, &id);
853 SNDERR("unable to get id");
856 err = snd_config_get_string(conf, &str);
858 SNDERR("Invalid type for %s", id);
861 err = snd_config_search_definition(ctl_root, "ctl_type", str, &type_conf);
863 if (snd_config_get_type(type_conf) != SND_CONFIG_TYPE_COMPOUND) {
864 SNDERR("Invalid type for CTL type %s definition", str);
867 snd_config_for_each(i, next, type_conf) {
868 snd_config_t *n = snd_config_iterator_entry(i);
870 if (snd_config_get_id(n, &id) < 0)
872 if (strcmp(id, "comment") == 0)
874 if (strcmp(id, "lib") == 0) {
875 err = snd_config_get_string(n, &lib);
877 SNDERR("Invalid type for %s", id);
882 if (strcmp(id, "open") == 0) {
883 err = snd_config_get_string(n, &open_name);
885 SNDERR("Invalid type for %s", id);
890 SNDERR("Unknown field %s", id);
896 buf = malloc(strlen(str) + 32);
902 sprintf(buf, "_snd_ctl_%s_open", str);
905 const char *const *build_in = build_in_ctls;
907 if (!strcmp(*build_in, str))
911 if (*build_in == NULL) {
912 buf1 = malloc(strlen(str) + sizeof(ALSA_PLUGIN_DIR) + 32);
918 sprintf(buf1, "%s/libasound_module_ctl_%s.so", ALSA_PLUGIN_DIR, str);
922 snd_control_open_symbols();
924 open_func = snd_dlobj_cache_get(lib, open_name,
925 SND_DLSYM_VERSION(SND_CONTROL_DLSYM_VERSION), 1);
927 err = open_func(ctlp, name, ctl_root, ctl_conf, mode);
929 (*ctlp)->open_func = open_func;
932 snd_dlobj_cache_put(open_func);
939 snd_config_delete(type_conf);
945 static int snd_ctl_open_noupdate(snd_ctl_t **ctlp, snd_config_t *root, const char *name, int mode)
948 snd_config_t *ctl_conf;
949 err = snd_config_search_definition(root, "ctl", name, &ctl_conf);
951 SNDERR("Invalid CTL %s", name);
954 err = snd_ctl_open_conf(ctlp, name, root, ctl_conf, mode);
955 snd_config_delete(ctl_conf);
961 * \param ctlp Returned CTL handle
962 * \param name ASCII identifier of the CTL handle
963 * \param mode Open mode (see #SND_CTL_NONBLOCK, #SND_CTL_ASYNC)
964 * \return 0 on success otherwise a negative error code
966 int snd_ctl_open(snd_ctl_t **ctlp, const char *name, int mode)
969 assert(ctlp && name);
970 err = snd_config_update();
973 return snd_ctl_open_noupdate(ctlp, snd_config, name, mode);
977 * \brief Opens a CTL using local configuration
978 * \param ctlp Returned CTL handle
979 * \param name ASCII identifier of the CTL handle
980 * \param mode Open mode (see #SND_CTL_NONBLOCK, #SND_CTL_ASYNC)
981 * \param lconf Local configuration
982 * \return 0 on success otherwise a negative error code
984 int snd_ctl_open_lconf(snd_ctl_t **ctlp, const char *name,
985 int mode, snd_config_t *lconf)
987 assert(ctlp && name && lconf);
988 return snd_ctl_open_noupdate(ctlp, lconf, name, mode);
992 * \brief Opens a fallback CTL
993 * \param ctlp Returned CTL handle
994 * \param root Configuration root
995 * \param name ASCII identifier of the CTL handle used as fallback
996 * \param orig_name The original ASCII name
997 * \param mode Open mode (see #SND_CTL_NONBLOCK, #SND_CTL_ASYNC)
998 * \return 0 on success otherwise a negative error code
1000 int snd_ctl_open_fallback(snd_ctl_t **ctlp, snd_config_t *root,
1001 const char *name, const char *orig_name, int mode)
1004 assert(ctlp && name && root);
1005 err = snd_ctl_open_noupdate(ctlp, root, name, mode);
1007 free((*ctlp)->name);
1008 (*ctlp)->name = orig_name ? strdup(orig_name) : NULL;
1014 #define TYPE(v) [SND_CTL_ELEM_TYPE_##v] = #v
1015 #define IFACE(v) [SND_CTL_ELEM_IFACE_##v] = #v
1016 #define IFACE1(v, n) [SND_CTL_ELEM_IFACE_##v] = #n
1017 #define EVENT(v) [SND_CTL_EVENT_##v] = #v
1019 static const char *const snd_ctl_elem_type_names[] = {
1029 static const char *const snd_ctl_elem_iface_names[] = {
1039 static const char *const snd_ctl_event_type_names[] = {
1045 * \brief get name of a CTL element type
1046 * \param type CTL element type
1047 * \return ascii name of CTL element type
1049 const char *snd_ctl_elem_type_name(snd_ctl_elem_type_t type)
1051 assert(type <= SND_CTL_ELEM_TYPE_LAST);
1052 return snd_ctl_elem_type_names[type];
1056 * \brief get name of a CTL element related interface
1057 * \param iface CTL element related interface
1058 * \return ascii name of CTL element related interface
1060 const char *snd_ctl_elem_iface_name(snd_ctl_elem_iface_t iface)
1062 assert(iface <= SND_CTL_ELEM_IFACE_LAST);
1063 return snd_ctl_elem_iface_names[iface];
1067 * \brief get name of a CTL event type
1068 * \param type CTL event type
1069 * \return ascii name of CTL event type
1071 const char *snd_ctl_event_type_name(snd_ctl_event_type_t type)
1073 assert(type <= SND_CTL_EVENT_LAST);
1074 return snd_ctl_event_type_names[type];
1078 * \brief allocate space for CTL element identifiers list
1079 * \param obj CTL element identifiers list
1080 * \param entries Entries to allocate
1081 * \return 0 on success otherwise a negative error code
1083 int snd_ctl_elem_list_alloc_space(snd_ctl_elem_list_t *obj, unsigned int entries)
1086 obj->pids = calloc(entries, sizeof(*obj->pids));
1091 obj->space = entries;
1096 * \brief free previously allocated space for CTL element identifiers list
1097 * \param obj CTL element identifiers list
1099 void snd_ctl_elem_list_free_space(snd_ctl_elem_list_t *obj)
1107 * \brief Get event mask for an element related event
1108 * \param obj CTL event
1109 * \return event mask for element related event
1111 unsigned int snd_ctl_event_elem_get_mask(const snd_ctl_event_t *obj)
1114 assert(obj->type == SND_CTL_EVENT_ELEM);
1115 return obj->data.elem.mask;
1119 * \brief Get CTL element identifier for an element related event
1120 * \param obj CTL event
1121 * \param ptr Pointer to returned CTL element identifier
1123 void snd_ctl_event_elem_get_id(const snd_ctl_event_t *obj, snd_ctl_elem_id_t *ptr)
1126 assert(obj->type == SND_CTL_EVENT_ELEM);
1127 *ptr = obj->data.elem.id;
1131 * \brief Get element numeric identifier for an element related event
1132 * \param obj CTL event
1133 * \return element numeric identifier
1135 unsigned int snd_ctl_event_elem_get_numid(const snd_ctl_event_t *obj)
1138 assert(obj->type == SND_CTL_EVENT_ELEM);
1139 return obj->data.elem.id.numid;
1143 * \brief Get interface part of CTL element identifier for an element related event
1144 * \param obj CTL event
1145 * \return interface part of element identifier
1147 snd_ctl_elem_iface_t snd_ctl_event_elem_get_interface(const snd_ctl_event_t *obj)
1150 assert(obj->type == SND_CTL_EVENT_ELEM);
1151 return obj->data.elem.id.iface;
1155 * \brief Get device part of CTL element identifier for an element related event
1156 * \param obj CTL event
1157 * \return device part of element identifier
1159 unsigned int snd_ctl_event_elem_get_device(const snd_ctl_event_t *obj)
1162 assert(obj->type == SND_CTL_EVENT_ELEM);
1163 return obj->data.elem.id.device;
1167 * \brief Get subdevice part of CTL element identifier for an element related event
1168 * \param obj CTL event
1169 * \return subdevice part of element identifier
1171 unsigned int snd_ctl_event_elem_get_subdevice(const snd_ctl_event_t *obj)
1174 assert(obj->type == SND_CTL_EVENT_ELEM);
1175 return obj->data.elem.id.subdevice;
1179 * \brief Get name part of CTL element identifier for an element related event
1180 * \param obj CTL event
1181 * \return name part of element identifier
1183 const char *snd_ctl_event_elem_get_name(const snd_ctl_event_t *obj)
1186 assert(obj->type == SND_CTL_EVENT_ELEM);
1187 return (const char *)obj->data.elem.id.name;
1191 * \brief Get index part of CTL element identifier for an element related event
1192 * \param obj CTL event
1193 * \return index part of element identifier
1195 unsigned int snd_ctl_event_elem_get_index(const snd_ctl_event_t *obj)
1198 assert(obj->type == SND_CTL_EVENT_ELEM);
1199 return obj->data.elem.id.index;
1203 int _snd_ctl_poll_descriptor(snd_ctl_t *ctl)
1206 return ctl->poll_fd;
1211 * \brief get size of #snd_ctl_elem_id_t
1212 * \return size in bytes
1214 size_t snd_ctl_elem_id_sizeof()
1216 return sizeof(snd_ctl_elem_id_t);
1220 * \brief allocate an invalid #snd_ctl_elem_id_t using standard malloc
1221 * \param ptr returned pointer
1222 * \return 0 on success otherwise negative error code
1224 int snd_ctl_elem_id_malloc(snd_ctl_elem_id_t **ptr)
1227 *ptr = calloc(1, sizeof(snd_ctl_elem_id_t));
1234 * \brief frees a previously allocated #snd_ctl_elem_id_t
1235 * \param obj pointer to object to free
1237 void snd_ctl_elem_id_free(snd_ctl_elem_id_t *obj)
1243 * \brief clear given #snd_ctl_elem_id_t object
1244 * \param obj pointer to object to clear
1246 void snd_ctl_elem_id_clear(snd_ctl_elem_id_t *obj)
1248 memset(obj, 0, sizeof(snd_ctl_elem_id_t));
1252 * \brief copy one #snd_ctl_elem_id_t to another
1253 * \param dst pointer to destination
1254 * \param src pointer to source
1256 void snd_ctl_elem_id_copy(snd_ctl_elem_id_t *dst, const snd_ctl_elem_id_t *src)
1263 * \brief Get numeric identifier from a CTL element identifier
1264 * \param obj CTL element identifier
1265 * \return CTL element numeric identifier
1267 unsigned int snd_ctl_elem_id_get_numid(const snd_ctl_elem_id_t *obj)
1274 * \brief Get interface part of a CTL element identifier
1275 * \param obj CTL element identifier
1276 * \return CTL element related interface
1278 snd_ctl_elem_iface_t snd_ctl_elem_id_get_interface(const snd_ctl_elem_id_t *obj)
1285 * \brief Get device part of a CTL element identifier
1286 * \param obj CTL element identifier
1287 * \return CTL element related device
1289 unsigned int snd_ctl_elem_id_get_device(const snd_ctl_elem_id_t *obj)
1296 * \brief Get subdevice part of a CTL element identifier
1297 * \param obj CTL element identifier
1298 * \return CTL element related subdevice
1300 unsigned int snd_ctl_elem_id_get_subdevice(const snd_ctl_elem_id_t *obj)
1303 return obj->subdevice;
1307 * \brief Get name part of a CTL element identifier
1308 * \param obj CTL element identifier
1309 * \return CTL element name
1311 const char *snd_ctl_elem_id_get_name(const snd_ctl_elem_id_t *obj)
1314 return (const char *)obj->name;
1318 * \brief Get index part of a CTL element identifier
1319 * \param obj CTL element identifier
1320 * \return CTL element index
1322 unsigned int snd_ctl_elem_id_get_index(const snd_ctl_elem_id_t *obj)
1329 * \brief Set numeric identifier for a CTL element identifier
1330 * \param obj CTL element identifier
1331 * \param val CTL element numeric identifier
1333 void snd_ctl_elem_id_set_numid(snd_ctl_elem_id_t *obj, unsigned int val)
1340 * \brief Set interface part for a CTL element identifier
1341 * \param obj CTL element identifier
1342 * \param val CTL element related interface
1344 void snd_ctl_elem_id_set_interface(snd_ctl_elem_id_t *obj, snd_ctl_elem_iface_t val)
1351 * \brief Set device part for a CTL element identifier
1352 * \param obj CTL element identifier
1353 * \param val CTL element related device
1355 void snd_ctl_elem_id_set_device(snd_ctl_elem_id_t *obj, unsigned int val)
1362 * \brief Set subdevice part for a CTL element identifier
1363 * \param obj CTL element identifier
1364 * \param val CTL element related subdevice
1366 void snd_ctl_elem_id_set_subdevice(snd_ctl_elem_id_t *obj, unsigned int val)
1369 obj->subdevice = val;
1373 * \brief Set name part for a CTL element identifier
1374 * \param obj CTL element identifier
1375 * \param val CTL element name
1377 void snd_ctl_elem_id_set_name(snd_ctl_elem_id_t *obj, const char *val)
1380 strncpy((char *)obj->name, val, sizeof(obj->name));
1384 * \brief Set index part for a CTL element identifier
1385 * \param obj CTL element identifier
1386 * \param val CTL element index
1388 void snd_ctl_elem_id_set_index(snd_ctl_elem_id_t *obj, unsigned int val)
1395 * \brief get size of #snd_ctl_card_info_t
1396 * \return size in bytes
1398 size_t snd_ctl_card_info_sizeof()
1400 return sizeof(snd_ctl_card_info_t);
1404 * \brief allocate an invalid #snd_ctl_card_info_t using standard malloc
1405 * \param ptr returned pointer
1406 * \return 0 on success otherwise negative error code
1408 int snd_ctl_card_info_malloc(snd_ctl_card_info_t **ptr)
1411 *ptr = calloc(1, sizeof(snd_ctl_card_info_t));
1418 * \brief frees a previously allocated #snd_ctl_card_info_t
1419 * \param obj pointer to object to free
1421 void snd_ctl_card_info_free(snd_ctl_card_info_t *obj)
1427 * \brief clear given #snd_ctl_card_info_t object
1428 * \param obj pointer to object to clear
1430 void snd_ctl_card_info_clear(snd_ctl_card_info_t *obj)
1432 memset(obj, 0, sizeof(snd_ctl_card_info_t));
1436 * \brief copy one #snd_ctl_card_info_t to another
1437 * \param dst pointer to destination
1438 * \param src pointer to source
1440 void snd_ctl_card_info_copy(snd_ctl_card_info_t *dst, const snd_ctl_card_info_t *src)
1447 * \brief Get card number from a CTL card info
1448 * \param obj CTL card info
1449 * \return card number
1451 int snd_ctl_card_info_get_card(const snd_ctl_card_info_t *obj)
1458 * \brief Get card identifier from a CTL card info
1459 * \param obj CTL card info
1460 * \return card identifier
1462 const char *snd_ctl_card_info_get_id(const snd_ctl_card_info_t *obj)
1465 return (const char *)obj->id;
1469 * \brief Get card driver name from a CTL card info
1470 * \param obj CTL card info
1471 * \return card driver name
1473 const char *snd_ctl_card_info_get_driver(const snd_ctl_card_info_t *obj)
1476 return (const char *)obj->driver;
1480 * \brief Get card name from a CTL card info
1481 * \param obj CTL card info
1484 const char *snd_ctl_card_info_get_name(const snd_ctl_card_info_t *obj)
1487 return (const char *)obj->name;
1491 * \brief Get card long name from a CTL card info
1492 * \param obj CTL card info
1493 * \return card long name
1495 const char *snd_ctl_card_info_get_longname(const snd_ctl_card_info_t *obj)
1498 return (const char *)obj->longname;
1502 * \brief Get card mixer name from a CTL card info
1503 * \param obj CTL card info
1504 * \return card mixer name
1506 const char *snd_ctl_card_info_get_mixername(const snd_ctl_card_info_t *obj)
1509 return (const char *)obj->mixername;
1513 * \brief Get card component list from a CTL card info
1514 * \param obj CTL card info
1515 * \return card mixer identifier
1517 const char *snd_ctl_card_info_get_components(const snd_ctl_card_info_t *obj)
1520 return (const char *)obj->components;
1524 * \brief get size of #snd_ctl_event_t
1525 * \return size in bytes
1527 size_t snd_ctl_event_sizeof()
1529 return sizeof(snd_ctl_event_t);
1533 * \brief allocate an invalid #snd_ctl_event_t using standard malloc
1534 * \param ptr returned pointer
1535 * \return 0 on success otherwise negative error code
1537 int snd_ctl_event_malloc(snd_ctl_event_t **ptr)
1540 *ptr = calloc(1, sizeof(snd_ctl_event_t));
1547 * \brief frees a previously allocated #snd_ctl_event_t
1548 * \param obj pointer to object to free
1550 void snd_ctl_event_free(snd_ctl_event_t *obj)
1556 * \brief clear given #snd_ctl_event_t object
1557 * \param obj pointer to object to clear
1559 void snd_ctl_event_clear(snd_ctl_event_t *obj)
1561 memset(obj, 0, sizeof(snd_ctl_event_t));
1565 * \brief copy one #snd_ctl_event_t to another
1566 * \param dst pointer to destination
1567 * \param src pointer to source
1569 void snd_ctl_event_copy(snd_ctl_event_t *dst, const snd_ctl_event_t *src)
1576 * \brief Get type of a CTL event
1577 * \param obj CTL event
1578 * \return CTL event type
1580 snd_ctl_event_type_t snd_ctl_event_get_type(const snd_ctl_event_t *obj)
1587 * \brief get size of #snd_ctl_elem_list_t
1588 * \return size in bytes
1590 size_t snd_ctl_elem_list_sizeof()
1592 return sizeof(snd_ctl_elem_list_t);
1596 * \brief allocate an invalid #snd_ctl_elem_list_t using standard malloc
1597 * \param ptr returned pointer
1598 * \return 0 on success otherwise negative error code
1600 int snd_ctl_elem_list_malloc(snd_ctl_elem_list_t **ptr)
1603 *ptr = calloc(1, sizeof(snd_ctl_elem_list_t));
1610 * \brief frees a previously allocated #snd_ctl_elem_list_t
1611 * \param obj pointer to object to free
1613 void snd_ctl_elem_list_free(snd_ctl_elem_list_t *obj)
1619 * \brief clear given #snd_ctl_elem_list_t object
1620 * \param obj pointer to object to clear
1622 void snd_ctl_elem_list_clear(snd_ctl_elem_list_t *obj)
1624 memset(obj, 0, sizeof(snd_ctl_elem_list_t));
1628 * \brief copy one #snd_ctl_elem_list_t to another
1629 * \param dst pointer to destination
1630 * \param src pointer to source
1632 void snd_ctl_elem_list_copy(snd_ctl_elem_list_t *dst, const snd_ctl_elem_list_t *src)
1639 * \brief Set index of first wanted CTL element identifier in a CTL element identifiers list
1640 * \param obj CTL element identifiers list
1641 * \param val index of CTL element to put at position 0 of list
1643 void snd_ctl_elem_list_set_offset(snd_ctl_elem_list_t *obj, unsigned int val)
1650 * \brief Get number of used entries in CTL element identifiers list
1651 * \param obj CTL element identifier list
1652 * \return number of used entries
1654 unsigned int snd_ctl_elem_list_get_used(const snd_ctl_elem_list_t *obj)
1661 * \brief Get total count of elements present in CTL device (information present in every filled CTL element identifiers list)
1662 * \param obj CTL element identifier list
1663 * \return total number of elements
1665 unsigned int snd_ctl_elem_list_get_count(const snd_ctl_elem_list_t *obj)
1672 * \brief Get CTL element identifier for an entry of a CTL element identifiers list
1673 * \param obj CTL element identifier list
1674 * \param idx Index of entry
1675 * \param ptr Pointer to returned CTL element identifier
1677 void snd_ctl_elem_list_get_id(const snd_ctl_elem_list_t *obj, unsigned int idx, snd_ctl_elem_id_t *ptr)
1680 assert(idx < obj->used);
1681 *ptr = obj->pids[idx];
1685 * \brief Get CTL element numeric identifier for an entry of a CTL element identifiers list
1686 * \param obj CTL element identifier list
1687 * \param idx Index of entry
1688 * \return CTL element numeric identifier
1690 unsigned int snd_ctl_elem_list_get_numid(const snd_ctl_elem_list_t *obj, unsigned int idx)
1693 assert(idx < obj->used);
1694 return obj->pids[idx].numid;
1698 * \brief Get interface part of CTL element identifier for an entry of a CTL element identifiers list
1699 * \param obj CTL element identifier list
1700 * \param idx Index of entry
1701 * \return CTL element related interface
1703 snd_ctl_elem_iface_t snd_ctl_elem_list_get_interface(const snd_ctl_elem_list_t *obj, unsigned int idx)
1706 assert(idx < obj->used);
1707 return obj->pids[idx].iface;
1711 * \brief Get device part of CTL element identifier for an entry of a CTL element identifiers list
1712 * \param obj CTL element identifier list
1713 * \param idx Index of entry
1714 * \return CTL element related device
1716 unsigned int snd_ctl_elem_list_get_device(const snd_ctl_elem_list_t *obj, unsigned int idx)
1719 assert(idx < obj->used);
1720 return obj->pids[idx].device;
1724 * \brief Get subdevice part of CTL element identifier for an entry of a CTL element identifiers list
1725 * \param obj CTL element identifier list
1726 * \param idx Index of entry
1727 * \return CTL element related subdevice
1729 unsigned int snd_ctl_elem_list_get_subdevice(const snd_ctl_elem_list_t *obj, unsigned int idx)
1732 assert(idx < obj->used);
1733 return obj->pids[idx].subdevice;
1737 * \brief Get name part of CTL element identifier for an entry of a CTL element identifiers list
1738 * \param obj CTL element identifier list
1739 * \param idx Index of entry
1740 * \return CTL element name
1742 const char *snd_ctl_elem_list_get_name(const snd_ctl_elem_list_t *obj, unsigned int idx)
1745 assert(idx < obj->used);
1746 return (const char *)obj->pids[idx].name;
1750 * \brief Get index part of CTL element identifier for an entry of a CTL element identifiers list
1751 * \param obj CTL element identifier list
1752 * \param idx Index of entry
1753 * \return CTL element index
1755 unsigned int snd_ctl_elem_list_get_index(const snd_ctl_elem_list_t *obj, unsigned int idx)
1758 assert(idx < obj->used);
1759 return obj->pids[idx].index;
1763 * \brief get size of #snd_ctl_elem_info_t
1764 * \return size in bytes
1766 size_t snd_ctl_elem_info_sizeof()
1768 return sizeof(snd_ctl_elem_info_t);
1772 * \brief allocate an invalid #snd_ctl_elem_info_t using standard malloc
1773 * \param ptr returned pointer
1774 * \return 0 on success otherwise negative error code
1776 int snd_ctl_elem_info_malloc(snd_ctl_elem_info_t **ptr)
1779 *ptr = calloc(1, sizeof(snd_ctl_elem_info_t));
1786 * \brief frees a previously allocated #snd_ctl_elem_info_t
1787 * \param obj pointer to object to free
1789 void snd_ctl_elem_info_free(snd_ctl_elem_info_t *obj)
1795 * \brief clear given #snd_ctl_elem_info_t object
1796 * \param obj pointer to object to clear
1798 void snd_ctl_elem_info_clear(snd_ctl_elem_info_t *obj)
1800 memset(obj, 0, sizeof(snd_ctl_elem_info_t));
1804 * \brief copy one #snd_ctl_elem_info_t to another
1805 * \param dst pointer to destination
1806 * \param src pointer to source
1808 void snd_ctl_elem_info_copy(snd_ctl_elem_info_t *dst, const snd_ctl_elem_info_t *src)
1815 * \brief Get type from a CTL element id/info
1816 * \param obj CTL element id/info
1817 * \return CTL element content type
1819 snd_ctl_elem_type_t snd_ctl_elem_info_get_type(const snd_ctl_elem_info_t *obj)
1826 * \brief Get info about readability from a CTL element id/info
1827 * \param obj CTL element id/info
1828 * \return 0 if element is not readable, 1 if element is readable
1830 int snd_ctl_elem_info_is_readable(const snd_ctl_elem_info_t *obj)
1833 return !!(obj->access & SNDRV_CTL_ELEM_ACCESS_READ);
1837 * \brief Get info about writability from a CTL element id/info
1838 * \param obj CTL element id/info
1839 * \return 0 if element is not writable, 1 if element is not writable
1841 int snd_ctl_elem_info_is_writable(const snd_ctl_elem_info_t *obj)
1844 return !!(obj->access & SNDRV_CTL_ELEM_ACCESS_WRITE);
1848 * \brief Get info about notification feasibility from a CTL element id/info
1849 * \param obj CTL element id/info
1850 * \return 0 if all element value changes are notified to subscribed applications, 1 otherwise
1852 int snd_ctl_elem_info_is_volatile(const snd_ctl_elem_info_t *obj)
1855 return !!(obj->access & SNDRV_CTL_ELEM_ACCESS_VOLATILE);
1859 * \brief Get info about status from a CTL element id/info
1860 * \param obj CTL element id/info
1861 * \return 0 if element value is not active, 1 if is active
1863 int snd_ctl_elem_info_is_inactive(const snd_ctl_elem_info_t *obj)
1866 return !!(obj->access & SNDRV_CTL_ELEM_ACCESS_INACTIVE);
1870 * \brief Get info whether an element is locked
1871 * \param obj CTL element id/info
1872 * \return 0 if element value is currently changeable, 1 if it's locked by another application
1874 int snd_ctl_elem_info_is_locked(const snd_ctl_elem_info_t *obj)
1877 return !!(obj->access & SNDRV_CTL_ELEM_ACCESS_LOCK);
1881 * \brief Get info if I own an element
1882 * \param obj CTL element id/info
1883 * \return 0 if element value is currently changeable, 1 if it's locked by another application
1885 int snd_ctl_elem_info_is_owner(const snd_ctl_elem_info_t *obj)
1888 return !!(obj->access & SNDRV_CTL_ELEM_ACCESS_OWNER);
1892 * \brief Get info if it's a user element
1893 * \param obj CTL element id/info
1894 * \return 0 if element value is a system element, 1 if it's a user-created element
1896 int snd_ctl_elem_info_is_user(const snd_ctl_elem_info_t *obj)
1899 return !!(obj->access & SNDRV_CTL_ELEM_ACCESS_USER);
1903 * \brief Get info about TLV readability from a CTL element id/info
1904 * \param obj CTL element id/info
1905 * \return 0 if element's TLV is not readable, 1 if element's TLV is readable
1907 int snd_ctl_elem_info_is_tlv_readable(const snd_ctl_elem_info_t *obj)
1910 return !!(obj->access & SNDRV_CTL_ELEM_ACCESS_TLV_READ);
1914 * \brief Get info about TLV writeability from a CTL element id/info
1915 * \param obj CTL element id/info
1916 * \return 0 if element's TLV is not writable, 1 if element's TLV is writable
1918 int snd_ctl_elem_info_is_tlv_writable(const snd_ctl_elem_info_t *obj)
1921 return !!(obj->access & SNDRV_CTL_ELEM_ACCESS_TLV_WRITE);
1925 * \brief Get info about TLV command possibility from a CTL element id/info
1926 * \param obj CTL element id/info
1927 * \return 0 if element's TLV command is not possible, 1 if element's TLV command is supported
1929 int snd_ctl_elem_info_is_tlv_commandable(const snd_ctl_elem_info_t *obj)
1932 return !!(obj->access & SNDRV_CTL_ELEM_ACCESS_TLV_COMMAND);
1936 * \brief (DEPRECATED) Get info about values passing policy from a CTL element value
1937 * \param obj CTL element id/info
1938 * \return 0 if element value need to be passed by contents, 1 if need to be passed with a pointer
1940 int snd_ctl_elem_info_is_indirect(const snd_ctl_elem_info_t *obj)
1945 link_warning(snd_ctl_elem_info_is_indirect, "Warning: snd_ctl_elem_info_is_indirect is deprecated, do not use it");
1948 * \brief Get owner of a locked element
1949 * \param obj CTL element id/info
1950 * \return value entries count
1952 pid_t snd_ctl_elem_info_get_owner(const snd_ctl_elem_info_t *obj)
1959 * \brief Get number of value entries from a CTL element id/info
1960 * \param obj CTL element id/info
1961 * \return value entries count
1963 unsigned int snd_ctl_elem_info_get_count(const snd_ctl_elem_info_t *obj)
1970 * \brief Get minimum value from a #SND_CTL_ELEM_TYPE_INTEGER CTL element id/info
1971 * \param obj CTL element id/info
1972 * \return Minimum value
1974 long snd_ctl_elem_info_get_min(const snd_ctl_elem_info_t *obj)
1977 assert(obj->type == SND_CTL_ELEM_TYPE_INTEGER);
1978 return obj->value.integer.min;
1982 * \brief Get maximum value from a #SND_CTL_ELEM_TYPE_INTEGER CTL element id/info
1983 * \param obj CTL element id/info
1984 * \return Maximum value
1986 long snd_ctl_elem_info_get_max(const snd_ctl_elem_info_t *obj)
1989 assert(obj->type == SND_CTL_ELEM_TYPE_INTEGER);
1990 return obj->value.integer.max;
1994 * \brief Get value step from a #SND_CTL_ELEM_TYPE_INTEGER CTL element id/info
1995 * \param obj CTL element id/info
1998 long snd_ctl_elem_info_get_step(const snd_ctl_elem_info_t *obj)
2001 assert(obj->type == SND_CTL_ELEM_TYPE_INTEGER);
2002 return obj->value.integer.step;
2006 * \brief Get minimum value from a #SND_CTL_ELEM_TYPE_INTEGER64 CTL element id/info
2007 * \param obj CTL element id/info
2008 * \return Minimum value
2010 long long snd_ctl_elem_info_get_min64(const snd_ctl_elem_info_t *obj)
2013 assert(obj->type == SND_CTL_ELEM_TYPE_INTEGER64);
2014 return obj->value.integer64.min;
2018 * \brief Get maximum value from a #SND_CTL_ELEM_TYPE_INTEGER64 CTL element id/info
2019 * \param obj CTL element id/info
2020 * \return Maximum value
2022 long long snd_ctl_elem_info_get_max64(const snd_ctl_elem_info_t *obj)
2025 assert(obj->type == SND_CTL_ELEM_TYPE_INTEGER64);
2026 return obj->value.integer64.max;
2030 * \brief Get value step from a #SND_CTL_ELEM_TYPE_INTEGER64 CTL element id/info
2031 * \param obj CTL element id/info
2034 long long snd_ctl_elem_info_get_step64(const snd_ctl_elem_info_t *obj)
2037 assert(obj->type == SND_CTL_ELEM_TYPE_INTEGER64);
2038 return obj->value.integer64.step;
2042 * \brief Get number of items available from a #SND_CTL_ELEM_TYPE_ENUMERATED CTL element id/info
2043 * \param obj CTL element id/info
2044 * \return items count
2046 unsigned int snd_ctl_elem_info_get_items(const snd_ctl_elem_info_t *obj)
2049 assert(obj->type == SND_CTL_ELEM_TYPE_ENUMERATED);
2050 return obj->value.enumerated.items;
2054 * \brief Select item in a #SND_CTL_ELEM_TYPE_ENUMERATED CTL element id/info
2055 * \param obj CTL element id/info
2056 * \param val item number
2058 void snd_ctl_elem_info_set_item(snd_ctl_elem_info_t *obj, unsigned int val)
2061 obj->value.enumerated.item = val;
2065 * \brief Get name for selected item in a #SND_CTL_ELEM_TYPE_ENUMERATED CTL element id/info
2066 * \param obj CTL element id/info
2067 * \return name of chosen item
2069 const char *snd_ctl_elem_info_get_item_name(const snd_ctl_elem_info_t *obj)
2072 assert(obj->type == SND_CTL_ELEM_TYPE_ENUMERATED);
2073 return obj->value.enumerated.name;
2077 * \brief Get count of dimensions for given element
2078 * \param obj CTL element id/info
2079 * \return zero value if no dimensions are defined, otherwise positive value with count of dimensions
2082 int INTERNAL(snd_ctl_elem_info_get_dimensions)(const snd_ctl_elem_info_t *obj)
2084 int snd_ctl_elem_info_get_dimensions(const snd_ctl_elem_info_t *obj)
2090 for (i = 3; i >= 0; i--)
2091 if (obj->dimen.d[i])
2095 use_default_symbol_version(__snd_ctl_elem_info_get_dimensions, snd_ctl_elem_info_get_dimensions, ALSA_0.9.3);
2098 * \brief Get specified of dimension width for given element
2099 * \param obj CTL element id/info
2100 * \param idx The dimension index
2101 * \return zero value if no dimension width is defined, otherwise positive value with with of specified dimension
2104 int INTERNAL(snd_ctl_elem_info_get_dimension)(const snd_ctl_elem_info_t *obj, unsigned int idx)
2106 int snd_ctl_elem_info_get_dimension(const snd_ctl_elem_info_t *obj, unsigned int idx)
2112 return obj->dimen.d[idx];
2114 use_default_symbol_version(__snd_ctl_elem_info_get_dimension, snd_ctl_elem_info_get_dimension, ALSA_0.9.3);
2117 * \brief Get CTL element identifier of a CTL element id/info
2118 * \param obj CTL element id/info
2119 * \param ptr Pointer to returned CTL element identifier
2121 void snd_ctl_elem_info_get_id(const snd_ctl_elem_info_t *obj, snd_ctl_elem_id_t *ptr)
2128 * \brief Get element numeric identifier of a CTL element id/info
2129 * \param obj CTL element id/info
2130 * \return element numeric identifier
2132 unsigned int snd_ctl_elem_info_get_numid(const snd_ctl_elem_info_t *obj)
2135 return obj->id.numid;
2139 * \brief Get interface part of CTL element identifier of a CTL element id/info
2140 * \param obj CTL element id/info
2141 * \return interface part of element identifier
2143 snd_ctl_elem_iface_t snd_ctl_elem_info_get_interface(const snd_ctl_elem_info_t *obj)
2146 return obj->id.iface;
2150 * \brief Get device part of CTL element identifier of a CTL element id/info
2151 * \param obj CTL element id/info
2152 * \return device part of element identifier
2154 unsigned int snd_ctl_elem_info_get_device(const snd_ctl_elem_info_t *obj)
2157 return obj->id.device;
2161 * \brief Get subdevice part of CTL element identifier of a CTL element id/info
2162 * \param obj CTL element id/info
2163 * \return subdevice part of element identifier
2165 unsigned int snd_ctl_elem_info_get_subdevice(const snd_ctl_elem_info_t *obj)
2168 return obj->id.subdevice;
2172 * \brief Get name part of CTL element identifier of a CTL element id/info
2173 * \param obj CTL element id/info
2174 * \return name part of element identifier
2176 const char *snd_ctl_elem_info_get_name(const snd_ctl_elem_info_t *obj)
2179 return (const char *)obj->id.name;
2183 * \brief Get index part of CTL element identifier of a CTL element id/info
2184 * \param obj CTL element id/info
2185 * \return index part of element identifier
2187 unsigned int snd_ctl_elem_info_get_index(const snd_ctl_elem_info_t *obj)
2190 return obj->id.index;
2194 * \brief Set CTL element identifier of a CTL element id/info
2195 * \param obj CTL element id/info
2196 * \param ptr CTL element identifier
2198 void snd_ctl_elem_info_set_id(snd_ctl_elem_info_t *obj, const snd_ctl_elem_id_t *ptr)
2205 * \brief Set element numeric identifier of a CTL element id/info
2206 * \param obj CTL element id/info
2207 * \param val element numeric identifier
2209 void snd_ctl_elem_info_set_numid(snd_ctl_elem_info_t *obj, unsigned int val)
2212 obj->id.numid = val;
2216 * \brief Set interface part of CTL element identifier of a CTL element id/info
2217 * \param obj CTL element id/info
2218 * \param val interface part of element identifier
2220 void snd_ctl_elem_info_set_interface(snd_ctl_elem_info_t *obj, snd_ctl_elem_iface_t val)
2223 obj->id.iface = val;
2227 * \brief Set device part of CTL element identifier of a CTL element id/info
2228 * \param obj CTL element id/info
2229 * \param val device part of element identifier
2231 void snd_ctl_elem_info_set_device(snd_ctl_elem_info_t *obj, unsigned int val)
2234 obj->id.device = val;
2238 * \brief Set subdevice part of CTL element identifier of a CTL element id/info
2239 * \param obj CTL element id/info
2240 * \param val subdevice part of element identifier
2242 void snd_ctl_elem_info_set_subdevice(snd_ctl_elem_info_t *obj, unsigned int val)
2245 obj->id.subdevice = val;
2249 * \brief Set name part of CTL element identifier of a CTL element id/info
2250 * \param obj CTL element id/info
2251 * \param val name part of element identifier
2253 void snd_ctl_elem_info_set_name(snd_ctl_elem_info_t *obj, const char *val)
2256 strncpy((char *)obj->id.name, val, sizeof(obj->id.name));
2260 * \brief Set index part of CTL element identifier of a CTL element id/info
2261 * \param obj CTL element id/info
2262 * \param val index part of element identifier
2264 void snd_ctl_elem_info_set_index(snd_ctl_elem_info_t *obj, unsigned int val)
2267 obj->id.index = val;
2271 * \brief get size of #snd_ctl_elem_value_t
2272 * \return size in bytes
2274 size_t snd_ctl_elem_value_sizeof()
2276 return sizeof(snd_ctl_elem_value_t);
2280 * \brief allocate an invalid #snd_ctl_elem_value_t using standard malloc
2281 * \param ptr returned pointer
2282 * \return 0 on success otherwise negative error code
2284 int snd_ctl_elem_value_malloc(snd_ctl_elem_value_t **ptr)
2287 *ptr = calloc(1, sizeof(snd_ctl_elem_value_t));
2294 * \brief frees a previously allocated #snd_ctl_elem_value_t
2295 * \param obj pointer to object to free
2297 void snd_ctl_elem_value_free(snd_ctl_elem_value_t *obj)
2303 * \brief clear given #snd_ctl_elem_value_t object
2304 * \param obj pointer to object to clear
2306 void snd_ctl_elem_value_clear(snd_ctl_elem_value_t *obj)
2308 memset(obj, 0, sizeof(snd_ctl_elem_value_t));
2312 * \brief copy one #snd_ctl_elem_value_t to another
2313 * \param dst pointer to destination
2314 * \param src pointer to source
2316 void snd_ctl_elem_value_copy(snd_ctl_elem_value_t *dst, const snd_ctl_elem_value_t *src)
2323 * \brief compare one #snd_ctl_elem_value_t to another
2324 * \param dst pointer to destination
2325 * \param src pointer to source
2326 * \return 0 on match, less than or greater than otherwise, see memcmp
2328 int snd_ctl_elem_value_compare(snd_ctl_elem_value_t *left, const snd_ctl_elem_value_t *right)
2330 assert(left && right);
2331 return memcmp(left, right, sizeof(*left));
2335 * \brief Get CTL element identifier of a CTL element id/value
2336 * \param obj CTL element id/value
2337 * \param ptr Pointer to returned CTL element identifier
2339 void snd_ctl_elem_value_get_id(const snd_ctl_elem_value_t *obj, snd_ctl_elem_id_t *ptr)
2346 * \brief Get element numeric identifier of a CTL element id/value
2347 * \param obj CTL element id/value
2348 * \return element numeric identifier
2350 unsigned int snd_ctl_elem_value_get_numid(const snd_ctl_elem_value_t *obj)
2353 return obj->id.numid;
2357 * \brief Get interface part of CTL element identifier of a CTL element id/value
2358 * \param obj CTL element id/value
2359 * \return interface part of element identifier
2361 snd_ctl_elem_iface_t snd_ctl_elem_value_get_interface(const snd_ctl_elem_value_t *obj)
2364 return obj->id.iface;
2368 * \brief Get device part of CTL element identifier of a CTL element id/value
2369 * \param obj CTL element id/value
2370 * \return device part of element identifier
2372 unsigned int snd_ctl_elem_value_get_device(const snd_ctl_elem_value_t *obj)
2375 return obj->id.device;
2379 * \brief Get subdevice part of CTL element identifier of a CTL element id/value
2380 * \param obj CTL element id/value
2381 * \return subdevice part of element identifier
2383 unsigned int snd_ctl_elem_value_get_subdevice(const snd_ctl_elem_value_t *obj)
2386 return obj->id.subdevice;
2390 * \brief Get name part of CTL element identifier of a CTL element id/value
2391 * \param obj CTL element id/value
2392 * \return name part of element identifier
2394 const char *snd_ctl_elem_value_get_name(const snd_ctl_elem_value_t *obj)
2397 return (const char *)obj->id.name;
2401 * \brief Get index part of CTL element identifier of a CTL element id/value
2402 * \param obj CTL element id/value
2403 * \return index part of element identifier
2405 unsigned int snd_ctl_elem_value_get_index(const snd_ctl_elem_value_t *obj)
2408 return obj->id.index;
2412 * \brief Set CTL element identifier of a CTL element id/value
2413 * \param obj CTL element id/value
2414 * \param ptr CTL element identifier
2416 void snd_ctl_elem_value_set_id(snd_ctl_elem_value_t *obj, const snd_ctl_elem_id_t *ptr)
2423 * \brief Set element numeric identifier of a CTL element id/value
2424 * \param obj CTL element id/value
2425 * \param val element numeric identifier
2427 void snd_ctl_elem_value_set_numid(snd_ctl_elem_value_t *obj, unsigned int val)
2430 obj->id.numid = val;
2434 * \brief Set interface part of CTL element identifier of a CTL element id/value
2435 * \param obj CTL element id/value
2436 * \param val interface part of element identifier
2438 void snd_ctl_elem_value_set_interface(snd_ctl_elem_value_t *obj, snd_ctl_elem_iface_t val)
2441 obj->id.iface = val;
2445 * \brief Set device part of CTL element identifier of a CTL element id/value
2446 * \param obj CTL element id/value
2447 * \param val device part of element identifier
2449 void snd_ctl_elem_value_set_device(snd_ctl_elem_value_t *obj, unsigned int val)
2452 obj->id.device = val;
2456 * \brief Set subdevice part of CTL element identifier of a CTL element id/value
2457 * \param obj CTL element id/value
2458 * \param val subdevice part of element identifier
2460 void snd_ctl_elem_value_set_subdevice(snd_ctl_elem_value_t *obj, unsigned int val)
2463 obj->id.subdevice = val;
2467 * \brief Set name part of CTL element identifier of a CTL element id/value
2468 * \param obj CTL element id/value
2469 * \param val name part of element identifier
2471 void snd_ctl_elem_value_set_name(snd_ctl_elem_value_t *obj, const char *val)
2474 strncpy((char *)obj->id.name, val, sizeof(obj->id.name));
2478 * \brief Set index part of CTL element identifier of a CTL element id/value
2479 * \param obj CTL element id/value
2480 * \param val index part of element identifier
2482 void snd_ctl_elem_value_set_index(snd_ctl_elem_value_t *obj, unsigned int val)
2485 obj->id.index = val;
2489 * \brief Get value for an entry of a #SND_CTL_ELEM_TYPE_BOOLEAN CTL element id/value
2490 * \param obj CTL element id/value
2491 * \param idx Entry index
2492 * \return value for the entry
2494 int snd_ctl_elem_value_get_boolean(const snd_ctl_elem_value_t *obj, unsigned int idx)
2497 assert(idx < sizeof(obj->value.integer.value) / sizeof(obj->value.integer.value[0]));
2498 return obj->value.integer.value[idx];
2502 * \brief Get value for an entry of a #SND_CTL_ELEM_TYPE_INTEGER CTL element id/value
2503 * \param obj CTL element id/value
2504 * \param idx Entry index
2505 * \return value for the entry
2507 long snd_ctl_elem_value_get_integer(const snd_ctl_elem_value_t *obj, unsigned int idx)
2510 assert(idx < sizeof(obj->value.integer.value) / sizeof(obj->value.integer.value[0]));
2511 return obj->value.integer.value[idx];
2515 * \brief Get value for an entry of a #SND_CTL_ELEM_TYPE_INTEGER64 CTL element id/value
2516 * \param obj CTL element id/value
2517 * \param idx Entry index
2518 * \return value for the entry
2520 long long snd_ctl_elem_value_get_integer64(const snd_ctl_elem_value_t *obj, unsigned int idx)
2523 assert(idx < sizeof(obj->value.integer64.value) / sizeof(obj->value.integer64.value[0]));
2524 return obj->value.integer64.value[idx];
2528 * \brief Get value for an entry of a #SND_CTL_ELEM_TYPE_ENUMERATED CTL element id/value
2529 * \param obj CTL element id/value
2530 * \param idx Entry index
2531 * \return value for the entry
2533 unsigned int snd_ctl_elem_value_get_enumerated(const snd_ctl_elem_value_t *obj, unsigned int idx)
2536 assert(idx < sizeof(obj->value.enumerated.item) / sizeof(obj->value.enumerated.item[0]));
2537 return obj->value.enumerated.item[idx];
2541 * \brief Get value for an entry of a #SND_CTL_ELEM_TYPE_BYTES CTL element id/value
2542 * \param obj CTL element id/value
2543 * \param idx Entry index
2544 * \return value for the entry
2546 unsigned char snd_ctl_elem_value_get_byte(const snd_ctl_elem_value_t *obj, unsigned int idx)
2549 assert(idx < sizeof(obj->value.bytes.data));
2550 return obj->value.bytes.data[idx];
2554 * \brief Set value for an entry of a #SND_CTL_ELEM_TYPE_BOOLEAN CTL element id/value
2555 * \param obj CTL element id/value
2556 * \param idx Entry index
2557 * \param val value for the entry
2559 void snd_ctl_elem_value_set_boolean(snd_ctl_elem_value_t *obj, unsigned int idx, long val)
2562 obj->value.integer.value[idx] = val;
2566 * \brief Set value for an entry of a #SND_CTL_ELEM_TYPE_INTEGER CTL element id/value
2567 * \param obj CTL element id/value
2568 * \param idx Entry index
2569 * \param val value for the entry
2571 void snd_ctl_elem_value_set_integer(snd_ctl_elem_value_t *obj, unsigned int idx, long val)
2574 obj->value.integer.value[idx] = val;
2578 * \brief Set value for an entry of a #SND_CTL_ELEM_TYPE_INTEGER64 CTL element id/value
2579 * \param obj CTL element id/value
2580 * \param idx Entry index
2581 * \param val value for the entry
2583 void snd_ctl_elem_value_set_integer64(snd_ctl_elem_value_t *obj, unsigned int idx, long long val)
2586 obj->value.integer64.value[idx] = val;
2590 * \brief Set value for an entry of a #SND_CTL_ELEM_TYPE_ENUMERATED CTL element id/value
2591 * \param obj CTL element id/value
2592 * \param idx Entry index
2593 * \param val value for the entry
2595 void snd_ctl_elem_value_set_enumerated(snd_ctl_elem_value_t *obj, unsigned int idx, unsigned int val)
2598 obj->value.enumerated.item[idx] = val;
2602 * \brief Set value for an entry of a #SND_CTL_ELEM_TYPE_BYTES CTL element id/value
2603 * \param obj CTL element id/value
2604 * \param idx Entry index
2605 * \param val value for the entry
2607 void snd_ctl_elem_value_set_byte(snd_ctl_elem_value_t *obj, unsigned int idx, unsigned char val)
2610 obj->value.bytes.data[idx] = val;
2614 * \brief Set CTL element #SND_CTL_ELEM_TYPE_BYTES value
2615 * \param obj CTL handle
2616 * \param data Bytes value
2617 * \param size Size in bytes
2619 void snd_ctl_elem_set_bytes(snd_ctl_elem_value_t *obj, void *data, size_t size)
2622 if (size >= sizeof(obj->value.bytes.data)) {
2626 memcpy(obj->value.bytes.data, data, size);
2630 * \brief Get value for a #SND_CTL_ELEM_TYPE_BYTES CTL element id/value
2631 * \param obj CTL element id/value
2632 * \return Pointer to CTL element value
2634 const void * snd_ctl_elem_value_get_bytes(const snd_ctl_elem_value_t *obj)
2637 return obj->value.bytes.data;
2641 * \brief Get value for a #SND_CTL_ELEM_TYPE_IEC958 CTL element id/value
2642 * \param obj CTL element id/value
2643 * \param ptr Pointer to returned CTL element value
2645 void snd_ctl_elem_value_get_iec958(const snd_ctl_elem_value_t *obj, snd_aes_iec958_t *ptr)
2648 memcpy(ptr, &obj->value.iec958, sizeof(*ptr));
2652 * \brief Set value for a #SND_CTL_ELEM_TYPE_IEC958 CTL element id/value
2653 * \param obj CTL element id/value
2654 * \param ptr Pointer to CTL element value
2656 void snd_ctl_elem_value_set_iec958(snd_ctl_elem_value_t *obj, const snd_aes_iec958_t *ptr)
2659 memcpy(&obj->value.iec958, ptr, sizeof(obj->value.iec958));