void midibus::play (event * a_e24, unsigned char a_channel) { #ifdef HAVE_LIBASOUND automutex locker(m_mutex); snd_seq_event_t ev; snd_midi_event_t *midi_ev; /* ALSA MIDI parser */ unsigned char buffer[3]; /* temp for MIDI data */ /* fill buffer and set midi channel */ buffer[0] = a_e24->get_status(); buffer[0] += (a_channel & 0x0F); a_e24->get_data(&buffer[1], &buffer[2]); snd_midi_event_new(10, &midi_ev); /* clear event */ snd_seq_ev_clear(&ev); snd_midi_event_encode(midi_ev, buffer, 3, &ev); snd_midi_event_free(midi_ev); /* set source */ snd_seq_ev_set_source(&ev, m_local_addr_port); snd_seq_ev_set_subs(&ev); snd_seq_ev_set_direct(&ev); // its immediate /* pump it into the queue */ snd_seq_event_output(m_seq, &ev); #endif // HAVE_LIBASOUND }
void sendMessageNow (const MidiMessage& message) { if (message.getRawDataSize() > maxEventSize) { maxEventSize = message.getRawDataSize(); snd_midi_event_free (midiParser); snd_midi_event_new (maxEventSize, &midiParser); } snd_seq_event_t event; snd_seq_ev_clear (&event); snd_midi_event_encode (midiParser, message.getRawData(), message.getRawDataSize(), &event); snd_midi_event_reset_encode (midiParser); snd_seq_ev_set_source (&event, 0); snd_seq_ev_set_subs (&event); snd_seq_ev_set_direct (&event); snd_seq_event_output (seqHandle, &event); snd_seq_drain_output (seqHandle); }
void DssiPluginMidiManager::convertMidiMessages (MidiBuffer& midiMessages, const int blockSamples) { const uint8* data; int numBytesOfMidiData, samplePosition; MidiBuffer::Iterator it (midiMessages); currentMidiCount = 0; while (it.getNextEvent (data, numBytesOfMidiData, samplePosition)) { if (numBytesOfMidiData > maxEventSize) { maxEventSize = numBytesOfMidiData; snd_midi_event_free (midiParser); snd_midi_event_new (maxEventSize, &midiParser); } snd_seq_event_t* event = & midiEventsBuffer [currentMidiCount]; snd_seq_ev_clear (event); snd_midi_event_encode (midiParser, data, numBytesOfMidiData, event); if (++currentMidiCount >= 2048) break; } snd_midi_event_reset_encode (midiParser); }
void sendMessageNow (const MidiMessage& message) { if (message.getRawDataSize() > maxEventSize) { maxEventSize = message.getRawDataSize(); snd_midi_event_free (midiParser); snd_midi_event_new (maxEventSize, &midiParser); } snd_seq_event_t event; snd_seq_ev_clear (&event); long numBytes = (long) message.getRawDataSize(); const uint8* data = message.getRawData(); while (numBytes > 0) { const long numSent = snd_midi_event_encode (midiParser, data, numBytes, &event); if (numSent <= 0) break; numBytes -= numSent; data += numSent; snd_seq_ev_set_source (&event, 0); snd_seq_ev_set_subs (&event); snd_seq_ev_set_direct (&event); snd_seq_event_output (seqHandle, &event); } snd_seq_drain_output (seqHandle); snd_midi_event_reset_encode (midiParser); }
/* * release the midi device if it was registered */ int snd_seq_oss_midi_check_exit_port(int client, int port) { struct seq_oss_midi *mdev; unsigned long flags; int index; if ((mdev = find_slot(client, port)) != NULL) { spin_lock_irqsave(®ister_lock, flags); midi_devs[mdev->seq_device] = NULL; spin_unlock_irqrestore(®ister_lock, flags); snd_use_lock_free(&mdev->use_lock); snd_use_lock_sync(&mdev->use_lock); snd_midi_event_free(mdev->coder); kfree(mdev); } spin_lock_irqsave(®ister_lock, flags); for (index = max_midi_devs - 1; index >= 0; index--) { if (midi_devs[index]) break; } max_midi_devs = index + 1; spin_unlock_irqrestore(®ister_lock, flags); return 0; }
static void stream_close(alsa_seqmidi_t *self, int dir) { stream_t *str = &self->stream[dir]; if (str->codec) snd_midi_event_free(str->codec); if (str->new_ports) jack_ringbuffer_free(str->new_ports); }
void midi_uninit() { if (s_midi == NULL) return; snd_midi_event_free(s_midiCoder); snd_seq_port_subscribe_free(s_midiSubscription); snd_seq_delete_port(s_midi, s_midiPort); snd_seq_close(s_midi); s_midi = NULL; }
void AlsaSeqMidiInDriver::close() { if (!this->is_open()) throw std::logic_error("Device not open"); if (m_impl->decoder) snd_midi_event_free (m_impl->decoder); snd_seq_close(m_impl->seq); m_impl->seq=0; }
static void a2j_stream_close (struct a2j * self) { struct a2j_stream *str = &self->stream; if (str->codec) snd_midi_event_free (str->codec); if (str->new_ports) jack_ringbuffer_free (str->new_ports); }
/* delete given midi synth port */ static void snd_seq_midisynth_delete(struct seq_midisynth *msynth) { if (msynth == NULL) return; if (msynth->seq_client > 0) { /* delete port */ snd_seq_event_port_detach(msynth->seq_client, msynth->seq_port); } snd_midi_event_free(msynth->parser); }
void run() { const int maxEventSize = 16 * 1024; snd_midi_event_t* midiParser; if (snd_midi_event_new (maxEventSize, &midiParser) >= 0) { HeapBlock <uint8> buffer (maxEventSize); const int numPfds = snd_seq_poll_descriptors_count (seqHandle, POLLIN); struct pollfd* const pfd = (struct pollfd*) alloca (numPfds * sizeof (struct pollfd)); snd_seq_poll_descriptors (seqHandle, pfd, numPfds, POLLIN); while (! threadShouldExit()) { if (poll (pfd, numPfds, 500) > 0) { snd_seq_event_t* inputEvent = nullptr; snd_seq_nonblock (seqHandle, 1); do { if (snd_seq_event_input (seqHandle, &inputEvent) >= 0) { // xxx what about SYSEXes that are too big for the buffer? const int numBytes = snd_midi_event_decode (midiParser, buffer, maxEventSize, inputEvent); snd_midi_event_reset_decode (midiParser); if (numBytes > 0) { const MidiMessage message ((const uint8*) buffer, numBytes, Time::getMillisecondCounter() * 0.001); callback->handleIncomingMidiMessage (midiInput, message); } snd_seq_free_event (inputEvent); } } while (snd_seq_event_input_pending (seqHandle, 0) > 0); snd_seq_free_event (inputEvent); } } snd_midi_event_free (midiParser); } };
static int snd_rawmidi_virtual_close(snd_rawmidi_t *rmidi) { snd_rawmidi_virtual_t *virt = rmidi->private_data; virt->open--; if (virt->open) return 0; snd_seq_close(virt->handle); if (virt->midi_event) snd_midi_event_free(virt->midi_event); free(virt); return 0; }
void sys_alsa_close_midi() { alsa_nmidiin = alsa_nmidiout = 0; if(midi_handle) { snd_seq_close(midi_handle); if(midiev) { snd_midi_event_free(midiev); } } }
Alsa::~Alsa() { // Close a connection if it exists. closePort(); // Cleanup. if ( _apiData->vport >= 0 ) snd_seq_delete_port( _apiData->seq, _apiData->vport ); if ( _apiData->coder ) snd_midi_event_free( _apiData->coder ); if ( _apiData->buffer ) free( _apiData->buffer ); snd_seq_close( _apiData->seq ); delete _apiData; }
/* takes an native event, encodes to alsa event, puts it in the queue */ void midibus::play( event *a_e24, unsigned char a_channel ) { lock(); snd_seq_event_t ev; /* alsa midi parser */ snd_midi_event_t *midi_ev; /* temp for midi data */ unsigned char buffer[3]; /* fill buffer and set midi channel */ buffer[0] = a_e24->get_status(); buffer[0] += (a_channel & 0x0F); a_e24->get_data( &buffer[1], &buffer[2] ); snd_midi_event_new( 10, &midi_ev ); /* clear event */ snd_seq_ev_clear( &ev ); snd_midi_event_encode( midi_ev, buffer, 3, &ev ); snd_midi_event_free( midi_ev ); /* set source */ snd_seq_ev_set_source(&ev, m_local_addr_port ); snd_seq_ev_set_subs(&ev); /* set tag unique to each sequence for removal purposes */ //ev.tag = a_tag; // its immediate snd_seq_ev_set_direct( &ev ); /* pump it into the queue */ snd_seq_event_output(m_seq, &ev); unlock(); }
bool sendMessageNow (const MidiMessage& message) { if (message.getRawDataSize() > maxEventSize) { maxEventSize = message.getRawDataSize(); snd_midi_event_free (midiParser); snd_midi_event_new ((size_t) maxEventSize, &midiParser); } snd_seq_event_t event; snd_seq_ev_clear (&event); long numBytes = (long) message.getRawDataSize(); const uint8* data = message.getRawData(); snd_seq_t* seqHandle = port.client->get(); bool success = true; while (numBytes > 0) { const long numSent = snd_midi_event_encode (midiParser, data, numBytes, &event); if (numSent <= 0) { success = numSent == 0; break; } numBytes -= numSent; data += numSent; snd_seq_ev_set_source (&event, 0); snd_seq_ev_set_subs (&event); snd_seq_ev_set_direct (&event); if (snd_seq_event_output_direct (seqHandle, &event) < 0) { success = false; break; } } snd_midi_event_reset_encode (midiParser); return success; }
/* delete given midi synth port */ static void snd_seq_midisynth_delete(seq_midisynth_t *msynth) { snd_seq_port_info_t port; if (msynth == NULL) return; if (msynth->seq_client > 0) { /* delete port */ memset(&port, 0, sizeof(port)); port.addr.client = msynth->seq_client; port.addr.port = msynth->seq_port; snd_seq_kernel_client_ctl(port.addr.client, SNDRV_SEQ_IOCTL_DELETE_PORT, &port); } if (msynth->parser) snd_midi_event_free(msynth->parser); }
/* * release the midi device if it was registered */ void snd_seq_oss_midi_clear_all(void) { int i; struct seq_oss_midi *mdev; unsigned long flags; spin_lock_irqsave(®ister_lock, flags); for (i = 0; i < max_midi_devs; i++) { if ((mdev = midi_devs[i]) != NULL) { snd_midi_event_free(mdev->coder); kfree(mdev); midi_devs[i] = NULL; } } max_midi_devs = 0; spin_unlock_irqrestore(®ister_lock, flags); }
INT32 closeMidiDevice(MidiDeviceHandle* handle) { int err; TRACE0("> closeMidiDevice()\n"); if (!handle) { ERROR0("< ERROR: closeMidiDevice(): handle is NULL\n"); return MIDI_INVALID_HANDLE; } if (!handle->deviceHandle) { ERROR0("< ERROR: closeMidiDevice(): native handle is NULL\n"); return MIDI_INVALID_HANDLE; } err = snd_rawmidi_close((snd_rawmidi_t*) handle->deviceHandle); TRACE1(" snd_rawmidi_close() returns %d\n", err); if (handle->platformData) { snd_midi_event_free((snd_midi_event_t*) handle->platformData); } free(handle); TRACE0("< closeMidiDevice: succeeded\n"); return err; }
void midibus::play (event * e24, midibyte channel) { #ifdef SEQ64_HAVE_LIBASOUND automutex locker(m_mutex); midibyte buffer[4]; /* temp for MIDI data */ buffer[0] = e24->get_status(); /* fill buffer */ buffer[0] += (channel & 0x0F); e24->get_data(buffer[1], buffer[2]); /* set MIDI data */ snd_midi_event_t * midi_ev; /* ALSA MIDI parser */ snd_midi_event_new(SEQ64_MIDI_EVENT_SIZE_MAX, &midi_ev); snd_seq_event_t ev; snd_seq_ev_clear(&ev); /* clear event */ snd_midi_event_encode(midi_ev, buffer, 3, &ev); /* encode 3 raw bytes */ snd_midi_event_free(midi_ev); /* free the parser */ snd_seq_ev_set_source(&ev, m_local_addr_port); /* set source */ snd_seq_ev_set_subs(&ev); snd_seq_ev_set_direct(&ev); /* it is immediate */ snd_seq_event_output(m_seq, &ev); /* pump into the queue */ #endif // SEQ64_HAVE_LIBASOUND }
int snd_rawmidi_virtual_open(snd_rawmidi_t **inputp, snd_rawmidi_t **outputp, const char *name, snd_seq_t *seq_handle, int port, int merge, int mode) { int err; snd_rawmidi_t *rmidi; snd_rawmidi_virtual_t *virt = NULL; struct pollfd pfd; if (inputp) *inputp = 0; if (outputp) *outputp = 0; virt = calloc(1, sizeof(*virt)); if (virt == NULL) { err = -ENOMEM; goto _err; } virt->handle = seq_handle; virt->port = port; err = snd_midi_event_new(256, &virt->midi_event); if (err < 0) goto _err; snd_midi_event_init(virt->midi_event); snd_midi_event_no_status(virt->midi_event, !merge); if (inputp) { rmidi = calloc(1, sizeof(*rmidi)); if (rmidi == NULL) { err = -ENOMEM; goto _err; } if (name) rmidi->name = strdup(name); rmidi->type = SND_RAWMIDI_TYPE_VIRTUAL; rmidi->stream = SND_RAWMIDI_STREAM_INPUT; rmidi->mode = mode; err = snd_seq_poll_descriptors(seq_handle, &pfd, 1, POLLIN); if (err < 0) goto _err; rmidi->poll_fd = pfd.fd; rmidi->ops = &snd_rawmidi_virtual_ops; rmidi->private_data = virt; virt->open++; *inputp = rmidi; } if (outputp) { rmidi = calloc(1, sizeof(*rmidi)); if (rmidi == NULL) { err = -ENOMEM; goto _err; } if (name) rmidi->name = strdup(name); rmidi->type = SND_RAWMIDI_TYPE_VIRTUAL; rmidi->stream = SND_RAWMIDI_STREAM_OUTPUT; rmidi->mode = mode; err = snd_seq_poll_descriptors(seq_handle, &pfd, 1, POLLOUT); if (err < 0) goto _err; rmidi->poll_fd = pfd.fd; rmidi->ops = &snd_rawmidi_virtual_ops; rmidi->private_data = virt; virt->open++; *outputp = rmidi; } return 0; _err: if (seq_handle) snd_seq_close(seq_handle); if (virt) { if (virt->midi_event) snd_midi_event_free(virt->midi_event); free(virt); } if (inputp) free(*inputp); if (outputp) free(*outputp); return err; }
~MidiOutputDevice() { snd_midi_event_free (midiParser); snd_seq_close (seqHandle); }
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; }
DssiPluginMidiManager::~DssiPluginMidiManager () { snd_midi_event_free (midiParser); }
~MidiOutputDevice() { snd_midi_event_free (midiParser); port.deletePort(); }
int snd_seq_oss_midi_check_new_port(struct snd_seq_port_info *pinfo) { int i; struct seq_oss_midi *mdev; unsigned long flags; debug_printk(("check for MIDI client %d port %d\n", pinfo->addr.client, pinfo->addr.port)); /* */ if (! (pinfo->type & SNDRV_SEQ_PORT_TYPE_MIDI_GENERIC)) return 0; /* */ if ((pinfo->capability & PERM_WRITE) != PERM_WRITE && (pinfo->capability & PERM_READ) != PERM_READ) return 0; /* */ if ((mdev = find_slot(pinfo->addr.client, pinfo->addr.port)) != NULL) { /* */ snd_use_lock_free(&mdev->use_lock); return 0; } /* */ if ((mdev = kzalloc(sizeof(*mdev), GFP_KERNEL)) == NULL) { snd_printk(KERN_ERR "can't malloc midi info\n"); return -ENOMEM; } /* */ mdev->client = pinfo->addr.client; mdev->port = pinfo->addr.port; mdev->flags = pinfo->capability; mdev->opened = 0; snd_use_lock_init(&mdev->use_lock); /* */ strlcpy(mdev->name, pinfo->name, sizeof(mdev->name)); /* */ if (snd_midi_event_new(MAX_MIDI_EVENT_BUF, &mdev->coder) < 0) { snd_printk(KERN_ERR "can't malloc midi coder\n"); kfree(mdev); return -ENOMEM; } /* */ snd_midi_event_no_status(mdev->coder, 1); /* */ spin_lock_irqsave(®ister_lock, flags); for (i = 0; i < max_midi_devs; i++) { if (midi_devs[i] == NULL) break; } if (i >= max_midi_devs) { if (max_midi_devs >= SNDRV_SEQ_OSS_MAX_MIDI_DEVS) { spin_unlock_irqrestore(®ister_lock, flags); snd_midi_event_free(mdev->coder); kfree(mdev); return -ENOMEM; } max_midi_devs++; } mdev->seq_device = i; midi_devs[mdev->seq_device] = mdev; spin_unlock_irqrestore(®ister_lock, flags); return 0; }
void samplv1_jack::close (void) { #ifdef CONFIG_ALSA_MIDI // close alsa sequencer client... if (m_alsa_seq) { if (m_alsa_thread) { delete m_alsa_thread; m_alsa_thread = NULL; } if (m_alsa_buffer) { ::jack_ringbuffer_free(m_alsa_buffer); m_alsa_buffer = NULL; } if (m_alsa_decoder) { snd_midi_event_free(m_alsa_decoder); m_alsa_decoder = NULL; } if (m_alsa_port >= 0) { snd_seq_delete_simple_port(m_alsa_seq, m_alsa_port); m_alsa_port = -1; } snd_seq_close(m_alsa_seq); // m_alsa_client = -1; m_alsa_seq = NULL; } #endif if (m_client == NULL) return; #ifdef CONFIG_JACK_MIDI // unregister midi port if (m_midi_in) { ::jack_port_unregister(m_client, m_midi_in); m_midi_in = NULL; } #endif // unregister audio ports const uint16_t nchannels = samplv1::channels(); for (uint16_t k = 0; k < nchannels; ++k) { if (m_audio_outs && m_audio_outs[k]) { ::jack_port_unregister(m_client, m_audio_outs[k]); m_audio_outs[k] = NULL; } if (m_outs && m_outs[k]) m_outs[k] = NULL; if (m_audio_ins && m_audio_ins[k]) { ::jack_port_unregister(m_client, m_audio_ins[k]); m_audio_ins[k] = NULL; } if (m_ins && m_ins[k]) m_ins[k] = NULL; } if (m_outs) { delete [] m_outs; m_outs = NULL; } if (m_ins) { delete [] m_ins; m_ins = NULL; } if (m_audio_outs) { delete [] m_audio_outs; m_audio_outs = NULL; } if (m_audio_ins) { delete [] m_audio_ins; m_audio_ins = NULL; } // close client ::jack_client_close(m_client); m_client = NULL; }
/* * register a new port if it doesn't exist yet */ int snd_seq_oss_midi_check_new_port(struct snd_seq_port_info *pinfo) { int i; struct seq_oss_midi *mdev; unsigned long flags; /* the port must include generic midi */ if (! (pinfo->type & SNDRV_SEQ_PORT_TYPE_MIDI_GENERIC)) return 0; /* either read or write subscribable */ if ((pinfo->capability & PERM_WRITE) != PERM_WRITE && (pinfo->capability & PERM_READ) != PERM_READ) return 0; /* * look for the identical slot */ if ((mdev = find_slot(pinfo->addr.client, pinfo->addr.port)) != NULL) { /* already exists */ snd_use_lock_free(&mdev->use_lock); return 0; } /* * allocate midi info record */ mdev = kzalloc(sizeof(*mdev), GFP_KERNEL); if (!mdev) return -ENOMEM; /* copy the port information */ mdev->client = pinfo->addr.client; mdev->port = pinfo->addr.port; mdev->flags = pinfo->capability; mdev->opened = 0; snd_use_lock_init(&mdev->use_lock); /* copy and truncate the name of synth device */ strlcpy(mdev->name, pinfo->name, sizeof(mdev->name)); /* create MIDI coder */ if (snd_midi_event_new(MAX_MIDI_EVENT_BUF, &mdev->coder) < 0) { pr_err("ALSA: seq_oss: can't malloc midi coder\n"); kfree(mdev); return -ENOMEM; } /* OSS sequencer adds running status to all sequences */ snd_midi_event_no_status(mdev->coder, 1); /* * look for en empty slot */ spin_lock_irqsave(®ister_lock, flags); for (i = 0; i < max_midi_devs; i++) { if (midi_devs[i] == NULL) break; } if (i >= max_midi_devs) { if (max_midi_devs >= SNDRV_SEQ_OSS_MAX_MIDI_DEVS) { spin_unlock_irqrestore(®ister_lock, flags); snd_midi_event_free(mdev->coder); kfree(mdev); return -ENOMEM; } max_midi_devs++; } mdev->seq_device = i; midi_devs[mdev->seq_device] = mdev; spin_unlock_irqrestore(®ister_lock, flags); return 0; }
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; }
int main(int argc, char **argv) { int i; int listen_port = -1; char *client_name = "net2alsamidi"; char *connect_client = NULL; int connect_port = -1; for (i = 1; i < argc; i++) { if (strcmp(argv[i], "--port") == 0) { if (++i == argc) usage(argv[0]); listen_port = atoi(argv[i]); } else if (strcmp(argv[i], "--name") == 0) { if (++i == argc) usage(argv[0]); client_name = argv[i]; } else if (strcmp(argv[i], "--connect") == 0) { if (++i == argc) usage(argv[0]); connect_client = argv[i]; if (++i == argc) usage(argv[0]); connect_port = atoi(argv[i]); } else { usage(argv[0]); } } if (listen_port > 0) { snd_seq_t *seq; int port; if (snd_seq_open(&seq, "default", SND_SEQ_OPEN_OUTPUT, 0) < 0) { fprintf(stderr, "Cannot open the ALSA sequencer.\n"); exit(1); } snd_seq_set_client_name(seq, client_name); port = snd_seq_create_simple_port(seq, "from NetMIDI client", SND_SEQ_PORT_CAP_READ | SND_SEQ_PORT_CAP_SUBS_READ, SND_SEQ_PORT_TYPE_MIDI_GENERIC | SND_SEQ_PORT_TYPE_APPLICATION); if ((connect_client != NULL) && (connect_port >= 0)) { int connect_client_id = -1; { snd_seq_client_info_t *client_info; snd_seq_client_info_malloc(&client_info); while (snd_seq_query_next_client(seq, client_info) == 0) { if (strcmp(snd_seq_client_info_get_name(client_info), connect_client) == 0) { connect_client_id = snd_seq_client_info_get_client(client_info); break; } } snd_seq_client_info_free(client_info); } if (connect_client_id < 0) connect_client_id = atoi(connect_client); snd_seq_connect_to(seq, port, connect_client_id, connect_port); } { int server_socket; struct sockaddr_in server_address; if ((server_socket = socket(AF_INET, SOCK_STREAM, 0)) < 0) { fprintf(stderr, "Cannot start a NetMIDI server on port %d.\n", listen_port); exit(1); } server_address.sin_family = AF_INET; server_address.sin_port = htons(listen_port); server_address.sin_addr.s_addr = INADDR_ANY; if (bind(server_socket, (struct sockaddr *)(&server_address), sizeof(server_address)) < 0) { fprintf(stderr, "Cannot start a NetMIDI server on port %d.\n", listen_port); exit(1); } if (listen(server_socket, 1) < 0) { fprintf(stderr, "Cannot start a NetMIDI server on port %d.\n", listen_port); exit(1); } while (1) { int socket_to_client; if ((socket_to_client = accept(server_socket, NULL, NULL)) >= 0) { snd_midi_event_t *midi_event_parser; snd_seq_event_t *event; unsigned char buffer[BUFFER_SIZE]; int bytes_read; { char one = 1; setsockopt(socket_to_client, IPPROTO_TCP, TCP_NODELAY, &one, sizeof(one)); } snd_midi_event_new(BUFFER_SIZE, &midi_event_parser); while ((bytes_read = recv(socket_to_client, buffer, BUFFER_SIZE, 0)) > 0) { for (i = 0; i < bytes_read; i++) { if (snd_midi_event_encode_byte(midi_event_parser, buffer[i], event) == 1) { snd_seq_event_output_direct(seq, event); } } } snd_midi_event_free(midi_event_parser); close(socket_to_client); } } close(server_socket); } snd_seq_delete_simple_port(seq, port); snd_seq_close(seq); } else { usage(argv[0]); } return 0; }