/* alsa_rawmidi_init: * Inits the ALSA RawMIDI interface. */ static int alsa_rawmidi_init(int input, int voices) { int ret = -1, err; char tmp1[128], tmp2[128], temp[256]; #if ALLEGRO_ALSA_VERSION == 9 snd_rawmidi_info_t *info; const char *device = NULL; #else /* ALLEGRO_ALSA_VERSION == 5 */ snd_rawmidi_info_t info; int card = -1; int device = -1; #endif if (input) { ret = -1; } else { #if ALLEGRO_ALSA_VERSION == 9 device = get_config_string(uconvert_ascii("sound", tmp1), uconvert_ascii("alsa_rawmidi_device", tmp2), "default"); err = snd_rawmidi_open(NULL, &rawmidi_handle, device, 0); #else /* ALLEGRO_ALSA_VERSION == 5 */ card = get_config_int(uconvert_ascii("sound", tmp1), uconvert_ascii("alsa_rawmidi_card", tmp2), snd_defaults_rawmidi_card()); device = get_config_int(uconvert_ascii("sound", tmp1), uconvert_ascii("alsa_rawmidi_device", tmp2), snd_defaults_rawmidi_device()); err = snd_rawmidi_open(&rawmidi_handle, card, device, SND_RAWMIDI_OPEN_OUTPUT_APPEND); #endif if (err) { snprintf(temp, sizeof(temp), "Could not open card/rawmidi device: %s", snd_strerror(err)); ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text(temp)); ret = -1; } ret = 0; } if (rawmidi_handle) { #if ALLEGRO_ALSA_VERSION == 9 snd_rawmidi_nonblock(rawmidi_handle, 0); snd_rawmidi_info_malloc(&info); snd_rawmidi_info(rawmidi_handle, info); _al_sane_strncpy(alsa_rawmidi_desc, snd_rawmidi_info_get_name(info), sizeof(alsa_rawmidi_desc)); #else /* ALLEGRO_ALSA_VERSION == 5 */ snd_rawmidi_block_mode(rawmidi_handle, 1); snd_rawmidi_info(rawmidi_handle, &info); _al_sane_strncpy(alsa_rawmidi_desc, info.name, sizeof(alsa_rawmidi_desc)); #endif midi_alsa.desc = alsa_rawmidi_desc; alsa_rawmidi_errors = 0; } return ret; }
static int midi_open(const char *name, int input) { int err; snd_rawmidi_t *line; snd_rawmidi_params_t *params; if (input == MIDI_READ) err = snd_rawmidi_open(&line, NULL, name, SND_RAWMIDI_NONBLOCK); else err = snd_rawmidi_open(NULL, &line, name, SND_RAWMIDI_NONBLOCK); if (err) { #ifdef NO_SNDLIB fprintf(stderr, "can't open %s: %s\n", name, strerror(err)); #else return(mus_error(MUS_MIDI_OPEN_ERROR, "can't open %s: %s", name, strerror(err))); #endif return(-1); } snd_rawmidi_params_malloc(¶ms); err = snd_rawmidi_params_set_buffer_size(line, params, DEV_BUFSIZE); if (err) { snd_rawmidi_params_free(params); snd_rawmidi_close(line); #ifdef NO_SNDLIB fprintf(stderr, "can't set %s buffer size to %d: %s\n", name, DEV_BUFSIZE, strerror(err)); #else return(mus_error(MUS_MIDI_MISC_ERROR, "can't set %s buffer size to %d: %s", name, DEV_BUFSIZE, strerror(err))); #endif return(-1); } return(new_midi_line(name, line, params, input)); }
int main(int argc, char *argv[]) { int status; int mode=0; pthread_t midiinthread; 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(EXIT_FAILURE); } // type "man pthread_create" for more information about this function: status=pthread_create(&midiinthread, NULL, midiinfunction, midiin); if (status==-1) { errormessage("Unable to create MIDI input thread."); exit(EXIT_FAILURE); } CHECK_ZERO(sleep(60)); // do nothing for a while; thread does all the work. snd_rawmidi_close(midiin); midiin=NULL; // snd_rawmidi_close() does not clear invalid pointer, printf("\n"); // so might be a good idea to erase it after closing. return EXIT_SUCCESS; }
bool Dicer_control_process::start() { // Open the Dicer (RAW MIDI interface). #ifdef WIN32 // TODO: add Dicer support for Windows. return false; #else int err; if ((err = snd_rawmidi_open(&this->midi_in, &this->midi_out, DEVICE_ID, 0)) < 0) // Open in blocking mode (for the read function). { qCWarning(DS_DICER) << "can not open MIDI interface on Dicer: " << snd_strerror(err); return false; } #endif // Dicer is ready to work. this->is_open = true; // Clear all buttons for both Dicer. if (this->clear_dicer(DICER_LEFT) == false) { qCWarning(DS_DICER) << "can not clear Dicer left"; return false; } if (this->clear_dicer(DICER_RIGHT) == false) { qCWarning(DS_DICER) << "can not clear Dicer right"; return false; } // Run the loop which reads incoming MIDI command. this->reader_thread.start(); return true; }
char *mus_midi_describe(void) { int i, err; snd_rawmidi_t *line; snd_rawmidi_info_t *info; char *buf = NULL; char one[256]; snd_rawmidi_info_malloc(&info); buf = (char *)CALLOC(1024, sizeof(char)); for (i = 0; i < 8; i++) { /* presumably this should use the card|device from the info struct, not a blind loop */ err = snd_rawmidi_open(&line, NULL, mus_midi_device_name(i << 16), SND_RAWMIDI_NONBLOCK); /* do the "devices" matter here? */ if (err < 0) continue; err = snd_rawmidi_info(line, info); if (err < 0) break; sprintf(one, "%s: card: %d, device: %d, stream: %d, flags: %x, id: %s, name: %s[%s; %d]\n", mus_midi_device_name(i << 16), snd_rawmidi_info_get_card(info), /* card number */ snd_rawmidi_info_get_device(info), /* device number */ snd_rawmidi_info_get_stream(info), /* snd_rawmidi_stream_t */ snd_rawmidi_info_get_flags(info), /* 1=out 2=in 4=dupex */ snd_rawmidi_info_get_id(info), /* hardware id (out in?) */ snd_rawmidi_info_get_name(info), snd_rawmidi_info_get_subdevice_name(info), snd_rawmidi_info_get_subdevices_count(info)); strcat(buf, one); } snd_rawmidi_info_free(info); return(buf); }
int MidiInit(void *arg) { int status; int mode = SND_RAWMIDI_SYNC; char *portname = arg; midi.midiin = NULL; midi.midiout = NULL; char resetPad[3] = {0xB0, 0x00, 0x00}; char setDrumMapping[3] = {0xB0, 0x00, 0x02}; // configure drum rack layout // open in/out if ((status = snd_rawmidi_open(&(midi.midiin), &(midi.midiout), portname, mode)) < 0) { errormessage("Problem opening MIDI input: %s", snd_strerror(status)); exit(1); } // reset launchpad (replace with generic reset) if ((status = snd_rawmidi_write(midi.midiout, resetPad, 3)) < 0) { errormessage("Problem writing to MIDI output: %s", snd_strerror(status)); exit(1); } // reset launchpad (replace with generic reset) if ((status = snd_rawmidi_write(midi.midiout, setDrumMapping, 3)) < 0) { errormessage("Problem writing to MIDI output: %s", snd_strerror(status)); exit(1); } return NULL; }
/* alsa_rawmidi_detect: * ALSA RawMIDI detection. */ static int alsa_rawmidi_detect(int input) { #if ALLEGRO_ALSA_VERSION == 9 const char *device = NULL; #else /* ALLEGRO_ALSA_VERSION == 5 */ int card = -1; int device = -1; #endif int ret = FALSE, err; char tmp1[128], tmp2[128], temp[256]; snd_rawmidi_t *handle = NULL; if (input) { ret = FALSE; } else { #if ALLEGRO_ALSA_VERSION == 9 device = get_config_string(uconvert_ascii("sound", tmp1), uconvert_ascii("alsa_rawmidi_device", tmp2), "default"); err = snd_rawmidi_open(NULL, &handle, device, 0); #else /* ALLEGRO_ALSA_VERSION == 5 */ card = get_config_int(uconvert_ascii("sound", tmp1), uconvert_ascii("alsa_rawmidi_card", tmp2), snd_defaults_rawmidi_card()); device = get_config_int(uconvert_ascii("sound", tmp1), uconvert_ascii("alsa_rawmidi_device", tmp2), snd_defaults_rawmidi_device()); err = snd_rawmidi_open(&handle, card, device, SND_RAWMIDI_OPEN_OUTPUT_APPEND); #endif if (err) { snprintf(temp, sizeof(temp), "Could not open card/rawmidi device: %s", snd_strerror(err)); ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text(temp)); ret = FALSE; } else { snd_rawmidi_close(handle); ret = TRUE; } } return ret; }
void launchpad_open() { int err = snd_rawmidi_open(&in, &out, "hw:2,0,0", SND_RAWMIDI_NONBLOCK); if (err < 0) { printf("Failed to open midi device: %s\n", snd_strerror(err)); exit(1); } }
static int midoalsa_init(void *arg) { int err; err = snd_rawmidi_open(NULL, &handle, device, SND_RAWMIDI_NONBLOCK | SND_RAWMIDI_SYNC); if (err) { S_printf("%s: unable to open %s for writing: %s\n", midoalsa_name, device, snd_strerror(err)); return 0; } return 1; }
void init_pattern(char *dmx_universe) { int mode = SND_RAWMIDI_NONBLOCK; int status; if ((status = snd_rawmidi_open(&midiin, NULL, MIDI_PORTNAME, mode)) < 0) { fprintf(stderr, "Problem opening MIDI input: %s", snd_strerror(status)); exit(1); } memset(dmx_universe, 0, 450); }
static int midoalsa_open(snd_rawmidi_t **handle_p, const char *dev_name) { int err; err = snd_rawmidi_open(NULL, handle_p, dev_name, SND_RAWMIDI_NONBLOCK | SND_RAWMIDI_SYNC); if (err) { S_printf("%s: unable to open %s for writing: %s\n", midoalsa_name, dev_name, snd_strerror(err)); return 0; } /* NONBLOCK flag is needed only so that open() not to block forever */ snd_rawmidi_nonblock(*handle_p, 0); return 1; }
int main( int argc, char *argv[] ) { int buf_size = 7; char* midi_device = (char*) malloc(sizeof(char) * buf_size); printf("The Key of Evil\n\nHit C7 on your midi controller to exit after the images have started\n\n"); printf("Listing MIDI hardware\n"); list_midi_interfaces(midi_device,buf_size); printf("User selected %s\n",midi_device); register int err; // Open input MIDI device selected by user if ((err = snd_rawmidi_open(&midiInHandle, 0, midi_device, 0)) < 0) { printf("Can't open MIDI input: %s\n", snd_strerror(err)); } /* Initialise GTK+ */ gtk_init(&argc, &argv); // Create photo display window = GTK_WINDOW(gtk_window_new(GTK_WINDOW_TOPLEVEL)); pixbuf = gdk_pixbuf_new_from_file_at_scale("e4.jpg", 1280, 1024, TRUE, NULL); picture=gtk_image_new_from_pixbuf(pixbuf); // signal handlers g_signal_connect (G_OBJECT (window), "delete_event",G_CALLBACK (delete_event), NULL); g_signal_connect (G_OBJECT (window), "destroy", G_CALLBACK (destroy), NULL); //g_signal_connect (G_OBJECT (window), "key_press_event", G_CALLBACK (button_press_callback), NULL); // pack the image into the window & display gtk_container_add(GTK_CONTAINER(window), GTK_WIDGET(picture)); gtk_widget_show_all(GTK_WIDGET(window)); // Set window to have no border etc. gtk_window_set_decorated(window, FALSE); gtk_window_fullscreen(window); //register the funtion to run when no other gtk work happening g_idle_add ((GSourceFunc)check_midi,NULL); /* Start main event loop */ gtk_main(); return 0; }
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[BUFFER_SIZE]; int ret; while(1) { //FTDI2MIDI ret = ftdi_read_data(&ftdi, buf, BUFFER_SIZE); if(ret < 0) break; if(ret > 0) snd_rawmidi_write(midi_out, buf, BUFFER_SIZE); //MIDI2FTDI /* ret = snd_rawmidi_read(midi_in, buf,BUFFER_SIZE); if(ret < 0 && ret != -EAGAIN) break; if(ret > 0) ftdi_write_data(&ftdi, buf,BUFFER_SIZE); */ usleep(LATENCY); } exit(0); }
/** * 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; }
static PyObject *pyrm_open(PyObject *self, PyObject *args) { int status; const char *port; if(MidiIn!=NULL) return midiexcept("midi already openend", 0); if(!PyArg_ParseTuple(args, "s", &port)) return NULL; status = snd_rawmidi_open(&MidiIn, &MidiOut, port, SND_RAWMIDI_SYNC|SND_RAWMIDI_NONBLOCK); if(status<0) return midiexcept2("error opening midi port '%s': %s", port, status); status = snd_rawmidi_nonblock(MidiOut, 0); /* set blocking mode */ if(status<0) return midiexcept("error setting up midi: %s", status); Py_RETURN_NONE; }
int main(int argc, char *argv[]) { int status; // for storing error codes int mode=SND_RAWMIDI_SYNC; // automatic MIDI out flushing snd_rawmidi_t* midiin=NULL; // structure to access MIDI input snd_rawmidi_t* midiout=NULL; // structure to access MIDI output 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, &midiout, portname, mode)) < 0) { errormessage("Problem opening MIDI input: %s", snd_strerror(status)); exit(EXIT_FAILURE); } printf("Type control-c to exit.\n"); echomidi(midiin, midiout); // never gets here, but here is how to close MIDI gracefully: snd_rawmidi_close(midiin); snd_rawmidi_close(midiout); midiin=NULL; // snd_rawmidi_close() does not clear invalid pointer, midiout=NULL; // so might be a good idea to erase it after closing. return EXIT_SUCCESS; }
static int midi_port_open(alsa_rawmidi_t *midi, midi_port_t *port) { int err; int type; char name[64]; snd_rawmidi_t **in = NULL; snd_rawmidi_t **out = NULL; if (port->id.id[2] == 0) { in = &port->rawmidi; type = JackPortIsOutput; } else { out = &port->rawmidi; type = JackPortIsInput; } if ((err = snd_rawmidi_open(in, out, port->dev, SND_RAWMIDI_NONBLOCK))<0) return err; /* Some devices (emu10k1) have subdevs with the same name, * and we need to generate unique port name for jack */ snprintf(name, sizeof(name), "%s", port->name); if (midi_port_open_jack(midi, port, type, name)) { int num; num = port->id.id[3] ? port->id.id[3] : port->id.id[1]; snprintf(name, sizeof(name), "%s %d", port->name, num); if (midi_port_open_jack(midi, port, type, name)) return 2; } if ((port->event_ring = jack_ringbuffer_create(MAX_EVENTS*sizeof(event_head_t)))==NULL) return 3; if ((port->data_ring = jack_ringbuffer_create(MAX_DATA))==NULL) return 4; return 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 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; }
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 main(int argc, char *argv[]) { fd_set rfds; int res; int err; int version = -1, ioret = -1; unsigned numevs, c; unsigned char read_buffer[sizeof(struct input_event)*3]; /* max 3 events per read */ unsigned char ch; unsigned char cCommand[3]; unsigned char cStates[255]; struct input_event *currev; char device_name[1024]; char *device_out = NULL; device_out = argv[2]; int fd_in = -1,fd_out = -1; snd_rawmidi_t *handle_in = 0,*handle_out = 0; memset(&cStates, 0, sizeof(cStates)); /* struct sigaction sighandler; memset(&sighandler, 0, sizeof(sighandler)); sighandler.sa_handler = catch_signal; sigaction(SIGINT, &sighandler, NULL); sigaction(SIGQUIT, &sighandler, NULL); */ signal(SIGINT,catch_signal); if ( argc < 2 ) { fprintf(stderr, "Device needed\n"); return -1; } FD_ZERO(&rfds); fd = open(argv[1], O_RDONLY); if ( -1 == fd ) { fprintf(stderr, "unable to read from mice - please give me a keyboard.\n"); return -1; } ioret = ioctl(fd, EVIOCGVERSION, &version); ioret = ioctl(fd, EVIOCGNAME(sizeof(device_name)), device_name); ioret = ioctl(fd, EVIOCGRAB, &grab); if ( -1 == ioret ) { perror("ioctl()"); } fprintf(stdout, "ver: %d, ret = %d\n", version, ioret); printf("device name is: %s\n", device_name); printf("EVIOCGRAB is: %lu\n", EVIOCGRAB); 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); } } /* to read the config file: char *option; char *value; fscanf( "%20[^#=]s=%80[^\n]", &option, &value ); */ FD_SET(fd, &rfds); while ( 1 ) { res = select(fd + 1, &rfds, NULL, NULL, NULL); if ( -1 == res && EINTR == errno ) { continue; } if ( -1 == res ) { perror("select() failed"); fprintf(stderr, "failed to select, fd is %d\n", fd); return -1; } if ( FD_ISSET(fd, &rfds) ) { // fprintf(stdout, "got some data\n"); res = read(fd, read_buffer, sizeof(read_buffer)); if ( -1 == res) { fprintf(stderr, "error reading data\n"); return -1; } // fprintf(stdout, "got %d bytes\n", res); numevs = ( res / sizeof(struct input_event) ); /* get how many input events we got */ // fprintf(stdout, "got %u events\n", numevs); for ( c = 0; c < numevs; c++ ) { currev = (struct input_event *)(read_buffer + (sizeof(struct input_event) * c)); // fprintf(stdout, "event time %ld/%ld\n", currev->time.tv_sec, currev->time.tv_usec); // fprintf(stdout, "event type = %hd, code = %hd, value = %d\n", currev->type, currev->code, currev->value); if ( 1 == currev->type ) { if ( 1 == currev->value ) { // press fprintf(stdout, " %hd \n", currev->code); // note on ch=0x90; snd_rawmidi_write(handle_out,&ch,1); ch=currev->code; snd_rawmidi_write(handle_out,&ch,1); ch=127; snd_rawmidi_write(handle_out,&ch,1); // controller up ch=0xB0; snd_rawmidi_write(handle_out,&ch,1); ch=currev->code; snd_rawmidi_write(handle_out,&ch,1); ch=127; snd_rawmidi_write(handle_out,&ch,1); if ( 1 == cStates[currev->code] ) { // toggle was on already cStates[currev->code] = 0; // send a note-off ch=0x91; snd_rawmidi_write(handle_out,&ch,1); ch=currev->code; snd_rawmidi_write(handle_out,&ch,1); ch=0; snd_rawmidi_write(handle_out,&ch,1); // and a controller down ch=0xB1; snd_rawmidi_write(handle_out,&ch,1); ch=currev->code; snd_rawmidi_write(handle_out,&ch,1); ch=0; snd_rawmidi_write(handle_out,&ch,1); } else { // toggle was off or uninitialised cStates[currev->code] = 1; // send a note-on ch=0x91; snd_rawmidi_write(handle_out,&ch,1); ch=currev->code; snd_rawmidi_write(handle_out,&ch,1); ch=127; snd_rawmidi_write(handle_out,&ch,1); // and controller up ch=0xB1; snd_rawmidi_write(handle_out,&ch,1); ch=currev->code; snd_rawmidi_write(handle_out,&ch,1); ch=127; snd_rawmidi_write(handle_out,&ch,1); } snd_rawmidi_drain(handle_out); } else if ( 2 == currev->value ) { // repeat fprintf(stdout, "*%hd*\n", currev->code); } else if ( 0 == currev->value ) { // release fprintf(stdout, "[%hd]\n", currev->code); // note off ch=0x90; snd_rawmidi_write(handle_out,&ch,1); ch=currev->code; snd_rawmidi_write(handle_out,&ch,1); ch=0; snd_rawmidi_write(handle_out,&ch,1); // controller down ch=0xB0; snd_rawmidi_write(handle_out,&ch,1); ch=currev->code; snd_rawmidi_write(handle_out,&ch,1); ch=0; snd_rawmidi_write(handle_out,&ch,1); snd_rawmidi_drain(handle_out); // sleep(1); } else { // dunno fprintf(stdout, "?%hd? - What is value %d?\n", currev->code, currev->value); } } } } else { fprintf(stderr, "odd ... no data and we only listen in 1 fd\n"); } } return 0; }
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; }
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; }
int main (int argc, char *argv []) { int argn = 1; if (argn == argc || streq (argv [argn], "-h") || streq (argv [argn], "--help")) { puts ("midicast [-v] [-p port] [-i interface]"); puts ("Reads MIDI events from port and sends to Zyre MIDI group"); puts (" -h, --help: this help"); puts (" -v, --verbose: trace events as they happen"); puts (" -p, --port: specify port name, e.g. '-p hw:1,0,0'"); puts (" -i, --interface: specify WiFi interface, e.g. '-i wlan0'"); return 0; } char *midi_port_name = "hw:2,0"; char *wifi_interface = NULL; bool verbose = false; while (argn < argc) { if (streq (argv [argn], "-p") || streq (argv [argn], "--port")) midi_port_name = argv [++argn]; else if (streq (argv [argn], "-i") || streq (argv [argn], "--interface")) wifi_interface = argv [++argn]; else if (streq (argv [argn], "-v") || streq (argv [argn], "--verbose")) verbose = true; argn++; } snd_rawmidi_t *output; int rc = snd_rawmidi_open (NULL, &output, midi_port_name, SND_RAWMIDI_SYNC); if (rc < 0) { zsys_error ("cannot open port \"%s\": %s", midi_port_name, snd_strerror (rc)); return 0; } zsys_info ("forwarding MIDI cast to %s", midi_port_name); zyre_t *zyre = zyre_new (NULL); if (wifi_interface) zyre_set_interface (zyre, wifi_interface); zyre_start (zyre); zyre_join (zyre, "MIDI"); zsys_info ("this player is %s", zyre_name (zyre)); while (!zsys_interrupted) { zyre_event_t *event = zyre_event_new (zyre); if (!event) { printf (" interrupted\n"); break; } if (zyre_event_type (event) == ZYRE_EVENT_JOIN) zsys_info ("[%s] player joined", zyre_event_peer_name (event)); else if (zyre_event_type (event) == ZYRE_EVENT_LEAVE) zsys_info ("[%s] player left", zyre_event_peer_name (event)); else if (zyre_event_type (event) == ZYRE_EVENT_SHOUT) { if (streq (zyre_event_group (event), "MIDI")) { zframe_t *frame = zmsg_first (zyre_event_msg (event)); // Forward the MIDI event snd_rawmidi_write (output, zframe_data (frame), zframe_size (frame)); if (verbose) { printf ("%zd:", zframe_size (frame)); int byte_nbr; for (byte_nbr = 0; byte_nbr < zframe_size (frame); byte_nbr++) printf (" %02X", zframe_data (frame) [byte_nbr]); printf ("\n"); } } } zyre_event_destroy (&event); } snd_rawmidi_close (output); zyre_destroy (&zyre); return 0; }
// for each ALSA device, call iterator. userData is passed to the iterator // returns total number of iterations static int iterateRawmidiDevices(snd_rawmidi_stream_t direction, DeviceIteratorPtr iterator, void* userData) { int count = 0; int subdeviceCount; int card, dev, subDev; char devname[16]; int err; snd_ctl_t *handle; snd_rawmidi_t *rawmidi; snd_rawmidi_info_t *rawmidi_info; snd_ctl_card_info_t *card_info, *defcardinfo = NULL; UINT32 deviceID; int doContinue = TRUE; snd_rawmidi_info_malloc(&rawmidi_info); snd_ctl_card_info_malloc(&card_info); // 1st try "default" device if (direction == SND_RAWMIDI_STREAM_INPUT) { err = snd_rawmidi_open(&rawmidi, NULL, ALSA_DEFAULT_DEVICE_NAME, SND_RAWMIDI_NONBLOCK); } else if (direction == SND_RAWMIDI_STREAM_OUTPUT) { err = snd_rawmidi_open(NULL, &rawmidi, ALSA_DEFAULT_DEVICE_NAME, SND_RAWMIDI_NONBLOCK); } else { ERROR0("ERROR: iterateRawmidiDevices(): direction is neither" " SND_RAWMIDI_STREAM_INPUT nor SND_RAWMIDI_STREAM_OUTPUT\n"); err = MIDI_INVALID_ARGUMENT; } if (err < 0) { ERROR1("ERROR: snd_rawmidi_open (\"default\"): %s\n", snd_strerror(err)); } else { err = snd_rawmidi_info(rawmidi, rawmidi_info); snd_rawmidi_close(rawmidi); if (err < 0) { ERROR1("ERROR: snd_rawmidi_info (\"default\"): %s\n", snd_strerror(err)); } else { // try to get card info card = snd_rawmidi_info_get_card(rawmidi_info); if (card >= 0) { sprintf(devname, ALSA_HARDWARE_CARD, card); if (snd_ctl_open(&handle, devname, SND_CTL_NONBLOCK) >= 0) { if (snd_ctl_card_info(handle, card_info) >= 0) { defcardinfo = card_info; } snd_ctl_close(handle); } } // call calback function for the device if (iterator != NULL) { doContinue = (*iterator)(ALSA_DEFAULT_DEVICE_ID, rawmidi_info, defcardinfo, userData); } count++; } } // iterate cards card = -1; TRACE0("testing for cards...\n"); if (snd_card_next(&card) >= 0) { TRACE1("Found card %d\n", card); while (doContinue && (card >= 0)) { sprintf(devname, ALSA_HARDWARE_CARD, card); TRACE1("Opening control for alsa rawmidi device \"%s\"...\n", devname); err = snd_ctl_open(&handle, devname, SND_CTL_NONBLOCK); if (err < 0) { ERROR2("ERROR: snd_ctl_open, card=%d: %s\n", card, snd_strerror(err)); } else { TRACE0("snd_ctl_open() SUCCESS\n"); err = snd_ctl_card_info(handle, card_info); if (err < 0) { ERROR2("ERROR: snd_ctl_card_info, card=%d: %s\n", card, snd_strerror(err)); } else { TRACE0("snd_ctl_card_info() SUCCESS\n"); dev = -1; while (doContinue) { if (snd_ctl_rawmidi_next_device(handle, &dev) < 0) { ERROR0("snd_ctl_rawmidi_next_device\n"); } TRACE0("snd_ctl_rawmidi_next_device() SUCCESS\n"); if (dev < 0) { break; } snd_rawmidi_info_set_device(rawmidi_info, dev); snd_rawmidi_info_set_subdevice(rawmidi_info, 0); snd_rawmidi_info_set_stream(rawmidi_info, direction); err = snd_ctl_rawmidi_info(handle, rawmidi_info); TRACE0("after snd_ctl_rawmidi_info()\n"); if (err < 0) { if (err != -ENOENT) { ERROR2("ERROR: snd_ctl_rawmidi_info, card=%d: %s", card, snd_strerror(err)); } } else { TRACE0("snd_ctl_rawmidi_info() SUCCESS\n"); subdeviceCount = needEnumerateSubdevices(ALSA_RAWMIDI) ? snd_rawmidi_info_get_subdevices_count(rawmidi_info) : 1; if (iterator!=NULL) { for (subDev = 0; subDev < subdeviceCount; subDev++) { TRACE3(" Iterating %d,%d,%d\n", card, dev, subDev); deviceID = encodeDeviceID(card, dev, subDev); doContinue = (*iterator)(deviceID, rawmidi_info, card_info, userData); count++; TRACE0("returned from iterator\n"); if (!doContinue) { break; } } } else { count += subdeviceCount; } } } // of while(doContinue) } snd_ctl_close(handle); } if (snd_card_next(&card) < 0) { break; } } } else { ERROR0("No cards found!\n"); } snd_ctl_card_info_free(card_info); snd_rawmidi_info_free(rawmidi_info); return count; }
/* direction has to be either SND_RAWMIDI_STREAM_INPUT or SND_RAWMIDI_STREAM_OUTPUT. Returns 0 on success. Otherwise, MIDI_OUT_OF_MEMORY, MIDI_INVALID_ARGUMENT or a negative ALSA error code is returned. */ INT32 openMidiDevice(snd_rawmidi_stream_t direction, INT32 deviceIndex, MidiDeviceHandle** handle) { snd_rawmidi_t* native_handle; snd_midi_event_t* event_parser = NULL; int err; UINT32 deviceID; char devicename[100]; #ifdef ALSA_MIDI_USE_PLUGHW int usePlugHw = 1; #else int usePlugHw = 0; #endif TRACE0("> openMidiDevice()\n"); (*handle) = (MidiDeviceHandle*) calloc(sizeof(MidiDeviceHandle), 1); if (!(*handle)) { ERROR0("ERROR: openDevice: out of memory\n"); return MIDI_OUT_OF_MEMORY; } // TODO: iterate to get dev ID from index err = getMidiDeviceID(direction, deviceIndex, &deviceID); TRACE1(" openMidiDevice(): deviceID: %d\n", (int) deviceID); getDeviceStringFromDeviceID(devicename, deviceID, usePlugHw, ALSA_RAWMIDI); TRACE1(" openMidiDevice(): deviceString: %s\n", devicename); // finally open the device if (direction == SND_RAWMIDI_STREAM_INPUT) { err = snd_rawmidi_open(&native_handle, NULL, devicename, SND_RAWMIDI_NONBLOCK); } else if (direction == SND_RAWMIDI_STREAM_OUTPUT) { err = snd_rawmidi_open(NULL, &native_handle, devicename, SND_RAWMIDI_NONBLOCK); } else { ERROR0(" ERROR: openMidiDevice(): direction is neither SND_RAWMIDI_STREAM_INPUT nor SND_RAWMIDI_STREAM_OUTPUT\n"); err = MIDI_INVALID_ARGUMENT; } if (err < 0) { ERROR1("< ERROR: openMidiDevice(): snd_rawmidi_open() returned %d\n", err); free(*handle); (*handle) = NULL; return err; } /* We opened with non-blocking behaviour to not get hung if the device is used by a different process. Writing, however, should be blocking. So we change it here. */ if (direction == SND_RAWMIDI_STREAM_OUTPUT) { err = snd_rawmidi_nonblock(native_handle, 0); if (err < 0) { ERROR1(" ERROR: openMidiDevice(): snd_rawmidi_nonblock() returned %d\n", err); snd_rawmidi_close(native_handle); free(*handle); (*handle) = NULL; return err; } } if (direction == SND_RAWMIDI_STREAM_INPUT) { err = snd_midi_event_new(EVENT_PARSER_BUFSIZE, &event_parser); if (err < 0) { ERROR1(" ERROR: openMidiDevice(): snd_midi_event_new() returned %d\n", err); snd_rawmidi_close(native_handle); free(*handle); (*handle) = NULL; return err; } } (*handle)->deviceHandle = (void*) native_handle; (*handle)->startTime = getTimeInMicroseconds(); (*handle)->platformData = event_parser; TRACE0("< openMidiDevice(): succeeded\n"); return err; }