diff options
Diffstat (limited to 'alsa-lib/test/midiloop.c')
-rw-r--r-- | alsa-lib/test/midiloop.c | 190 |
1 files changed, 190 insertions, 0 deletions
diff --git a/alsa-lib/test/midiloop.c b/alsa-lib/test/midiloop.c new file mode 100644 index 0000000..31fbcd3 --- /dev/null +++ b/alsa-lib/test/midiloop.c @@ -0,0 +1,190 @@ +#include <stdlib.h> +#include <stdio.h> +#include <ctype.h> +#include <sys/time.h> +#include "../include/asoundlib.h" +#include <string.h> +#include <signal.h> + +static void usage(void) +{ + fprintf(stderr, "Usage: midiloop [options]\n"); + fprintf(stderr, " options:\n"); + fprintf(stderr, " -v: verbose mode\n"); + fprintf(stderr, " -i <rawmidi device> : test input device\n"); + fprintf(stderr, " -o <rawmidi device> : test output device\n"); +} + +int stop = 0; + +void sighandler(int dummy ATTRIBUTE_UNUSED) +{ + stop=1; +} + +long long timediff(struct timeval t1, struct timeval t2) +{ + signed long l; + + t1.tv_sec -= t2.tv_sec; + l = (signed long) t1.tv_usec - (signed long) t2.tv_usec; + if (l < 0) { + t1.tv_sec--; + l = -l; + l %= 1000000; + } + return ((long long)t1.tv_sec * (long long)1000000) + (long long)l; +} + +int writepattern(snd_rawmidi_t *handle_out, unsigned char *obuf) +{ + int patsize, i; + + patsize = 0; + for (i = 0; i < 15; i++) { + obuf[patsize++] = 0x90 + i; + obuf[patsize++] = 0x40; + obuf[patsize++] = 0x3f; + obuf[patsize++] = 0xb0 + i; + obuf[patsize++] = 0x2e; + obuf[patsize++] = 0x7a; + obuf[patsize++] = 0x80 + i; + obuf[patsize++] = 0x23; + obuf[patsize++] = 0x24; + obuf[patsize++] = 0xf0; + obuf[patsize++] = i; + obuf[patsize++] = 0xf7; + } + i = snd_rawmidi_write(handle_out, obuf, patsize); + if (i != patsize) { + printf("Written only %i bytes from %i bytes\n", i, patsize); + exit(EXIT_FAILURE); + } + return patsize; +} + +int main(int argc, char** argv) +{ + int i, j, k, opos, ipos, patsize; + int err; + int verbose = 0; + snd_rawmidi_t *handle_in = NULL, *handle_out = NULL; + unsigned char ibuf[512], obuf[512]; + char *iname = "hw:0,0", *oname = "hw:0,0"; + struct timeval start, end; + long long diff; + snd_rawmidi_status_t *istat, *ostat; + + for (i = 1 ; i<argc ; i++) { + if (argv[i][0]=='-') { + if (!strcmp(argv[i], "--help")) { + usage(); + return 0; + } + switch (argv[i][1]) { + case 'h': + usage(); + return 0; + case 'v': + verbose = 1; + break; + case 'i': + if (i + 1 < argc) + iname = argv[++i]; + break; + case 'o': + if (i + 1 < argc) + oname = argv[++i]; + break; + } + } + } + + if (iname == NULL) + iname = oname; + if (oname == NULL) + oname = iname; + + if (verbose) { + fprintf(stderr, "Using: \n"); + fprintf(stderr, " Input: %s Output: %s\n", iname, oname); + } + + err = snd_rawmidi_open(&handle_in, NULL, iname, SND_RAWMIDI_NONBLOCK); + if (err) { + fprintf(stderr,"snd_rawmidi_open %s failed: %d\n",iname,err); + exit(EXIT_FAILURE); + } + + err = snd_rawmidi_open(NULL, &handle_out, oname, 0); + if (err) { + fprintf(stderr,"snd_rawmidi_open %s failed: %d\n",oname,err); + exit(EXIT_FAILURE); + } + + signal(SIGINT, sighandler); + + i = snd_rawmidi_read(handle_in, ibuf, sizeof(ibuf)); + if (i > 0) { + printf("Read ahead: %i\n", i); + for (j = 0; j < i; j++) + printf("%02x:", ibuf[j]); + printf("\n"); + exit(EXIT_FAILURE); + } + + snd_rawmidi_nonblock(handle_in, 0); + + patsize = writepattern(handle_out, obuf); + gettimeofday(&start, NULL); + patsize = writepattern(handle_out, obuf); + + k = ipos = opos = err = 0; + while (!stop) { + i = snd_rawmidi_read(handle_in, ibuf, sizeof(ibuf)); + for (j = 0; j < i; j++, ipos++) + if (obuf[k] != ibuf[j]) { + printf("ipos = %i, i[0x%x] != o[0x%x]\n", ipos, ibuf[j], obuf[k]); + if (opos > 0) + stop = 1; + } else { + printf("match success: ipos = %i, opos = %i [%i:0x%x]\n", ipos, opos, k, obuf[k]); + k++; opos++; + if (k >= patsize) { + patsize = writepattern(handle_out, obuf); + k = 0; + } + } + } + + gettimeofday(&end, NULL); + + printf("End...\n"); + + snd_rawmidi_status_alloca(&istat); + snd_rawmidi_status_alloca(&ostat); + err = snd_rawmidi_status(handle_in, istat); + if (err < 0) + fprintf(stderr, "input stream status error: %d\n", err); + err = snd_rawmidi_status(handle_out, ostat); + if (err < 0) + fprintf(stderr, "output stream status error: %d\n", err); + printf("input.status.avail = %i\n", snd_rawmidi_status_get_avail(istat)); + printf("input.status.xruns = %i\n", snd_rawmidi_status_get_xruns(istat)); + printf("output.status.avail = %i\n", snd_rawmidi_status_get_avail(ostat)); + printf("output.status.xruns = %i\n", snd_rawmidi_status_get_xruns(ostat)); + + diff = timediff(end, start); + printf("Time diff: %Liusec (%Li bytes/sec)\n", diff, ((long long)opos * 1000000) / diff); + + if (verbose) { + fprintf(stderr,"Closing\n"); + } + + snd_rawmidi_drain(handle_in); + snd_rawmidi_close(handle_in); + snd_rawmidi_drain(handle_out); + snd_rawmidi_close(handle_out); + + return 0; +} |