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