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