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