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(¶ms);
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);
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
00182
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 }