#include #include #include #include #include "../include/asoundlib.h" #include #include static void usage(void) { fprintf(stderr, "Usage: midiloop [options]\n"); fprintf(stderr, " options:\n"); fprintf(stderr, " -v: verbose mode\n"); fprintf(stderr, " -i : test input device\n"); fprintf(stderr, " -o : 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 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 = %zi\n", snd_rawmidi_status_get_avail(istat)); printf("input.status.xruns = %zi\n", snd_rawmidi_status_get_xruns(istat)); printf("output.status.avail = %zi\n", snd_rawmidi_status_get_avail(ostat)); printf("output.status.xruns = %zi\n", snd_rawmidi_status_get_xruns(ostat)); diff = timediff(end, start); printf("Time diff: %lliusec (%lli 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; }