//check for midi input when not busy static void check_midi() { unsigned char command; unsigned char note; unsigned char velocity; register int err; //check whether we can read the midi stream if ((err = snd_rawmidi_read(midiInHandle, &command, 1)) < 0) { printf("Can't read MIDI input: %s\n", snd_strerror(err)); } else { //if no error then read the note and velocity parts of the midi message snd_rawmidi_read(midiInHandle, ¬e, 1); snd_rawmidi_read(midiInHandle, &velocity, 1); } //TODO: Should add in a check to make sure we are getting a note command //update the image with the last note midi_update_image(note,velocity); //print out the note, currently for debug printf("note %d, command %d, velocity %d\n",note,command,velocity); }
void *midiinfunction(void *arg) { // this is the parameter passed via last argument of pthread_create(): snd_rawmidi_t* midiin=(snd_rawmidi_t*)arg; char buffer[1]; int count=0; int status; while (1) { if (midiin==NULL) { break; } if ((status=snd_rawmidi_read(midiin, buffer, 1)) < 0) { errormessage("Problem reading MIDI input: %s", snd_strerror(status)); } count++; if ((unsigned char)buffer[0] >=0x80) { // print command in hex printf("0x%x ", (unsigned char)buffer[0]); } else { printf("%d ", (unsigned char)buffer[0]); } fflush(stdout); if (count % 20==0) { printf("\n"); } } return NULL; }
int mus_midi_read(int line, unsigned char *buffer, int bytes) { if ((line < 0) || (line >= midis)) return(-1); if (midi_directions[line] == MIDI_READ) return(snd_rawmidi_read(midi_lines[line], buffer, bytes)); #ifdef NO_SNDLIB fprintf(stderr, "can't read from output %s\n", midi_names[line]); #else return(mus_error(MUS_MIDI_READ_ERROR, "can't read from output %s", midi_names[line])); #endif return(-1); }
void generate_pattern(char *dmx_universe) { int i; int bytes; bytes = snd_rawmidi_read(midiin, &midi_buf, sizeof(midi_buf)); for (i = 0; i < bytes; i++) { process_midi(midi_buf[i]); } for (i = 0; i < 150; i++) { SET_LED(i, 0, 0, 0); if (i < chan[0]) SET_LED(i, 255, 0, 0); if (i < chan[1]) SET_LED(i, 0, 255, 0); if (i < chan[2]) SET_LED(i, 0, 0, 255); if (i < chan[3]) SET_LED(i, 255, 255, 0); if (i < chan[4]) SET_LED(i, 255, 0, 255); if (i < chan[5]) SET_LED(i, 0, 255, 255); if (i < chan[6]) SET_LED(i, 255, 255, 255); if (i < chan[7]) SET_LED(i, 0, 0, 0); if ((i < chan[0x10]) && (i > (chan[0x10] - 10))) SET_LED(i, 255, 0, 0); if ((i < chan[0x11]) && (i > (chan[0x11] - 10))) SET_LED(i, 0, 255, 0); if ((i < chan[0x12]) && (i > (chan[0x12] - 10))) SET_LED(i, 0, 0, 255); if ((i < chan[0x13]) && (i > (chan[0x13] - 10))) SET_LED(i, 255, 255, 0); if ((i < chan[0x14]) && (i > (chan[0x14] - 10))) SET_LED(i, 255, 0, 255); if ((i < chan[0x15]) && (i > (chan[0x15] - 10))) SET_LED(i, 0, 255, 255); if ((i < chan[0x16]) && (i > (chan[0x16] - 10))) SET_LED(i, 255, 255, 255); if ((i < chan[0x17]) && (i > (chan[0x17] - 10))) SET_LED(i, 0, 0, 0); } }
void *midifunction(void *arg) { // this is the parameter passed via last argument of pthread_create(): struct midinodes *midi = (struct midinodes*)arg; char buffer[1]; int count = 0; int status; int byteNum = 0; char outBuffer[3] = {0x90, 0x00, 15}; note currentNote; printf("midi thread start\n"); while (1) { if ((status = snd_rawmidi_read(midi->midiin, buffer, 1)) < 0) { errormessage("Problem reading MIDI input: %s", snd_strerror(status)); } count++; // determine part of message if(byteNum == 0) { // note outBuffer[1] = currentNote.key = buffer[0]; byteNum = 1; } else { if(buffer[0] > 0) outBuffer[2] = currentNote.vel = NOTE_ON; else outBuffer[2] = currentNote.vel = NOTE_OFF; byteNum = 0; } // after velocity, write if(byteNum == 0) { if ((status = snd_rawmidi_write(midi->midiout, outBuffer, 3)) < 0) { errormessage("Problem writing to MIDI output: %s", snd_strerror(status)); exit(1); } printf("Note: %d %d %d \n", outBuffer[0], currentNote.key, currentNote.vel); SynthNoteStart(currentNote); } fflush(stdout); } return NULL; }
int main(void) { snd_rawmidi_open(&midi_in, &midi_out, "virtual", SND_RAWMIDI_NONBLOCK); //snd_rawmidi_open(&midi_in, &midi_out, "virtual", 0); if (ftdi_init( &ftdi )) { fprintf(stderr, "usb - init error !\n"); return 1; } if (ftdi_usb_open(&ftdi, 0x0403, 0x6001)) { fprintf(stderr, "usb - open error (cannot find?) !\n"); fprintf(stderr, "ftdi_usb_open failed, error (%s)\n", ftdi_get_error_string(&ftdi)); ftdi_deinit( &ftdi ); return 2; } if (ftdi_usb_reset( &ftdi )) { fprintf(stderr, "usb - reset error !\n"); ftdi_usb_close( &ftdi ); ftdi_deinit( &ftdi ); return 3; } ftdi_disable_bitbang( &ftdi ); ftdi_set_baudrate(&ftdi, BAUD); unsigned char buf; int ret; while(1) { //FTDI2MIDI ret = ftdi_read_data(&ftdi,&buf,1); if(ret < 0) break; if(ret > 0) snd_rawmidi_write(midi_out, &buf, 1); //MIDI2FTDI ret = snd_rawmidi_read(midi_in,&buf,1); if(ret < 0 && ret != -EAGAIN) break; if(ret > 0) ftdi_write_data(&ftdi, &buf, 1); usleep(1000); } exit(0); }
static int midireadloop(unsigned char *buffer) { int bufpos=0, cmdlen; unsigned char sb; int status; while(MidiIn!=NULL) { Py_BEGIN_ALLOW_THREADS status = snd_rawmidi_read(MidiIn, &sb, 1); Py_END_ALLOW_THREADS if(status<0) { midiexcept("error reading midi: %s", status); return -1; } buffer[bufpos++] = sb; if(sb&0x80) { /* received command byte */ if(buffer[0]==0xF0 && sb==0xF7) { /* SysEx End */ cmdlen = bufpos; } else if(bufpos>1) { /* previous command incomplete */ buffer[0] = sb; bufpos = 1; cmdlen = getmidicmdlen(sb); } else cmdlen = getmidicmdlen(sb); } if(bufpos==cmdlen) { /* command complete */ status = filtercmd(buffer, bufpos); if(status==0) return bufpos; else if(status<0) return -1; bufpos = 0; } } midiexcept("midi closed", 0); return -1; }
/* * Low level input. */ static int do_midi_input(process_midi_t *proc) { input_port_t *port = (input_port_t*) proc->port; if (!midi_is_ready(proc)) return 0; if (port->base.is_ready) { jack_ringbuffer_data_t vec[2]; int res; jack_ringbuffer_get_write_vector(port->base.data_ring, vec); if (jack_ringbuffer_write_space(port->base.event_ring) < sizeof(event_head_t) || vec[0].len < 1) { port->overruns++; if (port->base.npfds) debug_log("midi_in: internal overflow on %s", port->base.name); // remove from poll to prevent busy-looping port->base.npfds = 0; return 1; } res = snd_rawmidi_read(port->base.rawmidi, vec[0].buf, vec[0].len); if (res < 0 && res != -EWOULDBLOCK) { error_log("midi_in: reading from port %s failed: %s", port->base.name, snd_strerror(res)); return 0; } else if (res > 0) { event_head_t event; event.time = proc->cur_time; event.size = res; event.overruns = port->overruns; port->overruns = 0; debug_log("midi_in: read %d bytes at %d", (int)event.size, (int)event.time); jack_ringbuffer_write_advance(port->base.data_ring, event.size); jack_ringbuffer_write(port->base.event_ring, (char*)&event, sizeof(event)); } port->base.is_ready = 0; } if (!midi_update_pfds(proc)) return 0; return 1; }
/** * Opens MIDI device. This function modifies global input and output variables. * * \return FALSE on success, TRUE on error. **/ gboolean open_device() { int err; err = snd_rawmidi_open(&input, &output, device_port, SND_RAWMIDI_SYNC); if (err) { fprintf(stderr, "snd_rawmidi_open %s failed: %d\n", device_port, err); return TRUE; } err = snd_rawmidi_nonblock(output, 0); if (err) { fprintf(stderr, "snd_rawmidi_nonblock failed: %d\n", err); return TRUE; } snd_rawmidi_read(input, NULL, 0); /* trigger reading */ return FALSE; }
void echomidi(snd_rawmidi_t* midiin, snd_rawmidi_t* midiout) { unsigned char readbuffer; // storage for input MIDI byte stream unsigned char buffer[1024]={0}; // storage space for incoming commands int dataptr=0; // writing index in buffer int argsLeft=0; // bytes left to read for a command int transpose=6;// transposition for note out int newnote; // temp storage for output note int status; // storage for error codes while(true) { if ((status=snd_rawmidi_read(midiin, &readbuffer, 1)) < 0) { errormessage("Problem reading MIDI input: %s", snd_strerror(status)); } if (readbuffer & 0x80) {// a command byte has arrived argsLeft=getArgsExpected(readbuffer); dataptr=0; buffer[dataptr++]=readbuffer; } else {// a data byte has arrived if ((dataptr==0) || (argsLeft <=0)) { argsLeft=getArgsExpected(buffer[0]); dataptr=1; } buffer[dataptr++]=readbuffer; argsLeft--; } if ((argsLeft==0) && (((buffer[0] & 0xf0)==0x90) || ((buffer[0] & 0xf0)==0x80))) { newnote=buffer[1] + transpose; if ((newnote > 0) && (newnote < 128)) { buffer[1]=(unsigned char)newnote; if ((status=snd_rawmidi_write(midiout, buffer, 3)) < 0) { errormessage("Problem with MIDI out: %s", snd_strerror(status)); exit(EXIT_FAILURE); } else if (((buffer[0] & 0xf0)==0x90) && ((buffer[2] & 0x0f)!=0)) { printf("New note: %d\n", newnote); } } } if (dataptr > 1000) { dataptr=0; } } }
MidiAlsaRaw::MidiAlsaRaw() : MidiClientRaw(), m_inputp( &m_input ), m_outputp( &m_output ), m_quit( false ) { int err; if( ( err = snd_rawmidi_open( m_inputp, m_outputp, probeDevice().toLatin1().constData(), 0 ) ) < 0 ) { printf( "cannot open MIDI-device: %s\n", snd_strerror( err ) ); return; } snd_rawmidi_read( m_input, NULL, 0 ); snd_rawmidi_nonblock( m_input, 1 ); m_npfds = snd_rawmidi_poll_descriptors_count( m_input ); m_pfds = new pollfd[m_npfds]; snd_rawmidi_poll_descriptors( m_input, m_pfds, m_npfds ); start( QThread::LowPriority ); }
int main(int argc, char **argv) { int inputf, e, err; int sock; struct input_event buffer; int npfds; struct pollfd *pfds; struct sockaddr_in si_me, si_other; int len, slen = sizeof(si_other); int optval = 1; if(argc < 2) { fprintf(stderr, "%s <device>\n", argv[0]); exit(-1); } e = snd_rawmidi_open(&input, &output, argv[1], SND_RAWMIDI_NONBLOCK); if (e == -1) { fprintf(stderr, "snd:rawmidi:open-%X\n", e); return 1; } if ((sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1) { perror("udp socket"); return 1; } memset((void *) &si_me, 0, sizeof(si_me)); si_me.sin_family = AF_INET; si_me.sin_port = htons(UDPMIDI_PORT); si_me.sin_addr.s_addr = htonl(INADDR_ANY); memset((void *) &si_other, 0, sizeof(si_me)); si_other.sin_family = AF_INET; si_other.sin_port = htons(UDPMIDI_PORT); si_other.sin_addr.s_addr = htonl(INADDR_BROADCAST); if (bind(sock, (const struct sockaddr*)&si_me, sizeof(si_me)) == -1) { perror("udp port"); close(sock); return 1; } if (setsockopt(sock, SOL_SOCKET, SO_BROADCAST, &optval, sizeof (optval)) ==- 1) { perror("udp broadcast"); close(sock); return 1; } npfds = snd_rawmidi_poll_descriptors_count(input) + 1; pfds = malloc((npfds + 1) * sizeof(struct pollfd)); snd_rawmidi_poll_descriptors(input, pfds, npfds); pfds[npfds-1].fd = sock; pfds[npfds-1].events = POLLRDNORM; setvbuf (stdout, NULL, _IONBF, BUFSIZ); while(1) { int i,rlen, midiin; err = poll(pfds, npfds, 200); midiin = 0; for (i = 0; i < npfds; ++i) { if (pfds[i].revents & POLLIN) midiin = 1; } if (midiin) { unsigned char buf[10]; unsigned char outbuf[12]; printf("m"); rlen = snd_rawmidi_read(input, buf, sizeof(buf)); if (rlen == -EAGAIN) continue; if (rlen < 0) { fprintf(stderr, "Cannot read from port \"%s\": %s", argv[1], snd_strerror(err)); break; } // UDP broadcast memcpy(outbuf, packet_signature, 2); if (rlen > 10) continue; memcpy(outbuf + 2, buf, rlen); if (sendto(sock, outbuf, 2 + rlen, 0, (struct sockaddr *)&si_other, sizeof(si_other)) == -1) { fprintf(stderr, "Error sending broadcast packet.\n"); } memcpy(last_packet, outbuf, rlen + 2); } if (pfds[npfds-1].revents & POLLRDNORM) { int len,slen; unsigned char buffer[10]; slen = sizeof(si_other); len = recvfrom(sock, buffer, 10, 0, (struct sockaddr *)&si_other, &slen); // Drop our own broadcast packets if (memcmp(last_packet, buffer, len) == 0) continue; printf("u"); if (len > 2 && memcmp(buffer, packet_signature, 2) == 0) { int wlen = snd_rawmidi_write(output, buffer + 2, len - 2); if (wlen < len - 2) { fprintf(stderr, "Midi out: Wrote %d of %d bytes\n", wlen, len - 2); } } } } return 0; }
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; }
int launchpad_read(char note[3]) { return snd_rawmidi_read(in, note, 3); }
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 = %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: %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; }
void *interpretMidiInputStreamPrivateALSA(void * arg) { int portToWatch = *(int*)arg; if (portToWatch < 0 || portToWatch > 1000) { // the port to watch is invalid -- because the program has died // before the thread function could start. Cause of invalid port // data should be examined more carefully. return NULL; } int* argsExpected = NULL; // MIDI parameter bytes expected to follow int* argsLeft = NULL; // MIDI parameter bytes left to wait for uchar packet[1]; // bytes for sequencer driver MidiMessage* message = NULL; // holder for current MIDI message int newSigTime = 0; // for millisecond timer int lastSigTime = -1; // for millisecond timer int zeroSigTime = -1; // for timing incoming events int device = -1; // for sorting out the bytes by input device Array<uchar>* sysexIn; // MIDI Input sysex temporary storage // Note on the use of argsExpected and argsLeft for sysexs: // If argsExpected is -1, then a sysex message is coming in. // If argsLeft < 0, then the sysex message has not finished comming // in. If argsLeft == 0 and argsExpected == -1, then the sysex // has finished coming in and is to be sent to the correct // location. // allocate space for MIDI messages, each device has a different message // holding spot in case the messages overlap in the input stream message = new MidiMessage[MidiInPort_alsa::numDevices]; argsExpected = new int[MidiInPort_alsa::numDevices]; argsLeft = new int[MidiInPort_alsa::numDevices]; sysexIn = new Array<uchar>[MidiInPort_alsa::numDevices]; for (int j=0; j<MidiInPort_alsa::numDevices; j++) { sysexIn[j].allowGrowth(); sysexIn[j].setSize(32); sysexIn[j].setSize(0); sysexIn[j].setGrowth(512); } // interpret MIDI bytes as they come into the computer // and repackage them as MIDI messages. int packetReadCount; while (1) { top_of_loop: packetReadCount = 0; // If the all Sequencer_alsa classes have been deleted, // then Sequencer_alsa::rawmidi_in will have zero size. // If the size is zero, then that means the thread will be // killed soon, and we do not want any processing to happen // in this thread. If the port to watch is NULL, then that // means that the MIDI input is not open, and we should not // add any MIDI data to the input buffers. These cases are // handled by the following if-else statement: if (Sequencer_alsa::rawmidi_in.getSize() > 0 && Sequencer_alsa::rawmidi_in[portToWatch] != NULL) { packetReadCount = snd_rawmidi_read( Sequencer_alsa::rawmidi_in[portToWatch], packet, 1); } else { usleep(100000); // sleep for 1/10th of a second if the Input // port is not open. continue; } if (packetReadCount != 1) { // this if statement is used to prevent cases where the // read function above will time out and return 0 bytes // read. This if statment will also take care of -1 // error return values by ignoring them. continue; } if (Sequencer_alsa::initialized == 0) { continue; } // determination of a full MIDI message from the input MIDI // stream is based here on the observation that MIDI status // bytes and subsequent data bytes are NOT returned in the same // read() call. Rather, they are spread out over multiple read() // returns, with only a single value per return. So if we // find a status byte, we then determine the number of expected // operands and process that number of subsequent read()s to // to determine the complete midi message. // store the MIDI input device to which the incoming MIDI // byte belongs. device = portToWatch; // ignore the active sensing 0xfe and MIDI clock 0xf8 commands: if (packet[0] == 0xfe || packet[0] == 0xf8) { continue; } if (packet[0] & 0x80) { // a command byte has arrived switch (packet[0] & 0xf0) { case 0xf0: if (packet[0] == 0xf0) { argsExpected[device] = -1; argsLeft[device] = -1; if (sysexIn[device].getSize() != 0) { // ignore the command for now. It is most // likely an active sensing message. goto top_of_loop; } else { uchar datum = 0xf0; sysexIn[device].append(datum); } } if (packet[0] == 0xf7) { argsLeft[device] = 0; // indicates sysex is done uchar datum = 0xf7; sysexIn[device].append(datum); } else if (argsExpected[device] != -1) { // this is a system message that may or may // not be coming while a sysex is coming in argsExpected[device] = 0; } else { // this is a system message that is not coming // while a system exclusive is coming in //argsExpected[device] = 0; } break; case 0xc0: if (argsExpected[device] < 0) { std::cout << "Error: received program change during sysex" << std::endl; exit(1); } else { argsExpected[device] = 1; } break; case 0xd0: if (argsExpected[device] < 0) { std::cout << "Error: received aftertouch message during" " sysex" << std::endl; exit(1); } else { argsExpected[device] = 1; } break; default: if (argsExpected[device] < 0) { std::cout << "Error: received another message during sysex" << std::endl; exit(1); } else { argsExpected[device] = 2; } break; } if (argsExpected[device] >= 0) { argsLeft[device] = argsExpected[device]; } newSigTime = MidiInPort_alsa::midiTimer.getTime(); message[device].time = newSigTime - zeroSigTime; if (packet[0] != 0xf7) { message[device].p0() = packet[0]; } message[device].p1() = 0; message[device].p2() = 0; message[device].p3() = 0; if (packet[0] == 0xf7) { goto sysex_done; } } else if (argsLeft[device]) { // not a command byte coming in if (message[device].time == 0) { // store the receipt time of the first message byte newSigTime = MidiInPort_alsa::midiTimer.getTime(); message[device].time = newSigTime - zeroSigTime; } if (argsExpected[device] < 0) { // continue processing a sysex message sysexIn[device].append(packet[0]); } else { // handle a message other than a sysex message if (argsLeft[device] == argsExpected[device]) { message[device].p1() = packet[0]; } else { message[device].p2() = packet[0]; } argsLeft[device]--; } // if MIDI message is complete, setup for running status, and // insert note into proper buffer. if (argsExpected[device] >= 0 && !argsLeft[device]) { // store parameter data for running status switch (message[device].p0() & 0xf0) { case 0xc0: argsLeft[device] = 1; break; case 0xd0: argsLeft[device] = 1; break; // fix by dan default: argsLeft[device] = 2; break; // 0x80 expects two arguments // 0x90 expects two arguments // 0xa0 expects two arguments // 0xb0 expects two arguments // 0xe0 expects two arguments } lastSigTime = newSigTime; sysex_done: // come here when a sysex is completely done // insert the MIDI message into the appropriate buffer // do not insert into buffer if the MIDI input device // is paused (which can mean closed). Or if the // pauseQ array is pointing to NULL (which probably means that // things are about to shut down). if (MidiInPort_alsa::pauseQ != NULL && MidiInPort_alsa::pauseQ[device] == 0) { if (argsExpected[device] < 0) { // store the sysex in the MidiInPort_alsa // buffer for sysexs and return the storage // location: int sysexlocation = MidiInPort_alsa::installSysexPrivate(device, sysexIn[device].getBase(), sysexIn[device].getSize()); message[device].p0() = 0xf0; message[device].p1() = sysexlocation; sysexIn[device].setSize(0); // empty the sysex storage argsExpected[device] = 0; // no run status for sysex argsLeft[device] = 0; // turn off sysex input flag } MidiInPort_alsa::midiBuffer[device]->insert( message[device]); // if (MidiInPort_alsa::callbackFunction != NULL) { // MidiInPort_alsa::callbackFunction(device); // } if (MidiInPort_alsa::trace[device]) { std::cout << '[' << std::hex << (int)message[device].p0() << ':' << std::dec << (int)message[device].p1() << ',' << (int)message[device].p2() << ']' << std::flush; } message[device].time = 0; } else { if (MidiInPort_alsa::trace[device]) { std::cout << '[' << std::hex << (int)message[device].p0() << 'P' << std::dec << (int)message[device].p1() << ',' << (int)message[device].p2() << ']' << std::flush; } } } } } // end while (1) // This code is not yet reached, but should be made to do so eventually if (message != NULL) { delete message; message = NULL; } if (argsExpected != NULL) { delete argsExpected; argsExpected = NULL; } if (argsLeft != NULL) { delete argsLeft; argsLeft = NULL; } if (sysexIn != NULL) { delete sysexIn; sysexIn = NULL; } return NULL; }
int main(int argc,char** argv) { int i; int err; int thru=0; int verbose = 0; char *device_in = NULL; char *lcm_out = NULL; int fd_in = -1,fd_out = -1; snd_rawmidi_t *handle_out = 0; if (argc!=3) { usage(); exit(0); } device_in = argv[1]; lcm_out = argv[2]; lcm = lcm_create ("udpm://239.255.76.67:7667?ttl=0"); if (!lcm) return 1; struct timeval thisTime; fprintf(stderr,"Using: \n"); fprintf(stderr,"Input: "); fprintf(stderr,"device %s\n",device_in); fprintf(stderr,"Output: "); fprintf(stderr,"LCM channel %s\n", lcm_out); fprintf(stderr,"Read midi in\n"); fprintf(stderr,"Press ctrl-c to stop\n"); fprintf(stderr,"Broadcasting LCM: %s\n", lcm_out); 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); return -1; } } signal(SIGINT,sighandler); int num = 0; int val[10]; int sysExclusive = 0; if (handle_in) { unsigned char ch; while (!stop) { snd_rawmidi_read(handle_in,&ch,1); // check to make sure this isn't a system exclusive message (begins with 0xF0. Ends with a 0xF7) if (ch == 0xF0) { sysExclusive = 1; //fprintf(stderr,"sys exclusive\n"); } if (sysExclusive == 0) { val[num] = (int)ch; if (num >= 2) { //fprintf(stderr,"read %02x --> %02x --> %d\n", val[0], val[1], val[2]); num = 0; // send LCM message lcmt_midi msg; gettimeofday(&thisTime, NULL); msg.timestamp = (thisTime.tv_sec * 1000.0) + (float)thisTime.tv_usec/1000.0 + 0.5; msg.event[0] = val[0]; msg.event[1] = val[1]; msg.event[2] = val[2]; lcmt_midi_publish (lcm, lcm_out, &msg); } else { num ++; } //fprintf(stderr,"read %02x\n", ch); } if (ch == 0xF7) { sysExclusive = 0; } } } fprintf(stderr,"Closing.\n"); if (handle_in) { snd_rawmidi_drain(handle_in); snd_rawmidi_close(handle_in); } lcm_destroy (lcm); return 0; }
gpointer read_data_thread(gboolean *stop) { /* This is mostly taken straight from alsa-utils-1.0.19 amidi/amidi.c by Clemens Ladisch <*****@*****.**> */ int err; int npfds; struct pollfd *pfds; GString *string = NULL; npfds = snd_rawmidi_poll_descriptors_count(input); pfds = alloca(npfds * sizeof(struct pollfd)); snd_rawmidi_poll_descriptors(input, pfds, npfds); do { unsigned char buf[256]; int i, length; unsigned short revents; /* SysEx messages can't contain bytes with 8th bit set. memset our buffer to 0xFF, so if for some reason we'll get out of reply bounds, we'll catch it */ memset(buf, '\0', sizeof(buf)); err = poll(pfds, npfds, 200); if (err < 0 && errno == EINTR) break; if (err < 0) { g_error("poll failed: %s", strerror(errno)); break; } if ((err = snd_rawmidi_poll_descriptors_revents(input, pfds, npfds, &revents)) < 0) { g_error("cannot get poll events: %s", snd_strerror(errno)); break; } if (revents & (POLLERR | POLLHUP)) break; if (!(revents & POLLIN)) continue; err = snd_rawmidi_read(input, buf, sizeof(buf)); if (err == -EAGAIN) continue; if (err < 0) { g_error("cannot read: %s", snd_strerror(err)); break; } length = 0; for (i = 0; i < err; ++i) if ((unsigned char)buf[i] != 0xFE) /* ignore active sensing */ buf[length++] = buf[i]; i = 0; while (i < length) { int pos; int bytes; if (string == NULL) { while (buf[i] != 0xF0 && i < length) i++; } pos = i; for (bytes = 0; (bytes<length-i) && (buf[i+bytes] != 0xF7); bytes++); if (buf[i+bytes] == 0xF7) bytes++; i += bytes; if (string == NULL) string = g_string_new_len((gchar*)&buf[pos], bytes); else g_string_append_len(string, (gchar*)&buf[pos], bytes); if ((unsigned char)string->str[string->len-1] == 0xF7) { /* push message on stack */ push_message(string); string = NULL; } } } while (*stop == FALSE); if (string) { g_string_free(string, TRUE); string = NULL; } return NULL; }
//int main() { int main(int argc, char *argv[]) { //initscr(); //Initialize ncurses //noecho(); set_timbres(); make_table(); //Set up note frequencies int the table freq_table[] Organ theOrgan; Reverb* rev1 = new Reverb(2500, 0.8); //Reverb* rev2 = new Reverb(4000, 0.8); //Reverb* rev3 = new Reverb(5500, 0.8); int rc; int size; snd_pcm_t *handle; snd_pcm_hw_params_t *params; unsigned int val; int dir; snd_pcm_uframes_t frames; char *buffer; /* Open PCM device for playback. */ rc = snd_pcm_open(&handle, "default", SND_PCM_STREAM_PLAYBACK, 0); if (rc < 0) { fprintf(stderr, "unable to open pcm device: %s\n", snd_strerror(rc)); exit(1); } /* Allocate a hardware parameters object. */ snd_pcm_hw_params_alloca(¶ms); /* Fill it in with default values. */ snd_pcm_hw_params_any(handle, params); /* Set the desired hardware parameters. */ /* Set period size to 32 frames. */ frames = 16; snd_pcm_hw_params_set_period_size_near(handle, params, &frames, &dir); /* Write the parameters to the driver */ rc = snd_pcm_hw_params(handle, params); if (rc < 0) { fprintf(stderr, "unable to set hw parameters: %s\n", snd_strerror(rc)); exit(1); } snd_pcm_uframes_t bufferSize; snd_pcm_hw_params_get_buffer_size( params, &bufferSize ); fprintf(stderr, "alsa_buffer_size: %lu frames\n", bufferSize); rc = snd_pcm_set_params(handle, SND_PCM_FORMAT_S16_LE, SND_PCM_ACCESS_RW_INTERLEAVED, 2, 44100, 32, 50000); //Latency /* Use a buffer large enough to hold one period */ snd_pcm_hw_params_get_period_size(params, &frames, &dir); size = frames * 4; /* 2 bytes/sample, 2 channels */ buffer = (char *) malloc(size); int16_t* buffer_16 = (int16_t *) buffer; //Cast buffer for 16-bit values /* We want to loop for 5 seconds */ snd_pcm_hw_params_get_period_time(params, &val, &dir); /* 5 seconds in microseconds divided by * period time */ //loops = 5000000 / val; //rc = snd_pcm_nonblock(handle, 0); // Make init for MIDI INPUT int status; int mode = SND_RAWMIDI_SYNC | SND_RAWMIDI_NONBLOCK; snd_rawmidi_t* midiin = NULL; const char* portname = "hw:1,0,0"; // see alsarawportlist.c example program if ((argc > 1) && (strncmp("hw:", argv[1], 3) == 0)) { portname = argv[1]; } if ((status = snd_rawmidi_open(&midiin, NULL, portname, mode)) < 0) { errormessage("Problem opening MIDI input: %s", snd_strerror(status)); exit(1); } int count = 0; // Current count of bytes received. char mid_buffer[1]; // Storage for input buffer received int framesleft=0; //Storage for MIDI-parsing: int midi_cmd; int midi_count=0; int midi_channel=0; int midi_note; int midi_offset=1; //Transpose value // while (true) { for(int i=0;i<frames;i++) { float organOut = theOrgan.next(); //Read output from organ float outValue = organOut*3.0 + rev1->next(organOut)*0.5 //+ rev2->next(organOut)*0.25 //+ rev3->next(organOut)*0.12 ; buffer_16[i*2] = (int16_t)outValue; buffer_16[i*2+1] = (int16_t)outValue; } rc = snd_pcm_writei(handle, buffer, frames); if (rc == -EPIPE) { /* EPIPE means underrun */ fprintf(stderr, "underrun occurred\n"); snd_pcm_prepare(handle); } else if (rc < 0) { fprintf(stderr, "error from writei: %s\n", snd_strerror(rc)); } else if (rc != (int)frames) { fprintf(stderr, "short write, write %d frames\n", rc); } else { /* */ } //MIDI code status = snd_rawmidi_read(midiin, mid_buffer, 1); if(status > 0) { unsigned char theByte = mid_buffer[0]; //Simple MIDI parser //Blame RG 2014 if((theByte & 0x80) == 0x80) //Is it a command? { if((theByte & 0x90) == 0x90) //Note on { midi_channel = (theByte & 0x0f); #ifdef debug fprintf(stderr, "midi_channel: %d \n", midi_channel); #endif midi_count=1; midi_cmd=0x90; } else { if((theByte & 0x90) == 0x80) //Note off { midi_channel = (theByte & 0x0f); #ifdef debug fprintf(stderr, "midi_channel: %d \n", midi_channel); #endif midi_count=1; midi_cmd=0x80; } } } //End of command processing else { if (midi_count==1) { midi_note = (theByte+midi_offset); midi_count++; } else { if (midi_count==2) { //Velocity info here midi_count=1; if(midi_cmd == 0x90) { if(theByte!=00) //21.11.2014 (Check if note on with vel 0 is used as note off!) { theOrgan.noteOn(midi_channel, midi_note); #ifdef debug fprintf(stderr, "play note: %d \n", midi_note); #endif } else { theOrgan.noteOff(midi_channel, midi_note); #ifdef debug fprintf(stderr, "note on, volume 0: %d \n", midi_note); #endif } } if(midi_cmd == 0x80) { theOrgan.noteOff(midi_channel, midi_note); #ifdef debug fprintf(stderr, "note off: %d \n", midi_note); #endif } } } } //count++; } //END MIDI CODE char command[80]; struct pollfd fds; int ret; fds.fd = 0; /* this is STDIN */ fds.events = POLLIN; ret = poll(&fds, 1, 0); if(ret == 1) { read(STDIN_FILENO, command, 80); switch(command[0]) { case '0': printf("Command 0\n"); theOrgan.setReg(0); break; case '1': printf("Command 1\n"); theOrgan.setReg(1); break; case '2': printf("Command 2\n"); theOrgan.setReg(2); break; case '3': printf("Command 3\n"); theOrgan.setReg(3); break; case '4': printf("Command 4\n"); theOrgan.setReg(4); break; } } else if(ret == 0) { //printf("No\n"); } else printf("Error\n"); } snd_pcm_drain(handle); snd_pcm_close(handle); free(buffer); snd_rawmidi_close(midiin); midiin = NULL; // snd_rawmidi_close() does not clear invalid pointer, return 0; }
void Dicer_control_process::exec_midi_commands_reader_process() { #ifdef WIN32 // TODO: add Dicer support for Windows. return; #else unsigned char midi_buf[3] = {0x00, 0x00, 0x00}; dicer_t dicer_index; dicer_mode_t mode; dicer_button_t button_index; dicer_button_pressed_t button_hitted; // Start infinite loop which read MIDI commands. for (;;) { // Read MIDI command from DICER (blocking). int err = 0; if ((err = snd_rawmidi_read(this->midi_in, midi_buf, sizeof(midi_buf))) < 0) { qCWarning(DS_DICER) << "can not read MIDI command on Dicer: " << snd_strerror(err); } else { #if 0 cout << "read" << "\tl/r+mode:" << hex << "0x"<< static_cast<unsigned int>(static_cast<unsigned char>(midi_buf[0])) << "\tbutton:" << hex << "0x"<< static_cast<unsigned int>(static_cast<unsigned char>(midi_buf[1])) << "\tdown/up::" << hex << "0x"<< static_cast<unsigned int>(static_cast<unsigned char>(midi_buf[2])) << endl; #endif // Extracting command. if (this->extract_midi_buffer(midi_buf, dicer_index, mode, button_index, button_hitted) == true) { #if 0 cout << "extract" << "\tdicer:" << dicer_index << "\tmode:" << mode << "\tbutton_index:" << button_index << "\tbutton_pressed:" << button_hitted << endl; #endif // Send a signal: a button was pressed or released on the Dicer. switch (button_hitted) { case PRESSED: emit this->button_pressed(dicer_index, mode, button_index); break; case RELEASED: emit this->button_released(dicer_index, mode, button_index); break; default: qCWarning(DS_DICER) << "can not extract MIDI command on Dicer"; } } else { qCWarning(DS_DICER) << "can not extract MIDI command on Dicer"; } } } //QThread::currentThread()->quit(); #endif return; }
void MidiAlsaRaw::run() { unsigned char buf[128]; //int cnt = 0; while( m_quit == false ) { msleep( 5 ); // must do that, otherwise this thread takes // too much CPU-time, even with LowPriority... int err = poll( m_pfds, m_npfds, 10000 ); if( err < 0 && errno == EINTR ) { printf( "MidiAlsaRaw::run(): Got EINTR while " "polling. Will stop polling MIDI-events from " "MIDI-port.\n" ); break; } if( err < 0 ) { printf( "poll failed: %s\nWill stop polling " "MIDI-events from MIDI-port.\n", strerror( errno ) ); break; } if( err == 0 ) { //printf( "there seems to be no active MIDI-device %d\n", ++cnt ); continue; } unsigned short revents; if( ( err = snd_rawmidi_poll_descriptors_revents( m_input, m_pfds, m_npfds, &revents ) ) < 0 ) { printf( "cannot get poll events: %s\nWill stop polling " "MIDI-events from MIDI-port.\n", snd_strerror( errno ) ); break; } if( revents & ( POLLERR | POLLHUP ) ) { printf( "POLLERR or POLLHUP\n" ); break; } if( !( revents & POLLIN ) ) { continue; } err = snd_rawmidi_read( m_input, buf, sizeof( buf ) ); if( err == -EAGAIN ) { continue; } if( err < 0 ) { printf( "cannot read from port \"%s\": %s\nWill stop " "polling MIDI-events from MIDI-port.\n", /*port_name*/"default", snd_strerror( err ) ); break; } if( err == 0 ) { continue; } for( int i = 0; i < err; ++i ) { parseData( buf[i] ); } } }