bool mastermidibus::get_midi_event (event * inev) { #ifdef SEQ64_HAVE_LIBASOUND automutex locker(m_mutex); snd_seq_event_t * ev; bool sysex = false; bool result = false; midibyte buffer[0x1000]; /* temporary buffer for MIDI data */ snd_seq_event_input(m_alsa_seq, &ev); if (! rc().manual_alsa_ports()) { switch (ev->type) { case SND_SEQ_EVENT_PORT_START: { port_start(ev->data.addr.client, ev->data.addr.port); result = true; break; } case SND_SEQ_EVENT_PORT_EXIT: { port_exit(ev->data.addr.client, ev->data.addr.port); result = true; break; } case SND_SEQ_EVENT_PORT_CHANGE: { result = true; break; } default: break; } } if (result) return false; snd_midi_event_t * midi_ev; /* for ALSA MIDI parser */ snd_midi_event_new(sizeof(buffer), &midi_ev); /* make ALSA MIDI parser */ long bytes = snd_midi_event_decode(midi_ev, buffer, sizeof(buffer), ev); if (bytes <= 0) { /* * This happens even at startup, before anything is really happening. * Let's not show it. * * if (bytes < 0) * { * errprint("error decoding MIDI event"); * } */ return false; } inev->set_timestamp(ev->time.tick); inev->set_status_keep_channel(buffer[0]); /** * We will only get EVENT_SYSEX on the first packet of MIDI data; * the rest we have to poll for. SysEx processing is currently * disabled. */ #ifdef USE_SYSEX_PROCESSING /* currently disabled */ inev->set_sysex_size(bytes); if (buffer[0] == EVENT_MIDI_SYSEX) { inev->restart_sysex(); /* set up for sysex if needed */ sysex = inev->append_sysex(buffer, bytes); } else { #endif /* * Some keyboards send Note On with velocity 0 for Note Off, so we * take care of that situation here by creating a Note Off event, * with the channel nybble preserved. Note that we call * event :: set_status_keep_channel() instead of using stazed's * set_status function with the "record" parameter. A little more * confusing, but faster. */ inev->set_data(buffer[1], buffer[2]); if (inev->is_note_off_recorded()) inev->set_status_keep_channel(EVENT_NOTE_OFF); sysex = false; #ifdef USE_SYSEX_PROCESSING } #endif while (sysex) /* sysex messages might be more than one message */ { snd_seq_event_input(m_alsa_seq, &ev); long bytes = snd_midi_event_decode(midi_ev, buffer, sizeof(buffer), ev); if (bytes > 0) sysex = inev->append_sysex(buffer, bytes); else sysex = false; } snd_midi_event_free(midi_ev); #endif // SEQ64_HAVE_LIBASOUND return true; }
bool mastermidibus::get_midi_event( event *a_in ) { lock(); snd_seq_event_t *ev; bool sysex = false; /* temp for midi data */ unsigned char buffer[0x1000]; snd_seq_event_input(m_alsa_seq, &ev); bool ret = false; if (! global_manual_alsa_ports ) { switch( ev->type ){ case SND_SEQ_EVENT_PORT_START: { //printf("SND_SEQ_EVENT_PORT_START: addr[%d:%d]\n", // ev->data.addr.client, ev->data.addr.port ); port_start( ev->data.addr.client, ev->data.addr.port ); ret = true; break; } case SND_SEQ_EVENT_PORT_EXIT: { //printf("SND_SEQ_EVENT_PORT_EXIT: addr[%d:%d]\n", // ev->data.addr.client, ev->data.addr.port ); port_exit( ev->data.addr.client, ev->data.addr.port ); ret = true; break; } case SND_SEQ_EVENT_PORT_CHANGE: { //printf("SND_SEQ_EVENT_PORT_CHANGE: addr[%d:%d]\n", // ev->data.addr.client, // ev->data.addr.port ); ret = true; break; } default: break; } } if( ret ){ unlock(); return false; } /* alsa midi parser */ snd_midi_event_t *midi_ev; snd_midi_event_new( 0x1000, &midi_ev ); long bytes = snd_midi_event_decode( midi_ev, buffer, 0x1000, ev ); a_in->set_timestamp( ev->time.tick ); a_in->set_status( buffer[0] ); a_in->set_size( bytes ); /* we will only get EVENT_SYSEX on the first packet of midi data, the rest we have to poll for */ //if ( buffer[0] == EVENT_SYSEX ){ if ( 0 ){ /* set up for sysex if needed */ a_in->start_sysex( ); sysex = a_in->append_sysex( buffer, bytes ); } else { a_in->set_data( buffer[1], buffer[2] ); // some keyboards send on's with vel 0 for off if ( a_in->get_status() == EVENT_NOTE_ON && a_in->get_note_velocity() == 0x00 ){ a_in->set_status( EVENT_NOTE_OFF ); } sysex = false; } /* sysex messages might be more than one message */ while ( sysex ){ snd_seq_event_input(m_alsa_seq, &ev); bytes = snd_midi_event_decode( midi_ev, buffer, 0x1000, ev ); sysex = a_in->append_sysex( buffer, bytes ); } snd_seq_free_event( ev ); snd_midi_event_free( midi_ev ); unlock(); return true; }
bool mastermidibus::get_midi_event (event * a_in) { #ifdef HAVE_LIBASOUND automutex locker(m_mutex); snd_seq_event_t * ev; bool sysex = false; bool result = false; unsigned char buffer[0x1000]; /* temporary buffer for midi data */ snd_seq_event_input(m_alsa_seq, &ev); if (! global_manual_alsa_ports) { switch (ev->type) { case SND_SEQ_EVENT_PORT_START: { port_start(ev->data.addr.client, ev->data.addr.port); result = true; break; } case SND_SEQ_EVENT_PORT_EXIT: { port_exit(ev->data.addr.client, ev->data.addr.port); result = true; break; } case SND_SEQ_EVENT_PORT_CHANGE: { result = true; break; } default: break; } } if (result) return false; snd_midi_event_t * midi_ev; /* alsa midi parser */ snd_midi_event_new(sizeof(buffer), &midi_ev); long bytes = snd_midi_event_decode(midi_ev, buffer, sizeof(buffer), ev); if (bytes <= 0) return false; a_in->set_timestamp(ev->time.tick); a_in->set_status(buffer[0]); a_in->set_size(bytes); /* * We will only get EVENT_SYSEX on the first packet of MIDI data; * the rest we have to poll for. */ #if 0 if ( buffer[0] == EVENT_SYSEX ) { a_in->start_sysex(); /* set up for sysex if needed */ sysex = a_in->append_sysex(buffer, bytes); } else { #endif /* some keyboards send Note On with velocity 0 for Note Off */ a_in->set_data(buffer[1], buffer[2]); if (a_in->get_status() == EVENT_NOTE_ON && a_in->get_note_velocity() == 0) a_in->set_status(EVENT_NOTE_OFF); sysex = false; #if 0 } #endif while (sysex) /* sysex messages might be more than one message */ { snd_seq_event_input(m_alsa_seq, &ev); long bytes = snd_midi_event_decode(midi_ev, buffer, sizeof(buffer), ev); if (bytes > 0) sysex = a_in->append_sysex(buffer, bytes); else sysex = false; } snd_midi_event_free(midi_ev); #endif // HAVE_LIBASOUND return true; }