#include <stdio.h> #include <stdlib.h> #include <ctype.h> #include "../include/asoundlib.h" #include <signal.h> static void usage(void) { fprintf(stderr, "usage: rawmidi [options]\n"); fprintf(stderr, " options:\n"); fprintf(stderr, " -v: verbose mode\n"); fprintf(stderr, " -i device-id : test ALSA input device\n"); fprintf(stderr, " -o device-id : test ALSA output device\n"); fprintf(stderr, " -I node : test input node\n"); fprintf(stderr, " -O node : test output node\n"); fprintf(stderr, " -t: test midi thru\n"); fprintf(stderr, " example:\n"); fprintf(stderr, " rawmidi -i hw:0,0 -O /dev/midi1\n"); fprintf(stderr, " tests input for card 0, device 0, using snd_rawmidi API\n"); fprintf(stderr, " and /dev/midi1 using file descriptors\n"); } int stop=0; void sighandler(int dum) { stop=1; } int main(int argc,char** argv) { int i; int err; int thru=0; int verbose = 0; char *device_in = NULL; char *device_out = NULL; char *node_in = NULL; char *node_out = NULL; int fd_in = -1,fd_out = -1; snd_rawmidi_t *handle_in = 0,*handle_out = 0; if (argc==1) { usage(); exit(0); } for (i = 1 ; i<argc ; i++) { if (argv[i][0]=='-') { switch (argv[i][1]) { case 'h': usage(); break; case 'v': verbose = 1; break; case 't': thru = 1; break; case 'i': if (i + 1 < argc) device_in = argv[++i]; break; case 'I': if (i + 1 < argc) node_in = argv[++i]; break; case 'o': if (i + 1 < argc) device_out = argv[++i]; break; case 'O': if (i + 1 < argc) node_out = argv[++i]; break; } } } if (verbose) { fprintf(stderr,"Using: \n"); fprintf(stderr,"Input: "); if (device_in) { fprintf(stderr,"device %s\n",device_in); }else if (node_in){ fprintf(stderr,"%s\n",node_in); }else{ fprintf(stderr,"NONE\n"); } fprintf(stderr,"Output: "); if (device_out) { fprintf(stderr,"device %s\n",device_out); }else if (node_out){ fprintf(stderr,"%s\n",node_out); }else{ fprintf(stderr,"NONE\n"); } } if (device_in) { err = snd_rawmidi_open(&handle_in,NULL,device_in,0); if (err) { fprintf(stderr,"snd_rawmidi_open %s failed: %d\n",device_in,err); } } if (node_in && (!node_out || strcmp(node_out,node_in))) { fd_in = open(node_in,O_RDONLY); if (fd_in<0) { fprintf(stderr,"open %s for input failed\n",node_in); } } signal(SIGINT,sighandler); if (device_out) { err = snd_rawmidi_open(NULL,&handle_out,device_out,0); if (err) { fprintf(stderr,"snd_rawmidi_open %s failed: %d\n",device_out,err); } } if (node_out && (!node_in || strcmp(node_out,node_in))) { fd_out = open(node_out,O_WRONLY); if (fd_out<0) { fprintf(stderr,"open %s for output failed\n",node_out); } } if (node_in && node_out && strcmp(node_out,node_in)==0) { fd_in = fd_out = open(node_out,O_RDWR); if (fd_out<0) { fprintf(stderr,"open %s for input and output failed\n",node_out); } } if (!thru) { if (handle_in || fd_in!=-1) { fprintf(stderr,"Read midi in\n"); fprintf(stderr,"Press ctrl-c to stop\n"); } if (handle_in) { unsigned char ch; while (!stop) { snd_rawmidi_read(handle_in,&ch,1); if (verbose) { fprintf(stderr,"read %02x\n",ch); } } } if (fd_in!=-1) { unsigned char ch; while (!stop) { read(fd_in,&ch,1); if (verbose) { fprintf(stderr,"read %02x\n",ch); } } } if (handle_out || fd_out!=-1) { fprintf(stderr,"Writing note on / note off\n"); } if (handle_out) { unsigned char ch; ch=0x90; snd_rawmidi_write(handle_out,&ch,1); ch=60; snd_rawmidi_write(handle_out,&ch,1); ch=100; snd_rawmidi_write(handle_out,&ch,1); snd_rawmidi_drain(handle_out); sleep(1); ch=0x90; snd_rawmidi_write(handle_out,&ch,1); ch=60; snd_rawmidi_write(handle_out,&ch,1); ch=0; snd_rawmidi_write(handle_out,&ch,1); snd_rawmidi_drain(handle_out); } if (fd_out!=-1) { unsigned char ch; ch=0x90; write(fd_out,&ch,1); ch=60; write(fd_out,&ch,1); ch=100; write(fd_out,&ch,1); sleep(1); ch=0x90; write(fd_out,&ch,1); ch=60; write(fd_out,&ch,1); ch=0; write(fd_out,&ch,1); } } else { if ((handle_in || fd_in!=-1) && (handle_out || fd_out!=-1)) { if (verbose) { fprintf(stderr,"Testing midi thru in\n"); } while (!stop) { unsigned char ch; if (handle_in) { snd_rawmidi_read(handle_in,&ch,1); } if (fd_in!=-1) { read(fd_in,&ch,1); } if (verbose) { fprintf(stderr,"thru: %02x\n",ch); } if (handle_out) { snd_rawmidi_write(handle_out,&ch,1); snd_rawmidi_drain(handle_out); } if (fd_out!=-1) { write(fd_out,&ch,1); } } }else{ fprintf(stderr,"Testing midi thru needs both input and output\n"); exit(-1); } } if (verbose) { fprintf(stderr,"Closing\n"); } if (handle_in) { snd_rawmidi_drain(handle_in); snd_rawmidi_close(handle_in); } if (handle_out) { snd_rawmidi_drain(handle_out); snd_rawmidi_close(handle_out); } if (fd_in!=-1) { close(fd_in); } if (fd_out!=-1) { close(fd_out); } return 0; }