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