Blame test/midiloop.c

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