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
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 "timer_local.h"
71 
72 #include <signal.h>
73 
snd_timer_open_conf(snd_timer_t ** timer,const char * name,snd_config_t * timer_root,snd_config_t * timer_conf,int mode)74 static 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 
snd_timer_open_noupdate(snd_timer_t ** timer,snd_config_t * root,const char * name,int mode)178 static 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  */
snd_timer_open(snd_timer_t ** timer,const char * name,int mode)202 int 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 	err = snd_config_update_ref(&top);
209 	if (err < 0)
210 		return err;
211 	err = snd_timer_open_noupdate(timer, top, name, mode);
212 	snd_config_unref(top);
213 	return err;
214 }
215 
216 /**
217  * \brief Opens a new connection to the timer interface using local configuration
218  * \param timer Returned handle (NULL if not wanted)
219  * \param name ASCII identifier of the timer handle
220  * \param mode Open mode
221  * \param lconf Local configuration
222  * \return 0 on success otherwise a negative error code
223  *
224  * Opens a new connection to the timer interface specified with
225  * an ASCII identifier and mode.
226  */
snd_timer_open_lconf(snd_timer_t ** timer,const char * name,int mode,snd_config_t * lconf)227 int snd_timer_open_lconf(snd_timer_t **timer, const char *name,
228 			 int mode, snd_config_t *lconf)
229 {
230 	assert(timer && name && lconf);
231 	return snd_timer_open_noupdate(timer, lconf, name, mode);
232 }
233 
234 /**
235  * \brief close timer handle
236  * \param timer timer handle
237  * \return 0 on success otherwise a negative error code
238  *
239  * Closes the specified timer handle and frees all associated
240  * resources.
241  */
snd_timer_close(snd_timer_t * timer)242 int snd_timer_close(snd_timer_t *timer)
243 {
244 	int err;
245   	assert(timer);
246 	while (!list_empty(&timer->async_handlers)) {
247 		snd_async_handler_t *h = list_entry(timer->async_handlers.next, snd_async_handler_t, hlist);
248 		snd_async_del_handler(h);
249 	}
250 	err = timer->ops->close(timer);
251 	if (timer->dl_handle)
252 		snd_dlclose(timer->dl_handle);
253 	free(timer->name);
254 	free(timer);
255 	return err;
256 }
257 
258 /**
259  * \brief get identifier of timer handle
260  * \param timer a timer handle
261  * \return ascii identifier of timer handle
262  *
263  * Returns the ASCII identifier of given timer handle. It's the same
264  * identifier specified in snd_timer_open().
265  */
snd_timer_name(snd_timer_t * timer)266 const char *snd_timer_name(snd_timer_t *timer)
267 {
268 	assert(timer);
269 	return timer->name;
270 }
271 
272 /**
273  * \brief get type of timer handle
274  * \param timer a timer handle
275  * \return type of timer handle
276  *
277  * Returns the type #snd_timer_type_t of given timer handle.
278  */
snd_timer_type(snd_timer_t * timer)279 snd_timer_type_t snd_timer_type(snd_timer_t *timer)
280 {
281 	assert(timer);
282 	return timer->type;
283 }
284 
285 /**
286  * \brief Add an async handler for a timer
287  * \param handler Returned handler handle
288  * \param timer timer handle
289  * \param callback Callback function
290  * \param private_data Callback private data
291  * \return 0 otherwise a negative error code on failure
292  *
293  * The asynchronous callback is called when new timer event occurs.
294  */
snd_async_add_timer_handler(snd_async_handler_t ** handler,snd_timer_t * timer,snd_async_callback_t callback,void * private_data)295 int snd_async_add_timer_handler(snd_async_handler_t **handler, snd_timer_t *timer,
296 				snd_async_callback_t callback, void *private_data)
297 {
298 	int err;
299 	int was_empty;
300 	snd_async_handler_t *h;
301 	err = snd_async_add_handler(&h, timer->poll_fd,
302 				    callback, private_data);
303 	if (err < 0)
304 		return err;
305 	h->type = SND_ASYNC_HANDLER_TIMER;
306 	h->u.timer = timer;
307 	was_empty = list_empty(&timer->async_handlers);
308 	list_add_tail(&h->hlist, &timer->async_handlers);
309 	if (was_empty) {
310 		err = snd_timer_async(timer, snd_async_handler_get_signo(h), getpid());
311 		if (err < 0) {
312 			snd_async_del_handler(h);
313 			return err;
314 		}
315 	}
316 	*handler = h;
317 	return 0;
318 }
319 
320 /**
321  * \brief Return timer handle related to an async handler
322  * \param handler Async handler handle
323  * \return timer handle
324  */
snd_async_handler_get_timer(snd_async_handler_t * handler)325 snd_timer_t *snd_async_handler_get_timer(snd_async_handler_t *handler)
326 {
327 	if (handler->type != SND_ASYNC_HANDLER_TIMER) {
328 		SNDMSG("invalid handler type %d", handler->type);
329 		return NULL;
330 	}
331 	return handler->u.timer;
332 }
333 
334 /**
335  * \brief get count of poll descriptors for timer handle
336  * \param timer timer handle
337  * \return count of poll descriptors
338  */
snd_timer_poll_descriptors_count(snd_timer_t * timer)339 int snd_timer_poll_descriptors_count(snd_timer_t *timer)
340 {
341 	assert(timer);
342 	return 1;
343 }
344 
345 /**
346  * \brief get poll descriptors
347  * \param timer timer handle
348  * \param pfds array of poll descriptors
349  * \param space space in the poll descriptor array
350  * \return count of filled descriptors
351  */
snd_timer_poll_descriptors(snd_timer_t * timer,struct pollfd * pfds,unsigned int space)352 int snd_timer_poll_descriptors(snd_timer_t *timer, struct pollfd *pfds, unsigned int space)
353 {
354 	assert(timer);
355 	if (space >= 1) {
356 		pfds->fd = timer->poll_fd;
357 		switch (timer->mode & O_ACCMODE) {
358 		case O_WRONLY:
359 			pfds->events = POLLOUT|POLLERR|POLLNVAL;
360 			break;
361 		case O_RDONLY:
362 			pfds->events = POLLIN|POLLERR|POLLNVAL;
363 			break;
364 		case O_RDWR:
365 			pfds->events = POLLOUT|POLLIN|POLLERR|POLLNVAL;
366 			break;
367 		default:
368 			return -EIO;
369 		}
370 		return 1;
371 	}
372 	return 0;
373 }
374 
375 /**
376  * \brief get returned events from poll descriptors
377  * \param timer timer handle
378  * \param pfds array of poll descriptors
379  * \param nfds count of poll descriptors
380  * \param revents returned events
381  * \return zero if success, otherwise a negative error code
382  */
snd_timer_poll_descriptors_revents(snd_timer_t * timer,struct pollfd * pfds,unsigned int nfds,unsigned short * revents)383 int snd_timer_poll_descriptors_revents(snd_timer_t *timer, struct pollfd *pfds, unsigned int nfds, unsigned short *revents)
384 {
385         assert(timer && pfds && revents);
386         if (nfds == 1) {
387                 *revents = pfds->revents;
388                 return 0;
389         }
390         return -EINVAL;
391 }
392 
393 /**
394  * \brief set nonblock mode
395  * \param timer timer handle
396  * \param nonblock 0 = block, 1 = nonblock mode
397  * \return 0 on success otherwise a negative error code
398  */
snd_timer_nonblock(snd_timer_t * timer,int nonblock)399 int snd_timer_nonblock(snd_timer_t *timer, int nonblock)
400 {
401 	int err;
402 	assert(timer);
403 	if ((err = timer->ops->nonblock(timer, nonblock)) < 0)
404 		return err;
405 	if (nonblock)
406 		timer->mode |= SND_TIMER_OPEN_NONBLOCK;
407 	else
408 		timer->mode &= ~SND_TIMER_OPEN_NONBLOCK;
409 	return 0;
410 }
411 
412 #ifndef DOC_HIDDEN
413 /**
414  * \brief set async mode
415  * \param timer timer handle
416  * \param sig Signal to raise: < 0 disable, 0 default (SIGIO)
417  * \param pid Process ID to signal: 0 current
418  * \return 0 on success otherwise a negative error code
419  *
420  * A signal is raised every period.
421  */
snd_timer_async(snd_timer_t * timer,int sig,pid_t pid)422 int snd_timer_async(snd_timer_t *timer, int sig, pid_t pid)
423 {
424 	assert(timer);
425         if (sig == 0)
426                 sig = SIGIO;
427 	if (pid == 0)
428 		pid = getpid();
429 	return timer->ops->async(timer, sig, pid);
430 }
431 #endif
432 
433 /**
434  * \brief get size of the snd_timer_info_t structure in bytes
435  * \return size of the snd_timer_info_t structure in bytes
436  */
snd_timer_info_sizeof()437 size_t snd_timer_info_sizeof()
438 {
439 	return sizeof(snd_timer_info_t);
440 }
441 
442 /**
443  * \brief allocate a new snd_timer_info_t structure
444  * \param info returned pointer
445  * \return 0 on success otherwise a negative error code if fails
446  *
447  * Allocates a new snd_timer_info_t structure using the standard
448  * malloc C library function.
449  */
snd_timer_info_malloc(snd_timer_info_t ** info)450 int snd_timer_info_malloc(snd_timer_info_t **info)
451 {
452 	assert(info);
453 	*info = calloc(1, sizeof(snd_timer_info_t));
454 	if (!*info)
455 		return -ENOMEM;
456 	return 0;
457 }
458 
459 /**
460  * \brief frees the snd_timer_info_t structure
461  * \param info pointer to the snd_timer_info_t structure to free
462  *
463  * Frees the given snd_timer_info_t structure using the standard
464  * free C library function.
465  */
snd_timer_info_free(snd_timer_info_t * info)466 void snd_timer_info_free(snd_timer_info_t *info)
467 {
468 	assert(info);
469 	free(info);
470 }
471 
472 /**
473  * \brief copy one snd_timer_info_t structure to another
474  * \param dst destination snd_timer_info_t structure
475  * \param src source snd_timer_info_t structure
476  */
snd_timer_info_copy(snd_timer_info_t * dst,const snd_timer_info_t * src)477 void snd_timer_info_copy(snd_timer_info_t *dst, const snd_timer_info_t *src)
478 {
479 	assert(dst && src);
480 	*dst = *src;
481 }
482 
483 /**
484  * \brief determine, if timer is slave
485  * \param info pointer to #snd_timer_info_t structure
486  * \return nonzero if timer is slave
487  */
snd_timer_info_is_slave(snd_timer_info_t * info)488 int snd_timer_info_is_slave(snd_timer_info_t * info)
489 {
490 	assert(info);
491 	return info->flags & SNDRV_TIMER_FLG_SLAVE ? 1 : 0;
492 }
493 
494 /**
495  * \brief get timer card
496  * \param info pointer to #snd_timer_info_t structure
497  * \return timer card number
498  */
snd_timer_info_get_card(snd_timer_info_t * info)499 int snd_timer_info_get_card(snd_timer_info_t * info)
500 {
501 	assert(info);
502 	return info->card;
503 }
504 
505 /**
506  * \brief get timer id
507  * \param info pointer to #snd_timer_info_t structure
508  * \return timer id
509  */
snd_timer_info_get_id(snd_timer_info_t * info)510 const char *snd_timer_info_get_id(snd_timer_info_t * info)
511 {
512 	assert(info);
513 	return (const char *)info->id;
514 }
515 
516 /**
517  * \brief get timer name
518  * \param info pointer to #snd_timer_info_t structure
519  * \return timer name
520  */
snd_timer_info_get_name(snd_timer_info_t * info)521 const char *snd_timer_info_get_name(snd_timer_info_t * info)
522 {
523 	assert(info);
524 	return (const char *)info->name;
525 }
526 
527 
528 /**
529  * \brief get timer resolution in us
530  * \param info pointer to #snd_timer_info_t structure
531  * \return timer resolution
532  */
snd_timer_info_get_resolution(snd_timer_info_t * info)533 long snd_timer_info_get_resolution(snd_timer_info_t * info)
534 {
535 	assert(info);
536 	return info->resolution;
537 }
538 
539 /**
540  * \brief get information about timer handle
541  * \param timer timer handle
542  * \param info pointer to a snd_timer_info_t structure to be filled
543  * \return 0 on success otherwise a negative error code
544  */
snd_timer_info(snd_timer_t * timer,snd_timer_info_t * info)545 int snd_timer_info(snd_timer_t *timer, snd_timer_info_t * info)
546 {
547 	assert(timer);
548 	assert(info);
549 	return timer->ops->info(timer, info);
550 }
551 
552 /**
553  * \brief get size of the snd_timer_params_t structure in bytes
554  * \return size of the snd_timer_params_t structure in bytes
555  */
snd_timer_params_sizeof()556 size_t snd_timer_params_sizeof()
557 {
558 	return sizeof(snd_timer_params_t);
559 }
560 
561 /**
562  * \brief allocate a new snd_timer_params_t structure
563  * \param params returned pointer
564  * \return 0 on success otherwise a negative error code if fails
565  *
566  * Allocates a new snd_timer_params_t structure using the standard
567  * malloc C library function.
568  */
snd_timer_params_malloc(snd_timer_params_t ** params)569 int snd_timer_params_malloc(snd_timer_params_t **params)
570 {
571 	assert(params);
572 	*params = calloc(1, sizeof(snd_timer_params_t));
573 	if (!*params)
574 		return -ENOMEM;
575 	return 0;
576 }
577 
578 /**
579  * \brief frees the snd_timer_params_t structure
580  * \param params pointer to the snd_timer_params_t structure to free
581  *
582  * Frees the given snd_timer_params_t structure using the standard
583  * free C library function.
584  */
snd_timer_params_free(snd_timer_params_t * params)585 void snd_timer_params_free(snd_timer_params_t *params)
586 {
587 	assert(params);
588 	free(params);
589 }
590 
591 /**
592  * \brief copy one snd_timer_params_t structure to another
593  * \param dst destination snd_timer_params_t structure
594  * \param src source snd_timer_params_t structure
595  */
snd_timer_params_copy(snd_timer_params_t * dst,const snd_timer_params_t * src)596 void snd_timer_params_copy(snd_timer_params_t *dst, const snd_timer_params_t *src)
597 {
598 	assert(dst && src);
599 	*dst = *src;
600 }
601 
602 /**
603  * \brief set timer auto start
604  * \param params pointer to #snd_timer_params_t structure
605  * \param auto_start The boolean value to set
606  */
snd_timer_params_set_auto_start(snd_timer_params_t * params,int auto_start)607 int snd_timer_params_set_auto_start(snd_timer_params_t * params, int auto_start)
608 {
609 	assert(params);
610 	if (auto_start)
611 		params->flags |= SNDRV_TIMER_PSFLG_AUTO;
612 	else
613 		params->flags &= ~SNDRV_TIMER_PSFLG_AUTO;
614 	return 0;
615 }
616 
617 /**
618  * \brief determine if timer has auto start flag
619  * \param params pointer to #snd_timer_params_t structure
620  * \return nonzero if timer has auto start flag
621  */
snd_timer_params_get_auto_start(snd_timer_params_t * params)622 int snd_timer_params_get_auto_start(snd_timer_params_t * params)
623 {
624 	assert(params);
625 	return params->flags & SNDRV_TIMER_PSFLG_AUTO ? 1 : 0;
626 }
627 
628 /**
629  * \brief set timer exclusive use
630  * \param params pointer to #snd_timer_params_t structure
631  * \param exclusive The boolean value to set
632  */
633 #ifndef DOXYGEN
INTERNAL(snd_timer_params_set_exclusive)634 EXPORT_SYMBOL int INTERNAL(snd_timer_params_set_exclusive)(snd_timer_params_t * params, int exclusive)
635 #else
636 int snd_timer_params_set_exclusive(snd_timer_params_t * params, int exclusive)
637 #endif
638 {
639 	assert(params);
640 	if (exclusive)
641 		params->flags |= SNDRV_TIMER_PSFLG_EXCLUSIVE;
642 	else
643 		params->flags &= ~SNDRV_TIMER_PSFLG_EXCLUSIVE;
644 	return 0;
645 }
646 use_default_symbol_version(__snd_timer_params_set_exclusive, snd_timer_params_set_exclusive, ALSA_0.9.0);
647 
648 /**
649  * \brief determine if timer has exclusive flag
650  * \param params pointer to #snd_timer_params_t structure
651  * \return nonzero if timer has exclusive flag
652  */
653 #ifndef DOXYGEN
INTERNAL(snd_timer_params_get_exclusive)654 EXPORT_SYMBOL int INTERNAL(snd_timer_params_get_exclusive)(snd_timer_params_t * params)
655 #else
656 int snd_timer_params_get_exclusive(snd_timer_params_t * params)
657 #endif
658 {
659 	assert(params);
660 	return params->flags & SNDRV_TIMER_PSFLG_EXCLUSIVE ? 1 : 0;
661 }
662 use_default_symbol_version(__snd_timer_params_get_exclusive, snd_timer_params_get_exclusive, ALSA_0.9.0);
663 
664 /**
665  * \brief set timer early event
666  * \param params pointer to #snd_timer_params_t structure
667  * \param early_event The boolean value to set
668  */
snd_timer_params_set_early_event(snd_timer_params_t * params,int early_event)669 int snd_timer_params_set_early_event(snd_timer_params_t * params, int early_event)
670 {
671 	assert(params);
672 	if (early_event)
673 		params->flags |= SNDRV_TIMER_PSFLG_EARLY_EVENT;
674 	else
675 		params->flags &= ~SNDRV_TIMER_PSFLG_EARLY_EVENT;
676 	return 0;
677 }
678 
679 /**
680  * \brief determine if timer has early event flag
681  * \param params pointer to #snd_timer_params_t structure
682  * \return nonzero if timer has early event flag set
683  */
snd_timer_params_get_early_event(snd_timer_params_t * params)684 int snd_timer_params_get_early_event(snd_timer_params_t * params)
685 {
686 	assert(params);
687 	return params->flags & SNDRV_TIMER_PSFLG_EARLY_EVENT ? 1 : 0;
688 }
689 
690 /**
691  * \brief set timer ticks
692  * \param params pointer to #snd_timer_params_t structure
693  * \param ticks Ticks to set
694  */
snd_timer_params_set_ticks(snd_timer_params_t * params,long ticks)695 void snd_timer_params_set_ticks(snd_timer_params_t * params, long ticks)
696 {
697 	assert(params);
698 	params->ticks = ticks;
699 }
700 
701 /**
702  * \brief get timer ticks
703  * \param params pointer to #snd_timer_params_t structure
704  * \return timer ticks
705  */
snd_timer_params_get_ticks(snd_timer_params_t * params)706 long snd_timer_params_get_ticks(snd_timer_params_t * params)
707 {
708 	assert(params);
709 	return params->ticks;
710 }
711 
712 /**
713  * \brief set timer queue size (32-1024)
714  * \param params pointer to #snd_timer_params_t structure
715  * \param queue_size The queue size to set
716  */
snd_timer_params_set_queue_size(snd_timer_params_t * params,long queue_size)717 void snd_timer_params_set_queue_size(snd_timer_params_t * params, long queue_size)
718 {
719 	assert(params);
720 	params->queue_size = queue_size;
721 }
722 
723 /**
724  * \brief get queue size
725  * \param params pointer to #snd_timer_params_t structure
726  * \return queue size
727  */
snd_timer_params_get_queue_size(snd_timer_params_t * params)728 long snd_timer_params_get_queue_size(snd_timer_params_t * params)
729 {
730 	assert(params);
731 	return params->queue_size;
732 }
733 
734 /**
735  * \brief set timer event filter
736  * \param params pointer to #snd_timer_params_t structure
737  * \param filter The event filter bits to set
738  */
739 #ifndef DOXYGEN
INTERNAL(snd_timer_params_set_filter)740 EXPORT_SYMBOL void INTERNAL(snd_timer_params_set_filter)(snd_timer_params_t * params, unsigned int filter)
741 #else
742 void snd_timer_params_set_filter(snd_timer_params_t * params, unsigned int filter)
743 #endif
744 {
745 	assert(params);
746 	params->filter = filter;
747 }
748 use_default_symbol_version(__snd_timer_params_set_filter, snd_timer_params_set_filter, ALSA_0.9.0);
749 
750 /**
751  * \brief get timer event filter
752  * \param params pointer to #snd_timer_params_t structure
753  * \return timer event filter
754  */
755 #ifndef DOXYGEN
INTERNAL(snd_timer_params_get_filter)756 EXPORT_SYMBOL unsigned int INTERNAL(snd_timer_params_get_filter)(snd_timer_params_t * params)
757 #else
758 unsigned int snd_timer_params_get_filter(snd_timer_params_t * params)
759 #endif
760 {
761 	assert(params);
762 	return params->filter;
763 }
764 use_default_symbol_version(__snd_timer_params_get_filter, snd_timer_params_get_filter, ALSA_0.9.0);
765 
766 /**
767  * \brief set parameters for timer handle
768  * \param timer timer handle
769  * \param params pointer to a #snd_timer_params_t structure
770  * \return 0 on success otherwise a negative error code
771  */
snd_timer_params(snd_timer_t * timer,snd_timer_params_t * params)772 int snd_timer_params(snd_timer_t *timer, snd_timer_params_t * params)
773 {
774 	assert(timer);
775 	assert(params);
776 	return timer->ops->params(timer, params);
777 }
778 
779 /**
780  * \brief get size of the snd_timer_status_t structure in bytes
781  * \return size of the snd_timer_status_t structure in bytes
782  */
snd_timer_status_sizeof()783 size_t snd_timer_status_sizeof()
784 {
785 	return sizeof(snd_timer_status_t);
786 }
787 
788 /**
789  * \brief allocate a new snd_timer_status_t structure
790  * \param status returned pointer
791  * \return 0 on success otherwise a negative error code if fails
792  *
793  * Allocates a new snd_timer_status_t structure using the standard
794  * malloc C library function.
795  */
snd_timer_status_malloc(snd_timer_status_t ** status)796 int snd_timer_status_malloc(snd_timer_status_t **status)
797 {
798 	assert(status);
799 	*status = calloc(1, sizeof(snd_timer_status_t));
800 	if (!*status)
801 		return -ENOMEM;
802 	return 0;
803 }
804 
805 /**
806  * \brief frees the snd_timer_status_t structure
807  * \param status pointer to the snd_timer_status_t structure to free
808  *
809  * Frees the given snd_timer_status_t structure using the standard
810  * free C library function.
811  */
snd_timer_status_free(snd_timer_status_t * status)812 void snd_timer_status_free(snd_timer_status_t *status)
813 {
814 	assert(status);
815 	free(status);
816 }
817 
818 /**
819  * \brief copy one snd_timer_status_t structure to another
820  * \param dst destination snd_timer_status_t structure
821  * \param src source snd_timer_status_t structure
822  */
snd_timer_status_copy(snd_timer_status_t * dst,const snd_timer_status_t * src)823 void snd_timer_status_copy(snd_timer_status_t *dst, const snd_timer_status_t *src)
824 {
825 	assert(dst && src);
826 	*dst = *src;
827 }
828 
829 
830 
831 /**
832  * \brief get timestamp
833  * \param status pointer to #snd_timer_status_t structure
834  * \return timestamp
835  */
snd_timer_status_get_timestamp(snd_timer_status_t * status)836 snd_htimestamp_t snd_timer_status_get_timestamp(snd_timer_status_t * status)
837 {
838 	assert(status);
839 	return status->tstamp;
840 }
841 
842 /**
843  * \brief get resolution in us
844  * \param status pointer to #snd_timer_status_t structure
845  * \return resolution
846  */
snd_timer_status_get_resolution(snd_timer_status_t * status)847 long snd_timer_status_get_resolution(snd_timer_status_t * status)
848 {
849 	assert(status);
850 	return status->resolution;
851 }
852 
853 /**
854  * \brief get master tick lost count
855  * \param status pointer to #snd_timer_status_t structure
856  * \return master tick lost count
857  */
snd_timer_status_get_lost(snd_timer_status_t * status)858 long snd_timer_status_get_lost(snd_timer_status_t * status)
859 {
860 	assert(status);
861 	return status->lost;
862 }
863 
864 /**
865  * \brief get overrun count
866  * \param status pointer to #snd_timer_status_t structure
867  * \return overrun count
868  */
snd_timer_status_get_overrun(snd_timer_status_t * status)869 long snd_timer_status_get_overrun(snd_timer_status_t * status)
870 {
871 	assert(status);
872 	return status->overrun;
873 }
874 
875 /**
876  * \brief get count of used queue elements
877  * \param status pointer to #snd_timer_status_t structure
878  * \return count of used queue elements
879  */
snd_timer_status_get_queue(snd_timer_status_t * status)880 long snd_timer_status_get_queue(snd_timer_status_t * status)
881 {
882 	assert(status);
883 	return status->queue;
884 }
885 
886 /**
887  * \brief get status from timer handle
888  * \param timer timer handle
889  * \param status pointer to a #snd_timer_status_t structure to be filled
890  * \return 0 on success otherwise a negative error code
891  */
snd_timer_status(snd_timer_t * timer,snd_timer_status_t * status)892 int snd_timer_status(snd_timer_t *timer, snd_timer_status_t * status)
893 {
894 	assert(timer);
895 	assert(status);
896 	return timer->ops->status(timer, status);
897 }
898 
899 /**
900  * \brief start the timer
901  * \param timer timer handle
902  * \return 0 on success otherwise a negative error code
903  */
snd_timer_start(snd_timer_t * timer)904 int snd_timer_start(snd_timer_t *timer)
905 {
906 	assert(timer);
907 	return timer->ops->rt_start(timer);
908 }
909 
910 /**
911  * \brief stop the timer
912  * \param timer timer handle
913  * \return 0 on success otherwise a negative error code
914  */
snd_timer_stop(snd_timer_t * timer)915 int snd_timer_stop(snd_timer_t *timer)
916 {
917 	assert(timer);
918 	return timer->ops->rt_stop(timer);
919 }
920 
921 /**
922  * \brief continue the timer
923  * \param timer timer handle
924  * \return 0 on success otherwise a negative error code
925  */
snd_timer_continue(snd_timer_t * timer)926 int snd_timer_continue(snd_timer_t *timer)
927 {
928 	assert(timer);
929 	return timer->ops->rt_continue(timer);
930 }
931 
932 /**
933  * \brief read bytes using timer handle
934  * \param timer timer handle
935  * \param buffer buffer to store the input bytes
936  * \param size input buffer size in bytes
937  */
snd_timer_read(snd_timer_t * timer,void * buffer,size_t size)938 ssize_t snd_timer_read(snd_timer_t *timer, void *buffer, size_t size)
939 {
940 	assert(timer);
941 	assert(((timer->mode & O_ACCMODE) == O_RDONLY) || ((timer->mode & O_ACCMODE) == O_RDWR));
942 	assert(buffer || size == 0);
943 	return (timer->ops->read)(timer, buffer, size);
944 }
945 
946 /**
947  * \brief (DEPRECATED) get maximum timer ticks
948  * \param info pointer to #snd_timer_info_t structure
949  * \return maximum timer ticks
950  */
snd_timer_info_get_ticks(snd_timer_info_t * info)951 long snd_timer_info_get_ticks(snd_timer_info_t * info)
952 {
953 	assert(info);
954 	return 1;
955 }
956 #ifndef DOC_HIDDEN
957 link_warning(snd_timer_info_get_ticks, "Warning: snd_timer_info_get_ticks is deprecated");
958 #endif
959