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