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); }
MidiOutputDevice (MidiOutput* const output, const AlsaPort& p) : midiOutput (output), port (p), maxEventSize (16 * 1024) { jassert (port.isValid() && midiOutput != nullptr); snd_midi_event_new (maxEventSize, &midiParser); }
void Alsa::initialize() { // Set up the ALSA sequencer client. snd_seq_t *seq; int result = snd_seq_open( &seq, "default", SND_SEQ_OPEN_OUTPUT, SND_SEQ_NONBLOCK ); if ( result < 0 ) { std::cerr << "error: CxxMidi::Output::Alsa::initialize: error creating ALSA sequencer client object" << std::endl; } // Set client name. snd_seq_set_client_name( seq, "CxxMidi (RtMidi) output" ); // Save our api-specific connection information. _apiData= new AlsaMidiData; _apiData->seq = seq; _apiData->vport = -1; _apiData->bufferSize = 32; _apiData->coder = 0; _apiData->buffer = 0; result = snd_midi_event_new( _apiData->bufferSize, &_apiData->coder ); if ( result < 0 ) { delete _apiData; std::cerr << "error: CxxMidi::Output::Alsa::initialize: error initializing MIDI event parser" << std::endl; return; } _apiData->buffer = (unsigned char *) malloc( _apiData->bufferSize ); if ( _apiData->buffer == NULL ) { delete _apiData; std::cerr << "error: CxxMidi::Output::Alsa::initialize: error allocating buffer memory" << std::endl; } snd_midi_event_init( _apiData->coder ); }
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); }
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 }
MidiOutputDevice (MidiOutput* output, snd_seq_t* handle) : midiOutput (output), seqHandle (handle), maxEventSize (16 * 1024) { jassert (seqHandle != 0 && midiOutput != 0); snd_midi_event_new (maxEventSize, &midiParser); }
bool Midi2UdpThread::initSeq() { if(snd_seq_open(&seq_handle, "default", SND_SEQ_OPEN_INPUT, 0) < 0) { printf("midi2udp: Error opening ALSA sequencer.\n"); return false; } snd_seq_set_client_name(seq_handle, "DSMIDIWIFI MIDI2UDP"); char portname[64] = "DSMIDIWIFI MIDI2UDP IN"; int res = midi_in_port = snd_seq_create_simple_port(seq_handle, portname, SND_SEQ_PORT_CAP_WRITE|SND_SEQ_PORT_CAP_SUBS_WRITE, SND_SEQ_PORT_TYPE_APPLICATION); if(res < 0) { printf("midi2udp: Error creating MIDI port!\n"); snd_seq_close(seq_handle); return false; } res = snd_midi_event_new(MAX_MIDI_MESSAGE_LENGTH, &eventparser); if(res != 0) { printf("midi2udp: Error making midi event parser!\n"); snd_seq_close(seq_handle); return false; } snd_midi_event_init(eventparser); midi_event = (snd_seq_event_t*)malloc(sizeof(snd_seq_event_t)); return true; }
static int osc_midi ( DssiEditor *pDssiEditor, lo_arg **argv ) { static snd_midi_event_t *s_pAlsaCoder = NULL; static snd_seq_event_t s_aAlsaEvent[4]; const unsigned char *data = argv[0]->m; #ifdef CONFIG_DEBUG qDebug("osc_midi: path \"%s\", midi 0x%02x 0x%02x 0x%02x 0x%02x", pDssiEditor->path, data[0], data[1], data[2], data[3]); #endif qtractorDssiPlugin *pDssiPlugin = pDssiEditor->plugin; if (pDssiPlugin == NULL) return 1; qtractorMidiManager *pMidiManager = (pDssiPlugin->list())->midiManager(); if (pMidiManager == NULL) return 1; if (s_pAlsaCoder == NULL && snd_midi_event_new(4, &s_pAlsaCoder)) return 1; snd_midi_event_reset_encode(s_pAlsaCoder); if (snd_midi_event_encode(s_pAlsaCoder, &data[1], 3, s_aAlsaEvent) < 1) return 1; // Send the event directly to snd_seq_event_t *pEvent = &s_aAlsaEvent[0]; if (snd_seq_ev_is_channel_type(pEvent)) pMidiManager->direct(pEvent); return 0; }
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); }
static void stream_init(alsa_seqmidi_t *self, int dir) { stream_t *str = &self->stream[dir]; str->new_ports = jack_ringbuffer_create(MAX_PORTS*sizeof(port_t*)); snd_midi_event_new(MAX_EVENT_SIZE, &str->codec); }
MidiOutputDevice (MidiOutput* const midiOutput_, snd_seq_t* const seqHandle_) : midiOutput (midiOutput_), seqHandle (seqHandle_), maxEventSize (16 * 1024) { jassert (seqHandle != 0 && midiOutput != 0); snd_midi_event_new (maxEventSize, &midiParser); }
static int snd_seq_midisynth_new(seq_midisynth_t *msynth, snd_card_t *card, int device, int subdevice) { if (snd_midi_event_new(MAX_MIDI_EVENT_BUF, &msynth->parser) < 0) return -ENOMEM; msynth->card = card; msynth->device = device; msynth->subdevice = subdevice; return 0; }
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 bool a2j_stream_init(struct a2j * self) { struct a2j_stream *str = &self->stream; str->new_ports = jack_ringbuffer_create (MAX_PORTS * sizeof(struct a2j_port *)); if (str->new_ports == NULL) { return false; } snd_midi_event_new (MAX_EVENT_SIZE, &str->codec); INIT_LIST_HEAD (&str->list); return true; }
/* 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(); }
void AlsaSeqMidiInDriver::open(device_id_t device) { if (this->is_open()) throw std::logic_error("Device already open"); int err; err = snd_seq_open(&m_impl->seq, "default", SND_SEQ_OPEN_INPUT, SND_SEQ_NONBLOCK); if ( err < 0) { throw std::runtime_error("Error opening ALSA sequencer."); } std::ostringstream os; os << "gephex input " << device; std::string device_name = os.str(); err = snd_seq_set_client_name(m_impl->seq, device_name.c_str()); err = snd_seq_create_simple_port(m_impl->seq, device_name.c_str(), SND_SEQ_PORT_CAP_WRITE| SND_SEQ_PORT_CAP_SUBS_WRITE, SND_SEQ_PORT_TYPE_APPLICATION); if (err < 0) { snd_seq_close (m_impl->seq); throw std::runtime_error("Error creating sequencer port."); } else { m_impl->portid = err; snd_seq_ev_clear (&m_impl->SEv); snd_seq_ev_set_source (&m_impl->SEv, m_impl->portid); snd_seq_ev_set_subs (&m_impl->SEv); snd_seq_ev_set_direct (&m_impl->SEv); } if( snd_midi_event_new (32, &m_impl->decoder) ) throw std::runtime_error ("Error creating midi event parser"); snd_midi_event_init(m_impl->decoder); snd_midi_event_no_status (m_impl->decoder,1); }
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; }
void QMidi::outSendMsg(qint32 msg) { #if defined(Q_OS_WIN) midiOutShortMsg(midiOutPtr,(DWORD)msg); #elif defined(Q_OS_LINUX) snd_seq_event_t ev; snd_midi_event_t* mev; snd_seq_ev_clear(&ev); snd_seq_ev_set_source(&ev, 0); snd_seq_ev_set_subs(&ev); snd_seq_ev_set_direct(&ev); snd_midi_event_new(sizeof(msg), &mev); snd_midi_event_resize_buffer(mev, sizeof(msg)); snd_midi_event_encode(mev,(unsigned char*)&msg, sizeof(msg), &ev); snd_seq_event_output(midiOutPtr, &ev); snd_seq_drain_output(midiOutPtr); #elif defined(Q_OS_HAIKU) midiOutLocProd->SprayData((void*)&msg,sizeof(msg),true); #endif }
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 }
void sys_alsa_putmidibyte(int portno, int byte) { static snd_midi_event_t *dev = NULL; int res; snd_seq_event_t ev; if (!dev) { snd_midi_event_new(ALSA_MAX_EVENT_SIZE, &dev); //assert(dev); snd_midi_event_init(dev); } snd_seq_ev_clear(&ev); res = snd_midi_event_encode_byte(dev, byte, &ev); if (res > 0 && ev.type != SND_SEQ_EVENT_NONE) { // got a complete event, output it snd_seq_ev_set_direct(&ev); snd_seq_ev_set_subs(&ev); snd_seq_ev_set_source(&ev, alsa_midioutfd[portno]); snd_seq_event_output_direct(midi_handle, &ev); } if (res != 0) // reinitialize the parser snd_midi_event_init(dev); }
/* * 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; }
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; }
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; }
//============================================================================== DssiPluginMidiManager::DssiPluginMidiManager () : maxEventSize (16 * 1024), currentMidiCount (0) { snd_midi_event_new (maxEventSize, &midiParser); }
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; }
void samplv1_jack::open ( const char *client_id ) { // init param ports for (uint32_t i = 0; i < samplv1::NUM_PARAMS; ++i) { const samplv1::ParamIndex index = samplv1::ParamIndex(i); m_params[i] = samplv1_param::paramDefaultValue(index); samplv1::setParamPort(index, &m_params[i]); } // open client m_client = ::jack_client_open(client_id, JackNullOption, NULL); if (m_client == NULL) return; // set sample rate samplv1::setSampleRate(float(jack_get_sample_rate(m_client))); // samplv1::reset(); // register audio ports & buffers uint16_t nchannels = samplv1::channels(); m_audio_ins = new jack_port_t * [nchannels]; m_audio_outs = new jack_port_t * [nchannels]; m_ins = new float * [nchannels]; m_outs = new float * [nchannels]; char port_name[32]; for (uint16_t k = 0; k < nchannels; ++k) { ::snprintf(port_name, sizeof(port_name), "in_%d", k + 1); m_audio_ins[k] = ::jack_port_register(m_client, port_name, JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0); m_ins[k] = NULL; ::snprintf(port_name, sizeof(port_name), "out_%d", k + 1); m_audio_outs[k] = ::jack_port_register(m_client, port_name, JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0); m_outs[k] = NULL; } // register midi port #ifdef CONFIG_JACK_MIDI m_midi_in = ::jack_port_register(m_client, "in", JACK_DEFAULT_MIDI_TYPE, JackPortIsInput, 0); #endif #ifdef CONFIG_ALSA_MIDI m_alsa_seq = NULL; // m_alsa_client = -1; m_alsa_port = -1; m_alsa_decoder = NULL; m_alsa_buffer = NULL; m_alsa_thread = NULL; // open alsa sequencer client... if (snd_seq_open(&m_alsa_seq, "hw", SND_SEQ_OPEN_INPUT, 0) >= 0) { snd_seq_set_client_name(m_alsa_seq, client_id); // m_alsa_client = snd_seq_client_id(m_alsa_seq); m_alsa_port = snd_seq_create_simple_port(m_alsa_seq, "in", SND_SEQ_PORT_CAP_WRITE | SND_SEQ_PORT_CAP_SUBS_WRITE, SND_SEQ_PORT_TYPE_MIDI_GENERIC | SND_SEQ_PORT_TYPE_APPLICATION); snd_midi_event_new(1024, &m_alsa_decoder); m_alsa_buffer = ::jack_ringbuffer_create( 1024 * (sizeof(jack_midi_event_t) + 4)); m_alsa_thread = new samplv1_alsa_thread(this); m_alsa_thread->start(QThread::TimeCriticalPriority); } #endif // CONFIG_ALSA_MIDI // setup any local, initial buffers... samplv1::setBufferSize(::jack_get_buffer_size(m_client)); jack_set_buffer_size_callback(m_client, samplv1_jack_buffer_size, this); // set process callbacks... ::jack_set_process_callback(m_client, samplv1_jack_process, this); #ifdef CONFIG_JACK_SESSION // JACK session event callback... if (::jack_set_session_callback) { ::jack_set_session_callback(m_client, samplv1_jack_session_event, this); } #endif }
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; }
void sys_alsa_do_open_midi(int nmidiin, int *midiinvec, int nmidiout, int *midioutvec) { char portname[50]; int err = 0; int client; int i; snd_seq_client_info_t *alsainfo; alsa_nmidiin = 0; alsa_nmidiout = 0; if (nmidiout == 0 && nmidiin == 0) return; if(nmidiin>MAXMIDIINDEV ) { post("midi input ports reduced to maximum %d", MAXMIDIINDEV); nmidiin=MAXMIDIINDEV; } if(nmidiout>MAXMIDIOUTDEV) { post("midi output ports reduced to maximum %d", MAXMIDIOUTDEV); nmidiout=MAXMIDIOUTDEV; } if (nmidiin>0 && nmidiout>0) err = snd_seq_open(&midi_handle,"default",SND_SEQ_OPEN_DUPLEX,0); else if (nmidiin > 0) err = snd_seq_open(&midi_handle,"default",SND_SEQ_OPEN_INPUT,0); else if (nmidiout > 0) err = snd_seq_open(&midi_handle,"default",SND_SEQ_OPEN_OUTPUT,0); if (err!=0) { sys_setalarm(1000000); post("couldn't open alsa sequencer"); return; } for (i=0;i<nmidiin;i++) { int port; sprintf(portname,"Pure Data Midi-In %d",i+1); port = snd_seq_create_simple_port(midi_handle,portname, SND_SEQ_PORT_CAP_WRITE |SND_SEQ_PORT_CAP_SUBS_WRITE, SND_SEQ_PORT_TYPE_APPLICATION); alsa_midiinfd[i] = port; if (port < 0) goto error; } for (i=0;i<nmidiout;i++) { int port; sprintf(portname,"Pure Data Midi-Out %d",i+1); port = snd_seq_create_simple_port(midi_handle,portname, SND_SEQ_PORT_CAP_READ | SND_SEQ_PORT_CAP_SUBS_READ, SND_SEQ_PORT_TYPE_APPLICATION); alsa_midioutfd[i] = port; if (port < 0) goto error; } snd_seq_client_info_malloc(&alsainfo); snd_seq_get_client_info(midi_handle,alsainfo); snd_seq_client_info_set_name(alsainfo,"Pure Data"); client = snd_seq_client_info_get_client(alsainfo); snd_seq_set_client_info(midi_handle,alsainfo); snd_seq_client_info_free(alsainfo); post("Opened Alsa Client %d in:%d out:%d",client,nmidiin,nmidiout); sys_setalarm(0); snd_midi_event_new(ALSA_MAX_EVENT_SIZE,&midiev); alsa_nmidiout = nmidiout; alsa_nmidiin = nmidiin; return; error: sys_setalarm(1000000); post("couldn't open alsa MIDI output device"); return; }
/* 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; }