/* open associated midi device for input */ static int midisynth_subscribe(void *private_data, struct snd_seq_port_subscribe *info) { int err; struct seq_midisynth *msynth = private_data; struct snd_rawmidi_runtime *runtime; struct snd_rawmidi_params params; /* open midi port */ if ((err = snd_rawmidi_kernel_open(msynth->card, msynth->device, msynth->subdevice, SNDRV_RAWMIDI_LFLG_INPUT, &msynth->input_rfile)) < 0) { snd_printd("midi input open failed!!!\n"); return err; } runtime = msynth->input_rfile.input->runtime; memset(¶ms, 0, sizeof(params)); params.avail_min = 1; params.buffer_size = input_buffer_size; if ((err = snd_rawmidi_input_params(msynth->input_rfile.input, ¶ms)) < 0) { snd_rawmidi_kernel_release(&msynth->input_rfile); return err; } snd_midi_event_reset_encode(msynth->parser); runtime->event = snd_midi_input_event; runtime->private_data = msynth; snd_rawmidi_kernel_read(msynth->input_rfile.input, NULL, 0); return 0; }
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 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 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 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); }
static void do_jack_output(alsa_seqmidi_t *self, port_t *port, struct process_info* info) { stream_t *str = &self->stream[info->dir]; int nevents = jack_midi_get_event_count(port->jack_buf); int i; for (i=0; i<nevents; ++i) { jack_midi_event_t jack_event; snd_seq_event_t alsa_event; int64_t frame_offset; int64_t out_time; snd_seq_real_time_t out_rt; int err; jack_midi_event_get(&jack_event, port->jack_buf, i); snd_seq_ev_clear(&alsa_event); snd_midi_event_reset_encode(str->codec); if (!snd_midi_event_encode(str->codec, jack_event.buffer, jack_event.size, &alsa_event)) continue; // invalid event snd_seq_ev_set_source(&alsa_event, self->port_id); snd_seq_ev_set_dest(&alsa_event, port->remote.client, port->remote.port); /* NOTE: in case of xrun it could become negative, so it is essential to use signed type! */ frame_offset = (int64_t)jack_event.time + info->period_start + info->nframes - info->cur_frames; if (frame_offset < 0) { frame_offset = info->nframes + jack_event.time; error_log("internal xrun detected: frame_offset = %"PRId64"\n", frame_offset); } /* Ken Ellinwood reported problems with this assert. * Seems, magic 2 should be replaced with nperiods. */ //FIXME: assert (frame_offset < info->nframes*2); //if (frame_offset < info->nframes * info->nperiods) // debug_log("alsa_out: BLAH-BLAH-BLAH"); out_time = info->alsa_time + (frame_offset * NSEC_PER_SEC) / info->sample_rate; debug_log("alsa_out: frame_offset = %lld, info->alsa_time = %lld, out_time = %lld, port->last_out_time = %lld", frame_offset, info->alsa_time, out_time, port->last_out_time); // we should use absolute time to prevent reordering caused by rounding errors if (out_time < port->last_out_time) { debug_log("alsa_out: limiting out_time %lld at %lld", out_time, port->last_out_time); out_time = port->last_out_time; } else port->last_out_time = out_time; out_rt.tv_nsec = out_time % NSEC_PER_SEC; out_rt.tv_sec = out_time / NSEC_PER_SEC; snd_seq_ev_schedule_real(&alsa_event, self->queue, 0, &out_rt); err = snd_seq_event_output(self->seq, &alsa_event); debug_log("alsa_out: written %d bytes to %s at %+d (%lld): %d", (int)jack_event.size, port->name, (int)frame_offset, out_time, err); } }
static int snd_rawmidi_virtual_drop(snd_rawmidi_t *rmidi) { snd_rawmidi_virtual_t *virt = rmidi->private_data; if (rmidi->stream == SND_RAWMIDI_STREAM_OUTPUT) { snd_seq_drop_output(virt->handle); snd_midi_event_reset_encode(virt->midi_event); virt->pending = 0; } else { snd_seq_drop_input(virt->handle); snd_midi_event_reset_decode(virt->midi_event); virt->in_buf_ofs = 0; } return 0; }
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; }
/** * \brief Initializes MIDI parsers * \param dev MIDI event parser * \return 0 on success otherwise a negative error code * * Initializes MIDI parsers (both encode and decode) */ void snd_midi_event_init(snd_midi_event_t *dev) { snd_midi_event_reset_encode(dev); snd_midi_event_reset_decode(dev); }
void Udp2MidiThread::run() { QUdpSocket *udpSocket = new QUdpSocket(); bool bres = udpSocket->bind(PC_PORT); if( bres == false ) { printf("Could not bind to port %d!\n", PC_PORT); return; } forever { if (abort) { delete udpSocket; return; } if( udpSocket->waitForReadyRead(250) == true ) { // Receive from UDP QHostAddress from_address; int len = udpSocket->readDatagram((char*)midimsg, MAX_MIDI_MESSAGE_LENGTH, &from_address); if( len == -1 ) { printf("udp2midi: Error receiving data!\n"); } if( (len == 3) && (midimsg[0] == 0) && (midimsg[1] == 0) && (midimsg[2] == 0) ) { string from_ip = from_address.toString().toStdString(); printf("Keepalive from: %s\n", from_ip.c_str()); midi2udp->add_ip(from_ip); } else { // Send to MIDI printf("udp2midi: Sending event: "); for(int i=0; i<len; ++i) { printf("0x%x ", midimsg[i]); } printf("\n"); long res = snd_midi_event_encode(eventparser, midimsg, len, midi_event); if( res < 0) { printf("Error encoding midi event!\n"); } snd_midi_event_reset_encode(eventparser); if(midi_event->type == SND_SEQ_EVENT_NOTEON) { printf("udp2midi: Note on: %d, channel %d\n", midi_event->data.note.note, midi_event->data.control.channel); } else if(midi_event->type == SND_SEQ_EVENT_NOTEOFF){ printf("udp2midi: Note off: %d, channel %d\n", midi_event->data.note.note, midi_event->data.control.channel); } snd_seq_ev_set_subs(midi_event); snd_seq_ev_set_direct(midi_event); snd_seq_ev_set_source(midi_event, midi_out_port); snd_seq_event_output_direct(seq_handle, midi_event); snd_seq_free_event(midi_event); } } } }
void midi_reset() { if (s_midi == NULL) return; snd_midi_event_reset_encode(s_midiCoder); }