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