/test/timer.c

00001 #include <stdio.h>
00002 #include <stdlib.h>
00003 #include <string.h>
00004 #include <sys/time.h>
00005 #include "../include/asoundlib.h"
00006 
00007 void show_status(void *handle)
00008 {
00009         int err;
00010         snd_timer_status_t *status;
00011         
00012         snd_timer_status_alloca(&status);
00013         if ((err = snd_timer_status(handle, status)) < 0) {
00014                 fprintf(stderr, "timer status %i (%s)\n", err, snd_strerror(err));
00015                 return;
00016         }
00017         printf("STATUS:\n");
00018         printf("  resolution = %li\n", snd_timer_status_get_resolution(status));
00019         printf("  lost = %li\n", snd_timer_status_get_lost(status));
00020         printf("  overrun = %li\n", snd_timer_status_get_overrun(status));
00021         printf("  queue = %li\n", snd_timer_status_get_queue(status));
00022 }
00023 
00024 void read_loop(void *handle, int master_ticks, int timeout)
00025 {
00026         int count, err;
00027         struct pollfd *fds;
00028         snd_timer_read_t tr;
00029         
00030         count = snd_timer_poll_descriptors_count(handle);
00031         fds = calloc(count, sizeof(struct pollfd));
00032         if (fds == NULL) {
00033                 fprintf(stderr, "malloc error\n");
00034                 exit(EXIT_FAILURE);
00035         }
00036         while (master_ticks-- > 0) {
00037                 if ((err = snd_timer_poll_descriptors(handle, fds, count)) < 0) {
00038                         fprintf(stderr, "snd_timer_poll_descriptors error: %s\n", snd_strerror(err));
00039                         exit(EXIT_FAILURE);
00040                 }
00041                 if ((err = poll(fds, count, timeout)) < 0) {
00042                         fprintf(stderr, "poll error %i (%s)\n", err, strerror(err));
00043                         exit(EXIT_FAILURE);
00044                 }
00045                 if (err == 0) {
00046                         fprintf(stderr, "timer time out!!\n");
00047                         exit(EXIT_FAILURE);
00048                 }
00049                 while (snd_timer_read(handle, &tr, sizeof(tr)) == sizeof(tr)) {
00050                         printf("TIMER: resolution = %uns, ticks = %u\n",
00051                                 tr.resolution, tr.ticks);
00052                 }
00053         }
00054         free(fds);
00055 }
00056 
00057 static void async_callback(snd_async_handler_t *ahandler)
00058 {
00059         snd_timer_t *handle = snd_async_handler_get_timer(ahandler);
00060         int *acount = snd_async_handler_get_callback_private(ahandler);
00061         snd_timer_read_t tr;
00062         
00063         while (snd_timer_read(handle, &tr, sizeof(tr)) == sizeof(tr)) {
00064                 printf("TIMER: resolution = %uns, ticks = %u\n",
00065                         tr.resolution, tr.ticks);
00066         }
00067         (*acount)++;
00068 }
00069 
00070 int main(int argc, char *argv[])
00071 {
00072         int idx, err;
00073         int class = SND_TIMER_CLASS_GLOBAL;
00074         int sclass = SND_TIMER_CLASS_NONE;
00075         int card = 0;
00076         int device = SND_TIMER_GLOBAL_SYSTEM;
00077         int subdevice = 0;
00078         int list = 0;
00079         int async = 0;
00080         int acount = 0;
00081         snd_timer_t *handle;
00082         snd_timer_id_t *id;
00083         snd_timer_info_t *info;
00084         snd_timer_params_t *params;
00085         char timername[64];
00086         snd_async_handler_t *ahandler;
00087 
00088         snd_timer_id_alloca(&id);
00089         snd_timer_info_alloca(&info);
00090         snd_timer_params_alloca(&params);
00091 
00092         idx = 1;
00093         while (idx < argc) {
00094                 if (!strncmp(argv[idx], "class=", 5)) {
00095                         class = atoi(argv[idx]+6);
00096                 } else if (!strncmp(argv[idx], "sclass=", 6)) {
00097                         sclass = atoi(argv[idx]+7);
00098                 } else if (!strncmp(argv[idx], "card=", 5)) {
00099                         card = atoi(argv[idx]+5);
00100                 } else if (!strncmp(argv[idx], "device=", 7)) {
00101                         device = atoi(argv[idx]+7);
00102                 } else if (!strncmp(argv[idx], "subdevice=", 10)) {
00103                         subdevice = atoi(argv[idx]+10);
00104                 } else if (!strcmp(argv[idx], "list")) {
00105                         list = 1;
00106                 } else if (!strcmp(argv[idx], "async")) {
00107                         async = 1;
00108                 }
00109                 idx++;
00110         }
00111         if (class == SND_TIMER_CLASS_SLAVE && sclass == SND_TIMER_SCLASS_NONE) {
00112                 fprintf(stderr, "slave class is not set\n");
00113                 exit(EXIT_FAILURE);
00114         }
00115         if (list) {
00116                 snd_timer_query_t *qhandle;
00117                 if ((err = snd_timer_query_open(&qhandle, "hw", 0)) < 0) {
00118                         fprintf(stderr, "snd_timer_query_open error: %s\n", snd_strerror(err));
00119                         exit(EXIT_FAILURE);
00120                 }
00121                 snd_timer_id_set_class(id, SND_TIMER_CLASS_NONE);
00122                 while (1) {
00123                         if ((err = snd_timer_query_next_device(qhandle, id)) < 0) {
00124                                 fprintf(stderr, "timer next device error: %s\n", snd_strerror(err));
00125                                 break;
00126                         }
00127                         if (snd_timer_id_get_class(id) < 0)
00128                                 break;
00129                         printf("Timer device: class %i, sclass %i, card %i, device %i, subdevice %i\n",
00130                                         snd_timer_id_get_class(id),
00131                                         snd_timer_id_get_sclass(id),
00132                                         snd_timer_id_get_card(id),
00133                                         snd_timer_id_get_device(id),
00134                                         snd_timer_id_get_subdevice(id));
00135                 }
00136                 snd_timer_query_close(qhandle);
00137                 exit(EXIT_SUCCESS);
00138         }
00139         sprintf(timername, "hw:CLASS=%i,SCLASS=%i,CARD=%i,DEV=%i,SUBDEV=%i", class, sclass, card, device, subdevice);
00140         if ((err = snd_timer_open(&handle, timername, SND_TIMER_OPEN_NONBLOCK))<0) {
00141                 fprintf(stderr, "timer open %i (%s)\n", err, snd_strerror(err));
00142                 exit(EXIT_FAILURE);
00143         }
00144         printf("Using timer class %i, slave class %i, card %i, device %i, subdevice %i\n", class, sclass, card, device, subdevice);
00145         if ((err = snd_timer_info(handle, info)) < 0) {
00146                 fprintf(stderr, "timer info %i (%s)\n", err, snd_strerror(err));
00147                 exit(0);
00148         }
00149         printf("Timer info:\n");
00150         printf("  slave = %s\n", snd_timer_info_is_slave(info) ? "yes" : "no");
00151         printf("  card = %i\n", snd_timer_info_get_card(info));
00152         printf("  id = '%s'\n", snd_timer_info_get_id(info));
00153         printf("  name = '%s'\n", snd_timer_info_get_name(info));
00154         printf("  average resolution = %li\n", snd_timer_info_get_resolution(info));
00155         snd_timer_params_set_auto_start(params, 1);
00156         if (!snd_timer_info_is_slave(info)) {
00157                 snd_timer_params_set_ticks(params, (1000000000 / snd_timer_info_get_resolution(info)) / 50); /* 50Hz */
00158                 if (snd_timer_params_get_ticks(params) < 1)
00159                         snd_timer_params_set_ticks(params, 1);
00160                 printf("Using %li tick(s)\n", snd_timer_params_get_ticks(params));
00161         } else {
00162                 snd_timer_params_set_ticks(params, 1);
00163         }
00164         if ((err = snd_timer_params(handle, params)) < 0) {
00165                 fprintf(stderr, "timer params %i (%s)\n", err, snd_strerror(err));
00166                 exit(0);
00167         }
00168         show_status(handle);
00169         if (async) {
00170                 err = snd_async_add_timer_handler(&ahandler, handle, async_callback, &acount);
00171                 if (err < 0) {
00172                         fprintf(stderr, "unable to add async handler %i (%s)\n", err, snd_strerror(err));
00173                         exit(EXIT_FAILURE);
00174                 }
00175         }
00176         if ((err = snd_timer_start(handle)) < 0) {
00177                 fprintf(stderr, "timer start %i (%s)\n", err, snd_strerror(err));
00178                 exit(EXIT_FAILURE);
00179         }
00180         if (async) {
00181                 /* because all other work is done in the signal handler,
00182                    suspend the process */
00183                 while (acount < 25)
00184                         sleep(1);
00185                 snd_timer_stop(handle);
00186         } else {
00187                 read_loop(handle, 25, snd_timer_info_is_slave(info) ? 10000 : 25);
00188         }
00189         show_status(handle);
00190         snd_timer_close(handle);
00191         printf("Done\n");
00192         return EXIT_SUCCESS;
00193 }

Generated on Sun Apr 1 18:36:41 2007 for ALSA project - the C library reference by  doxygen 1.5.1