1 /**
2 * \file control/control.c
3 * \brief CTL interface - primitive controls
4 * \author Abramo Bagnara <abramo@alsa-project.org>
5 * \date 2000
6 *
7 * CTL interface is designed to access primitive controls.
8 * See \ref control page for more details.
9 */
10 /*
11 * Control Interface - main file
12 * Copyright (c) 2000 by Abramo Bagnara <abramo@alsa-project.org>
13 *
14 *
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.
19 *
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.
24 *
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
28 *
29 */
30
31 /*! \page control Control interface
32
33 <P>Control interface is designed to access primitive controls. There is
34 also an interface for notifying about control and structure changes.
35
36
37 \section control_general_overview General overview
38
39 In Alsa, there are physical sound cards, such as USB headsets, and
40 virtual sound cards, such as "pulse", which represents the PulseAudio
41 Sound system. Each sound card offers a control interface, making its
42 settings (e.g. volume knobs) available. The complete list of available
43 control interfaces can be obtained using snd_device_name_hint(),
44 giving -1 as card index and "ctl" as interface type. Each returned
45 NAME hint identifies a control interface.
46
47 Sound cards have an ID (a string), an index (an int, sometimes called
48 the "card number"), a name, a longname, a mixername and a "components"
49 property. The file /proc/asound/cards lists most of these properties
50 for physical sound cards. Virtual sound cards are not listed in that
51 file. The format is:
52
53 \verbatim
54 index [ID ] Driver - name
55 longname
56 \endverbatim
57
58 Note that the mixername and components are not listed.
59
60
61 \subsection control_cards_id Identifying and Opening Control Interfaces
62
63 To work with a control interface, is must be opened first, using
64 snd_ctl_open(). This function takes the interface name.
65
66 For physical sound cards, the control interface can be identified
67 using the string "hw:<index>" (e.g. `hw:2`). The NAME hint - which is
68 "hw:CARD=<ID>" - can also be used. Further, its device file (something
69 like `/dev/snd/controlC0`) is also acceptable. Either of them can be
70 given to snd_ctl_open().
71
72 For virtual sound cards, the NAME hint is given to snd_ctl_open().
73
74 The functions snd_card_get_index(), snd_card_get_name() and
75 snd_card_get_longname() can be used to find an identifying property
76 when another one is already known.
77
78 \section control_elements Elements
79
80 In ALSA control feature, each sound card can have control elements. The elements
81 are managed according to below model.
82
83 - Element set
84
85 - A set of elements with the same attribute (i.e. name, get/put operations).
86 Some element sets can be added to a sound card by drivers in kernel and
87 userspace applications.
88
89 - Element
90
91 - A control element might be a master volume control, for example, or a
92 read-only indicator, such as a sync status. An element has a type (e.g.
93 SNDRV_CTL_ELEM_TYPE_INTEGER or SNDRV_CTL_ELEM_TYPE_BOOLEAN) and - depending
94 on the type - min/max values, a step size, a set of possible values (for
95 enums), etc.
96
97 - Member
98
99 - An element usually includes one or more member(s) to have a value. For
100 example, a stereo volume control element has two members (for left/right),
101 while a mono volume has only one member. The member count can be obtained
102 using snd_ctl_elem_info_get_count(). Elements of type
103 "SNDRV_CTL_ELEM_TYPE_BYTES" or "SNDRV_CTL_ELEM_TYPE_IEC958" have no members
104 at all (and thus no member count), they have just a single value. The
105 members share the same properties (e.g. both volume control members have
106 the same min/max values). The value of each member can be changed by both
107 of userspace applications and drivers in kernel.
108
109
110 \subsection identifying_elements Identifying Elements
111
112 Each element has the following identifying properties:
113
114 - The numid (a numeric identifier, assigned when the sound card is
115 detected, constant while the sound card is kept connected)
116 - The interface type (e.g. MIXER, CARD or PCM)
117 - The device
118 - The subdevice
119 - Its name
120 - Its index
121
122 An element can be identified either by its short numid or by the full
123 set of fields (interface type, device, subdevice, name, index).
124 This set of fields is always the same (driver updates can change it,
125 but in practice this is rare). The numid can change on each boot.
126 In case of an USB sound card, the numid can also change when it
127 is reconnected. The short numid is used to reduce the lookup time.
128
129 \subsection element_lists Element Lists
130
131 An element list can be used to obtain a list of all elements of the
132 sound card. The list contains generic information (e.g. how many
133 elements the card has), and the identifying properties of the elements
134 (numid, card, name, ...). See #snd_ctl_elem_list_t to learn more about
135 element lists.
136
137
138 \subsection working_with_elements Working with Elements
139
140 It is possible to obtain information about an element using the
141 snd_ctl_elem_info_*() functions. For enums, the allowed values can be
142 obtained, for integers, the min/max values can be obtained, and so
143 on. In addition, these functions can report the identifying
144 properties. E.g. when the element is addressed using its numid, the
145 functions complements the name, index, etc.
146
147 To access the members (i.e. values) of a control, use the
148 snd_ctl_elem_value*() functions. These allow to get and set the
149 actual values or settings. It is also possible to get and set the ID
150 values (such as the numid or the name).
151
152
153 \subsection element_sets Element Sets
154
155 The type of element set is one of integer, integer64, boolean, enumerators,
156 bytes and IEC958 structure. This indicates the type of value for each member in
157 elements included in the element set.
158
159
160 \section events Events
161
162 When the value of a member is changed, corresponding events are transferred to
163 userspace applications. The applications should subscribe any events in advance.
164
165 \section tlv_blob Supplemental data for elements in an element set
166
167 TLV feature is designed to transfer data in a shape of Type/Length/Value,
168 between a driver and any userspace applications. The main purpose is to attach
169 supplement information for elements to an element set; e.g. dB range.
170
171 At first, this feature was implemented to add pre-defined data readable to
172 userspace applications. Soon, it was extended to handle several operations;
173 read, write and command. The original implementation remains as the read
174 operation. The command operation allows drivers to have own implementations
175 against requests from userspace applications.
176
177 This feature was introduced to ALSA control feature in 2006, at commit
178 c7a0708a2362, corresponding to a series of work for Linux kernel (42750b04c5ba
179 and 8aa9b586e420).
180
181 There's no limitation about maximum size of the data, therefore it can be used
182 to deliver quite large arbitrary data from userspace to in-kernel drivers via
183 ALSA control character device. Focusing on this nature, as of 2016, some
184 in-kernel implementations utilize this feature for I/O operations. This is
185 against the original design.
186 */
187
188 #include "control_local.h"
189 #include <stdio.h>
190 #include <stdlib.h>
191 #include <stdint.h>
192 #include <stdarg.h>
193 #include <unistd.h>
194 #include <string.h>
195 #include <fcntl.h>
196 #include <signal.h>
197 #include <poll.h>
198 #include <stdbool.h>
199 #include <limits.h>
200
201 /**
202 * \brief get identifier of CTL handle
203 * \param ctl CTL handle
204 * \return ascii identifier of CTL handle
205 *
206 * Returns the ASCII identifier of given CTL handle. It's the same
207 * identifier specified in snd_ctl_open().
208 */
snd_ctl_name(snd_ctl_t * ctl)209 const char *snd_ctl_name(snd_ctl_t *ctl)
210 {
211 assert(ctl);
212 return ctl->name;
213 }
214
215 /**
216 * \brief get type of CTL handle
217 * \param ctl CTL handle
218 * \return type of CTL handle
219 *
220 * Returns the type #snd_ctl_type_t of given CTL handle.
221 */
snd_ctl_type(snd_ctl_t * ctl)222 snd_ctl_type_t snd_ctl_type(snd_ctl_t *ctl)
223 {
224 assert(ctl);
225 return ctl->type;
226 }
227
228 /**
229 * \brief close CTL handle
230 * \param ctl CTL handle
231 * \return 0 on success otherwise a negative error code
232 *
233 * Closes the specified CTL handle and frees all associated
234 * resources.
235 */
snd_ctl_close(snd_ctl_t * ctl)236 int snd_ctl_close(snd_ctl_t *ctl)
237 {
238 int err;
239 while (!list_empty(&ctl->async_handlers)) {
240 snd_async_handler_t *h = list_entry(&ctl->async_handlers.next, snd_async_handler_t, hlist);
241 snd_async_del_handler(h);
242 }
243 err = ctl->ops->close(ctl);
244 free(ctl->name);
245 snd_dlobj_cache_put(ctl->open_func);
246 free(ctl);
247 return err;
248 }
249
250 /**
251 * \brief set nonblock mode
252 * \param ctl CTL handle
253 * \param nonblock 0 = block, 1 = nonblock mode, 2 = abort
254 * \return 0 on success otherwise a negative error code
255 */
snd_ctl_nonblock(snd_ctl_t * ctl,int nonblock)256 int snd_ctl_nonblock(snd_ctl_t *ctl, int nonblock)
257 {
258 int err;
259 assert(ctl);
260 err = ctl->ops->nonblock(ctl, nonblock);
261 if (err < 0)
262 return err;
263 ctl->nonblock = nonblock;
264 return 0;
265 }
266
267 #ifndef DOC_HIDDEN
snd_ctl_new(snd_ctl_t ** ctlp,snd_ctl_type_t type,const char * name,int mode)268 int snd_ctl_new(snd_ctl_t **ctlp, snd_ctl_type_t type, const char *name, int mode)
269 {
270 snd_ctl_t *ctl;
271 ctl = calloc(1, sizeof(*ctl));
272 if (!ctl)
273 return -ENOMEM;
274 ctl->type = type;
275 ctl->mode = mode;
276 if (name)
277 ctl->name = strdup(name);
278 INIT_LIST_HEAD(&ctl->async_handlers);
279 *ctlp = ctl;
280 return 0;
281 }
282
283
284 /**
285 * \brief set async mode
286 * \param ctl CTL handle
287 * \param sig Signal to raise: < 0 disable, 0 default (SIGIO)
288 * \param pid Process ID to signal: 0 current
289 * \return 0 on success otherwise a negative error code
290 *
291 * A signal is raised when a change happens.
292 */
snd_ctl_async(snd_ctl_t * ctl,int sig,pid_t pid)293 int snd_ctl_async(snd_ctl_t *ctl, int sig, pid_t pid)
294 {
295 assert(ctl);
296 if (sig == 0)
297 sig = SIGIO;
298 if (pid == 0)
299 pid = getpid();
300 return ctl->ops->async(ctl, sig, pid);
301 }
302 #endif
303
304 /**
305 * \brief get count of poll descriptors for CTL handle
306 * \param ctl CTL handle
307 * \return count of poll descriptors
308 */
snd_ctl_poll_descriptors_count(snd_ctl_t * ctl)309 int snd_ctl_poll_descriptors_count(snd_ctl_t *ctl)
310 {
311 assert(ctl);
312 if (ctl->ops->poll_descriptors_count)
313 return ctl->ops->poll_descriptors_count(ctl);
314 if (ctl->poll_fd < 0)
315 return 0;
316 return 1;
317 }
318
319 /**
320 * \brief get poll descriptors
321 * \param ctl CTL handle
322 * \param pfds array of poll descriptors
323 * \param space space in the poll descriptor array
324 * \return count of filled descriptors
325 */
snd_ctl_poll_descriptors(snd_ctl_t * ctl,struct pollfd * pfds,unsigned int space)326 int snd_ctl_poll_descriptors(snd_ctl_t *ctl, struct pollfd *pfds, unsigned int space)
327 {
328 assert(ctl && pfds);
329 if (ctl->ops->poll_descriptors)
330 return ctl->ops->poll_descriptors(ctl, pfds, space);
331 if (ctl->poll_fd < 0)
332 return 0;
333 if (space > 0) {
334 pfds->fd = ctl->poll_fd;
335 pfds->events = POLLIN|POLLERR|POLLNVAL;
336 return 1;
337 }
338 return 0;
339 }
340
341 /**
342 * \brief get returned events from poll descriptors
343 * \param ctl CTL handle
344 * \param pfds array of poll descriptors
345 * \param nfds count of poll descriptors
346 * \param revents returned events
347 * \return zero if success, otherwise a negative error code
348 */
snd_ctl_poll_descriptors_revents(snd_ctl_t * ctl,struct pollfd * pfds,unsigned int nfds,unsigned short * revents)349 int snd_ctl_poll_descriptors_revents(snd_ctl_t *ctl, struct pollfd *pfds, unsigned int nfds, unsigned short *revents)
350 {
351 assert(ctl && pfds && revents);
352 if (ctl->ops->poll_revents)
353 return ctl->ops->poll_revents(ctl, pfds, nfds, revents);
354 if (nfds == 1) {
355 *revents = pfds->revents;
356 return 0;
357 }
358 return -EINVAL;
359 }
360
361 /**
362 * \brief Ask to be informed about events (poll, #snd_async_add_ctl_handler, #snd_ctl_read)
363 * \param ctl CTL handle
364 * \param subscribe 0 = unsubscribe, 1 = subscribe, -1 = check subscribe or not
365 * \return 0 on success otherwise a negative error code
366 */
snd_ctl_subscribe_events(snd_ctl_t * ctl,int subscribe)367 int snd_ctl_subscribe_events(snd_ctl_t *ctl, int subscribe)
368 {
369 assert(ctl);
370 return ctl->ops->subscribe_events(ctl, subscribe);
371 }
372
373
374 /**
375 * \brief Get information about the sound card.
376 *
377 * Obtain information about the sound card previously opened using
378 * snd_ctl_open(). The object "info" must be allocated prior to calling this
379 * function. See snd_ctl_card_info_t for details.
380 *
381 * \param ctl The CTL handle.
382 * \param info The card information is stored here.
383 * \return 0 on success, otherwise a negative error code.
384 */
snd_ctl_card_info(snd_ctl_t * ctl,snd_ctl_card_info_t * info)385 int snd_ctl_card_info(snd_ctl_t *ctl, snd_ctl_card_info_t *info)
386 {
387 assert(ctl && info);
388 return ctl->ops->card_info(ctl, info);
389 }
390
391 /**
392 * \brief Get a list of element identifiers
393 *
394 * Before calling this function, memoru must be allocated using
395 * snd_ctl_elem_list_malloc().
396 *
397 * This function obtains data from the sound card driver and puts it
398 * into the list.
399 *
400 * If there was space allocated for the element identifiers (using
401 * snd_ctl_elem_list_alloc_space()), information will be filled in. If
402 * too little space was allocated, only a part of the elements will be
403 * queried. If there was too much space allocated, some of it remains
404 * unused. Use snd_ctl_elem_list_get_count() and
405 * snd_ctl_elem_list_get_used() to obtain information about space
406 * usage. See #snd_ctl_elem_list_t to learn more.
407 *
408 * \param ctl CTL handle
409 * \param list CTL element identifiers list pointer
410 * \return 0 on success otherwise a negative error code
411 */
snd_ctl_elem_list(snd_ctl_t * ctl,snd_ctl_elem_list_t * list)412 int snd_ctl_elem_list(snd_ctl_t *ctl, snd_ctl_elem_list_t *list)
413 {
414 assert(ctl && list);
415 assert(list->space == 0 || list->pids);
416 return ctl->ops->element_list(ctl, list);
417 }
418
419 /**
420 * \brief Get CTL element information
421 * \param ctl CTL handle
422 * \param info CTL element id/information pointer
423 * \return 0 on success otherwise a negative error code
424 */
snd_ctl_elem_info(snd_ctl_t * ctl,snd_ctl_elem_info_t * info)425 int snd_ctl_elem_info(snd_ctl_t *ctl, snd_ctl_elem_info_t *info)
426 {
427 assert(ctl && info && (info->id.name[0] || info->id.numid));
428 return ctl->ops->element_info(ctl, info);
429 }
430
431 #ifndef DOC_HIDDEN
432 #if 0 /* deprecated */
433 static bool validate_element_member_dimension(snd_ctl_elem_info_t *info)
434 {
435 unsigned int members;
436 unsigned int i;
437
438 if (info->dimen.d[0] == 0)
439 return true;
440
441 members = 1;
442 for (i = 0; i < ARRAY_SIZE(info->dimen.d); ++i) {
443 if (info->dimen.d[i] == 0)
444 break;
445 members *= info->dimen.d[i];
446
447 if (members > info->count)
448 return false;
449 }
450
451 for (++i; i < ARRAY_SIZE(info->dimen.d); ++i) {
452 if (info->dimen.d[i] > 0)
453 return false;
454 }
455
456 return members == info->count;
457 }
458 #else /* deprecated */
459 #define validate_element_member_dimension(info) true
460 #endif /* deprecated */
461
462 #define USER_ACCESS_DEFAULT (\
463 SNDRV_CTL_ELEM_ACCESS_READWRITE |\
464 SNDRV_CTL_ELEM_ACCESS_TLV_READWRITE |\
465 SNDRV_CTL_ELEM_ACCESS_USER)
466
467 #define USER_ACCESS_SETTABLE (\
468 SNDRV_CTL_ELEM_ACCESS_READWRITE |\
469 SNDRV_CTL_ELEM_ACCESS_VOLATILE |\
470 SNDRV_CTL_ELEM_ACCESS_TLV_READWRITE |\
471 SNDRV_CTL_ELEM_ACCESS_INACTIVE |\
472 SNDRV_CTL_ELEM_ACCESS_USER)
473
set_user_access(snd_ctl_elem_info_t * info)474 static inline int set_user_access(snd_ctl_elem_info_t *info)
475 {
476 if (info->access == 0) {
477 info->access = USER_ACCESS_DEFAULT;
478 } else {
479 if ((info->access & SNDRV_CTL_ELEM_ACCESS_READWRITE) == 0)
480 return -1;
481 if (info->access & ~USER_ACCESS_SETTABLE)
482 return -1;
483 info->access |= SNDRV_CTL_ELEM_ACCESS_USER;
484 }
485 return 0;
486 }
487
__snd_ctl_add_elem_set(snd_ctl_t * ctl,snd_ctl_elem_info_t * info,unsigned int element_count,unsigned int member_count)488 int __snd_ctl_add_elem_set(snd_ctl_t *ctl, snd_ctl_elem_info_t *info,
489 unsigned int element_count,
490 unsigned int member_count)
491 {
492 if (ctl == NULL || info->id.name[0] == '\0')
493 return -EINVAL;
494
495 if (set_user_access(info))
496 return -EINVAL;
497
498 info->owner = element_count;
499 info->count = member_count;
500
501 if (!validate_element_member_dimension(info))
502 return -EINVAL;
503
504 return ctl->ops->element_add(ctl, info);
505 }
506
507 #endif /* DOC_HIDDEN */
508
509 /**
510 * \brief Create and add some user-defined control elements of integer type.
511 * \param ctl A handle of backend module for control interface.
512 * \param info Common information for a new element set, with ID of the first new
513 * element.
514 * \param element_count The number of elements added by this operation.
515 * \param member_count The number of members which a element has to
516 * represent its states.
517 * \param min Minimum value for each member of the elements.
518 * \param max Maximum value for each member of the elements.
519 * \param step The step of value for each member in the elements.
520 * \return Zero on success, otherwise a negative error code.
521 *
522 * This function creates some user elements with integer type. These elements
523 * are not controlled by device drivers in kernel. They can be operated by the
524 * same way as usual elements added by the device drivers.
525 *
526 * The name field of \a id must be set with unique value to identify new control
527 * elements. After returning, all fields of \a id are filled. A element can be
528 * identified by the combination of name and index, or by numid.
529 *
530 * All of members in the new elements are locked. The value of each member is
531 * initialized with the minimum value.
532 *
533 * \par Errors:
534 * <dl>
535 * <dt>-EBUSY
536 * <dd>A element with ID \a id already exists.
537 * <dt>-EINVAL
538 * <dd>Some arguments include invalid value; i.e. ID field in \a info has no
539 * name, or the number of members is not between 1 to 127.
540 * <dt>-ENOMEM
541 * <dd>Out of memory, or there are too many user elements.
542 * <dt>-ENXIO
543 * <dd>This backend module does not support user elements of integer type.
544 * <dt>-ENODEV
545 * <dd>Device unplugged.
546 * </dl>
547 *
548 * \par Compatibility:
549 * This function is added in version 1.1.2.
550 */
snd_ctl_add_integer_elem_set(snd_ctl_t * ctl,snd_ctl_elem_info_t * info,unsigned int element_count,unsigned int member_count,long min,long max,long step)551 int snd_ctl_add_integer_elem_set(snd_ctl_t *ctl, snd_ctl_elem_info_t *info,
552 unsigned int element_count,
553 unsigned int member_count,
554 long min, long max, long step)
555 {
556 snd_ctl_elem_value_t data = {0};
557 unsigned int i;
558 unsigned int j;
559 unsigned int numid;
560 int err;
561
562 if (info == NULL)
563 return -EINVAL;
564
565 info->type = SND_CTL_ELEM_TYPE_INTEGER;
566 info->value.integer.min = min;
567 info->value.integer.max = max;
568 info->value.integer.step = step;
569
570 err = __snd_ctl_add_elem_set(ctl, info, element_count, member_count);
571 if (err < 0)
572 return err;
573 numid = snd_ctl_elem_id_get_numid(&info->id);
574
575 /* Set initial value to all of members in all of added elements. */
576 data.id = info->id;
577 for (i = 0; i < element_count; i++) {
578 snd_ctl_elem_id_set_numid(&data.id, numid + i);
579
580 for (j = 0; j < member_count; j++)
581 data.value.integer.value[j] = min;
582
583 err = ctl->ops->element_write(ctl, &data);
584 if (err < 0)
585 return err;
586 }
587
588 return 0;
589 }
590
591 /**
592 * \brief Create and add some user-defined control elements of integer64 type.
593 * \param ctl A handle of backend module for control interface.
594 * \param info Common information for a new element set, with ID of the first new
595 * element.
596 * \param element_count The number of elements added by this operation.
597 * \param member_count The number of members which a element has to
598 * represent its states.
599 * \param min Minimum value for each member of the elements.
600 * \param max Maximum value for each member of the elements.
601 * \param step The step of value for each member in the elements.
602 * \return Zero on success, otherwise a negative error code.
603 *
604 * This function creates some user elements with integer64 type. These elements
605 * are not controlled by device drivers in kernel. They can be operated by the
606 * same way as usual elements added by the device drivers.
607 *
608 * The name field of \a id must be set with unique value to identify new control
609 * elements. After returning, all fields of \a id are filled. A element can be
610 * identified by the combination of name and index, or by numid.
611 *
612 * All of members in the new elements are locked. The value of each member is
613 * initialized with the minimum value.
614 *
615 * \par Errors:
616 * <dl>
617 * <dt>-EBUSY
618 * <dd>A element with ID \a id already exists.
619 * <dt>-EINVAL
620 * <dd>Some arguments include invalid value; i.e. ID has no name, or the number
621 * of members is not between 1 to 127.
622 * <dt>-ENOMEM
623 * <dd>Out of memory, or there are too many user elements.
624 * <dt>-ENXIO
625 * <dd>This backend module does not support user elements of integer64 type.
626 * <dt>-ENODEV
627 * <dd>Device unplugged.
628 * </dl>
629 *
630 * \par Compatibility:
631 * This function is added in version 1.1.2.
632 */
snd_ctl_add_integer64_elem_set(snd_ctl_t * ctl,snd_ctl_elem_info_t * info,unsigned int element_count,unsigned int member_count,long long min,long long max,long long step)633 int snd_ctl_add_integer64_elem_set(snd_ctl_t *ctl, snd_ctl_elem_info_t *info,
634 unsigned int element_count,
635 unsigned int member_count,
636 long long min, long long max, long long step)
637 {
638 snd_ctl_elem_value_t data = {0};
639 unsigned int i;
640 unsigned int j;
641 unsigned int numid;
642 int err;
643
644 if (info == NULL)
645 return -EINVAL;
646
647 info->type = SND_CTL_ELEM_TYPE_INTEGER64;
648 info->value.integer64.min = min;
649 info->value.integer64.max = max;
650 info->value.integer64.step = step;
651
652 err = __snd_ctl_add_elem_set(ctl, info, element_count, member_count);
653 if (err < 0)
654 return err;
655 numid = snd_ctl_elem_id_get_numid(&info->id);
656
657 /* Set initial value to all of members in all of added elements. */
658 data.id = info->id;
659 for (i = 0; i < element_count; i++) {
660 snd_ctl_elem_id_set_numid(&data.id, numid + i);
661
662 for (j = 0; j < member_count; j++)
663 data.value.integer64.value[j] = min;
664
665 err = ctl->ops->element_write(ctl, &data);
666 if (err < 0)
667 return err;
668 }
669
670 return 0;
671 }
672
673 /**
674 * \brief Create and add some user-defined control elements of boolean type.
675 * \param ctl A handle of backend module for control interface.
676 * \param info Common information for a new element set, with ID of the first new
677 * element.
678 * \param element_count The number of elements added by this operation.
679 * \param member_count The number of members which a element has to
680 * represent its states.
681 *
682 * This function creates some user elements with boolean type. These elements
683 * are not controlled by device drivers in kernel. They can be operated by the
684 * same way as usual elements added by the device drivers.
685 *
686 * The name field of \a id must be set with unique value to identify new control
687 * elements. After returning, all fields of \a id are filled. A element can be
688 * identified by the combination of name and index, or by numid.
689 *
690 * All of members in the new elements are locked. The value of each member is
691 * initialized with false.
692 *
693 * \par Errors:
694 * <dl>
695 * <dt>-EBUSY
696 * <dd>A element with ID \a id already exists.
697 * <dt>-EINVAL
698 * <dd>Some parameters include invalid value; i.e. ID has no name, or the number
699 * of members is not between 1 to 127.
700 * <dt>-ENOMEM
701 * <dd>Out of memory, or there are too many user elements.
702 * <dt>-ENXIO
703 * <dd>This backend module does not support user elements of boolean type.
704 * <dt>-ENODEV
705 * <dd>Device unplugged.
706 * </dl>
707 *
708 * \par Compatibility:
709 * This function is added in version 1.1.2.
710 */
snd_ctl_add_boolean_elem_set(snd_ctl_t * ctl,snd_ctl_elem_info_t * info,unsigned int element_count,unsigned int member_count)711 int snd_ctl_add_boolean_elem_set(snd_ctl_t *ctl, snd_ctl_elem_info_t *info,
712 unsigned int element_count,
713 unsigned int member_count)
714 {
715 if (info == NULL)
716 return -EINVAL;
717
718 info->type = SND_CTL_ELEM_TYPE_BOOLEAN;
719 info->value.integer.min = 0;
720 info->value.integer.max = 1;
721
722 return __snd_ctl_add_elem_set(ctl, info, element_count, member_count);
723 }
724
725 /**
726 * \brief Create and add some user-defined control elements of enumerated type.
727 * \param ctl A handle of backend module for control interface.
728 * \param info Common information for a new element set, with ID of the first new
729 * element.
730 * \param element_count The number of elements added by this operation.
731 * \param member_count The number of members which a element has to
732 * represent its states.
733 * \param items Range of possible values (0 ... \a items - 1).
734 * \param labels An array containing \a items strings.
735 * \return Zero on success, otherwise a negative error code.
736 *
737 * This function creates some user elements with enumerated type. These elements
738 * are not controlled by device drivers in kernel. They can be operated by the
739 * same way as usual elements added by the device drivers.
740 *
741 * The name field of \a id must be set with unique value to identify new control
742 * elements. After returning, all fields of \a id are filled. A element can be
743 * identified by the combination of name and index, or by numid.
744 *
745 * All of members in the new elements are locked. The value of each member is
746 * initialized with the first entry of labels.
747 *
748 * \par Errors:
749 * <dl>
750 * <dt>-EBUSY
751 * <dd>A control element with ID \a id already exists.
752 * <dt>-EINVAL
753 * <dd>Some arguments include invalid value; i.e. \a element_count is not
754 * between 1 to 127, or \a items is not at least one, or a string in \a
755 * labels is empty, or longer than 63 bytes, or total length of the labels
756 * requires more than 64 KiB storage.
757 * <dt>-ENOMEM
758 * <dd>Out of memory, or there are too many user control elements.
759 * <dt>-ENXIO
760 * <dd>This driver does not support (enumerated) user controls.
761 * <dt>-ENODEV
762 * <dd>Device unplugged.
763 * </dl>
764 *
765 * \par Compatibility:
766 * This function is added in version 1.1.2.
767 */
snd_ctl_add_enumerated_elem_set(snd_ctl_t * ctl,snd_ctl_elem_info_t * info,unsigned int element_count,unsigned int member_count,unsigned int items,const char * const labels[])768 int snd_ctl_add_enumerated_elem_set(snd_ctl_t *ctl, snd_ctl_elem_info_t *info,
769 unsigned int element_count,
770 unsigned int member_count,
771 unsigned int items,
772 const char *const labels[])
773 {
774 unsigned int i, bytes;
775 char *buf, *p;
776 int err;
777
778 if (info == NULL || labels == NULL)
779 return -EINVAL;
780
781 info->type = SND_CTL_ELEM_TYPE_ENUMERATED;
782 info->owner = element_count;
783 info->count = member_count;
784 info->value.enumerated.items = items;
785
786 bytes = 0;
787 for (i = 0; i < items; ++i)
788 bytes += strlen(labels[i]) + 1;
789 if (bytes == 0)
790 return -EINVAL;
791 buf = malloc(bytes);
792 if (buf == NULL)
793 return -ENOMEM;
794 info->value.enumerated.names_ptr = (uintptr_t)buf;
795 info->value.enumerated.names_length = bytes;
796 p = buf;
797 for (i = 0; i < items; ++i) {
798 strcpy(p, labels[i]);
799 p += strlen(labels[i]) + 1;
800 }
801
802 err = __snd_ctl_add_elem_set(ctl, info, element_count, member_count);
803
804 free(buf);
805
806 return err;
807 }
808
809 /**
810 * \brief Create and add some user-defined control elements of bytes type.
811 * \param ctl A handle of backend module for control interface.
812 * \param info Common information for a new element set, with ID of the first new
813 * element.
814 * \param element_count The number of elements added by this operation.
815 * \param member_count The number of members which a element has to
816 * represent its states.
817 * \return Zero on success, otherwise a negative error code.
818 *
819 * This function creates some user elements with bytes type. These elements are
820 * not controlled by device drivers in kernel. They can be operated by the same
821 * way as usual elements added by the device drivers.
822 *
823 * The name field of \a id must be set with unique value to identify new control
824 * elements. After returning, all fields of \a id are filled. A element can be
825 * identified by the combination of name and index, or by numid.
826 *
827 * All of members in the new elements are locked. The value of each member is
828 * initialized with the minimum value.
829 *
830 * \par Errors:
831 * <dl>
832 * <dt>-EBUSY
833 * <dd>A element with ID \a id already exists.
834 * <dt>-EINVAL
835 * <dd>Some arguments include invalid value; i.e. ID has no name, or the number
836 * of members is not between 1 to 511.
837 * <dt>-ENOMEM
838 * <dd>Out of memory, or there are too many user elements.
839 * <dt>-ENXIO
840 * <dd>This backend module does not support user elements of bytes type.
841 * <dt>-ENODEV
842 * <dd>Device unplugged.
843 * </dl>
844 *
845 * \par Compatibility:
846 * This function is added in version 1.1.2.
847 */
snd_ctl_add_bytes_elem_set(snd_ctl_t * ctl,snd_ctl_elem_info_t * info,unsigned int element_count,unsigned int member_count)848 int snd_ctl_add_bytes_elem_set(snd_ctl_t *ctl, snd_ctl_elem_info_t *info,
849 unsigned int element_count,
850 unsigned int member_count)
851 {
852 if (info == NULL)
853 return -EINVAL;
854
855 info->type = SND_CTL_ELEM_TYPE_BYTES;
856
857 return __snd_ctl_add_elem_set(ctl, info, element_count, member_count);
858 }
859
860 /**
861 * \brief Create and add an user-defined control element of integer type.
862 *
863 * This is a wrapper function to snd_ctl_add_integer_elem_set() for a control
864 * element. This doesn't fill the id data with full information, thus it's
865 * recommended to use snd_ctl_add_integer_elem_set(), instead.
866 */
snd_ctl_elem_add_integer(snd_ctl_t * ctl,const snd_ctl_elem_id_t * id,unsigned int member_count,long min,long max,long step)867 int snd_ctl_elem_add_integer(snd_ctl_t *ctl, const snd_ctl_elem_id_t *id,
868 unsigned int member_count,
869 long min, long max, long step)
870 {
871 snd_ctl_elem_info_t info = {0};
872
873 assert(ctl && id && id->name[0]);
874
875 info.id = *id;
876
877 return snd_ctl_add_integer_elem_set(ctl, &info, 1, member_count,
878 min, max, step);
879 }
880
881 /**
882 * \brief Create and add an user-defined control element of integer64 type.
883 *
884 * This is a wrapper function to snd_ctl_add_integer64_elem_set() for a single
885 * control element. This doesn't fill the id data with full information, thus
886 * it's recommended to use snd_ctl_add_integer64_elem_set(), instead.
887 */
snd_ctl_elem_add_integer64(snd_ctl_t * ctl,const snd_ctl_elem_id_t * id,unsigned int member_count,long long min,long long max,long long step)888 int snd_ctl_elem_add_integer64(snd_ctl_t *ctl, const snd_ctl_elem_id_t *id,
889 unsigned int member_count,
890 long long min, long long max, long long step)
891 {
892 snd_ctl_elem_info_t info = {0};
893
894 assert(ctl && id && id->name[0]);
895
896 info.id = *id;
897
898 return snd_ctl_add_integer64_elem_set(ctl, &info, 1, member_count,
899 min, max, step);
900 }
901
902 /**
903 * \brief Create and add an user-defined control element of boolean type.
904 *
905 * This is a wrapper function to snd_ctl_add_boolean_elem_set() for a single
906 * control element. This doesn't fill the id data with full information, thus
907 * it's recommended to use snd_ctl_add_boolean_elem_set(), instead.
908 */
snd_ctl_elem_add_boolean(snd_ctl_t * ctl,const snd_ctl_elem_id_t * id,unsigned int member_count)909 int snd_ctl_elem_add_boolean(snd_ctl_t *ctl, const snd_ctl_elem_id_t *id,
910 unsigned int member_count)
911 {
912 snd_ctl_elem_info_t info = {0};
913
914 assert(ctl && id && id->name[0]);
915
916 info.id = *id;
917
918 return snd_ctl_add_boolean_elem_set(ctl, &info, 1, member_count);
919 }
920
921 /**
922 * \brief Create and add a user-defined control element of enumerated type.
923 *
924 * This is a wrapper function to snd_ctl_add_enumerated_elem_set() for a single
925 * control element. This doesn't fill the id data with full information, thus
926 * it's recommended to use snd_ctl_add_enumerated_elem_set(), instead.
927 *
928 * This function is added in version 1.0.25.
929 */
snd_ctl_elem_add_enumerated(snd_ctl_t * ctl,const snd_ctl_elem_id_t * id,unsigned int member_count,unsigned int items,const char * const labels[])930 int snd_ctl_elem_add_enumerated(snd_ctl_t *ctl, const snd_ctl_elem_id_t *id,
931 unsigned int member_count, unsigned int items,
932 const char *const labels[])
933 {
934 snd_ctl_elem_info_t info = {0};
935
936 assert(ctl && id && id->name[0] && labels);
937
938 info.id = *id;
939
940 return snd_ctl_add_enumerated_elem_set(ctl, &info, 1, member_count,
941 items, labels);
942 }
943
944 /**
945 * \brief Create and add a user-defined control element of IEC958 type.
946 * \param[in] ctl A handle of backend module for control interface.
947 * \param[in,out] id ID of the new control element.
948 *
949 * This function creates an user element with IEC958 type. This element is not
950 * controlled by device drivers in kernel. It can be operated by the same way as
951 * usual elements added by the device drivers.
952 *
953 * The name field of \a id must be set with unique value to identify a new
954 * control element. After returning, all fields of \a id are filled. A element
955 * can be identified by the combination of name and index, or by numid.
956 *
957 * A member in the new element is locked and filled with zero.
958 *
959 * \par Errors:
960 * <dl>
961 * <dt>-EBUSY
962 * <dd>A control element with ID \a id already exists.
963 * <dt>-EINVAL
964 * <dd>ID has no name.
965 * <dt>-ENOMEM
966 * <dd>Out of memory, or there are too many user elements.
967 * <dt>-ENXIO
968 * <dd>This backend module does not support user elements of IEC958 type.
969 * <dt>-ENODEV
970 * <dd>Device unplugged.
971 * </dl>
972 */
snd_ctl_elem_add_iec958(snd_ctl_t * ctl,const snd_ctl_elem_id_t * id)973 int snd_ctl_elem_add_iec958(snd_ctl_t *ctl, const snd_ctl_elem_id_t *id)
974 {
975 snd_ctl_elem_info_t info = {0};
976
977 assert(ctl && id && id->name[0]);
978
979 info.id = *id;
980 info.type = SND_CTL_ELEM_TYPE_IEC958;
981 info.owner = 1;
982 info.count = 1;
983 return ctl->ops->element_add(ctl, &info);
984 }
985
986 /**
987 * \brief Remove an user CTL element
988 * \param ctl CTL handle
989 * \param id CTL element identification
990 * \return 0 on success otherwise a negative error code
991 */
snd_ctl_elem_remove(snd_ctl_t * ctl,snd_ctl_elem_id_t * id)992 int snd_ctl_elem_remove(snd_ctl_t *ctl, snd_ctl_elem_id_t *id)
993 {
994 assert(ctl && id && (id->name[0] || id->numid));
995 return ctl->ops->element_remove(ctl, id);
996 }
997
998 /**
999 * \brief Get CTL element value.
1000 *
1001 * Read information from sound card. You must set the ID of the
1002 * element before calling this function.
1003 *
1004 * See snd_ctl_elem_value_t for details.
1005 *
1006 * \param ctl CTL handle.
1007 * \param data The element value. The ID must be set before calling
1008 * the function, and the actual value will be returned
1009 * here.
1010 *
1011 * \return 0 on success otherwise a negative error code.
1012 */
snd_ctl_elem_read(snd_ctl_t * ctl,snd_ctl_elem_value_t * data)1013 int snd_ctl_elem_read(snd_ctl_t *ctl, snd_ctl_elem_value_t *data)
1014 {
1015 assert(ctl && data && (data->id.name[0] || data->id.numid));
1016 return ctl->ops->element_read(ctl, data);
1017 }
1018
1019 /**
1020 * \brief Set CTL element value.
1021 *
1022 * Write new value(s) to the sound card. You must set the ID and the
1023 * value of the element before calling this function.
1024 *
1025 * See snd_ctl_elem_value_t for details.
1026 *
1027 * \param ctl CTL handle.
1028 * \param data The new value.
1029 *
1030 * \retval 0 on success
1031 * \retval >0 on success when value was changed
1032 * \retval <0 a negative error code
1033 */
snd_ctl_elem_write(snd_ctl_t * ctl,snd_ctl_elem_value_t * data)1034 int snd_ctl_elem_write(snd_ctl_t *ctl, snd_ctl_elem_value_t *data)
1035 {
1036 assert(ctl && data && (data->id.name[0] || data->id.numid));
1037 return ctl->ops->element_write(ctl, data);
1038 }
1039
snd_ctl_tlv_do(snd_ctl_t * ctl,int op_flag,const snd_ctl_elem_id_t * id,unsigned int * tlv,unsigned int tlv_size)1040 static int snd_ctl_tlv_do(snd_ctl_t *ctl, int op_flag,
1041 const snd_ctl_elem_id_t *id,
1042 unsigned int *tlv, unsigned int tlv_size)
1043 {
1044 snd_ctl_elem_info_t *info = NULL;
1045 int err;
1046
1047 if (id->numid == 0) {
1048 info = calloc(1, sizeof(*info));
1049 if (info == NULL)
1050 return -ENOMEM;
1051 info->id = *id;
1052 id = &info->id;
1053 err = snd_ctl_elem_info(ctl, info);
1054 if (err < 0)
1055 goto __err;
1056 if (id->numid == 0) {
1057 err = -ENOENT;
1058 goto __err;
1059 }
1060 }
1061 err = ctl->ops->element_tlv(ctl, op_flag, id->numid, tlv, tlv_size);
1062 __err:
1063 if (info)
1064 free(info);
1065 return err;
1066 }
1067
1068 /**
1069 * \brief Read structured data from an element set to given buffer.
1070 * \param ctl A handle of backend module for control interface.
1071 * \param id ID of an element.
1072 * \param tlv An array with members of unsigned int type.
1073 * \param tlv_size The length of the array.
1074 * \return 0 on success otherwise a negative error code
1075 *
1076 * The format of an array of \a tlv argument is:
1077 * tlv[0]: Type. One of SND_CTL_TLVT_XXX.
1078 * tlv[1]: Length. The length of value in units of byte.
1079 * tlv[2..]: Value. Depending on the type.
1080 *
1081 * Details are described in <sound/tlv.h>.
1082 */
snd_ctl_elem_tlv_read(snd_ctl_t * ctl,const snd_ctl_elem_id_t * id,unsigned int * tlv,unsigned int tlv_size)1083 int snd_ctl_elem_tlv_read(snd_ctl_t *ctl, const snd_ctl_elem_id_t *id,
1084 unsigned int *tlv, unsigned int tlv_size)
1085 {
1086 int err;
1087 assert(ctl && id && (id->name[0] || id->numid) && tlv);
1088 if (tlv_size < 2 * sizeof(int))
1089 return -EINVAL;
1090 /* 1.0.12 driver doesn't return the error even if the user TLV
1091 * is empty. So, initialize TLV here with an invalid type
1092 * and compare the returned value after ioctl for checking
1093 * the validity of TLV.
1094 */
1095 tlv[SNDRV_CTL_TLVO_TYPE] = -1;
1096 tlv[SNDRV_CTL_TLVO_LEN] = 0;
1097 err = snd_ctl_tlv_do(ctl, 0, id, tlv, tlv_size);
1098 if (err >= 0 && tlv[SNDRV_CTL_TLVO_TYPE] == (unsigned int)-1)
1099 err = -ENXIO;
1100 return err;
1101 }
1102
1103 /**
1104 * \brief Write structured data from given buffer to an element set.
1105 * \param ctl A handle of backend module for control interface.
1106 * \param id ID of an element.
1107 * \param tlv An array with members of unsigned int type. The second member
1108 * must represent total bytes of the rest of array.
1109 * \retval 0 on success
1110 * \retval >0 on success when value was changed
1111 * \retval <0 a negative error code
1112 *
1113 * The format of an array of \a tlv argument is:
1114 * tlv[0]: Type. One of SND_CTL_TLVT_XXX.
1115 * tlv[1]: Length. The length of value in units of byte.
1116 * tlv[2..]: Value. Depending on the type.
1117 *
1118 * Details are described in <sound/tlv.h>.
1119 */
snd_ctl_elem_tlv_write(snd_ctl_t * ctl,const snd_ctl_elem_id_t * id,const unsigned int * tlv)1120 int snd_ctl_elem_tlv_write(snd_ctl_t *ctl, const snd_ctl_elem_id_t *id,
1121 const unsigned int *tlv)
1122 {
1123 assert(ctl && id && (id->name[0] || id->numid) && tlv);
1124 return snd_ctl_tlv_do(ctl, 1, id, (unsigned int *)tlv,
1125 tlv[SNDRV_CTL_TLVO_LEN] + 2 * sizeof(unsigned int));
1126 }
1127
1128 /**
1129 * \brief Process structured data from given buffer for an element set.
1130 * \param ctl A handle of backend module for control interface.
1131 * \param id ID of an element.
1132 * \param tlv An array with members of unsigned int type. The second member
1133 * must represent total bytes of the rest of array.
1134 * \retval 0 on success
1135 * \retval >0 on success when value was changed
1136 * \retval <0 a negative error code
1137 *
1138 * The format of an array of \a tlv argument is:
1139 * tlv[0]: Type. One of SND_CTL_TLVT_XXX.
1140 * tlv[1]: Length. The length of value in units of byte.
1141 * tlv[2..]: Value. Depending on the type.
1142 *
1143 * Details are described in <sound/tlv.h>.
1144 */
snd_ctl_elem_tlv_command(snd_ctl_t * ctl,const snd_ctl_elem_id_t * id,const unsigned int * tlv)1145 int snd_ctl_elem_tlv_command(snd_ctl_t *ctl, const snd_ctl_elem_id_t *id,
1146 const unsigned int *tlv)
1147 {
1148 assert(ctl && id && (id->name[0] || id->numid) && tlv);
1149 return snd_ctl_tlv_do(ctl, -1, id, (unsigned int *)tlv,
1150 tlv[SNDRV_CTL_TLVO_LEN] + 2 * sizeof(unsigned int));
1151 }
1152
1153 /**
1154 * \brief Lock CTL element
1155 * \param ctl CTL handle
1156 * \param id CTL element id pointer
1157 * \return 0 on success otherwise a negative error code
1158 */
snd_ctl_elem_lock(snd_ctl_t * ctl,snd_ctl_elem_id_t * id)1159 int snd_ctl_elem_lock(snd_ctl_t *ctl, snd_ctl_elem_id_t *id)
1160 {
1161 assert(ctl && id);
1162 return ctl->ops->element_lock(ctl, id);
1163 }
1164
1165 /**
1166 * \brief Unlock CTL element
1167 * \param ctl CTL handle
1168 * \param id CTL element id pointer
1169 * \return 0 on success otherwise a negative error code
1170 */
snd_ctl_elem_unlock(snd_ctl_t * ctl,snd_ctl_elem_id_t * id)1171 int snd_ctl_elem_unlock(snd_ctl_t *ctl, snd_ctl_elem_id_t *id)
1172 {
1173 assert(ctl && id);
1174 return ctl->ops->element_unlock(ctl, id);
1175 }
1176
1177 /**
1178 * \brief Get next hardware dependent device number
1179 * \param ctl CTL handle
1180 * \param device current device on entry and next device on return
1181 * \return 0 on success otherwise a negative error code
1182 */
snd_ctl_hwdep_next_device(snd_ctl_t * ctl,int * device)1183 int snd_ctl_hwdep_next_device(snd_ctl_t *ctl, int *device)
1184 {
1185 assert(ctl && device);
1186 return ctl->ops->hwdep_next_device(ctl, device);
1187 }
1188
1189 /**
1190 * \brief Get info about a hardware dependent device
1191 * \param ctl CTL handle
1192 * \param info Hardware dependent device id/info pointer
1193 * \return 0 on success otherwise a negative error code
1194 */
snd_ctl_hwdep_info(snd_ctl_t * ctl,snd_hwdep_info_t * info)1195 int snd_ctl_hwdep_info(snd_ctl_t *ctl, snd_hwdep_info_t * info)
1196 {
1197 assert(ctl && info);
1198 return ctl->ops->hwdep_info(ctl, info);
1199 }
1200
1201 /**
1202 * \brief Get next PCM device number
1203 * \param ctl CTL handle
1204 * \param device current device on entry and next device on return
1205 * \return 0 on success otherwise a negative error code
1206 */
snd_ctl_pcm_next_device(snd_ctl_t * ctl,int * device)1207 int snd_ctl_pcm_next_device(snd_ctl_t *ctl, int * device)
1208 {
1209 assert(ctl && device);
1210 return ctl->ops->pcm_next_device(ctl, device);
1211 }
1212
1213 /**
1214 * \brief Get info about a PCM device
1215 * \param ctl CTL handle
1216 * \param info PCM device id/info pointer
1217 * \return 0 on success otherwise a negative error code
1218 */
snd_ctl_pcm_info(snd_ctl_t * ctl,snd_pcm_info_t * info)1219 int snd_ctl_pcm_info(snd_ctl_t *ctl, snd_pcm_info_t * info)
1220 {
1221 assert(ctl && info);
1222 return ctl->ops->pcm_info(ctl, info);
1223 }
1224
1225 /**
1226 * \brief Set preferred PCM subdevice number of successive PCM open
1227 * \param ctl CTL handle
1228 * \param subdev Preferred PCM subdevice number
1229 * \return 0 on success otherwise a negative error code
1230 */
snd_ctl_pcm_prefer_subdevice(snd_ctl_t * ctl,int subdev)1231 int snd_ctl_pcm_prefer_subdevice(snd_ctl_t *ctl, int subdev)
1232 {
1233 assert(ctl);
1234 return ctl->ops->pcm_prefer_subdevice(ctl, subdev);
1235 }
1236
1237 /**
1238 * \brief Get next RawMidi device number
1239 * \param ctl CTL handle
1240 * \param device current device on entry and next device on return
1241 * \return 0 on success otherwise a negative error code
1242 */
snd_ctl_rawmidi_next_device(snd_ctl_t * ctl,int * device)1243 int snd_ctl_rawmidi_next_device(snd_ctl_t *ctl, int * device)
1244 {
1245 assert(ctl && device);
1246 return ctl->ops->rawmidi_next_device(ctl, device);
1247 }
1248
1249 /**
1250 * \brief Get info about a RawMidi device
1251 * \param ctl CTL handle
1252 * \param info RawMidi device id/info pointer
1253 * \return 0 on success otherwise a negative error code
1254 */
snd_ctl_rawmidi_info(snd_ctl_t * ctl,snd_rawmidi_info_t * info)1255 int snd_ctl_rawmidi_info(snd_ctl_t *ctl, snd_rawmidi_info_t * info)
1256 {
1257 assert(ctl && info);
1258 return ctl->ops->rawmidi_info(ctl, info);
1259 }
1260
1261 /**
1262 * \brief Set preferred RawMidi subdevice number of successive RawMidi open
1263 * \param ctl CTL handle
1264 * \param subdev Preferred RawMidi subdevice number
1265 * \return 0 on success otherwise a negative error code
1266 */
snd_ctl_rawmidi_prefer_subdevice(snd_ctl_t * ctl,int subdev)1267 int snd_ctl_rawmidi_prefer_subdevice(snd_ctl_t *ctl, int subdev)
1268 {
1269 assert(ctl);
1270 return ctl->ops->rawmidi_prefer_subdevice(ctl, subdev);
1271 }
1272
1273 /**
1274 * \brief Get next UMP device number
1275 * \param ctl CTL handle
1276 * \param device current device on entry and next device on return
1277 * \return 0 on success otherwise a negative error code
1278 */
snd_ctl_ump_next_device(snd_ctl_t * ctl,int * device)1279 int snd_ctl_ump_next_device(snd_ctl_t *ctl, int *device)
1280 {
1281 assert(ctl && device);
1282 if (ctl->ops->ump_next_device)
1283 return ctl->ops->ump_next_device(ctl, device);
1284 return -ENXIO;
1285 }
1286
1287 /**
1288 * \brief Get UMP Endpoint info about a UMP RawMidi device
1289 * \param ctl CTL handle
1290 * \param info UMP Endpoint info pointer
1291 * \return 0 on success otherwise a negative error code
1292 */
snd_ctl_ump_endpoint_info(snd_ctl_t * ctl,snd_ump_endpoint_info_t * info)1293 int snd_ctl_ump_endpoint_info(snd_ctl_t *ctl, snd_ump_endpoint_info_t *info)
1294 {
1295 assert(ctl && info);
1296 return ctl->ops->ump_endpoint_info(ctl, info);
1297 }
1298
1299 /**
1300 * \brief Get UMP Block info about a UMP RawMidi device
1301 * \param ctl CTL handle
1302 * \param info UMP Block info pointer
1303 * \return 0 on success otherwise a negative error code
1304 */
snd_ctl_ump_block_info(snd_ctl_t * ctl,snd_ump_block_info_t * info)1305 int snd_ctl_ump_block_info(snd_ctl_t *ctl, snd_ump_block_info_t *info)
1306 {
1307 assert(ctl && info);
1308 return ctl->ops->ump_block_info(ctl, info);
1309 }
1310
1311 /**
1312 * \brief Set Power State to given SND_CTL_POWER_* value and do the power management
1313 * \param ctl CTL handle
1314 * \param state Desired Power State
1315 * \return 0 on success otherwise a negative error code
1316 */
snd_ctl_set_power_state(snd_ctl_t * ctl,unsigned int state)1317 int snd_ctl_set_power_state(snd_ctl_t *ctl, unsigned int state)
1318 {
1319 assert(ctl);
1320 if (ctl->ops->set_power_state)
1321 return ctl->ops->set_power_state(ctl, state);
1322 return -ENXIO;
1323 }
1324
1325 /**
1326 * \brief Get actual Power State
1327 * \param ctl CTL handle
1328 * \param state Destination value
1329 * \return 0 on success otherwise a negative error code
1330 */
snd_ctl_get_power_state(snd_ctl_t * ctl,unsigned int * state)1331 int snd_ctl_get_power_state(snd_ctl_t *ctl, unsigned int *state)
1332 {
1333 assert(ctl);
1334 if (ctl->ops->get_power_state)
1335 return ctl->ops->get_power_state(ctl, state);
1336 return -ENXIO;
1337 }
1338
1339 /**
1340 * \brief Read an event
1341 * \param ctl CTL handle
1342 * \param event Event pointer
1343 * \return number of events read otherwise a negative error code on failure
1344 */
snd_ctl_read(snd_ctl_t * ctl,snd_ctl_event_t * event)1345 int snd_ctl_read(snd_ctl_t *ctl, snd_ctl_event_t *event)
1346 {
1347 assert(ctl && event);
1348 return (ctl->ops->read)(ctl, event);
1349 }
1350
1351 /**
1352 * \brief Wait for a CTL to become ready (i.e. at least one event pending)
1353 * \param ctl CTL handle
1354 * \param timeout maximum time in milliseconds to wait
1355 * \return 0 otherwise a negative error code on failure
1356 */
snd_ctl_wait(snd_ctl_t * ctl,int timeout)1357 int snd_ctl_wait(snd_ctl_t *ctl, int timeout)
1358 {
1359 struct pollfd *pfd;
1360 unsigned short revents;
1361 int npfds, err, err_poll;
1362
1363 npfds = snd_ctl_poll_descriptors_count(ctl);
1364 if (npfds <= 0 || npfds >= 16) {
1365 SNDERR("Invalid poll_fds %d", npfds);
1366 return -EIO;
1367 }
1368 pfd = alloca(sizeof(*pfd) * npfds);
1369 err = snd_ctl_poll_descriptors(ctl, pfd, npfds);
1370 if (err < 0)
1371 return err;
1372 if (err != npfds) {
1373 SNDMSG("invalid poll descriptors %d", err);
1374 return -EIO;
1375 }
1376 for (;;) {
1377 err_poll = poll(pfd, npfds, timeout);
1378 if (err_poll < 0)
1379 return -errno;
1380 if (! err_poll)
1381 return 0;
1382 err = snd_ctl_poll_descriptors_revents(ctl, pfd, npfds, &revents);
1383 if (err < 0)
1384 return err;
1385 if (revents & (POLLERR | POLLNVAL))
1386 return -EIO;
1387 if (revents & (POLLIN | POLLOUT))
1388 return 1;
1389 }
1390 }
1391
1392 /**
1393 * \brief Add an async handler for a CTL
1394 * \param handler Returned handler handle
1395 * \param ctl CTL handle
1396 * \param callback Callback function
1397 * \param private_data Callback private data
1398 * \return 0 otherwise a negative error code on failure
1399 */
snd_async_add_ctl_handler(snd_async_handler_t ** handler,snd_ctl_t * ctl,snd_async_callback_t callback,void * private_data)1400 int snd_async_add_ctl_handler(snd_async_handler_t **handler, snd_ctl_t *ctl,
1401 snd_async_callback_t callback, void *private_data)
1402 {
1403 int err;
1404 int was_empty;
1405 snd_async_handler_t *h;
1406 err = snd_async_add_handler(&h, _snd_ctl_async_descriptor(ctl),
1407 callback, private_data);
1408 if (err < 0)
1409 return err;
1410 h->type = SND_ASYNC_HANDLER_CTL;
1411 h->u.ctl = ctl;
1412 was_empty = list_empty(&ctl->async_handlers);
1413 list_add_tail(&h->hlist, &ctl->async_handlers);
1414 if (was_empty) {
1415 err = snd_ctl_async(ctl, snd_async_handler_get_signo(h), getpid());
1416 if (err < 0) {
1417 snd_async_del_handler(h);
1418 return err;
1419 }
1420 }
1421 *handler = h;
1422 return 0;
1423 }
1424
1425 /**
1426 * \brief Return CTL handle related to an async handler
1427 * \param handler Async handler handle
1428 * \return CTL handle
1429 */
snd_async_handler_get_ctl(snd_async_handler_t * handler)1430 snd_ctl_t *snd_async_handler_get_ctl(snd_async_handler_t *handler)
1431 {
1432 assert(handler->type == SND_ASYNC_HANDLER_CTL);
1433 return handler->u.ctl;
1434 }
1435
1436 static const char *const build_in_ctls[] = {
1437 "hw", "empty", "remap", "shm", NULL
1438 };
1439
snd_ctl_open_conf(snd_ctl_t ** ctlp,const char * name,snd_config_t * ctl_root,snd_config_t * ctl_conf,int mode)1440 static int snd_ctl_open_conf(snd_ctl_t **ctlp, const char *name,
1441 snd_config_t *ctl_root, snd_config_t *ctl_conf, int mode)
1442 {
1443 const char *str;
1444 char *buf = NULL, *buf1 = NULL;
1445 int err;
1446 snd_config_t *conf, *type_conf = NULL;
1447 snd_config_iterator_t i, next;
1448 const char *lib = NULL, *open_name = NULL;
1449 const char *id;
1450 int (*open_func)(snd_ctl_t **, const char *, snd_config_t *, snd_config_t *, int) = NULL;
1451 #ifndef PIC
1452 extern void *snd_control_open_symbols(void);
1453 #endif
1454 if (snd_config_get_type(ctl_conf) != SND_CONFIG_TYPE_COMPOUND) {
1455 if (name)
1456 SNDERR("Invalid type for CTL %s definition", name);
1457 else
1458 SNDERR("Invalid type for CTL definition");
1459 return -EINVAL;
1460 }
1461 err = snd_config_search(ctl_conf, "type", &conf);
1462 if (err < 0) {
1463 SNDERR("type is not defined");
1464 return err;
1465 }
1466 err = snd_config_get_id(conf, &id);
1467 if (err < 0) {
1468 SNDERR("unable to get id");
1469 return err;
1470 }
1471 err = snd_config_get_string(conf, &str);
1472 if (err < 0) {
1473 SNDERR("Invalid type for %s", id);
1474 return err;
1475 }
1476 err = snd_config_search_definition(ctl_root, "ctl_type", str, &type_conf);
1477 if (err >= 0) {
1478 if (snd_config_get_type(type_conf) != SND_CONFIG_TYPE_COMPOUND) {
1479 SNDERR("Invalid type for CTL type %s definition", str);
1480 err = -EINVAL;
1481 goto _err;
1482 }
1483 snd_config_for_each(i, next, type_conf) {
1484 snd_config_t *n = snd_config_iterator_entry(i);
1485 const char *id;
1486 if (snd_config_get_id(n, &id) < 0)
1487 continue;
1488 if (strcmp(id, "comment") == 0)
1489 continue;
1490 if (strcmp(id, "lib") == 0) {
1491 err = snd_config_get_string(n, &lib);
1492 if (err < 0) {
1493 SNDERR("Invalid type for %s", id);
1494 goto _err;
1495 }
1496 continue;
1497 }
1498 if (strcmp(id, "open") == 0) {
1499 err = snd_config_get_string(n, &open_name);
1500 if (err < 0) {
1501 SNDERR("Invalid type for %s", id);
1502 goto _err;
1503 }
1504 continue;
1505 }
1506 SNDERR("Unknown field %s", id);
1507 err = -EINVAL;
1508 goto _err;
1509 }
1510 }
1511 if (!open_name) {
1512 buf = malloc(strlen(str) + 32);
1513 if (buf == NULL) {
1514 err = -ENOMEM;
1515 goto _err;
1516 }
1517 open_name = buf;
1518 sprintf(buf, "_snd_ctl_%s_open", str);
1519 }
1520 if (!lib) {
1521 const char *const *build_in = build_in_ctls;
1522 while (*build_in) {
1523 if (!strcmp(*build_in, str))
1524 break;
1525 build_in++;
1526 }
1527 if (*build_in == NULL) {
1528 buf1 = malloc(strlen(str) + 32);
1529 if (buf1 == NULL) {
1530 err = -ENOMEM;
1531 goto _err;
1532 }
1533 lib = buf1;
1534 sprintf(buf1, "libasound_module_ctl_%s.so", str);
1535 }
1536 }
1537 #ifndef PIC
1538 snd_control_open_symbols();
1539 #endif
1540 open_func = snd_dlobj_cache_get(lib, open_name,
1541 SND_DLSYM_VERSION(SND_CONTROL_DLSYM_VERSION), 1);
1542 if (open_func) {
1543 err = open_func(ctlp, name, ctl_root, ctl_conf, mode);
1544 if (err >= 0) {
1545 (*ctlp)->open_func = open_func;
1546 err = 0;
1547 } else {
1548 snd_dlobj_cache_put(open_func);
1549 }
1550 } else {
1551 err = -ENXIO;
1552 }
1553 _err:
1554 if (type_conf)
1555 snd_config_delete(type_conf);
1556 free(buf);
1557 free(buf1);
1558 return err;
1559 }
1560
snd_ctl_open_noupdate(snd_ctl_t ** ctlp,snd_config_t * root,const char * name,int mode,int hop)1561 static int snd_ctl_open_noupdate(snd_ctl_t **ctlp, snd_config_t *root,
1562 const char *name, int mode, int hop)
1563 {
1564 int err;
1565 snd_config_t *ctl_conf;
1566 const char *str;
1567
1568 err = snd_config_search_definition(root, "ctl", name, &ctl_conf);
1569 if (err < 0) {
1570 SNDERR("Invalid CTL %s", name);
1571 return err;
1572 }
1573 if (snd_config_get_string(ctl_conf, &str) >= 0)
1574 err = snd_ctl_open_noupdate(ctlp, root, str, mode, hop + 1);
1575 else {
1576 snd_config_set_hop(ctl_conf, hop);
1577 err = snd_ctl_open_conf(ctlp, name, root, ctl_conf, mode);
1578 }
1579 snd_config_delete(ctl_conf);
1580 return err;
1581 }
1582
1583 #ifndef DOC_HIDDEN
_snd_ctl_open_named_child(snd_ctl_t ** pctl,const char * name,snd_config_t * root,snd_config_t * conf,int mode,snd_config_t * parent_conf)1584 int _snd_ctl_open_named_child(snd_ctl_t **pctl, const char *name,
1585 snd_config_t *root, snd_config_t *conf,
1586 int mode, snd_config_t *parent_conf)
1587 {
1588 const char *str;
1589 int hop;
1590
1591 if ((hop = snd_config_check_hop(parent_conf)) < 0)
1592 return hop;
1593 if (snd_config_get_string(conf, &str) >= 0)
1594 return snd_ctl_open_noupdate(pctl, root, str, mode, hop + 1);
1595 return snd_ctl_open_conf(pctl, name, root, conf, mode);
1596 }
1597 #endif
1598
1599 /**
1600 * \brief Opens a sound card.
1601 *
1602 * \param ctlp Returned CTL handle.
1603 * \param name A string identifying the card (See \ref control_cards_id).
1604 * \param mode Open mode (see #SND_CTL_NONBLOCK, #SND_CTL_ASYNC).
1605 *
1606 * \return 0 on success otherwise a negative error code.
1607 */
snd_ctl_open(snd_ctl_t ** ctlp,const char * name,int mode)1608 int snd_ctl_open(snd_ctl_t **ctlp, const char *name, int mode)
1609 {
1610 snd_config_t *top;
1611 int err;
1612
1613 assert(ctlp && name);
1614 if (_snd_is_ucm_device(name)) {
1615 name = uc_mgr_alibcfg_by_device(&top, name);
1616 if (name == NULL)
1617 return -ENODEV;
1618 } else {
1619 err = snd_config_update_ref(&top);
1620 if (err < 0)
1621 return err;
1622 }
1623 err = snd_ctl_open_noupdate(ctlp, top, name, mode, 0);
1624 snd_config_unref(top);
1625 return err;
1626 }
1627
1628 /**
1629 * \brief Opens a CTL using local configuration
1630 * \param ctlp Returned CTL handle
1631 * \param name ASCII identifier of the CTL handle
1632 * \param mode Open mode (see #SND_CTL_NONBLOCK, #SND_CTL_ASYNC)
1633 * \param lconf Local configuration
1634 * \return 0 on success otherwise a negative error code
1635 */
snd_ctl_open_lconf(snd_ctl_t ** ctlp,const char * name,int mode,snd_config_t * lconf)1636 int snd_ctl_open_lconf(snd_ctl_t **ctlp, const char *name,
1637 int mode, snd_config_t *lconf)
1638 {
1639 assert(ctlp && name && lconf);
1640 return snd_ctl_open_noupdate(ctlp, lconf, name, mode, 0);
1641 }
1642
1643 /**
1644 * \brief Opens a fallback CTL
1645 * \param ctlp Returned CTL handle
1646 * \param root Configuration root
1647 * \param name ASCII identifier of the CTL handle used as fallback
1648 * \param orig_name The original ASCII name
1649 * \param mode Open mode (see #SND_CTL_NONBLOCK, #SND_CTL_ASYNC)
1650 * \return 0 on success otherwise a negative error code
1651 */
snd_ctl_open_fallback(snd_ctl_t ** ctlp,snd_config_t * root,const char * name,const char * orig_name,int mode)1652 int snd_ctl_open_fallback(snd_ctl_t **ctlp, snd_config_t *root,
1653 const char *name, const char *orig_name, int mode)
1654 {
1655 int err;
1656 assert(ctlp && name && root);
1657 err = snd_ctl_open_noupdate(ctlp, root, name, mode, 0);
1658 if (err >= 0) {
1659 free((*ctlp)->name);
1660 (*ctlp)->name = orig_name ? strdup(orig_name) : NULL;
1661 }
1662 return err;
1663 }
1664
1665 #ifndef DOC_HIDDEN
1666 #define TYPE(v) [SND_CTL_ELEM_TYPE_##v] = #v
1667 #define IFACE(v) [SND_CTL_ELEM_IFACE_##v] = #v
1668 #define IFACE1(v, n) [SND_CTL_ELEM_IFACE_##v] = #n
1669 #define EVENT(v) [SND_CTL_EVENT_##v] = #v
1670
1671 static const char *const snd_ctl_elem_type_names[] = {
1672 TYPE(NONE),
1673 TYPE(BOOLEAN),
1674 TYPE(INTEGER),
1675 TYPE(ENUMERATED),
1676 TYPE(BYTES),
1677 TYPE(IEC958),
1678 TYPE(INTEGER64),
1679 };
1680
1681 static const char *const snd_ctl_elem_iface_names[] = {
1682 IFACE(CARD),
1683 IFACE(HWDEP),
1684 IFACE(MIXER),
1685 IFACE(PCM),
1686 IFACE(RAWMIDI),
1687 IFACE(TIMER),
1688 IFACE(SEQUENCER),
1689 };
1690
1691 static const char *const snd_ctl_event_type_names[] = {
1692 EVENT(ELEM),
1693 };
1694 #endif
1695
1696 /**
1697 * \brief get name of a CTL element type
1698 * \param type CTL element type
1699 * \return ascii name of CTL element type
1700 */
snd_ctl_elem_type_name(snd_ctl_elem_type_t type)1701 const char *snd_ctl_elem_type_name(snd_ctl_elem_type_t type)
1702 {
1703 assert(type <= SND_CTL_ELEM_TYPE_LAST);
1704 return snd_ctl_elem_type_names[type];
1705 }
1706
1707 /**
1708 * \brief get name of a CTL element related interface
1709 * \param iface CTL element related interface
1710 * \return ascii name of CTL element related interface
1711 */
snd_ctl_elem_iface_name(snd_ctl_elem_iface_t iface)1712 const char *snd_ctl_elem_iface_name(snd_ctl_elem_iface_t iface)
1713 {
1714 assert(iface <= SND_CTL_ELEM_IFACE_LAST);
1715 return snd_ctl_elem_iface_names[iface];
1716 }
1717
1718 /**
1719 * \brief get name of a CTL event type
1720 * \param type CTL event type
1721 * \return ascii name of CTL event type
1722 */
snd_ctl_event_type_name(snd_ctl_event_type_t type)1723 const char *snd_ctl_event_type_name(snd_ctl_event_type_t type)
1724 {
1725 assert(type <= SND_CTL_EVENT_LAST);
1726 return snd_ctl_event_type_names[type];
1727 }
1728
1729 /**
1730 * \brief allocate space for CTL element identifiers list
1731 *
1732 * The space can be released with snd_ctl_elem_list_free_space().
1733 *
1734 * \param obj CTL element identifiers list.
1735 * \param entries How many entries to allocate. See
1736 * #snd_ctl_elem_list_t to learn how to obtain
1737 * this number in advance.
1738 * \return 0 on success otherwise a negative error code.
1739 */
snd_ctl_elem_list_alloc_space(snd_ctl_elem_list_t * obj,unsigned int entries)1740 int snd_ctl_elem_list_alloc_space(snd_ctl_elem_list_t *obj, unsigned int entries)
1741 {
1742 free(obj->pids);
1743 obj->pids = calloc(entries, sizeof(*obj->pids));
1744 if (!obj->pids) {
1745 obj->space = 0;
1746 return -ENOMEM;
1747 }
1748 obj->space = entries;
1749 return 0;
1750 }
1751
1752 /**
1753 * \brief free previously allocated space for CTL element identifiers list
1754 *
1755 * Releases space previously allocated using
1756 * snd_ctl_elem_list_alloc_space().
1757 *
1758 * \param obj CTL element identifiers list
1759 */
snd_ctl_elem_list_free_space(snd_ctl_elem_list_t * obj)1760 void snd_ctl_elem_list_free_space(snd_ctl_elem_list_t *obj)
1761 {
1762 free(obj->pids);
1763 obj->pids = NULL;
1764 obj->space = 0;
1765 }
1766
1767 /**
1768 * \brief Get event mask for an element related event
1769 * \param obj CTL event
1770 * \return event mask for element related event
1771 */
snd_ctl_event_elem_get_mask(const snd_ctl_event_t * obj)1772 unsigned int snd_ctl_event_elem_get_mask(const snd_ctl_event_t *obj)
1773 {
1774 assert(obj);
1775 assert(obj->type == SND_CTL_EVENT_ELEM);
1776 return obj->data.elem.mask;
1777 }
1778
1779 /**
1780 * \brief Get CTL element identifier for an element related event
1781 * \param obj CTL event
1782 * \param ptr Pointer to returned CTL element identifier
1783 */
snd_ctl_event_elem_get_id(const snd_ctl_event_t * obj,snd_ctl_elem_id_t * ptr)1784 void snd_ctl_event_elem_get_id(const snd_ctl_event_t *obj, snd_ctl_elem_id_t *ptr)
1785 {
1786 assert(obj && ptr);
1787 assert(obj->type == SND_CTL_EVENT_ELEM);
1788 *ptr = obj->data.elem.id;
1789 }
1790
1791 /**
1792 * \brief Get element numeric identifier for an element related event
1793 * \param obj CTL event
1794 * \return element numeric identifier
1795 */
snd_ctl_event_elem_get_numid(const snd_ctl_event_t * obj)1796 unsigned int snd_ctl_event_elem_get_numid(const snd_ctl_event_t *obj)
1797 {
1798 assert(obj);
1799 assert(obj->type == SND_CTL_EVENT_ELEM);
1800 return obj->data.elem.id.numid;
1801 }
1802
1803 /**
1804 * \brief Get interface part of CTL element identifier for an element related event
1805 * \param obj CTL event
1806 * \return interface part of element identifier
1807 */
snd_ctl_event_elem_get_interface(const snd_ctl_event_t * obj)1808 snd_ctl_elem_iface_t snd_ctl_event_elem_get_interface(const snd_ctl_event_t *obj)
1809 {
1810 assert(obj);
1811 assert(obj->type == SND_CTL_EVENT_ELEM);
1812 return obj->data.elem.id.iface;
1813 }
1814
1815 /**
1816 * \brief Get device part of CTL element identifier for an element related event
1817 * \param obj CTL event
1818 * \return device part of element identifier
1819 */
snd_ctl_event_elem_get_device(const snd_ctl_event_t * obj)1820 unsigned int snd_ctl_event_elem_get_device(const snd_ctl_event_t *obj)
1821 {
1822 assert(obj);
1823 assert(obj->type == SND_CTL_EVENT_ELEM);
1824 return obj->data.elem.id.device;
1825 }
1826
1827 /**
1828 * \brief Get subdevice part of CTL element identifier for an element related event
1829 * \param obj CTL event
1830 * \return subdevice part of element identifier
1831 */
snd_ctl_event_elem_get_subdevice(const snd_ctl_event_t * obj)1832 unsigned int snd_ctl_event_elem_get_subdevice(const snd_ctl_event_t *obj)
1833 {
1834 assert(obj);
1835 assert(obj->type == SND_CTL_EVENT_ELEM);
1836 return obj->data.elem.id.subdevice;
1837 }
1838
1839 /**
1840 * \brief Get name part of CTL element identifier for an element related event
1841 * \param obj CTL event
1842 * \return name part of element identifier
1843 */
snd_ctl_event_elem_get_name(const snd_ctl_event_t * obj)1844 const char *snd_ctl_event_elem_get_name(const snd_ctl_event_t *obj)
1845 {
1846 assert(obj);
1847 assert(obj->type == SND_CTL_EVENT_ELEM);
1848 return (const char *)obj->data.elem.id.name;
1849 }
1850
1851 /**
1852 * \brief Get index part of CTL element identifier for an element related event
1853 * \param obj CTL event
1854 * \return index part of element identifier
1855 */
snd_ctl_event_elem_get_index(const snd_ctl_event_t * obj)1856 unsigned int snd_ctl_event_elem_get_index(const snd_ctl_event_t *obj)
1857 {
1858 assert(obj);
1859 assert(obj->type == SND_CTL_EVENT_ELEM);
1860 return obj->data.elem.id.index;
1861 }
1862
1863 #ifndef DOC_HIDDEN
_snd_ctl_poll_descriptor(snd_ctl_t * ctl)1864 int _snd_ctl_poll_descriptor(snd_ctl_t *ctl)
1865 {
1866 assert(ctl);
1867 return ctl->poll_fd;
1868 }
1869 #endif
1870
1871 /**
1872 * \brief get size of #snd_ctl_elem_id_t
1873 * \return size in bytes
1874 */
snd_ctl_elem_id_sizeof()1875 size_t snd_ctl_elem_id_sizeof()
1876 {
1877 return sizeof(snd_ctl_elem_id_t);
1878 }
1879
1880 /**
1881 * \brief allocate an invalid #snd_ctl_elem_id_t using standard malloc
1882 * \param ptr returned pointer
1883 * \return 0 on success otherwise negative error code
1884 */
snd_ctl_elem_id_malloc(snd_ctl_elem_id_t ** ptr)1885 int snd_ctl_elem_id_malloc(snd_ctl_elem_id_t **ptr)
1886 {
1887 assert(ptr);
1888 *ptr = calloc(1, sizeof(snd_ctl_elem_id_t));
1889 if (!*ptr)
1890 return -ENOMEM;
1891 return 0;
1892 }
1893
1894 /**
1895 * \brief frees a previously allocated #snd_ctl_elem_id_t
1896 * \param obj pointer to object to free
1897 */
snd_ctl_elem_id_free(snd_ctl_elem_id_t * obj)1898 void snd_ctl_elem_id_free(snd_ctl_elem_id_t *obj)
1899 {
1900 free(obj);
1901 }
1902
1903 /**
1904 * \brief clear given #snd_ctl_elem_id_t object
1905 * \param obj pointer to object to clear
1906 */
snd_ctl_elem_id_clear(snd_ctl_elem_id_t * obj)1907 void snd_ctl_elem_id_clear(snd_ctl_elem_id_t *obj)
1908 {
1909 memset(obj, 0, sizeof(snd_ctl_elem_id_t));
1910 }
1911
1912 /**
1913 * \brief copy one #snd_ctl_elem_id_t to another
1914 * \param dst pointer to destination
1915 * \param src pointer to source
1916 */
snd_ctl_elem_id_copy(snd_ctl_elem_id_t * dst,const snd_ctl_elem_id_t * src)1917 void snd_ctl_elem_id_copy(snd_ctl_elem_id_t *dst, const snd_ctl_elem_id_t *src)
1918 {
1919 assert(dst && src);
1920 *dst = *src;
1921 }
1922
1923 /**
1924 * \brief compare one #snd_ctl_elem_id_t to another using numid
1925 * \param id1 pointer to first id
1926 * \param id2 pointer to second id
1927 * \retval zero when values are identical, other value on a difference (like strcmp)
1928 *
1929 * This comparison ignores the set of fields part.
1930 *
1931 * The return value can be used for sorting like qsort(). It gives persistent
1932 * results.
1933 */
snd_ctl_elem_id_compare_numid(const snd_ctl_elem_id_t * id1,const snd_ctl_elem_id_t * id2)1934 int snd_ctl_elem_id_compare_numid(const snd_ctl_elem_id_t *id1, const snd_ctl_elem_id_t *id2)
1935 {
1936 int64_t d;
1937
1938 assert(id1 && id2);
1939 d = (int64_t)id1->numid - (int64_t)id2->numid;
1940 if (d & ((int64_t)INT_MAX + 1)) { /* fast path */
1941 if (d > INT_MAX)
1942 d = INT_MAX;
1943 else if (d < INT_MIN)
1944 d = INT_MIN;
1945 }
1946 return d;
1947 }
1948
1949 /**
1950 * \brief compare one #snd_ctl_elem_id_t to another
1951 * \param id1 pointer to first id
1952 * \param id2 pointer to second id
1953 * \retval zero when values are identical, other value on a difference (like strcmp)
1954 *
1955 * This comparison ignores the numid part. The numid comparison can be easily
1956 * implemented using snd_ctl_elem_id_get_numid() calls.
1957 *
1958 * The identifier set fields are compared in this order: interface, device,
1959 * subdevice, name, index.
1960 *
1961 * The return value can be used for sorting like qsort(). It gives persistent
1962 * results.
1963 */
snd_ctl_elem_id_compare_set(const snd_ctl_elem_id_t * id1,const snd_ctl_elem_id_t * id2)1964 int snd_ctl_elem_id_compare_set(const snd_ctl_elem_id_t *id1, const snd_ctl_elem_id_t *id2)
1965 {
1966 int d;
1967
1968 assert(id1 && id2);
1969 /* although those values are unsigned integer, practically, */
1970 /* the useable limit is really much lower */
1971 assert((id1->iface | id1->device | id1->subdevice | id1->index) <= INT_MAX);
1972 assert((id2->iface | id2->device | id2->subdevice | id1->index) <= INT_MAX);
1973 d = id1->iface - id2->iface;
1974 if (d != 0)
1975 return d;
1976 d = id1->device - id2->device;
1977 if (d != 0)
1978 return d;
1979 d = id1->subdevice - id2->subdevice;
1980 if (d != 0)
1981 return d;
1982 d = strcmp((const char *)id1->name, (const char *)id2->name);
1983 if (d != 0)
1984 return d;
1985 return id1->index - id2->index;
1986 }
1987
1988 /**
1989 * \brief Get numeric identifier from a CTL element identifier
1990 * \param obj CTL element identifier
1991 * \return CTL element numeric identifier
1992 */
snd_ctl_elem_id_get_numid(const snd_ctl_elem_id_t * obj)1993 unsigned int snd_ctl_elem_id_get_numid(const snd_ctl_elem_id_t *obj)
1994 {
1995 assert(obj);
1996 return obj->numid;
1997 }
1998
1999 /**
2000 * \brief Get interface part of a CTL element identifier
2001 * \param obj CTL element identifier
2002 * \return CTL element related interface
2003 */
snd_ctl_elem_id_get_interface(const snd_ctl_elem_id_t * obj)2004 snd_ctl_elem_iface_t snd_ctl_elem_id_get_interface(const snd_ctl_elem_id_t *obj)
2005 {
2006 assert(obj);
2007 return obj->iface;
2008 }
2009
2010 /**
2011 * \brief Get device part of a CTL element identifier
2012 * \param obj CTL element identifier
2013 * \return CTL element related device
2014 */
snd_ctl_elem_id_get_device(const snd_ctl_elem_id_t * obj)2015 unsigned int snd_ctl_elem_id_get_device(const snd_ctl_elem_id_t *obj)
2016 {
2017 assert(obj);
2018 return obj->device;
2019 }
2020
2021 /**
2022 * \brief Get subdevice part of a CTL element identifier
2023 * \param obj CTL element identifier
2024 * \return CTL element related subdevice
2025 */
snd_ctl_elem_id_get_subdevice(const snd_ctl_elem_id_t * obj)2026 unsigned int snd_ctl_elem_id_get_subdevice(const snd_ctl_elem_id_t *obj)
2027 {
2028 assert(obj);
2029 return obj->subdevice;
2030 }
2031
2032 /**
2033 * \brief Get name part of a CTL element identifier
2034 * \param obj CTL element identifier
2035 * \return CTL element name
2036 */
snd_ctl_elem_id_get_name(const snd_ctl_elem_id_t * obj)2037 const char *snd_ctl_elem_id_get_name(const snd_ctl_elem_id_t *obj)
2038 {
2039 assert(obj);
2040 return (const char *)obj->name;
2041 }
2042
2043 /**
2044 * \brief Get index part of a CTL element identifier
2045 * \param obj CTL element identifier
2046 * \return CTL element index
2047 */
snd_ctl_elem_id_get_index(const snd_ctl_elem_id_t * obj)2048 unsigned int snd_ctl_elem_id_get_index(const snd_ctl_elem_id_t *obj)
2049 {
2050 assert(obj);
2051 return obj->index;
2052 }
2053
2054 /**
2055 * \brief Set numeric identifier for a CTL element identifier
2056 * \param obj CTL element identifier
2057 * \param val CTL element numeric identifier
2058 */
snd_ctl_elem_id_set_numid(snd_ctl_elem_id_t * obj,unsigned int val)2059 void snd_ctl_elem_id_set_numid(snd_ctl_elem_id_t *obj, unsigned int val)
2060 {
2061 assert(obj);
2062 obj->numid = val;
2063 }
2064
2065 /**
2066 * \brief Set interface part for a CTL element identifier
2067 * \param obj CTL element identifier
2068 * \param val CTL element related interface
2069 */
snd_ctl_elem_id_set_interface(snd_ctl_elem_id_t * obj,snd_ctl_elem_iface_t val)2070 void snd_ctl_elem_id_set_interface(snd_ctl_elem_id_t *obj, snd_ctl_elem_iface_t val)
2071 {
2072 assert(obj);
2073 obj->iface = val;
2074 }
2075
2076 /**
2077 * \brief Set device part for a CTL element identifier
2078 * \param obj CTL element identifier
2079 * \param val CTL element related device
2080 */
snd_ctl_elem_id_set_device(snd_ctl_elem_id_t * obj,unsigned int val)2081 void snd_ctl_elem_id_set_device(snd_ctl_elem_id_t *obj, unsigned int val)
2082 {
2083 assert(obj);
2084 obj->device = val;
2085 }
2086
2087 /**
2088 * \brief Set subdevice part for a CTL element identifier
2089 * \param obj CTL element identifier
2090 * \param val CTL element related subdevice
2091 */
snd_ctl_elem_id_set_subdevice(snd_ctl_elem_id_t * obj,unsigned int val)2092 void snd_ctl_elem_id_set_subdevice(snd_ctl_elem_id_t *obj, unsigned int val)
2093 {
2094 assert(obj);
2095 obj->subdevice = val;
2096 }
2097
2098 /**
2099 * \brief Set name part for a CTL element identifier
2100 * \param obj CTL element identifier
2101 * \param val CTL element name
2102 */
snd_ctl_elem_id_set_name(snd_ctl_elem_id_t * obj,const char * val)2103 void snd_ctl_elem_id_set_name(snd_ctl_elem_id_t *obj, const char *val)
2104 {
2105 assert(obj);
2106 snd_strlcpy((char *)obj->name, val, sizeof(obj->name));
2107 }
2108
2109 /**
2110 * \brief Set index part for a CTL element identifier
2111 * \param obj CTL element identifier
2112 * \param val CTL element index
2113 */
snd_ctl_elem_id_set_index(snd_ctl_elem_id_t * obj,unsigned int val)2114 void snd_ctl_elem_id_set_index(snd_ctl_elem_id_t *obj, unsigned int val)
2115 {
2116 assert(obj);
2117 obj->index = val;
2118 }
2119
2120 /**
2121 * \brief get size of #snd_ctl_card_info_t.
2122 * \return Size in bytes.
2123 */
snd_ctl_card_info_sizeof()2124 size_t snd_ctl_card_info_sizeof()
2125 {
2126 return sizeof(snd_ctl_card_info_t);
2127 }
2128
2129 /**
2130 * \brief Allocate an invalid #snd_ctl_card_info_t on the heap.
2131 *
2132 * Allocate space for a card info object on the heap. The allocated memory
2133 * must be freed using snd_ctl_card_info_free().
2134 *
2135 * See snd_ctl_card_info_t for details.
2136 *
2137 * \param ptr Pointer to a snd_ctl_card_info_t pointer. The address
2138 * of the allocated space will be returned here.
2139 * \return 0 on success, otherwise a negative error code.
2140 */
snd_ctl_card_info_malloc(snd_ctl_card_info_t ** ptr)2141 int snd_ctl_card_info_malloc(snd_ctl_card_info_t **ptr)
2142 {
2143 assert(ptr);
2144 *ptr = calloc(1, sizeof(snd_ctl_card_info_t));
2145 if (!*ptr)
2146 return -ENOMEM;
2147 return 0;
2148 }
2149
2150 /**
2151 * \brief Free an #snd_ctl_card_info_t previously allocated using
2152 * snd_ctl_card_info_malloc().
2153 *
2154 * \param obj Pointer to the snd_ctl_card_info_t.
2155 */
snd_ctl_card_info_free(snd_ctl_card_info_t * obj)2156 void snd_ctl_card_info_free(snd_ctl_card_info_t *obj)
2157 {
2158 free(obj);
2159 }
2160
2161 /**
2162 * \brief Clear given card info object.
2163 *
2164 * See snd_ctl_elem_value_t for details.
2165 *
2166 * \param obj Card info object.
2167 */
snd_ctl_card_info_clear(snd_ctl_card_info_t * obj)2168 void snd_ctl_card_info_clear(snd_ctl_card_info_t *obj)
2169 {
2170 memset(obj, 0, sizeof(snd_ctl_card_info_t));
2171 }
2172
2173 /**
2174 * \brief Bitwise copy of a #snd_ctl_card_info_t object.
2175 *
2176 * \param dst Pointer to destination.
2177 * \param src Pointer to source.
2178 */
snd_ctl_card_info_copy(snd_ctl_card_info_t * dst,const snd_ctl_card_info_t * src)2179 void snd_ctl_card_info_copy(snd_ctl_card_info_t *dst, const snd_ctl_card_info_t *src)
2180 {
2181 assert(dst && src);
2182 *dst = *src;
2183 }
2184
2185 /**
2186 * \brief Get the sound card index from the given info object.
2187 *
2188 * See snd_ctl_card_info_t for more details.
2189 *
2190 * \param obj The card info object.
2191 * \return Sound card index.
2192 */
snd_ctl_card_info_get_card(const snd_ctl_card_info_t * obj)2193 int snd_ctl_card_info_get_card(const snd_ctl_card_info_t *obj)
2194 {
2195 assert(obj);
2196 return obj->card;
2197 }
2198
2199 /**
2200 * \brief Get the sound card ID from the given info object.
2201 *
2202 * See snd_ctl_card_info_t for more details.
2203 *
2204 * \param obj The card info object.
2205 * \return Sound card ID.
2206 */
snd_ctl_card_info_get_id(const snd_ctl_card_info_t * obj)2207 const char *snd_ctl_card_info_get_id(const snd_ctl_card_info_t *obj)
2208 {
2209 assert(obj);
2210 return (const char *)obj->id;
2211 }
2212
2213 /**
2214 * \brief Get the sound card driver from the given info object.
2215 *
2216 * See snd_ctl_card_info_t for more details.
2217 *
2218 * \param obj The card info object.
2219 * \return The sound card driver.
2220 */
snd_ctl_card_info_get_driver(const snd_ctl_card_info_t * obj)2221 const char *snd_ctl_card_info_get_driver(const snd_ctl_card_info_t *obj)
2222 {
2223 assert(obj);
2224 return (const char *)obj->driver;
2225 }
2226
2227 /**
2228 * \brief Get the sound card name from the given info object.
2229 *
2230 * See snd_ctl_card_info_t for more details.
2231 *
2232 * \param obj The card info object.
2233 * \return Sound card name.
2234 */
snd_ctl_card_info_get_name(const snd_ctl_card_info_t * obj)2235 const char *snd_ctl_card_info_get_name(const snd_ctl_card_info_t *obj)
2236 {
2237 assert(obj);
2238 return (const char *)obj->name;
2239 }
2240
2241 /**
2242 * \brief Get the sound cards long name from the given info object.
2243 *
2244 * See snd_ctl_card_info_t for more details.
2245 *
2246 * \param obj The card info object.
2247 * \return Sound cards long name.
2248 */
snd_ctl_card_info_get_longname(const snd_ctl_card_info_t * obj)2249 const char *snd_ctl_card_info_get_longname(const snd_ctl_card_info_t *obj)
2250 {
2251 assert(obj);
2252 return (const char *)obj->longname;
2253 }
2254
2255 /**
2256 * \brief Get the sound card mixer name from the given info object.
2257 *
2258 * See snd_ctl_card_info_t for more details.
2259 *
2260 * \param obj The card info object.
2261 * \return Sound card mixer name.
2262 */
snd_ctl_card_info_get_mixername(const snd_ctl_card_info_t * obj)2263 const char *snd_ctl_card_info_get_mixername(const snd_ctl_card_info_t *obj)
2264 {
2265 assert(obj);
2266 return (const char *)obj->mixername;
2267 }
2268
2269 /**
2270 * \brief Get the sound cards "components" property from the given info object.
2271 *
2272 * See snd_ctl_card_info_t for more details.
2273 *
2274 * \param obj The card info object.
2275 * \return Sound cards "components" property.
2276 */
snd_ctl_card_info_get_components(const snd_ctl_card_info_t * obj)2277 const char *snd_ctl_card_info_get_components(const snd_ctl_card_info_t *obj)
2278 {
2279 assert(obj);
2280 return (const char *)obj->components;
2281 }
2282
2283 /**
2284 * \brief get size of #snd_ctl_event_t
2285 * \return size in bytes
2286 */
snd_ctl_event_sizeof()2287 size_t snd_ctl_event_sizeof()
2288 {
2289 return sizeof(snd_ctl_event_t);
2290 }
2291
2292 /**
2293 * \brief allocate an invalid #snd_ctl_event_t using standard malloc
2294 * \param ptr returned pointer
2295 * \return 0 on success otherwise negative error code
2296 */
snd_ctl_event_malloc(snd_ctl_event_t ** ptr)2297 int snd_ctl_event_malloc(snd_ctl_event_t **ptr)
2298 {
2299 assert(ptr);
2300 *ptr = calloc(1, sizeof(snd_ctl_event_t));
2301 if (!*ptr)
2302 return -ENOMEM;
2303 return 0;
2304 }
2305
2306 /**
2307 * \brief frees a previously allocated #snd_ctl_event_t
2308 * \param obj pointer to object to free
2309 */
snd_ctl_event_free(snd_ctl_event_t * obj)2310 void snd_ctl_event_free(snd_ctl_event_t *obj)
2311 {
2312 free(obj);
2313 }
2314
2315 /**
2316 * \brief clear given #snd_ctl_event_t object
2317 * \param obj pointer to object to clear
2318 */
snd_ctl_event_clear(snd_ctl_event_t * obj)2319 void snd_ctl_event_clear(snd_ctl_event_t *obj)
2320 {
2321 memset(obj, 0, sizeof(snd_ctl_event_t));
2322 }
2323
2324 /**
2325 * \brief copy one #snd_ctl_event_t to another
2326 * \param dst pointer to destination
2327 * \param src pointer to source
2328 */
snd_ctl_event_copy(snd_ctl_event_t * dst,const snd_ctl_event_t * src)2329 void snd_ctl_event_copy(snd_ctl_event_t *dst, const snd_ctl_event_t *src)
2330 {
2331 assert(dst && src);
2332 *dst = *src;
2333 }
2334
2335 /**
2336 * \brief Get type of a CTL event
2337 * \param obj CTL event
2338 * \return CTL event type
2339 */
snd_ctl_event_get_type(const snd_ctl_event_t * obj)2340 snd_ctl_event_type_t snd_ctl_event_get_type(const snd_ctl_event_t *obj)
2341 {
2342 assert(obj);
2343 return obj->type;
2344 }
2345
2346 /**
2347 * \brief get size of #snd_ctl_elem_list_t.
2348 * \return size in bytes
2349 */
snd_ctl_elem_list_sizeof()2350 size_t snd_ctl_elem_list_sizeof()
2351 {
2352 return sizeof(snd_ctl_elem_list_t);
2353 }
2354
2355 /**
2356 * \brief allocate a #snd_ctl_elem_list_t using standard malloc.
2357 *
2358 * The memory can be released using snd_ctl_elem_list_free().
2359 *
2360 * \param ptr returned pointer
2361 * \return 0 on success otherwise negative error code
2362 */
snd_ctl_elem_list_malloc(snd_ctl_elem_list_t ** ptr)2363 int snd_ctl_elem_list_malloc(snd_ctl_elem_list_t **ptr)
2364 {
2365 assert(ptr);
2366 *ptr = calloc(1, sizeof(snd_ctl_elem_list_t));
2367 if (!*ptr)
2368 return -ENOMEM;
2369 return 0;
2370 }
2371
2372 /**
2373 * \brief frees a previously allocated #snd_ctl_elem_list_t.
2374 *
2375 * Release memory previously allocated using
2376 * snd_ctl_elem_list_malloc().
2377 *
2378 * If you used snd_ctl_elem_list_alloc_space() on the list, you must
2379 * use snd_ctl_elem_list_free_space() \em before calling this
2380 * function.
2381 *
2382 * \param obj pointer to object to free
2383 */
snd_ctl_elem_list_free(snd_ctl_elem_list_t * obj)2384 void snd_ctl_elem_list_free(snd_ctl_elem_list_t *obj)
2385 {
2386 free(obj);
2387 }
2388
2389 /**
2390 * \brief Clear given #snd_ctl_elem_list_t object.
2391 *
2392 * This will make the stored identifiers inaccessible without freeing
2393 * their space.
2394 *
2395 * \warning The element identifier space cannot be freed after calling
2396 * this function. Therefore, snd_ctl_elem_list_free_space()
2397 * must be called in advance.
2398 *
2399 * \param obj pointer to object to clear
2400 */
snd_ctl_elem_list_clear(snd_ctl_elem_list_t * obj)2401 void snd_ctl_elem_list_clear(snd_ctl_elem_list_t *obj)
2402 {
2403 memset(obj, 0, sizeof(snd_ctl_elem_list_t));
2404 }
2405
2406 /**
2407 * \brief copy one #snd_ctl_elem_list_t to another.
2408 *
2409 * This performs a shallow copy. That means the both lists will share
2410 * the same space for the elements. The elements will not be copied.
2411 *
2412 * \param dst pointer to destination
2413 * \param src pointer to source
2414 */
snd_ctl_elem_list_copy(snd_ctl_elem_list_t * dst,const snd_ctl_elem_list_t * src)2415 void snd_ctl_elem_list_copy(snd_ctl_elem_list_t *dst, const snd_ctl_elem_list_t *src)
2416 {
2417 assert(dst && src);
2418 *dst = *src;
2419 }
2420
2421 /**
2422 * \brief Set index of first wanted CTL element identifier in a CTL element identifiers list
2423 * \param obj CTL element identifiers list
2424 * \param val index of CTL element to put at position 0 of list
2425 */
snd_ctl_elem_list_set_offset(snd_ctl_elem_list_t * obj,unsigned int val)2426 void snd_ctl_elem_list_set_offset(snd_ctl_elem_list_t *obj, unsigned int val)
2427 {
2428 assert(obj);
2429 obj->offset = val;
2430 }
2431
2432 /**
2433 * \brief Get number of used entries in CTL element identifiers list
2434 *
2435 * This function returns how many entries are actually filled with
2436 * useful information.
2437 *
2438 * See also snd_ctl_elem_list_get_count().
2439 *
2440 * \param obj CTL element identifier list
2441 * \return number of used entries
2442 */
snd_ctl_elem_list_get_used(const snd_ctl_elem_list_t * obj)2443 unsigned int snd_ctl_elem_list_get_used(const snd_ctl_elem_list_t *obj)
2444 {
2445 assert(obj);
2446 return obj->used;
2447 }
2448
2449 /**
2450 * \brief Get total count of elements present in CTL device
2451 *
2452 * This function returns how many entries were allocated using
2453 * snd_ctl_elem_list_alloc_space(). This information is present after
2454 * snd_ctl_elem_list() was called.
2455 *
2456 * See also snd_ctl_elem_list_get_used().
2457 *
2458 * \param obj CTL element identifier list
2459 * \return total number of elements
2460 */
snd_ctl_elem_list_get_count(const snd_ctl_elem_list_t * obj)2461 unsigned int snd_ctl_elem_list_get_count(const snd_ctl_elem_list_t *obj)
2462 {
2463 assert(obj);
2464 return obj->count;
2465 }
2466
2467 /**
2468 * \brief Get CTL element identifier for an entry of a CTL element identifiers list
2469 * \param obj CTL element identifier list
2470 * \param idx Index of entry
2471 * \param ptr Pointer to returned CTL element identifier
2472 */
snd_ctl_elem_list_get_id(const snd_ctl_elem_list_t * obj,unsigned int idx,snd_ctl_elem_id_t * ptr)2473 void snd_ctl_elem_list_get_id(const snd_ctl_elem_list_t *obj, unsigned int idx, snd_ctl_elem_id_t *ptr)
2474 {
2475 assert(obj && ptr);
2476 assert(idx < obj->used);
2477 *ptr = obj->pids[idx];
2478 }
2479
2480 /**
2481 * \brief Get CTL element numeric identifier for an entry of a CTL element identifiers list
2482 * \param obj CTL element identifier list
2483 * \param idx Index of entry
2484 * \return CTL element numeric identifier
2485 */
snd_ctl_elem_list_get_numid(const snd_ctl_elem_list_t * obj,unsigned int idx)2486 unsigned int snd_ctl_elem_list_get_numid(const snd_ctl_elem_list_t *obj, unsigned int idx)
2487 {
2488 assert(obj);
2489 assert(idx < obj->used);
2490 return obj->pids[idx].numid;
2491 }
2492
2493 /**
2494 * \brief Get interface part of CTL element identifier for an entry of a CTL element identifiers list
2495 * \param obj CTL element identifier list
2496 * \param idx Index of entry
2497 * \return CTL element related interface
2498 */
snd_ctl_elem_list_get_interface(const snd_ctl_elem_list_t * obj,unsigned int idx)2499 snd_ctl_elem_iface_t snd_ctl_elem_list_get_interface(const snd_ctl_elem_list_t *obj, unsigned int idx)
2500 {
2501 assert(obj);
2502 assert(idx < obj->used);
2503 return obj->pids[idx].iface;
2504 }
2505
2506 /**
2507 * \brief Get the device part of CTL element identifier for an entry of a CTL element identifiers list
2508 * \param obj CTL element identifier list
2509 * \param idx Index of entry
2510 * \return CTL element related device
2511 */
snd_ctl_elem_list_get_device(const snd_ctl_elem_list_t * obj,unsigned int idx)2512 unsigned int snd_ctl_elem_list_get_device(const snd_ctl_elem_list_t *obj, unsigned int idx)
2513 {
2514 assert(obj);
2515 assert(idx < obj->used);
2516 return obj->pids[idx].device;
2517 }
2518
2519 /**
2520 * \brief Get subdevice part of CTL element identifier for an entry of a CTL element identifiers list
2521 * \param obj CTL element identifier list
2522 * \param idx Index of entry
2523 * \return CTL element related subdevice
2524 */
snd_ctl_elem_list_get_subdevice(const snd_ctl_elem_list_t * obj,unsigned int idx)2525 unsigned int snd_ctl_elem_list_get_subdevice(const snd_ctl_elem_list_t *obj, unsigned int idx)
2526 {
2527 assert(obj);
2528 assert(idx < obj->used);
2529 return obj->pids[idx].subdevice;
2530 }
2531
2532 /**
2533 * \brief Get name part of CTL element identifier for an entry of a CTL element identifiers list
2534 * \param obj CTL element identifier list
2535 * \param idx Index of entry
2536 * \return CTL element name
2537 */
snd_ctl_elem_list_get_name(const snd_ctl_elem_list_t * obj,unsigned int idx)2538 const char *snd_ctl_elem_list_get_name(const snd_ctl_elem_list_t *obj, unsigned int idx)
2539 {
2540 assert(obj);
2541 assert(idx < obj->used);
2542 return (const char *)obj->pids[idx].name;
2543 }
2544
2545 /**
2546 * \brief Get index part of CTL element identifier for an entry of a CTL element identifiers list
2547 * \param obj CTL element identifier list
2548 * \param idx Index of entry
2549 * \return CTL element index
2550 */
snd_ctl_elem_list_get_index(const snd_ctl_elem_list_t * obj,unsigned int idx)2551 unsigned int snd_ctl_elem_list_get_index(const snd_ctl_elem_list_t *obj, unsigned int idx)
2552 {
2553 assert(obj);
2554 assert(idx < obj->used);
2555 return obj->pids[idx].index;
2556 }
2557
2558 /**
2559 * \brief get size of #snd_ctl_elem_info_t
2560 * \return size in bytes
2561 */
snd_ctl_elem_info_sizeof()2562 size_t snd_ctl_elem_info_sizeof()
2563 {
2564 return sizeof(snd_ctl_elem_info_t);
2565 }
2566
2567 /**
2568 * \brief allocate an invalid #snd_ctl_elem_info_t using standard malloc
2569 * \param ptr returned pointer
2570 * \return 0 on success otherwise negative error code
2571 */
snd_ctl_elem_info_malloc(snd_ctl_elem_info_t ** ptr)2572 int snd_ctl_elem_info_malloc(snd_ctl_elem_info_t **ptr)
2573 {
2574 assert(ptr);
2575 *ptr = calloc(1, sizeof(snd_ctl_elem_info_t));
2576 if (!*ptr)
2577 return -ENOMEM;
2578 return 0;
2579 }
2580
2581 /**
2582 * \brief frees a previously allocated #snd_ctl_elem_info_t
2583 * \param obj pointer to object to free
2584 */
snd_ctl_elem_info_free(snd_ctl_elem_info_t * obj)2585 void snd_ctl_elem_info_free(snd_ctl_elem_info_t *obj)
2586 {
2587 free(obj);
2588 }
2589
2590 /**
2591 * \brief clear given #snd_ctl_elem_info_t object
2592 * \param obj pointer to object to clear
2593 */
snd_ctl_elem_info_clear(snd_ctl_elem_info_t * obj)2594 void snd_ctl_elem_info_clear(snd_ctl_elem_info_t *obj)
2595 {
2596 memset(obj, 0, sizeof(snd_ctl_elem_info_t));
2597 }
2598
2599 /**
2600 * \brief copy one #snd_ctl_elem_info_t to another
2601 * \param dst pointer to destination
2602 * \param src pointer to source
2603 */
snd_ctl_elem_info_copy(snd_ctl_elem_info_t * dst,const snd_ctl_elem_info_t * src)2604 void snd_ctl_elem_info_copy(snd_ctl_elem_info_t *dst, const snd_ctl_elem_info_t *src)
2605 {
2606 assert(dst && src);
2607 *dst = *src;
2608 }
2609
2610 /**
2611 * \brief Get type from a CTL element id/info
2612 * \param obj CTL element id/info
2613 * \return CTL element content type
2614 */
snd_ctl_elem_info_get_type(const snd_ctl_elem_info_t * obj)2615 snd_ctl_elem_type_t snd_ctl_elem_info_get_type(const snd_ctl_elem_info_t *obj)
2616 {
2617 assert(obj);
2618 return obj->type;
2619 }
2620
2621 /**
2622 * \brief Get info about readability from a CTL element id/info
2623 * \param obj CTL element id/info
2624 * \return 0 if element is not readable, 1 if element is readable
2625 */
snd_ctl_elem_info_is_readable(const snd_ctl_elem_info_t * obj)2626 int snd_ctl_elem_info_is_readable(const snd_ctl_elem_info_t *obj)
2627 {
2628 assert(obj);
2629 return !!(obj->access & SNDRV_CTL_ELEM_ACCESS_READ);
2630 }
2631
2632 /**
2633 * \brief Get info about writability from a CTL element id/info
2634 * \param obj CTL element id/info
2635 * \return 0 if element is not writable, 1 if element is not writable
2636 */
snd_ctl_elem_info_is_writable(const snd_ctl_elem_info_t * obj)2637 int snd_ctl_elem_info_is_writable(const snd_ctl_elem_info_t *obj)
2638 {
2639 assert(obj);
2640 return !!(obj->access & SNDRV_CTL_ELEM_ACCESS_WRITE);
2641 }
2642
2643 /**
2644 * \brief Get info about notification feasibility from a CTL element id/info
2645 * \param obj CTL element id/info
2646 * \return 0 if all element value changes are notified to subscribed applications, 1 otherwise
2647 */
snd_ctl_elem_info_is_volatile(const snd_ctl_elem_info_t * obj)2648 int snd_ctl_elem_info_is_volatile(const snd_ctl_elem_info_t *obj)
2649 {
2650 assert(obj);
2651 return !!(obj->access & SNDRV_CTL_ELEM_ACCESS_VOLATILE);
2652 }
2653
2654 /**
2655 * \brief Get info about status from a CTL element id/info
2656 * \param obj CTL element id/info
2657 * \return 0 if element value is not active, 1 if is active
2658 */
snd_ctl_elem_info_is_inactive(const snd_ctl_elem_info_t * obj)2659 int snd_ctl_elem_info_is_inactive(const snd_ctl_elem_info_t *obj)
2660 {
2661 assert(obj);
2662 return !!(obj->access & SNDRV_CTL_ELEM_ACCESS_INACTIVE);
2663 }
2664
2665 /**
2666 * \brief Get info whether an element is locked
2667 * \param obj CTL element id/info
2668 * \return 0 if element value is currently changeable, 1 if it's locked by another application
2669 */
snd_ctl_elem_info_is_locked(const snd_ctl_elem_info_t * obj)2670 int snd_ctl_elem_info_is_locked(const snd_ctl_elem_info_t *obj)
2671 {
2672 assert(obj);
2673 return !!(obj->access & SNDRV_CTL_ELEM_ACCESS_LOCK);
2674 }
2675
2676 /**
2677 * \brief Get info if I own an element
2678 * \param obj CTL element id/info
2679 * \return 0 if element value is currently changeable, 1 if it's locked by another application
2680 */
snd_ctl_elem_info_is_owner(const snd_ctl_elem_info_t * obj)2681 int snd_ctl_elem_info_is_owner(const snd_ctl_elem_info_t *obj)
2682 {
2683 assert(obj);
2684 return !!(obj->access & SNDRV_CTL_ELEM_ACCESS_OWNER);
2685 }
2686
2687 /**
2688 * \brief Get info if it's a user element
2689 * \param obj CTL element id/info
2690 * \return 0 if element value is a system element, 1 if it's a user-created element
2691 */
snd_ctl_elem_info_is_user(const snd_ctl_elem_info_t * obj)2692 int snd_ctl_elem_info_is_user(const snd_ctl_elem_info_t *obj)
2693 {
2694 assert(obj);
2695 return !!(obj->access & SNDRV_CTL_ELEM_ACCESS_USER);
2696 }
2697
2698 /**
2699 * \brief Get info about TLV readability from a CTL element id/info
2700 * \param obj CTL element id/info
2701 * \return 0 if element's TLV is not readable, 1 if element's TLV is readable
2702 */
snd_ctl_elem_info_is_tlv_readable(const snd_ctl_elem_info_t * obj)2703 int snd_ctl_elem_info_is_tlv_readable(const snd_ctl_elem_info_t *obj)
2704 {
2705 assert(obj);
2706 return !!(obj->access & SNDRV_CTL_ELEM_ACCESS_TLV_READ);
2707 }
2708
2709 /**
2710 * \brief Get info about TLV writeability from a CTL element id/info
2711 * \param obj CTL element id/info
2712 * \return 0 if element's TLV is not writable, 1 if element's TLV is writable
2713 */
snd_ctl_elem_info_is_tlv_writable(const snd_ctl_elem_info_t * obj)2714 int snd_ctl_elem_info_is_tlv_writable(const snd_ctl_elem_info_t *obj)
2715 {
2716 assert(obj);
2717 return !!(obj->access & SNDRV_CTL_ELEM_ACCESS_TLV_WRITE);
2718 }
2719
2720 /**
2721 * \brief Get info about TLV command possibility from a CTL element id/info
2722 * \param obj CTL element id/info
2723 * \return 0 if element's TLV command is not possible, 1 if element's TLV command is supported
2724 */
snd_ctl_elem_info_is_tlv_commandable(const snd_ctl_elem_info_t * obj)2725 int snd_ctl_elem_info_is_tlv_commandable(const snd_ctl_elem_info_t *obj)
2726 {
2727 assert(obj);
2728 return !!(obj->access & SNDRV_CTL_ELEM_ACCESS_TLV_COMMAND);
2729 }
2730
2731 /**
2732 * \brief (DEPRECATED) Get info about values passing policy from a CTL element value
2733 * \param obj CTL element id/info
2734 * \return 0 if element value need to be passed by contents, 1 if need to be passed with a pointer
2735 */
snd_ctl_elem_info_is_indirect(const snd_ctl_elem_info_t * obj)2736 int snd_ctl_elem_info_is_indirect(const snd_ctl_elem_info_t *obj)
2737 {
2738 assert(obj);
2739 return 0;
2740 }
2741 link_warning(snd_ctl_elem_info_is_indirect, "Warning: snd_ctl_elem_info_is_indirect is deprecated, do not use it");
2742
2743 /**
2744 * \brief Get owner of a locked element
2745 * \param obj CTL element id/info
2746 * \return value entries count
2747 */
snd_ctl_elem_info_get_owner(const snd_ctl_elem_info_t * obj)2748 pid_t snd_ctl_elem_info_get_owner(const snd_ctl_elem_info_t *obj)
2749 {
2750 assert(obj);
2751 return obj->owner;
2752 }
2753
2754 /**
2755 * \brief Get number of value entries from a CTL element id/info
2756 * \param obj CTL element id/info
2757 * \return value entries count
2758 */
snd_ctl_elem_info_get_count(const snd_ctl_elem_info_t * obj)2759 unsigned int snd_ctl_elem_info_get_count(const snd_ctl_elem_info_t *obj)
2760 {
2761 assert(obj);
2762 return obj->count;
2763 }
2764
2765 /**
2766 * \brief Get minimum value from a #SND_CTL_ELEM_TYPE_INTEGER CTL element id/info
2767 * \param obj CTL element id/info
2768 * \return Minimum value
2769 */
snd_ctl_elem_info_get_min(const snd_ctl_elem_info_t * obj)2770 long snd_ctl_elem_info_get_min(const snd_ctl_elem_info_t *obj)
2771 {
2772 assert(obj);
2773 assert(obj->type == SND_CTL_ELEM_TYPE_INTEGER);
2774 return obj->value.integer.min;
2775 }
2776
2777 /**
2778 * \brief Get maximum value from a #SND_CTL_ELEM_TYPE_INTEGER CTL element id/info
2779 * \param obj CTL element id/info
2780 * \return Maximum value
2781 */
snd_ctl_elem_info_get_max(const snd_ctl_elem_info_t * obj)2782 long snd_ctl_elem_info_get_max(const snd_ctl_elem_info_t *obj)
2783 {
2784 assert(obj);
2785 assert(obj->type == SND_CTL_ELEM_TYPE_INTEGER);
2786 return obj->value.integer.max;
2787 }
2788
2789 /**
2790 * \brief Get value step from a #SND_CTL_ELEM_TYPE_INTEGER CTL element id/info
2791 * \param obj CTL element id/info
2792 * \return Step
2793 */
snd_ctl_elem_info_get_step(const snd_ctl_elem_info_t * obj)2794 long snd_ctl_elem_info_get_step(const snd_ctl_elem_info_t *obj)
2795 {
2796 assert(obj);
2797 assert(obj->type == SND_CTL_ELEM_TYPE_INTEGER);
2798 return obj->value.integer.step;
2799 }
2800
2801 /**
2802 * \brief Get minimum value from a #SND_CTL_ELEM_TYPE_INTEGER64 CTL element id/info
2803 * \param obj CTL element id/info
2804 * \return Minimum value
2805 */
snd_ctl_elem_info_get_min64(const snd_ctl_elem_info_t * obj)2806 long long snd_ctl_elem_info_get_min64(const snd_ctl_elem_info_t *obj)
2807 {
2808 assert(obj);
2809 assert(obj->type == SND_CTL_ELEM_TYPE_INTEGER64);
2810 return obj->value.integer64.min;
2811 }
2812
2813 /**
2814 * \brief Get maximum value from a #SND_CTL_ELEM_TYPE_INTEGER64 CTL element id/info
2815 * \param obj CTL element id/info
2816 * \return Maximum value
2817 */
snd_ctl_elem_info_get_max64(const snd_ctl_elem_info_t * obj)2818 long long snd_ctl_elem_info_get_max64(const snd_ctl_elem_info_t *obj)
2819 {
2820 assert(obj);
2821 assert(obj->type == SND_CTL_ELEM_TYPE_INTEGER64);
2822 return obj->value.integer64.max;
2823 }
2824
2825 /**
2826 * \brief Get value step from a #SND_CTL_ELEM_TYPE_INTEGER64 CTL element id/info
2827 * \param obj CTL element id/info
2828 * \return Step
2829 */
snd_ctl_elem_info_get_step64(const snd_ctl_elem_info_t * obj)2830 long long snd_ctl_elem_info_get_step64(const snd_ctl_elem_info_t *obj)
2831 {
2832 assert(obj);
2833 assert(obj->type == SND_CTL_ELEM_TYPE_INTEGER64);
2834 return obj->value.integer64.step;
2835 }
2836
2837 /**
2838 * \brief Get number of items available from a #SND_CTL_ELEM_TYPE_ENUMERATED CTL element id/info
2839 * \param obj CTL element id/info
2840 * \return items count
2841 */
snd_ctl_elem_info_get_items(const snd_ctl_elem_info_t * obj)2842 unsigned int snd_ctl_elem_info_get_items(const snd_ctl_elem_info_t *obj)
2843 {
2844 assert(obj);
2845 assert(obj->type == SND_CTL_ELEM_TYPE_ENUMERATED);
2846 return obj->value.enumerated.items;
2847 }
2848
2849 /**
2850 * \brief Select item in a #SND_CTL_ELEM_TYPE_ENUMERATED CTL element id/info
2851 * \param obj CTL element id/info
2852 * \param val item number
2853 */
snd_ctl_elem_info_set_item(snd_ctl_elem_info_t * obj,unsigned int val)2854 void snd_ctl_elem_info_set_item(snd_ctl_elem_info_t *obj, unsigned int val)
2855 {
2856 assert(obj);
2857 obj->value.enumerated.item = val;
2858 }
2859
2860 /**
2861 * \brief Get name for selected item in a #SND_CTL_ELEM_TYPE_ENUMERATED CTL element id/info
2862 * \param obj CTL element id/info
2863 * \return name of chosen item
2864 */
snd_ctl_elem_info_get_item_name(const snd_ctl_elem_info_t * obj)2865 const char *snd_ctl_elem_info_get_item_name(const snd_ctl_elem_info_t *obj)
2866 {
2867 assert(obj);
2868 assert(obj->type == SND_CTL_ELEM_TYPE_ENUMERATED);
2869 return obj->value.enumerated.name;
2870 }
2871
2872 /**
2873 * \brief Get count of dimensions for given element
2874 * \param obj CTL element id/info
2875 * \return zero value if no dimensions are defined, otherwise positive value with count of dimensions
2876 *
2877 * \deprecated Since 1.1.5
2878 * #snd_ctl_elem_info_get_dimensions is deprecated without any replacement.
2879 */
2880 #ifndef DOXYGEN
INTERNAL(snd_ctl_elem_info_get_dimensions)2881 EXPORT_SYMBOL int INTERNAL(snd_ctl_elem_info_get_dimensions)(const snd_ctl_elem_info_t *obj ATTRIBUTE_UNUSED)
2882 #else
2883 int snd_ctl_elem_info_get_dimensions(const snd_ctl_elem_info_t *obj)
2884 #endif
2885 {
2886 #if 0 /* deprecated */
2887 int i;
2888
2889 assert(obj);
2890 for (i = 3; i >= 0; i--)
2891 if (obj->dimen.d[i])
2892 break;
2893 return i + 1;
2894 #else
2895 return -EINVAL;
2896 #endif
2897 }
2898 use_default_symbol_version(__snd_ctl_elem_info_get_dimensions, snd_ctl_elem_info_get_dimensions, ALSA_0.9.3);
2899
2900 /**
2901 * \brief Get specified of dimension width for given element
2902 * \param obj CTL element id/info
2903 * \param idx The dimension index
2904 * \return zero value if no dimension width is defined, otherwise positive value with with of specified dimension
2905 *
2906 * \deprecated Since 1.1.5
2907 * #snd_ctl_elem_info_get_dimension is deprecated without any replacement.
2908 */
2909 #ifndef DOXYGEN
INTERNAL(snd_ctl_elem_info_get_dimension)2910 EXPORT_SYMBOL int INTERNAL(snd_ctl_elem_info_get_dimension)(const snd_ctl_elem_info_t *obj ATTRIBUTE_UNUSED, unsigned int idx ATTRIBUTE_UNUSED)
2911 #else
2912 int snd_ctl_elem_info_get_dimension(const snd_ctl_elem_info_t *obj, unsigned int idx)
2913 #endif
2914 {
2915 #if 0 /* deprecated */
2916 assert(obj);
2917 if (idx > 3)
2918 return 0;
2919 return obj->dimen.d[idx];
2920 #else /* deprecated */
2921 return -EINVAL;
2922 #endif /* deprecated */
2923 }
2924 use_default_symbol_version(__snd_ctl_elem_info_get_dimension, snd_ctl_elem_info_get_dimension, ALSA_0.9.3);
2925
2926 /**
2927 * \brief Set width to a specified dimension level of given element information.
2928 * \param info Information of an element.
2929 * \param dimension Dimension width for each level by member unit.
2930 * \return Zero on success, otherwise a negative error code.
2931 *
2932 * \par Errors:
2933 * <dl>
2934 * <dt>-EINVAL
2935 * <dd>Invalid arguments are given as parameters.
2936 * </dl>
2937 *
2938 * \par Compatibility:
2939 * This function is added in version 1.1.2.
2940 *
2941 * \deprecated Since 1.1.5
2942 * #snd_ctl_elem_info_set_dimension is deprecated without any replacement.
2943 */
snd_ctl_elem_info_set_dimension(snd_ctl_elem_info_t * info ATTRIBUTE_UNUSED,const int dimension[4]ATTRIBUTE_UNUSED)2944 int snd_ctl_elem_info_set_dimension(snd_ctl_elem_info_t *info ATTRIBUTE_UNUSED,
2945 const int dimension[4] ATTRIBUTE_UNUSED)
2946 {
2947 #if 0 /* deprecated */
2948 unsigned int i;
2949
2950 if (info == NULL)
2951 return -EINVAL;
2952
2953 for (i = 0; i < ARRAY_SIZE(info->dimen.d); i++) {
2954 if (dimension[i] < 0)
2955 return -EINVAL;
2956
2957 info->dimen.d[i] = dimension[i];
2958 }
2959
2960 return 0;
2961 #else /* deprecated */
2962 return -EINVAL;
2963 #endif /* deprecated */
2964 }
2965
2966 /**
2967 * \brief Get CTL element identifier of a CTL element id/info
2968 * \param obj CTL element id/info
2969 * \param ptr Pointer to returned CTL element identifier
2970 */
snd_ctl_elem_info_get_id(const snd_ctl_elem_info_t * obj,snd_ctl_elem_id_t * ptr)2971 void snd_ctl_elem_info_get_id(const snd_ctl_elem_info_t *obj, snd_ctl_elem_id_t *ptr)
2972 {
2973 assert(obj && ptr);
2974 *ptr = obj->id;
2975 }
2976
2977 /**
2978 * \brief Get element numeric identifier of a CTL element id/info
2979 * \param obj CTL element id/info
2980 * \return element numeric identifier
2981 */
snd_ctl_elem_info_get_numid(const snd_ctl_elem_info_t * obj)2982 unsigned int snd_ctl_elem_info_get_numid(const snd_ctl_elem_info_t *obj)
2983 {
2984 assert(obj);
2985 return obj->id.numid;
2986 }
2987
2988 /**
2989 * \brief Get interface part of CTL element identifier of a CTL element id/info
2990 * \param obj CTL element id/info
2991 * \return interface part of element identifier
2992 */
snd_ctl_elem_info_get_interface(const snd_ctl_elem_info_t * obj)2993 snd_ctl_elem_iface_t snd_ctl_elem_info_get_interface(const snd_ctl_elem_info_t *obj)
2994 {
2995 assert(obj);
2996 return obj->id.iface;
2997 }
2998
2999 /**
3000 * \brief Get device part of CTL element identifier of a CTL element id/info
3001 * \param obj CTL element id/info
3002 * \return device part of element identifier
3003 */
snd_ctl_elem_info_get_device(const snd_ctl_elem_info_t * obj)3004 unsigned int snd_ctl_elem_info_get_device(const snd_ctl_elem_info_t *obj)
3005 {
3006 assert(obj);
3007 return obj->id.device;
3008 }
3009
3010 /**
3011 * \brief Get subdevice part of CTL element identifier of a CTL element id/info
3012 * \param obj CTL element id/info
3013 * \return subdevice part of element identifier
3014 */
snd_ctl_elem_info_get_subdevice(const snd_ctl_elem_info_t * obj)3015 unsigned int snd_ctl_elem_info_get_subdevice(const snd_ctl_elem_info_t *obj)
3016 {
3017 assert(obj);
3018 return obj->id.subdevice;
3019 }
3020
3021 /**
3022 * \brief Get name part of CTL element identifier of a CTL element id/info
3023 * \param obj CTL element id/info
3024 * \return name part of element identifier
3025 */
snd_ctl_elem_info_get_name(const snd_ctl_elem_info_t * obj)3026 const char *snd_ctl_elem_info_get_name(const snd_ctl_elem_info_t *obj)
3027 {
3028 assert(obj);
3029 return (const char *)obj->id.name;
3030 }
3031
3032 /**
3033 * \brief Get index part of CTL element identifier of a CTL element id/info
3034 * \param obj CTL element id/info
3035 * \return index part of element identifier
3036 */
snd_ctl_elem_info_get_index(const snd_ctl_elem_info_t * obj)3037 unsigned int snd_ctl_elem_info_get_index(const snd_ctl_elem_info_t *obj)
3038 {
3039 assert(obj);
3040 return obj->id.index;
3041 }
3042
3043 /**
3044 * \brief Set CTL element identifier of a CTL element id/info
3045 * \param obj CTL element id/info
3046 * \param ptr CTL element identifier
3047 */
snd_ctl_elem_info_set_id(snd_ctl_elem_info_t * obj,const snd_ctl_elem_id_t * ptr)3048 void snd_ctl_elem_info_set_id(snd_ctl_elem_info_t *obj, const snd_ctl_elem_id_t *ptr)
3049 {
3050 assert(obj && ptr);
3051 obj->id = *ptr;
3052 }
3053
3054 /**
3055 * \brief Set element numeric identifier of a CTL element id/info
3056 * \param obj CTL element id/info
3057 * \param val element numeric identifier
3058 */
snd_ctl_elem_info_set_numid(snd_ctl_elem_info_t * obj,unsigned int val)3059 void snd_ctl_elem_info_set_numid(snd_ctl_elem_info_t *obj, unsigned int val)
3060 {
3061 assert(obj);
3062 obj->id.numid = val;
3063 }
3064
3065 /**
3066 * \brief Set interface part of CTL element identifier of a CTL element id/info
3067 * \param obj CTL element id/info
3068 * \param val interface part of element identifier
3069 */
snd_ctl_elem_info_set_interface(snd_ctl_elem_info_t * obj,snd_ctl_elem_iface_t val)3070 void snd_ctl_elem_info_set_interface(snd_ctl_elem_info_t *obj, snd_ctl_elem_iface_t val)
3071 {
3072 assert(obj);
3073 obj->id.iface = val;
3074 }
3075
3076 /**
3077 * \brief Set device part of CTL element identifier of a CTL element id/info
3078 * \param obj CTL element id/info
3079 * \param val device part of element identifier
3080 */
snd_ctl_elem_info_set_device(snd_ctl_elem_info_t * obj,unsigned int val)3081 void snd_ctl_elem_info_set_device(snd_ctl_elem_info_t *obj, unsigned int val)
3082 {
3083 assert(obj);
3084 obj->id.device = val;
3085 }
3086
3087 /**
3088 * \brief Set subdevice part of CTL element identifier of a CTL element id/info
3089 * \param obj CTL element id/info
3090 * \param val subdevice part of element identifier
3091 */
snd_ctl_elem_info_set_subdevice(snd_ctl_elem_info_t * obj,unsigned int val)3092 void snd_ctl_elem_info_set_subdevice(snd_ctl_elem_info_t *obj, unsigned int val)
3093 {
3094 assert(obj);
3095 obj->id.subdevice = val;
3096 }
3097
3098 /**
3099 * \brief Set name part of CTL element identifier of a CTL element id/info
3100 * \param obj CTL element id/info
3101 * \param val name part of element identifier
3102 */
snd_ctl_elem_info_set_name(snd_ctl_elem_info_t * obj,const char * val)3103 void snd_ctl_elem_info_set_name(snd_ctl_elem_info_t *obj, const char *val)
3104 {
3105 assert(obj);
3106 snd_strlcpy((char *)obj->id.name, val, sizeof(obj->id.name));
3107 }
3108
3109 /**
3110 * \brief Set index part of CTL element identifier of a CTL element id/info
3111 * \param obj CTL element id/info
3112 * \param val index part of element identifier
3113 */
snd_ctl_elem_info_set_index(snd_ctl_elem_info_t * obj,unsigned int val)3114 void snd_ctl_elem_info_set_index(snd_ctl_elem_info_t *obj, unsigned int val)
3115 {
3116 assert(obj);
3117 obj->id.index = val;
3118 }
3119
3120 /**
3121 * \brief Set readability/writeability parameter of a CTL element id/info
3122 * \param obj CTL element id/info
3123 * \param rval readability part of element identifier
3124 * \param wval writeability part of element identifier
3125 */
snd_ctl_elem_info_set_read_write(snd_ctl_elem_info_t * obj,int rval,int wval)3126 void snd_ctl_elem_info_set_read_write(snd_ctl_elem_info_t *obj, int rval, int wval)
3127 {
3128 assert(obj);
3129 obj->access = (obj->access & ~SNDRV_CTL_ELEM_ACCESS_READWRITE) |
3130 (rval ? SNDRV_CTL_ELEM_ACCESS_READ : 0) |
3131 (wval ? SNDRV_CTL_ELEM_ACCESS_WRITE : 0);
3132 }
3133
3134 /**
3135 * \brief Set TLV readability/writeability parameter of a CTL element id/info
3136 * \param obj CTL element id/info
3137 * \param rval TLV readability part of element identifier
3138 * \param wval TLV writeability part of element identifier
3139 */
snd_ctl_elem_info_set_tlv_read_write(snd_ctl_elem_info_t * obj,int rval,int wval)3140 void snd_ctl_elem_info_set_tlv_read_write(snd_ctl_elem_info_t *obj, int rval, int wval)
3141 {
3142 assert(obj);
3143 obj->access = (obj->access & ~SNDRV_CTL_ELEM_ACCESS_TLV_READWRITE) |
3144 (rval ? SNDRV_CTL_ELEM_ACCESS_TLV_READ : 0) |
3145 (wval ? SNDRV_CTL_ELEM_ACCESS_TLV_WRITE : 0);
3146 }
3147
3148 /**
3149 * \brief Set inactive parameter of a CTL element id/info
3150 * \param obj CTL element id/info
3151 * \param val inactive part of element identifier
3152 */
snd_ctl_elem_info_set_inactive(snd_ctl_elem_info_t * obj,int val)3153 void snd_ctl_elem_info_set_inactive(snd_ctl_elem_info_t *obj, int val)
3154 {
3155 assert(obj);
3156 obj->access = (obj->access & ~SNDRV_CTL_ELEM_ACCESS_INACTIVE) |
3157 (val ? SNDRV_CTL_ELEM_ACCESS_INACTIVE : 0);
3158 }
3159
3160 /**
3161 * \brief Get size of data structure for an element.
3162 * \return Size in bytes.
3163 */
snd_ctl_elem_value_sizeof()3164 size_t snd_ctl_elem_value_sizeof()
3165 {
3166 return sizeof(snd_ctl_elem_value_t);
3167 }
3168
3169 /**
3170 * \brief Allocate an invalid #snd_ctl_elem_value_t on the heap.
3171 *
3172 * Allocate space for a value object on the heap. The allocated memory
3173 * must be freed using snd_ctl_elem_value_free().
3174 *
3175 * See snd_ctl_elem_value_t for details.
3176 *
3177 * \param ptr Pointer to a snd_ctl_elem_value_t pointer. The address
3178 * of the allocated space will be returned here.
3179 * \return 0 on success, otherwise a negative error code.
3180 */
snd_ctl_elem_value_malloc(snd_ctl_elem_value_t ** ptr)3181 int snd_ctl_elem_value_malloc(snd_ctl_elem_value_t **ptr)
3182 {
3183 assert(ptr);
3184 *ptr = calloc(1, sizeof(snd_ctl_elem_value_t));
3185 if (!*ptr)
3186 return -ENOMEM;
3187 return 0;
3188 }
3189
3190 /**
3191 * \brief Free an #snd_ctl_elem_value_t previously allocated using
3192 * snd_ctl_elem_value_malloc().
3193 *
3194 * \param obj Pointer to the snd_ctl_elem_value_t.
3195 */
snd_ctl_elem_value_free(snd_ctl_elem_value_t * obj)3196 void snd_ctl_elem_value_free(snd_ctl_elem_value_t *obj)
3197 {
3198 free(obj);
3199 }
3200
3201 /**
3202 * \brief Clear given data of an element.
3203 *
3204 * See snd_ctl_elem_value_t for details.
3205 *
3206 * \param obj Data of an element.
3207 */
snd_ctl_elem_value_clear(snd_ctl_elem_value_t * obj)3208 void snd_ctl_elem_value_clear(snd_ctl_elem_value_t *obj)
3209 {
3210 memset(obj, 0, sizeof(snd_ctl_elem_value_t));
3211 }
3212
3213 /**
3214 * \brief Bitwise copy of a snd_ctl_elem_value_t value.
3215 * \param dst Pointer to destination.
3216 * \param src Pointer to source.
3217 */
snd_ctl_elem_value_copy(snd_ctl_elem_value_t * dst,const snd_ctl_elem_value_t * src)3218 void snd_ctl_elem_value_copy(snd_ctl_elem_value_t *dst,
3219 const snd_ctl_elem_value_t *src)
3220 {
3221 assert(dst && src);
3222 *dst = *src;
3223 }
3224
3225 /**
3226 * \brief Compare two snd_ctl_elem_value_t values, bytewise.
3227 *
3228 * \param left First value.
3229 * \param right Second value.
3230 * \return 0 on match, less than or greater than otherwise, see memcmp(3).
3231 */
snd_ctl_elem_value_compare(snd_ctl_elem_value_t * left,const snd_ctl_elem_value_t * right)3232 int snd_ctl_elem_value_compare(snd_ctl_elem_value_t *left,
3233 const snd_ctl_elem_value_t *right)
3234 {
3235 assert(left && right);
3236 return memcmp(left, right, sizeof(*left));
3237 }
3238
3239 /**
3240 * \brief Get the element identifier from the given element value.
3241 *
3242 * See snd_ctl_elem_value_t for more details.
3243 *
3244 * \param obj The element value.
3245 * \param ptr Pointer to an identifier object. The identifier is
3246 * stored there.
3247 */
snd_ctl_elem_value_get_id(const snd_ctl_elem_value_t * obj,snd_ctl_elem_id_t * ptr)3248 void snd_ctl_elem_value_get_id(const snd_ctl_elem_value_t *obj, snd_ctl_elem_id_t *ptr)
3249 {
3250 assert(obj && ptr);
3251 *ptr = obj->id;
3252 }
3253
3254 /**
3255 * \brief Get the identifiers 'numid' part from the given element value.
3256 *
3257 * See snd_ctl_elem_value_t for more details.
3258 *
3259 * \param obj The element value.
3260 * \return The numid.
3261 */
snd_ctl_elem_value_get_numid(const snd_ctl_elem_value_t * obj)3262 unsigned int snd_ctl_elem_value_get_numid(const snd_ctl_elem_value_t *obj)
3263 {
3264 assert(obj);
3265 return obj->id.numid;
3266 }
3267
3268 /**
3269 * \brief Get the identifiers 'interface' part from the given element value.
3270 *
3271 * See snd_ctl_elem_value_t for more details.
3272 *
3273 * \param obj The element value.
3274 * \return The interface part of element identifier.
3275 */
snd_ctl_elem_value_get_interface(const snd_ctl_elem_value_t * obj)3276 snd_ctl_elem_iface_t snd_ctl_elem_value_get_interface(const snd_ctl_elem_value_t *obj)
3277 {
3278 assert(obj);
3279 return obj->id.iface;
3280 }
3281
3282 /**
3283 * \brief Get the identifiers 'device' part from the given element value.
3284 *
3285 * See snd_ctl_elem_value_t for more details.
3286 *
3287 * \param obj The element value.
3288 * \return The device part of element identifier.
3289 */
snd_ctl_elem_value_get_device(const snd_ctl_elem_value_t * obj)3290 unsigned int snd_ctl_elem_value_get_device(const snd_ctl_elem_value_t *obj)
3291 {
3292 assert(obj);
3293 return obj->id.device;
3294 }
3295
3296 /**
3297 * \brief Get the identifiers 'subdevice' part from the given element value.
3298 *
3299 * See snd_ctl_elem_value_t for more details.
3300 *
3301 * \param obj The element value.
3302 * \return The subdevice part of element identifier.
3303 */
snd_ctl_elem_value_get_subdevice(const snd_ctl_elem_value_t * obj)3304 unsigned int snd_ctl_elem_value_get_subdevice(const snd_ctl_elem_value_t *obj)
3305 {
3306 assert(obj);
3307 return obj->id.subdevice;
3308 }
3309
3310 /**
3311 * \brief Get the identifiers 'name' part from the given element value.
3312 *
3313 * See snd_ctl_elem_value_t for more details.
3314 *
3315 * \param obj The element value.
3316 * \return The "name" part of element identifier.
3317 */
snd_ctl_elem_value_get_name(const snd_ctl_elem_value_t * obj)3318 const char *snd_ctl_elem_value_get_name(const snd_ctl_elem_value_t *obj)
3319 {
3320 assert(obj);
3321 return (const char *)obj->id.name;
3322 }
3323
3324 /**
3325 * \brief Get the identifiers 'index' part from the given element value.
3326 *
3327 * See snd_ctl_elem_value_t for more details.
3328 *
3329 * \param obj The element value.
3330 * \return The index part of element identifier.
3331 */
snd_ctl_elem_value_get_index(const snd_ctl_elem_value_t * obj)3332 unsigned int snd_ctl_elem_value_get_index(const snd_ctl_elem_value_t *obj)
3333 {
3334 assert(obj);
3335 return obj->id.index;
3336 }
3337
3338
3339 /**
3340 * \brief Set the element identifier within the given element value.
3341 *
3342 * See snd_ctl_elem_value_t for more details.
3343 *
3344 * \param obj The element value.
3345 * \param ptr The new identifier.
3346 */
snd_ctl_elem_value_set_id(snd_ctl_elem_value_t * obj,const snd_ctl_elem_id_t * ptr)3347 void snd_ctl_elem_value_set_id(snd_ctl_elem_value_t *obj, const snd_ctl_elem_id_t *ptr)
3348 {
3349 assert(obj && ptr);
3350 obj->id = *ptr;
3351 }
3352
3353 /**
3354 * \brief Set the identifiers 'numid' part within the given element value.
3355 *
3356 * See snd_ctl_elem_value_t for more details.
3357 *
3358 * \param obj The element value.
3359 * \param val The new numid.
3360 */
snd_ctl_elem_value_set_numid(snd_ctl_elem_value_t * obj,unsigned int val)3361 void snd_ctl_elem_value_set_numid(snd_ctl_elem_value_t *obj, unsigned int val)
3362 {
3363 assert(obj);
3364 obj->id.numid = val;
3365 }
3366
3367 /**
3368 * \brief Set the identifiers 'interface' part within the given element value.
3369 *
3370 * See snd_ctl_elem_value_t for more details.
3371 *
3372 * \param obj The element value.
3373 * \param val The new interface.
3374 */
snd_ctl_elem_value_set_interface(snd_ctl_elem_value_t * obj,snd_ctl_elem_iface_t val)3375 void snd_ctl_elem_value_set_interface(snd_ctl_elem_value_t *obj, snd_ctl_elem_iface_t val)
3376 {
3377 assert(obj);
3378 obj->id.iface = val;
3379 }
3380
3381 /**
3382 * \brief Set the identifiers 'device' part within the given element value.
3383 *
3384 * See snd_ctl_elem_value_t for more details.
3385 *
3386 * \param obj The element value.
3387 * \param val The new device.
3388 */
snd_ctl_elem_value_set_device(snd_ctl_elem_value_t * obj,unsigned int val)3389 void snd_ctl_elem_value_set_device(snd_ctl_elem_value_t *obj, unsigned int val)
3390 {
3391 assert(obj);
3392 obj->id.device = val;
3393 }
3394
3395 /**
3396 * \brief Set the identifiers 'subdevice' part within the given element value.
3397 *
3398 * See snd_ctl_elem_value_t for more details.
3399 *
3400 * \param obj The element value.
3401 * \param val The new subdevice.
3402 */
snd_ctl_elem_value_set_subdevice(snd_ctl_elem_value_t * obj,unsigned int val)3403 void snd_ctl_elem_value_set_subdevice(snd_ctl_elem_value_t *obj, unsigned int val)
3404 {
3405 assert(obj);
3406 obj->id.subdevice = val;
3407 }
3408
3409 /**
3410 * \brief Set the identifiers 'name' part within the given element value.
3411 *
3412 * See snd_ctl_elem_value_t for more details.
3413 *
3414 * \param obj The element value.
3415 * \param val The new name.
3416 */
snd_ctl_elem_value_set_name(snd_ctl_elem_value_t * obj,const char * val)3417 void snd_ctl_elem_value_set_name(snd_ctl_elem_value_t *obj, const char *val)
3418 {
3419 assert(obj);
3420 snd_strlcpy((char *)obj->id.name, val, sizeof(obj->id.name));
3421 }
3422
3423 /**
3424 * \brief Set the identifiers 'index' part within the given element value.
3425 *
3426 * See snd_ctl_elem_value_t for more details.
3427 *
3428 * \param obj The element value.
3429 * \param val The new index.
3430 */
snd_ctl_elem_value_set_index(snd_ctl_elem_value_t * obj,unsigned int val)3431 void snd_ctl_elem_value_set_index(snd_ctl_elem_value_t *obj, unsigned int val)
3432 {
3433 assert(obj);
3434 obj->id.index = val;
3435 }
3436
3437 /**
3438 * \brief Get an element members value.
3439 *
3440 * Use this function if the element is of type SNDRV_CTL_ELEM_TYPE_BOOLEAN. It
3441 * returns the value of one member. See \ref snd_ctl_elem_value_t and \ref
3442 * control for more details.
3443 *
3444 * \param obj The element value object
3445 * \param idx The index of the member.
3446 * \return The members value.
3447 */
snd_ctl_elem_value_get_boolean(const snd_ctl_elem_value_t * obj,unsigned int idx)3448 int snd_ctl_elem_value_get_boolean(const snd_ctl_elem_value_t *obj, unsigned int idx)
3449 {
3450 assert(obj);
3451 assert(idx < ARRAY_SIZE(obj->value.integer.value));
3452 return obj->value.integer.value[idx];
3453 }
3454
3455 /**
3456 * \brief Get an element members value.
3457 *
3458 * Use this function if the element is of type SNDRV_CTL_ELEM_TYPE_INTEGER. It
3459 * returns the value of one member. See \ref snd_ctl_elem_value_t and \ref
3460 * control for more details.
3461 *
3462 * \param obj The element value object.
3463 * \param idx The index of the member.
3464 * \return The members value.
3465 */
snd_ctl_elem_value_get_integer(const snd_ctl_elem_value_t * obj,unsigned int idx)3466 long snd_ctl_elem_value_get_integer(const snd_ctl_elem_value_t *obj, unsigned int idx)
3467 {
3468 assert(obj);
3469 assert(idx < ARRAY_SIZE(obj->value.integer.value));
3470 return obj->value.integer.value[idx];
3471 }
3472
3473 /**
3474 * \brief Get an element members value.
3475 *
3476 * Use this function if the element is of type SNDRV_CTL_ELEM_TYPE_INTEGER64. It
3477 * returns the value of one member. See \ref snd_ctl_elem_value_t and \ref
3478 * control for more details.
3479 *
3480 * \param obj The element value object.
3481 * \param idx The index of the member.
3482 * \return The members value.
3483 */
snd_ctl_elem_value_get_integer64(const snd_ctl_elem_value_t * obj,unsigned int idx)3484 long long snd_ctl_elem_value_get_integer64(const snd_ctl_elem_value_t *obj, unsigned int idx)
3485 {
3486 assert(obj);
3487 assert(idx < ARRAY_SIZE(obj->value.integer64.value));
3488 return obj->value.integer64.value[idx];
3489 }
3490
3491 /**
3492 * \brief Get an element members value.
3493 *
3494 * Use this function if the element is of type
3495 * SNDRV_CTL_ELEM_TYPE_ENUMERATED. It returns the index of the active item. See
3496 * \ref snd_ctl_elem_value_t and \ref control for more details.
3497 *
3498 * \param obj The element value object.
3499 * \param idx The index of the requested member.
3500 * \return The index of the active item.
3501 */
snd_ctl_elem_value_get_enumerated(const snd_ctl_elem_value_t * obj,unsigned int idx)3502 unsigned int snd_ctl_elem_value_get_enumerated(const snd_ctl_elem_value_t *obj, unsigned int idx)
3503 {
3504 assert(obj);
3505 assert(idx < ARRAY_SIZE(obj->value.enumerated.item));
3506 return obj->value.enumerated.item[idx];
3507 }
3508
3509 /**
3510 * \brief Get an element members value.
3511 *
3512 * Use this function if the element is of type SNDRV_CTL_ELEM_TYPE_BYTE. It
3513 * returns the value of one member. See \ref snd_ctl_elem_value_t and \ref
3514 * control for more details.
3515 *
3516 * \param obj The element value object.
3517 * \param idx The index of the member.
3518 * \return The members value.
3519 */
snd_ctl_elem_value_get_byte(const snd_ctl_elem_value_t * obj,unsigned int idx)3520 unsigned char snd_ctl_elem_value_get_byte(const snd_ctl_elem_value_t *obj, unsigned int idx)
3521 {
3522 assert(obj);
3523 assert(idx < ARRAY_SIZE(obj->value.bytes.data));
3524 return obj->value.bytes.data[idx];
3525 }
3526
3527 /**
3528 * \brief Set an element members value.
3529 *
3530 * Use this function if the element is of type SNDRV_CTL_ELEM_TYPE_BOOLEAN. It
3531 * sets the value of one member. See \ref snd_ctl_elem_value_t and \ref control
3532 * for more details.
3533 *
3534 * \param obj The element value object.
3535 * \param idx The index of the member.
3536 * \param val The new value.
3537 */
snd_ctl_elem_value_set_boolean(snd_ctl_elem_value_t * obj,unsigned int idx,long val)3538 void snd_ctl_elem_value_set_boolean(snd_ctl_elem_value_t *obj, unsigned int idx, long val)
3539 {
3540 assert(obj);
3541 assert(idx < ARRAY_SIZE(obj->value.integer.value));
3542 obj->value.integer.value[idx] = val;
3543 }
3544
3545 /**
3546 * \brief Set an element members value.
3547 *
3548 * Use this function if the element is of type SNDRV_CTL_ELEM_TYPE_INTEGER. It
3549 * sets the value of one member. See \ref snd_ctl_elem_value_t and \ref control
3550 * for more details.
3551 *
3552 * \param obj The element value object.
3553 * \param idx The index of the member.
3554 * \param val The new value.
3555 */
snd_ctl_elem_value_set_integer(snd_ctl_elem_value_t * obj,unsigned int idx,long val)3556 void snd_ctl_elem_value_set_integer(snd_ctl_elem_value_t *obj, unsigned int idx, long val)
3557 {
3558 assert(obj);
3559 assert(idx < ARRAY_SIZE(obj->value.integer.value));
3560 obj->value.integer.value[idx] = val;
3561 }
3562
3563 /**
3564 * \brief Set an element members value.
3565 *
3566 * Use this function if the element is of type SNDRV_CTL_ELEM_TYPE_INTEGER64. It
3567 * sets the value of one member. See \ref snd_ctl_elem_value_t and \ref control
3568 * for more details.
3569 *
3570 * \param obj The element value object.
3571 * \param idx The index of the member.
3572 * \param val The new value.
3573 */
snd_ctl_elem_value_set_integer64(snd_ctl_elem_value_t * obj,unsigned int idx,long long val)3574 void snd_ctl_elem_value_set_integer64(snd_ctl_elem_value_t *obj, unsigned int idx, long long val)
3575 {
3576 assert(obj);
3577 assert(idx < ARRAY_SIZE(obj->value.integer64.value));
3578 obj->value.integer64.value[idx] = val;
3579 }
3580
3581 /**
3582 * \brief Set an element members value.
3583 *
3584 * Use this function if the element is of type
3585 * SNDRV_CTL_ELEM_TYPE_ENUMERATED. It activates the specified item. See \ref
3586 * snd_ctl_elem_value_t and \ref control for more details.
3587 *
3588 * \param obj The element value object.
3589 * \param idx The index of the requested member.
3590 * \param val The new index of the item to be activated.
3591 */
snd_ctl_elem_value_set_enumerated(snd_ctl_elem_value_t * obj,unsigned int idx,unsigned int val)3592 void snd_ctl_elem_value_set_enumerated(snd_ctl_elem_value_t *obj, unsigned int idx, unsigned int val)
3593 {
3594 assert(obj);
3595 assert(idx < ARRAY_SIZE(obj->value.enumerated.item));
3596 obj->value.enumerated.item[idx] = val;
3597 }
3598
3599 /**
3600 * \brief Set an element members value.
3601 *
3602 * Use this function if the element is of type SNDRV_CTL_ELEM_TYPE_BYTE. It
3603 * sets the value of one member. See \ref snd_ctl_elem_value_t and \ref control
3604 * for more details.
3605 *
3606 * \param obj The element value object.
3607 * \param idx The index of the member.
3608 * \param val The new value.
3609 */
snd_ctl_elem_value_set_byte(snd_ctl_elem_value_t * obj,unsigned int idx,unsigned char val)3610 void snd_ctl_elem_value_set_byte(snd_ctl_elem_value_t *obj, unsigned int idx, unsigned char val)
3611 {
3612 assert(obj);
3613 assert(idx < ARRAY_SIZE(obj->value.bytes.data));
3614 obj->value.bytes.data[idx] = val;
3615 }
3616
3617 /**
3618 * \brief Replace the data stored within the element.
3619 *
3620 * Use this function if the element is of type SNDRV_CTL_ELEM_TYPE_BYTES. It
3621 * replaces the data stored in the element. Note that "bytes" elements don't
3622 * have members. They have only one single block of data.
3623 *
3624 * See \ref snd_ctl_elem_value_t and \ref control for more details.
3625 *
3626 * \param obj The element value object.
3627 * \param data Pointer to the new data.
3628 * \param size The size of the new data, in bytes.
3629 */
snd_ctl_elem_set_bytes(snd_ctl_elem_value_t * obj,void * data,size_t size)3630 void snd_ctl_elem_set_bytes(snd_ctl_elem_value_t *obj, void *data, size_t size)
3631 {
3632 assert(obj);
3633 assert(size <= ARRAY_SIZE(obj->value.bytes.data));
3634 memcpy(obj->value.bytes.data, data, size);
3635 }
3636
3637 /**
3638 * \brief Get the data stored within the element.
3639 *
3640 * Use this function if the element is of type SNDRV_CTL_ELEM_TYPE_BYTES. It
3641 * returns the data stored in the element. Note that "bytes" elements don't have
3642 * members. They have only one single block of data.
3643 *
3644 * See \ref snd_ctl_elem_value_t and \ref control for more details.
3645 *
3646 * \param obj The element value object.
3647 * \return Pointer to the elements data.
3648 */
snd_ctl_elem_value_get_bytes(const snd_ctl_elem_value_t * obj)3649 const void * snd_ctl_elem_value_get_bytes(const snd_ctl_elem_value_t *obj)
3650 {
3651 assert(obj);
3652 return obj->value.bytes.data;
3653 }
3654
3655 /**
3656 * \brief Get an elements IEC958 data.
3657 *
3658 * Use this function if the element is of type SNDRV_CTL_ELEM_TYPE_IEC958. Note that
3659 * "IEC958" elements don't have members. They have only one single
3660 * IEC958 information block.
3661 *
3662 * See \ref snd_ctl_elem_value_t and \ref control for more details.
3663 *
3664 * \param obj The element value object.
3665 * \param ptr Pointer to an IEC958 structure. The data is stored there.
3666 */
snd_ctl_elem_value_get_iec958(const snd_ctl_elem_value_t * obj,snd_aes_iec958_t * ptr)3667 void snd_ctl_elem_value_get_iec958(const snd_ctl_elem_value_t *obj, snd_aes_iec958_t *ptr)
3668 {
3669 assert(obj && ptr);
3670 memcpy(ptr, &obj->value.iec958, sizeof(*ptr));
3671 }
3672
3673 /**
3674 * \brief Set an elements IEC958 data.
3675 *
3676 * Use this function if the element is of type SNDRV_CTL_ELEM_TYPE_IEC958. Note
3677 * that "IEC958" elements don't have members. They have only one single IEC958
3678 * information block.
3679 *
3680 * See \ref snd_ctl_elem_value_t and \ref control for more details.
3681 *
3682 * \param obj The element value object.
3683 * \param ptr Pointer to the new IEC958 data.
3684 */
snd_ctl_elem_value_set_iec958(snd_ctl_elem_value_t * obj,const snd_aes_iec958_t * ptr)3685 void snd_ctl_elem_value_set_iec958(snd_ctl_elem_value_t *obj, const snd_aes_iec958_t *ptr)
3686 {
3687 assert(obj && ptr);
3688 memcpy(&obj->value.iec958, ptr, sizeof(obj->value.iec958));
3689 }
3690