OSDN Git Service

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