Home | History | Annotate | Download | only in timer
      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