1 /** 2 * \file timer/timer.c 3 * \brief Timer Interface 4 * \author Jaroslav Kysela <perex (at) perex.cz> 5 * \date 1998-2001 6 * 7 * Timer Interface is designed to access timers. 8 * See \ref timer page for more details. 9 */ 10 /* 11 * Timer Interface - main file 12 * Copyright (c) 1998-2001 by Jaroslav Kysela <perex (at) perex.cz> 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 timer Timer interface 32 33 <P> Timer interface is designed to use internal timers in sound hardware, but 34 it can be driven with any timer. 35 36 \section timer_general_overview General overview 37 38 The timer implementation uses ring buffer to store information about timing 39 events. In this buffer is recorded count of ticks and current tick resolution 40 in nanoseconds. 41 42 \section timer_open Opening 43 44 Timer devices can be opened in two ways. When #SND_TIMER_OPEN_NONBLOCK flag 45 is used, then the open functions return immediately with -EBUSY error code when 46 resources are occupied with another application. When #SND_TIMER_OPEN_NONBLOCK 47 is not used (by default) the open functions block the application requesting 48 device until resources are not free. 49 50 \section timer_events Events 51 52 Events are read via snd_timer_read() function. 53 54 \section timer_examples Examples 55 56 The full featured examples with cross-links: 57 58 \par Simple timer test program 59 \ref example_test_timer "example code" 60 \par 61 This example shows opening a timer device and reading of timer events. 62 63 */ 64 65 /** 66 * \example ../test/timer.c 67 * \anchor example_test_timer 68 */ 69 70 #include <stdio.h> 71 #include <stdlib.h> 72 #include <unistd.h> 73 #include <string.h> 74 #include <fcntl.h> 75 #include <signal.h> 76 #include <sys/ioctl.h> 77 #include "timer_local.h" 78 79 static int snd_timer_open_conf(snd_timer_t **timer, 80 const char *name, snd_config_t *timer_root, 81 snd_config_t *timer_conf, int mode) 82 { 83 const char *str; 84 char buf[256]; 85 int err; 86 snd_config_t *conf, *type_conf = NULL; 87 snd_config_iterator_t i, next; 88 const char *id; 89 const char *lib = NULL, *open_name = NULL; 90 int (*open_func)(snd_timer_t **, const char *, snd_config_t *, snd_config_t *, int) = NULL; 91 #ifndef PIC 92 extern void *snd_timer_open_symbols(void); 93 #endif 94 void *h = NULL; 95 if (snd_config_get_type(timer_conf) != SND_CONFIG_TYPE_COMPOUND) { 96 if (name) 97 SNDERR("Invalid type for TIMER %s definition", name); 98 else 99 SNDERR("Invalid type for TIMER definition"); 100 return -EINVAL; 101 } 102 err = snd_config_search(timer_conf, "type", &conf); 103 if (err < 0) { 104 SNDERR("type is not defined"); 105 return err; 106 } 107 err = snd_config_get_id(conf, &id); 108 if (err < 0) { 109 SNDERR("unable to get id"); 110 return err; 111 } 112 err = snd_config_get_string(conf, &str); 113 if (err < 0) { 114 SNDERR("Invalid type for %s", id); 115 return err; 116 } 117 err = snd_config_search_definition(timer_root, "timer_type", str, &type_conf); 118 if (err >= 0) { 119 if (snd_config_get_type(type_conf) != SND_CONFIG_TYPE_COMPOUND) { 120 SNDERR("Invalid type for TIMER type %s definition", str); 121 goto _err; 122 } 123 snd_config_for_each(i, next, type_conf) { 124 snd_config_t *n = snd_config_iterator_entry(i); 125 const char *id; 126 if (snd_config_get_id(n, &id) < 0) 127 continue; 128 if (strcmp(id, "comment") == 0) 129 continue; 130 if (strcmp(id, "lib") == 0) { 131 err = snd_config_get_string(n, &lib); 132 if (err < 0) { 133 SNDERR("Invalid type for %s", id); 134 goto _err; 135 } 136 continue; 137 } 138 if (strcmp(id, "open") == 0) { 139 err = snd_config_get_string(n, &open_name); 140 if (err < 0) { 141 SNDERR("Invalid type for %s", id); 142 goto _err; 143 } 144 continue; 145 } 146 SNDERR("Unknown field %s", id); 147 err = -EINVAL; 148 goto _err; 149 } 150 } 151 if (!open_name) { 152 open_name = buf; 153 snprintf(buf, sizeof(buf), "_snd_timer_%s_open", str); 154 } 155 #ifndef PIC 156 snd_timer_open_symbols(); 157 #endif 158 h = snd_dlopen(lib, RTLD_NOW); 159 if (h) 160 open_func = snd_dlsym(h, open_name, SND_DLSYM_VERSION(SND_TIMER_DLSYM_VERSION)); 161 err = 0; 162 if (!h) { 163 SNDERR("Cannot open shared library %s", lib); 164 err = -ENOENT; 165 } else if (!open_func) { 166 SNDERR("symbol %s is not defined inside %s", open_name, lib); 167 snd_dlclose(h); 168 err = -ENXIO; 169 } 170 _err: 171 if (type_conf) 172 snd_config_delete(type_conf); 173 if (! err) { 174 err = open_func(timer, name, timer_root, timer_conf, mode); 175 if (err < 0) 176 snd_dlclose(h); 177 else 178 (*timer)->dl_handle = h; 179 } 180 return err; 181 } 182 183 static int snd_timer_open_noupdate(snd_timer_t **timer, snd_config_t *root, const char *name, int mode) 184 { 185 int err; 186 snd_config_t *timer_conf; 187 err = snd_config_search_definition(root, "timer", name, &timer_conf); 188 if (err < 0) { 189 SNDERR("Unknown timer %s", name); 190 return err; 191 } 192 err = snd_timer_open_conf(timer, name, root, timer_conf, mode); 193 snd_config_delete(timer_conf); 194 return err; 195 } 196 197 /** 198 * \brief Opens a new connection to the timer interface. 199 * \param timer Returned handle (NULL if not wanted) 200 * \param name ASCII identifier of the timer handle 201 * \param mode Open mode 202 * \return 0 on success otherwise a negative error code 203 * 204 * Opens a new connection to the timer interface specified with 205 * an ASCII identifier and mode. 206 */ 207 int snd_timer_open(snd_timer_t **timer, const char *name, int mode) 208 { 209 int err; 210 assert(timer && name); 211 err = snd_config_update(); 212 if (err < 0) 213 return err; 214 return snd_timer_open_noupdate(timer, snd_config, name, mode); 215 } 216 217 /** 218 * \brief Opens a new connection to the timer interface using local configuration 219 * \param timer Returned handle (NULL if not wanted) 220 * \param name ASCII identifier of the timer handle 221 * \param mode Open mode 222 * \param lconf Local configuration 223 * \return 0 on success otherwise a negative error code 224 * 225 * Opens a new connection to the timer interface specified with 226 * an ASCII identifier and mode. 227 */ 228 int snd_timer_open_lconf(snd_timer_t **timer, const char *name, 229 int mode, snd_config_t *lconf) 230 { 231 assert(timer && name && lconf); 232 return snd_timer_open_noupdate(timer, lconf, name, mode); 233 } 234 235 /** 236 * \brief close timer handle 237 * \param timer timer handle 238 * \return 0 on success otherwise a negative error code 239 * 240 * Closes the specified timer handle and frees all associated 241 * resources. 242 */ 243 int snd_timer_close(snd_timer_t *timer) 244 { 245 int err; 246 assert(timer); 247 while (!list_empty(&timer->async_handlers)) { 248 snd_async_handler_t *h = list_entry(timer->async_handlers.next, snd_async_handler_t, hlist); 249 snd_async_del_handler(h); 250 } 251 err = timer->ops->close(timer); 252 if (timer->dl_handle) 253 snd_dlclose(timer->dl_handle); 254 free(timer->name); 255 free(timer); 256 return err; 257 } 258 259 /** 260 * \brief get identifier of timer handle 261 * \param timer a timer handle 262 * \return ascii identifier of timer handle 263 * 264 * Returns the ASCII identifier of given timer handle. It's the same 265 * identifier specified in snd_timer_open(). 266 */ 267 const char *snd_timer_name(snd_timer_t *timer) 268 { 269 assert(timer); 270 return timer->name; 271 } 272 273 /** 274 * \brief get type of timer handle 275 * \param timer a timer handle 276 * \return type of timer handle 277 * 278 * Returns the type #snd_timer_type_t of given timer handle. 279 */ 280 snd_timer_type_t snd_timer_type(snd_timer_t *timer) 281 { 282 assert(timer); 283 return timer->type; 284 } 285 286 /** 287 * \brief Add an async handler for a timer 288 * \param handler Returned handler handle 289 * \param timer timer handle 290 * \param callback Callback function 291 * \param private_data Callback private data 292 * \return 0 otherwise a negative error code on failure 293 * 294 * The asynchronous callback is called when new timer event occurs. 295 */ 296 int snd_async_add_timer_handler(snd_async_handler_t **handler, snd_timer_t *timer, 297 snd_async_callback_t callback, void *private_data) 298 { 299 int err; 300 int was_empty; 301 snd_async_handler_t *h; 302 err = snd_async_add_handler(&h, timer->poll_fd, 303 callback, private_data); 304 if (err < 0) 305 return err; 306 h->type = SND_ASYNC_HANDLER_TIMER; 307 h->u.timer = timer; 308 was_empty = list_empty(&timer->async_handlers); 309 list_add_tail(&h->hlist, &timer->async_handlers); 310 if (was_empty) { 311 err = snd_timer_async(timer, snd_async_handler_get_signo(h), getpid()); 312 if (err < 0) { 313 snd_async_del_handler(h); 314 return err; 315 } 316 } 317 *handler = h; 318 return 0; 319 } 320 321 /** 322 * \brief Return timer handle related to an async handler 323 * \param handler Async handler handle 324 * \return timer handle 325 */ 326 snd_timer_t *snd_async_handler_get_timer(snd_async_handler_t *handler) 327 { 328 if (handler->type != SND_ASYNC_HANDLER_TIMER) { 329 SNDMSG("invalid handler type %d", handler->type); 330 return NULL; 331 } 332 return handler->u.timer; 333 } 334 335 /** 336 * \brief get count of poll descriptors for timer handle 337 * \param timer timer handle 338 * \return count of poll descriptors 339 */ 340 int snd_timer_poll_descriptors_count(snd_timer_t *timer) 341 { 342 assert(timer); 343 return 1; 344 } 345 346 /** 347 * \brief get poll descriptors 348 * \param timer timer handle 349 * \param pfds array of poll descriptors 350 * \param space space in the poll descriptor array 351 * \return count of filled descriptors 352 */ 353 int snd_timer_poll_descriptors(snd_timer_t *timer, struct pollfd *pfds, unsigned int space) 354 { 355 assert(timer); 356 if (space >= 1) { 357 pfds->fd = timer->poll_fd; 358 switch (timer->mode & O_ACCMODE) { 359 case O_WRONLY: 360 pfds->events = POLLOUT|POLLERR|POLLNVAL; 361 break; 362 case O_RDONLY: 363 pfds->events = POLLIN|POLLERR|POLLNVAL; 364 break; 365 case O_RDWR: 366 pfds->events = POLLOUT|POLLIN|POLLERR|POLLNVAL; 367 break; 368 default: 369 return -EIO; 370 } 371 return 1; 372 } 373 return 0; 374 } 375 376 /** 377 * \brief get returned events from poll descriptors 378 * \param timer timer handle 379 * \param pfds array of poll descriptors 380 * \param nfds count of poll descriptors 381 * \param revents returned events 382 * \return zero if success, otherwise a negative error code 383 */ 384 int snd_timer_poll_descriptors_revents(snd_timer_t *timer, struct pollfd *pfds, unsigned int nfds, unsigned short *revents) 385 { 386 assert(timer && pfds && revents); 387 if (nfds == 1) { 388 *revents = pfds->revents; 389 return 0; 390 } 391 return -EINVAL; 392 } 393 394 /** 395 * \brief set nonblock mode 396 * \param timer timer handle 397 * \param nonblock 0 = block, 1 = nonblock mode 398 * \return 0 on success otherwise a negative error code 399 */ 400 int snd_timer_nonblock(snd_timer_t *timer, int nonblock) 401 { 402 int err; 403 assert(timer); 404 if ((err = timer->ops->nonblock(timer, nonblock)) < 0) 405 return err; 406 if (nonblock) 407 timer->mode |= SND_TIMER_OPEN_NONBLOCK; 408 else 409 timer->mode &= ~SND_TIMER_OPEN_NONBLOCK; 410 return 0; 411 } 412 413 #ifndef DOC_HIDDEN 414 /** 415 * \brief set async mode 416 * \param timer timer handle 417 * \param sig Signal to raise: < 0 disable, 0 default (SIGIO) 418 * \param pid Process ID to signal: 0 current 419 * \return 0 on success otherwise a negative error code 420 * 421 * A signal is raised every period. 422 */ 423 int snd_timer_async(snd_timer_t *timer, int sig, pid_t pid) 424 { 425 assert(timer); 426 if (sig == 0) 427 sig = SIGIO; 428 if (pid == 0) 429 pid = getpid(); 430 return timer->ops->async(timer, sig, pid); 431 } 432 #endif 433 434 /** 435 * \brief get size of the snd_timer_info_t structure in bytes 436 * \return size of the snd_timer_info_t structure in bytes 437 */ 438 size_t snd_timer_info_sizeof() 439 { 440 return sizeof(snd_timer_info_t); 441 } 442 443 /** 444 * \brief allocate a new snd_timer_info_t structure 445 * \param info returned pointer 446 * \return 0 on success otherwise a negative error code if fails 447 * 448 * Allocates a new snd_timer_info_t structure using the standard 449 * malloc C library function. 450 */ 451 int snd_timer_info_malloc(snd_timer_info_t **info) 452 { 453 assert(info); 454 *info = calloc(1, sizeof(snd_timer_info_t)); 455 if (!*info) 456 return -ENOMEM; 457 return 0; 458 } 459 460 /** 461 * \brief frees the snd_timer_info_t structure 462 * \param info pointer to the snd_timer_info_t structure to free 463 * 464 * Frees the given snd_timer_info_t structure using the standard 465 * free C library function. 466 */ 467 void snd_timer_info_free(snd_timer_info_t *info) 468 { 469 assert(info); 470 free(info); 471 } 472 473 /** 474 * \brief copy one snd_timer_info_t structure to another 475 * \param dst destination snd_timer_info_t structure 476 * \param src source snd_timer_info_t structure 477 */ 478 void snd_timer_info_copy(snd_timer_info_t *dst, const snd_timer_info_t *src) 479 { 480 assert(dst && src); 481 *dst = *src; 482 } 483 484 /** 485 * \brief determine, if timer is slave 486 * \param info pointer to #snd_timer_info_t structure 487 * \return nonzero if timer is slave 488 */ 489 int snd_timer_info_is_slave(snd_timer_info_t * info) 490 { 491 assert(info); 492 return info->flags & SNDRV_TIMER_FLG_SLAVE ? 1 : 0; 493 } 494 495 /** 496 * \brief get timer card 497 * \param info pointer to #snd_timer_info_t structure 498 * \return timer card number 499 */ 500 int snd_timer_info_get_card(snd_timer_info_t * info) 501 { 502 assert(info); 503 return info->card; 504 } 505 506 /** 507 * \brief get timer id 508 * \param info pointer to #snd_timer_info_t structure 509 * \return timer id 510 */ 511 const char *snd_timer_info_get_id(snd_timer_info_t * info) 512 { 513 assert(info); 514 return (const char *)info->id; 515 } 516 517 /** 518 * \brief get timer name 519 * \param info pointer to #snd_timer_info_t structure 520 * \return timer name 521 */ 522 const char *snd_timer_info_get_name(snd_timer_info_t * info) 523 { 524 assert(info); 525 return (const char *)info->name; 526 } 527 528 529 /** 530 * \brief get timer resolution in us 531 * \param info pointer to #snd_timer_info_t structure 532 * \return timer resolution 533 */ 534 long snd_timer_info_get_resolution(snd_timer_info_t * info) 535 { 536 assert(info); 537 return info->resolution; 538 } 539 540 /** 541 * \brief get information about timer handle 542 * \param timer timer handle 543 * \param info pointer to a snd_timer_info_t structure to be filled 544 * \return 0 on success otherwise a negative error code 545 */ 546 int snd_timer_info(snd_timer_t *timer, snd_timer_info_t * info) 547 { 548 assert(timer); 549 assert(info); 550 return timer->ops->info(timer, info); 551 } 552 553 /** 554 * \brief get size of the snd_timer_params_t structure in bytes 555 * \return size of the snd_timer_params_t structure in bytes 556 */ 557 size_t snd_timer_params_sizeof() 558 { 559 return sizeof(snd_timer_params_t); 560 } 561 562 /** 563 * \brief allocate a new snd_timer_params_t structure 564 * \param params returned pointer 565 * \return 0 on success otherwise a negative error code if fails 566 * 567 * Allocates a new snd_timer_params_t structure using the standard 568 * malloc C library function. 569 */ 570 int snd_timer_params_malloc(snd_timer_params_t **params) 571 { 572 assert(params); 573 *params = calloc(1, sizeof(snd_timer_params_t)); 574 if (!*params) 575 return -ENOMEM; 576 return 0; 577 } 578 579 /** 580 * \brief frees the snd_timer_params_t structure 581 * \param params pointer to the snd_timer_params_t structure to free 582 * 583 * Frees the given snd_timer_params_t structure using the standard 584 * free C library function. 585 */ 586 void snd_timer_params_free(snd_timer_params_t *params) 587 { 588 assert(params); 589 free(params); 590 } 591 592 /** 593 * \brief copy one snd_timer_params_t structure to another 594 * \param dst destination snd_timer_params_t structure 595 * \param src source snd_timer_params_t structure 596 */ 597 void snd_timer_params_copy(snd_timer_params_t *dst, const snd_timer_params_t *src) 598 { 599 assert(dst && src); 600 *dst = *src; 601 } 602 603 /** 604 * \brief set timer auto start 605 * \param params pointer to #snd_timer_params_t structure 606 * \param auto_start The boolean value to set 607 */ 608 int snd_timer_params_set_auto_start(snd_timer_params_t * params, int auto_start) 609 { 610 assert(params); 611 if (auto_start) 612 params->flags |= SNDRV_TIMER_PSFLG_AUTO; 613 else 614 params->flags &= ~SNDRV_TIMER_PSFLG_AUTO; 615 return 0; 616 } 617 618 /** 619 * \brief determine if timer has auto start flag 620 * \param params pointer to #snd_timer_params_t structure 621 * \return nonzero if timer has auto start flag 622 */ 623 int snd_timer_params_get_auto_start(snd_timer_params_t * params) 624 { 625 assert(params); 626 return params->flags & SNDRV_TIMER_PSFLG_AUTO ? 1 : 0; 627 } 628 629 /** 630 * \brief set timer exclusive use 631 * \param params pointer to #snd_timer_params_t structure 632 * \param exclusive The boolean value to set 633 */ 634 #ifndef DOXYGEN 635 int INTERNAL(snd_timer_params_set_exclusive)(snd_timer_params_t * params, int exclusive) 636 #else 637 int snd_timer_params_set_exclusive(snd_timer_params_t * params, int exclusive) 638 #endif 639 { 640 assert(params); 641 if (exclusive) 642 params->flags |= SNDRV_TIMER_PSFLG_EXCLUSIVE; 643 else 644 params->flags &= ~SNDRV_TIMER_PSFLG_EXCLUSIVE; 645 return 0; 646 } 647 use_default_symbol_version(__snd_timer_params_set_exclusive, snd_timer_params_set_exclusive, ALSA_0.9.0); 648 649 /** 650 * \brief determine if timer has exclusive flag 651 * \param params pointer to #snd_timer_params_t structure 652 * \return nonzero if timer has exclusive flag 653 */ 654 #ifndef DOXYGEN 655 int INTERNAL(snd_timer_params_get_exclusive)(snd_timer_params_t * params) 656 #else 657 int snd_timer_params_get_exclusive(snd_timer_params_t * params) 658 #endif 659 { 660 assert(params); 661 return params->flags & SNDRV_TIMER_PSFLG_EXCLUSIVE ? 1 : 0; 662 } 663 use_default_symbol_version(__snd_timer_params_get_exclusive, snd_timer_params_get_exclusive, ALSA_0.9.0); 664 665 /** 666 * \brief set timer early event 667 * \param params pointer to #snd_timer_params_t structure 668 * \param early_event The boolean value to set 669 */ 670 int snd_timer_params_set_early_event(snd_timer_params_t * params, int early_event) 671 { 672 assert(params); 673 if (early_event) 674 params->flags |= SNDRV_TIMER_PSFLG_EARLY_EVENT; 675 else 676 params->flags &= ~SNDRV_TIMER_PSFLG_EARLY_EVENT; 677 return 0; 678 } 679 680 /** 681 * \brief determine if timer has early event flag 682 * \param params pointer to #snd_timer_params_t structure 683 * \return nonzero if timer has early event flag set 684 */ 685 int snd_timer_params_get_early_event(snd_timer_params_t * params) 686 { 687 assert(params); 688 return params->flags & SNDRV_TIMER_PSFLG_EARLY_EVENT ? 1 : 0; 689 } 690 691 /** 692 * \brief set timer ticks 693 * \param params pointer to #snd_timer_params_t structure 694 * \param ticks Ticks to set 695 */ 696 void snd_timer_params_set_ticks(snd_timer_params_t * params, long ticks) 697 { 698 assert(params); 699 params->ticks = ticks; 700 } 701 702 /** 703 * \brief get timer ticks 704 * \param params pointer to #snd_timer_params_t structure 705 * \return timer ticks 706 */ 707 long snd_timer_params_get_ticks(snd_timer_params_t * params) 708 { 709 assert(params); 710 return params->ticks; 711 } 712 713 /** 714 * \brief set timer queue size (32-1024) 715 * \param params pointer to #snd_timer_params_t structure 716 * \param queue_size The queue size to set 717 */ 718 void snd_timer_params_set_queue_size(snd_timer_params_t * params, long queue_size) 719 { 720 assert(params); 721 params->queue_size = queue_size; 722 } 723 724 /** 725 * \brief get queue size 726 * \param params pointer to #snd_timer_params_t structure 727 * \return queue size 728 */ 729 long snd_timer_params_get_queue_size(snd_timer_params_t * params) 730 { 731 assert(params); 732 return params->queue_size; 733 } 734 735 /** 736 * \brief set timer event filter 737 * \param params pointer to #snd_timer_params_t structure 738 * \param filter The event filter bits to set 739 */ 740 #ifndef DOXYGEN 741 void INTERNAL(snd_timer_params_set_filter)(snd_timer_params_t * params, unsigned int filter) 742 #else 743 void snd_timer_params_set_filter(snd_timer_params_t * params, unsigned int filter) 744 #endif 745 { 746 assert(params); 747 params->filter = filter; 748 } 749 use_default_symbol_version(__snd_timer_params_set_filter, snd_timer_params_set_filter, ALSA_0.9.0); 750 751 /** 752 * \brief get timer event filter 753 * \param params pointer to #snd_timer_params_t structure 754 * \return timer event filter 755 */ 756 #ifndef DOXYGEN 757 unsigned int INTERNAL(snd_timer_params_get_filter)(snd_timer_params_t * params) 758 #else 759 unsigned int snd_timer_params_get_filter(snd_timer_params_t * params) 760 #endif 761 { 762 assert(params); 763 return params->filter; 764 } 765 use_default_symbol_version(__snd_timer_params_get_filter, snd_timer_params_get_filter, ALSA_0.9.0); 766 767 /** 768 * \brief set parameters for timer handle 769 * \param timer timer handle 770 * \param params pointer to a #snd_timer_params_t structure 771 * \return 0 on success otherwise a negative error code 772 */ 773 int snd_timer_params(snd_timer_t *timer, snd_timer_params_t * params) 774 { 775 assert(timer); 776 assert(params); 777 return timer->ops->params(timer, params); 778 } 779 780 /** 781 * \brief get size of the snd_timer_status_t structure in bytes 782 * \return size of the snd_timer_status_t structure in bytes 783 */ 784 size_t snd_timer_status_sizeof() 785 { 786 return sizeof(snd_timer_status_t); 787 } 788 789 /** 790 * \brief allocate a new snd_timer_status_t structure 791 * \param status returned pointer 792 * \return 0 on success otherwise a negative error code if fails 793 * 794 * Allocates a new snd_timer_status_t structure using the standard 795 * malloc C library function. 796 */ 797 int snd_timer_status_malloc(snd_timer_status_t **status) 798 { 799 assert(status); 800 *status = calloc(1, sizeof(snd_timer_status_t)); 801 if (!*status) 802 return -ENOMEM; 803 return 0; 804 } 805 806 /** 807 * \brief frees the snd_timer_status_t structure 808 * \param status pointer to the snd_timer_status_t structure to free 809 * 810 * Frees the given snd_timer_status_t structure using the standard 811 * free C library function. 812 */ 813 void snd_timer_status_free(snd_timer_status_t *status) 814 { 815 assert(status); 816 free(status); 817 } 818 819 /** 820 * \brief copy one snd_timer_status_t structure to another 821 * \param dst destination snd_timer_status_t structure 822 * \param src source snd_timer_status_t structure 823 */ 824 void snd_timer_status_copy(snd_timer_status_t *dst, const snd_timer_status_t *src) 825 { 826 assert(dst && src); 827 *dst = *src; 828 } 829 830 831 832 /** 833 * \brief get timestamp 834 * \param status pointer to #snd_timer_status_t structure 835 * \return timestamp 836 */ 837 snd_htimestamp_t snd_timer_status_get_timestamp(snd_timer_status_t * status) 838 { 839 assert(status); 840 return status->tstamp; 841 } 842 843 /** 844 * \brief get resolution in us 845 * \param status pointer to #snd_timer_status_t structure 846 * \return resolution 847 */ 848 long snd_timer_status_get_resolution(snd_timer_status_t * status) 849 { 850 assert(status); 851 return status->resolution; 852 } 853 854 /** 855 * \brief get master tick lost count 856 * \param status pointer to #snd_timer_status_t structure 857 * \return master tick lost count 858 */ 859 long snd_timer_status_get_lost(snd_timer_status_t * status) 860 { 861 assert(status); 862 return status->lost; 863 } 864 865 /** 866 * \brief get overrun count 867 * \param status pointer to #snd_timer_status_t structure 868 * \return overrun count 869 */ 870 long snd_timer_status_get_overrun(snd_timer_status_t * status) 871 { 872 assert(status); 873 return status->overrun; 874 } 875 876 /** 877 * \brief get count of used queue elements 878 * \param status pointer to #snd_timer_status_t structure 879 * \return count of used queue elements 880 */ 881 long snd_timer_status_get_queue(snd_timer_status_t * status) 882 { 883 assert(status); 884 return status->queue; 885 } 886 887 /** 888 * \brief get status from timer handle 889 * \param timer timer handle 890 * \param status pointer to a #snd_timer_status_t structure to be filled 891 * \return 0 on success otherwise a negative error code 892 */ 893 int snd_timer_status(snd_timer_t *timer, snd_timer_status_t * status) 894 { 895 assert(timer); 896 assert(status); 897 return timer->ops->status(timer, status); 898 } 899 900 /** 901 * \brief start the timer 902 * \param timer timer handle 903 * \return 0 on success otherwise a negative error code 904 */ 905 int snd_timer_start(snd_timer_t *timer) 906 { 907 assert(timer); 908 return timer->ops->rt_start(timer); 909 } 910 911 /** 912 * \brief stop the timer 913 * \param timer timer handle 914 * \return 0 on success otherwise a negative error code 915 */ 916 int snd_timer_stop(snd_timer_t *timer) 917 { 918 assert(timer); 919 return timer->ops->rt_stop(timer); 920 } 921 922 /** 923 * \brief continue the timer 924 * \param timer timer handle 925 * \return 0 on success otherwise a negative error code 926 */ 927 int snd_timer_continue(snd_timer_t *timer) 928 { 929 assert(timer); 930 return timer->ops->rt_continue(timer); 931 } 932 933 /** 934 * \brief read bytes using timer handle 935 * \param timer timer handle 936 * \param buffer buffer to store the input bytes 937 * \param size input buffer size in bytes 938 */ 939 ssize_t snd_timer_read(snd_timer_t *timer, void *buffer, size_t size) 940 { 941 assert(timer); 942 assert(((timer->mode & O_ACCMODE) == O_RDONLY) || ((timer->mode & O_ACCMODE) == O_RDWR)); 943 assert(buffer || size == 0); 944 return (timer->ops->read)(timer, buffer, size); 945 } 946 947 /** 948 * \brief (DEPRECATED) get maximum timer ticks 949 * \param info pointer to #snd_timer_info_t structure 950 * \return maximum timer ticks 951 */ 952 long snd_timer_info_get_ticks(snd_timer_info_t * info) 953 { 954 assert(info); 955 return 1; 956 } 957 #ifndef DOC_HIDDEN 958 link_warning(snd_timer_info_get_ticks, "Warning: snd_timer_info_get_ticks is deprecated"); 959 #endif 960