tizen 2.3.1 release
[external/alsa-lib.git] / test / midiloop.c
1 #include <stdlib.h>
2 #include <stdio.h>
3 #include <ctype.h>
4 #include <sys/time.h>
5 #include "../include/asoundlib.h"
6 #include <string.h>
7 #include <signal.h>
8
9 static void usage(void)
10 {
11         fprintf(stderr, "Usage: midiloop [options]\n");
12         fprintf(stderr, "  options:\n");
13         fprintf(stderr, "    -v: verbose mode\n");
14         fprintf(stderr, "    -i <rawmidi device> : test input device\n");
15         fprintf(stderr, "    -o <rawmidi device> : test output device\n");
16 }
17
18 int stop = 0;
19
20 void sighandler(int dummy ATTRIBUTE_UNUSED)
21 {
22         stop=1;
23 }
24
25 long long timediff(struct timeval t1, struct timeval t2)
26 {
27         signed long l;
28
29         t1.tv_sec -= t2.tv_sec;
30         l = (signed long) t1.tv_usec - (signed long) t2.tv_usec;
31         if (l < 0) {
32                 t1.tv_sec--;
33                 l = -l;
34                 l %= 1000000;
35         }
36         return ((long long)t1.tv_sec * (long long)1000000) + (long long)l;
37 }
38
39 int writepattern(snd_rawmidi_t *handle_out, unsigned char *obuf)
40 {
41         int patsize, i;
42
43         patsize = 0;
44         for (i = 0; i < 15; i++) {
45                 obuf[patsize++] = 0x90 + i;
46                 obuf[patsize++] = 0x40;
47                 obuf[patsize++] = 0x3f;
48                 obuf[patsize++] = 0xb0 + i;
49                 obuf[patsize++] = 0x2e;
50                 obuf[patsize++] = 0x7a;
51                 obuf[patsize++] = 0x80 + i;
52                 obuf[patsize++] = 0x23;
53                 obuf[patsize++] = 0x24;
54                 obuf[patsize++] = 0xf0;
55                 obuf[patsize++] = i;
56                 obuf[patsize++] = 0xf7;
57         }
58         i = snd_rawmidi_write(handle_out, obuf, patsize);
59         if (i != patsize) {
60                 printf("Written only %i bytes from %i bytes\n", i, patsize);
61                 exit(EXIT_FAILURE);
62         }
63         return patsize;
64 }
65
66 int main(int argc, char** argv)
67 {
68         int i, j, k, opos, ipos, patsize;
69         int err;
70         int verbose = 0;
71         snd_rawmidi_t *handle_in = NULL, *handle_out = NULL;
72         unsigned char ibuf[512], obuf[512];
73         char *iname = "hw:0,0", *oname = "hw:0,0";
74         struct timeval start, end;
75         long long diff;
76         snd_rawmidi_status_t *istat, *ostat;
77         
78         for (i = 1 ; i<argc ; i++) {
79                 if (argv[i][0]=='-') {
80                         if (!strcmp(argv[i], "--help")) {
81                                 usage();
82                                 return 0;
83                         }
84                         switch (argv[i][1]) {
85                                 case 'h':
86                                         usage();
87                                         return 0;
88                                 case 'v':
89                                         verbose = 1;
90                                         break;
91                                 case 'i':
92                                         if (i + 1 < argc)
93                                                 iname = argv[++i];
94                                         break;
95                                 case 'o':
96                                         if (i + 1 < argc)
97                                                 oname = argv[++i];
98                                         break;
99                         }                       
100                 }
101         }
102
103         if (iname == NULL)
104                 iname = oname;
105         if (oname == NULL)
106                 oname = iname;
107
108         if (verbose) {
109                 fprintf(stderr, "Using: \n");
110                 fprintf(stderr, "  Input: %s  Output: %s\n", iname, oname);
111         }
112         
113         err = snd_rawmidi_open(&handle_in, NULL, iname, SND_RAWMIDI_NONBLOCK);
114         if (err) {
115                 fprintf(stderr,"snd_rawmidi_open %s failed: %d\n",iname,err);
116                 exit(EXIT_FAILURE);
117         }
118
119         err = snd_rawmidi_open(NULL, &handle_out, oname, 0);
120         if (err) {
121                 fprintf(stderr,"snd_rawmidi_open %s failed: %d\n",oname,err);
122                 exit(EXIT_FAILURE);
123         }
124
125         signal(SIGINT, sighandler);
126
127         i = snd_rawmidi_read(handle_in, ibuf, sizeof(ibuf));
128         if (i > 0) {
129                 printf("Read ahead: %i\n", i);
130                 for (j = 0; j < i; j++)
131                         printf("%02x:", ibuf[j]);
132                 printf("\n");
133                 exit(EXIT_FAILURE);
134         }
135
136         snd_rawmidi_nonblock(handle_in, 0);
137
138         patsize = writepattern(handle_out, obuf);
139         gettimeofday(&start, NULL);
140         patsize = writepattern(handle_out, obuf);
141
142         k = ipos = opos = err = 0;
143         while (!stop) {
144                 i = snd_rawmidi_read(handle_in, ibuf, sizeof(ibuf));
145                 for (j = 0; j < i; j++, ipos++)
146                         if (obuf[k] != ibuf[j]) {
147                                 printf("ipos = %i, i[0x%x] != o[0x%x]\n", ipos, ibuf[j], obuf[k]);
148                                 if (opos > 0)
149                                         stop = 1;
150                         } else {
151                                 printf("match success: ipos = %i, opos = %i [%i:0x%x]\n", ipos, opos, k, obuf[k]);
152                                 k++; opos++;
153                                 if (k >= patsize) {
154                                         patsize = writepattern(handle_out, obuf);
155                                         k = 0;
156                                 }
157                         }
158         }
159
160         gettimeofday(&end, NULL);
161
162         printf("End...\n");
163
164         snd_rawmidi_status_alloca(&istat);
165         snd_rawmidi_status_alloca(&ostat);
166         err = snd_rawmidi_status(handle_in, istat);
167         if (err < 0)
168                 fprintf(stderr, "input stream status error: %d\n", err);
169         err = snd_rawmidi_status(handle_out, ostat);
170         if (err < 0)
171                 fprintf(stderr, "output stream status error: %d\n", err);
172         printf("input.status.avail = %zi\n", snd_rawmidi_status_get_avail(istat));
173         printf("input.status.xruns = %zi\n", snd_rawmidi_status_get_xruns(istat));
174         printf("output.status.avail = %zi\n", snd_rawmidi_status_get_avail(ostat));
175         printf("output.status.xruns = %zi\n", snd_rawmidi_status_get_xruns(ostat));
176
177         diff = timediff(end, start);
178         printf("Time diff: %Liusec (%Li bytes/sec)\n", diff, ((long long)opos * 1000000) / diff);
179
180         if (verbose) {
181                 fprintf(stderr,"Closing\n");
182         }
183         
184         snd_rawmidi_drain(handle_in); 
185         snd_rawmidi_close(handle_in);   
186         snd_rawmidi_drain(handle_out); 
187         snd_rawmidi_close(handle_out);  
188
189         return 0;
190 }