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