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 MIDIDevice::feedBack(t_input_channel channel, t_input_value value) { /* MIDI devices can have only 128 notes or controllers */ if (channel < 128) { snd_seq_event_t ev; MIDIInput* plugin; plugin = static_cast<MIDIInput*> (parent()); Q_ASSERT(plugin != NULL); Q_ASSERT(plugin->alsa() != NULL); Q_ASSERT(m_address != NULL); /* Setup an event structure */ snd_seq_ev_clear(&ev); snd_seq_ev_set_dest(&ev, m_address->client, m_address->port); snd_seq_ev_set_subs(&ev); snd_seq_ev_set_direct(&ev); /* Send control change, channel 1 (0) */ snd_seq_ev_set_controller(&ev, 0, channel, value >> 1); snd_seq_event_output(plugin->alsa(), &ev); snd_seq_drain_output(plugin->alsa()); /* Send note on/off, channel 1 (0) */ if (value == 0) snd_seq_ev_set_noteoff(&ev, 0, channel, 0); else snd_seq_ev_set_noteon(&ev, 0, channel, value >> 1); snd_seq_event_output(plugin->alsa(), &ev); snd_seq_drain_output(plugin->alsa()); }
void midi_noteon_alsa(struct midi_handle *mh, unsigned char port, unsigned char channel, unsigned char value, unsigned char volume) { struct midi_handle_alsa *mha = (struct midi_handle_alsa *) mh; snd_seq_event_t ev; struct snd_seq_real_time tstamp; int rc; if (port >= MAX_PORTS) return; memset(&tstamp, 0, sizeof(tstamp)); snd_seq_ev_clear(&ev); snd_seq_ev_set_source(&ev, mha->outputport[port]); snd_seq_ev_set_subs(&ev); /* snd_seq_ev_set_dest(&ev, 128, 0); */ snd_seq_ev_set_subs(&ev); snd_seq_ev_set_noteon(&ev, channel, value, volume); /* ev.data.note.duration = 1000; */ /* it's drums... there is no note off. */ snd_seq_ev_schedule_real(&ev, mha->queue, 1, &tstamp); /* printf("Sending event to port %d, chan=%d, note=%d, vel=%d, pid=%d\n", mha->outputport, ev.data.note.channel, ev.data.note.note, ev.data.note.velocity, getpid()); */ rc = snd_seq_event_output(mha->seqp, &ev); if (rc < 0) printf("Failed to output note.\n"); snd_seq_drain_output(mha->seqp); return; }
void stop_midireceiver (JackVST *jvst) { int err; snd_seq_event_t event; snd_seq_t *seq2 = create_sequencer ("jfstquit", true); jvst->midiquit = 1; snd_seq_connect_to (seq2, 0, snd_seq_client_id (jvst->seq),0); snd_seq_ev_clear (&event); snd_seq_ev_set_direct (&event); snd_seq_ev_set_subs (&event); snd_seq_ev_set_source (&event, 0); snd_seq_ev_set_controller (&event,1,0x80,50); if ((err = snd_seq_event_output (seq2, &event)) < 0) { fst_error ("cannot send stop event to midi thread: %s\n", snd_strerror (err)); } snd_seq_drain_output (seq2); snd_seq_close (seq2); pthread_join (jvst->midi_thread,NULL); snd_seq_close (jvst->seq); }
static void Func_NoteOn( int channel, int key, int velocity ) { snd_seq_event_t ev; snd_seq_ev_clear(&ev); snd_seq_ev_set_noteon(&ev, channel, key, velocity); sequence_event(&ev); }
static void Func_PolyAftertouch( int channel, int key, int pressure ) { snd_seq_event_t ev; snd_seq_ev_clear(&ev); snd_seq_ev_set_keypress(&ev, channel, key, pressure); sequence_event(&ev); }
void MIDIDevice::outputDMX(const QByteArray& universe) { MIDIOut* plugin = static_cast<MIDIOut*> (parent()); Q_ASSERT(plugin != NULL); Q_ASSERT(plugin->alsa() != NULL); Q_ASSERT(m_address != NULL); /* Setup a common event structure for all values */ snd_seq_event_t ev; snd_seq_ev_clear(&ev); snd_seq_ev_set_dest(&ev, m_address->client, m_address->port); snd_seq_ev_set_subs(&ev); snd_seq_ev_set_direct(&ev); /* Since MIDI devices can have only 128 real channels, we don't attempt to write more than that */ for (unsigned char channel = 0; channel < MAX_MIDI_DMX_CHANNELS; channel++) { /* Scale 0-255 to 0-127 */ char scaled = DMX2MIDI(universe[channel]); /* Since MIDI is so slow, we only send values that are actually changed. */ if (m_values[channel] == scaled) continue; /* Store the changed MIDI value */ m_values[channel] = scaled; if (mode() == Note) { if (scaled == 0) { /* 0 is sent as a note off command */ snd_seq_ev_set_noteoff(&ev, midiChannel(), channel, scaled); } else { /* 1-127 is sent as note on command */ snd_seq_ev_set_noteon(&ev, midiChannel(), channel, scaled); } snd_seq_event_output(plugin->alsa(), &ev); } else { /* Control change */ snd_seq_ev_set_controller(&ev, midiChannel(), channel, scaled); snd_seq_event_output_buffer(plugin->alsa(), &ev); } } /* Make sure that all values go to the MIDI endpoint */ snd_seq_drain_output(plugin->alsa()); }
static void note_on(int note, real_t power) { snd_seq_event_t ev; if (debug>1) fprintf(stderr, "midimatch: (%ld) note on: note:%-3d p:%.2f name:%s@%d\n", absolute_time, note, power, midi_notename(note), midi_octave(note)); else if (debug>0) fprintf(stderr, "."); stats_note_ons ++; act_freq[note] = 1; if (midi_file != NULL ) { midi_write_note_event(0x90 | midi_channel, note, 100, midi_file); } if ( use_sequencer ) { 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_seq_ev_set_noteon(&ev, midi_channel, note, 100) ; snd_seq_event_output(midi_sequencer, &ev); snd_seq_drain_output(midi_sequencer); } }
static void Func_ProgramChange( int channel, int program ) { snd_seq_event_t ev; snd_seq_ev_clear(&ev); snd_seq_ev_set_pgmchange(&ev, channel, program); sequence_event(&ev); }
static void Func_ControlChange( int channel, int number, int value ) { snd_seq_event_t ev; snd_seq_ev_clear(&ev); snd_seq_ev_set_controller(&ev, channel, number, value); sequence_event(&ev); }
/* * Initialize a midi event from the context. The source and * destination addresses will be set from the information * stored in the context, which depends on the previous * connection calls. In addition the time and channel are set. * This should be called first before any of the following * functions. * * Arguments: * ctxp - Client application * ep - Event to init * time - Midi time * devchan - Midi channel */ void SeqContext::seq_midi_event_init(snd_seq_event_t *ep, unsigned long time, int devchan) { int dev; /* our client index is encoded in upper bits of devchan */ dev = devchan >> 4; /* * If insufficient output devices have been registered, then we * just scale the device back to fit in the correct range. This * is not necessarily what you want. */ if (dev >= destlist->length()) dev = dev % destlist->length(); if( verbose ) fprintf(stderr, "init midi event: time=%d source=%d:%d;", (int)time, source.client, source.port); snd_seq_ev_clear(ep); snd_seq_ev_schedule_tick(ep, queue, 0, time); ep->source = source; if (destlist->length() > 0) { ep->dest = *(destlist->index(dev)); if( verbose ) fprintf(stderr, "dev=%d; destination=%d:%d\n", dev, ep->dest.client, ep->dest.port); } }
static void Func_ChannelAftertouch( int channel, int pressure ) { snd_seq_event_t ev; snd_seq_ev_clear(&ev); snd_seq_ev_set_chanpress(&ev, channel, pressure); sequence_event(&ev); }
static void Func_PitchBend( int channel, int lsb, int msb ) { snd_seq_event_t ev; snd_seq_ev_clear(&ev); snd_seq_ev_set_pitchbend(&ev, channel, (lsb | (msb << 7)) - 8192); sequence_event(&ev); }
void* lp2midi(void* nothing) { printf("waiting for launchpad events\n"); snd_seq_event_t event; while (1) { // wait for an event lp_receive(lp); // setup snd_seq_ev_clear(&event); snd_seq_ev_set_source(&event, midi_out); // set the output port number snd_seq_ev_set_subs(&event); // broadcast to subscribers // fill the event switch(lp->event[0]) { case NOTE: snd_seq_ev_set_noteon(&event, 0, lp->event[1], lp->event[2]); break; case CTRL: snd_seq_ev_set_controller(&event, 0, lp->event[1], lp->event[2]); break; } // send now snd_seq_ev_set_direct(&event); snd_seq_event_output(midi_client, &event); snd_seq_drain_output(midi_client); } }
static void note_off(int note, real_t power) { snd_seq_event_t ev; if (debug>2) fprintf(stderr, "midimatch: (%ld) note off: note:%-3d p:%.2f maxp:%0.2f\n", absolute_time, note, power, act_freq[note]); act_freq[note] = 0.0f; if (midi_file != NULL ) midi_write_note_event(0x80 | midi_channel, note, 100, midi_file); if ( use_sequencer ) { 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_seq_ev_set_noteoff(&ev, midi_channel, note, 100) ; snd_seq_event_output(midi_sequencer, &ev); snd_seq_drain_output(midi_sequencer); } }
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 JVlibForm::on_System_MIDI_progressBar_sliderReleased() { if (!System_PauseMidi_button->isChecked()) return; snd_seq_event_t ev; snd_seq_ev_clear(&ev); snd_seq_ev_set_direct(&ev); snd_seq_get_queue_status(seq, queue, status); // reset queue position snd_seq_ev_is_tick(&ev); snd_seq_ev_set_queue_pos_tick(&ev, queue, 0); snd_seq_event_output(seq, &ev); snd_seq_drain_output(seq); // scan the event queue for the closest tick >= 'x' int y = 0; for (std::vector<event>::iterator Event=all_events.begin(); Event!=all_events.end(); ++Event) { if (static_cast<int>(Event->tick) >= System_MIDI_progressBar->sliderPosition()) { ev.time.tick = Event->tick; event_num = y; break; } y++; } ev.dest.client = SND_SEQ_CLIENT_SYSTEM; ev.dest.port = SND_SEQ_PORT_SYSTEM_TIMER; snd_seq_ev_set_queue_pos_tick(&ev, queue, ev.time.tick); snd_seq_event_output(seq, &ev); snd_seq_drain_output(seq); snd_seq_real_time_t *new_time = new snd_seq_real_time_t; double x = static_cast<double>(ev.time.tick)/all_events.back().tick; new_time->tv_sec = (x*song_length_seconds); new_time->tv_nsec = 0; snd_seq_ev_set_queue_pos_real(&ev, queue, new_time); MIDI_time_display->setText(QString::number(static_cast<int>(new_time->tv_sec)/60).rightJustified(2,'0')+ ":"+QString::number(static_cast<int>(new_time->tv_sec)%60).rightJustified(2,'0')); if (System_PauseMidi_button->isChecked()) return; } // end on_System_MIDI_progressBar_sliderReleased
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); }
// Decoder. bool dequeue ( snd_seq_event_t *ev ) { qxgeditMidiRpn::Event event; if (!qxgeditMidiRpn::dequeue(event)) return false; snd_seq_ev_clear(ev); snd_seq_ev_schedule_tick(ev, 0, 0, event.time); snd_seq_ev_set_dest(ev, 0, event.port); snd_seq_ev_set_fixed(ev); switch (qxgeditMidiRpn::Type(event.status & 0x70)) { case qxgeditMidiRpn::CC: // 0x10 ev->type = SND_SEQ_EVENT_CONTROLLER; break; case qxgeditMidiRpn::RPN: // 0x20 ev->type = SND_SEQ_EVENT_REGPARAM; break; case qxgeditMidiRpn::NRPN: // 0x30 ev->type = SND_SEQ_EVENT_NONREGPARAM; break; case qxgeditMidiRpn::CC14: // 0x40 ev->type = SND_SEQ_EVENT_CONTROL14; break; default: return false; } ev->data.control.channel = event.status & 0x0f; ev->data.control.param = event.param; ev->data.control.value = event.value; return true; }
void qxgeditMidiDevice::sendSysex ( unsigned char *pSysex, unsigned short iSysex ) const { #ifdef CONFIG_DEBUG fprintf(stderr, "qxgeditMidiDevice::sendSysex(%p, %u)", pSysex, iSysex); fprintf(stderr, " sysex {"); for (unsigned short i = 0; i < iSysex; ++i) fprintf(stderr, " %02x", pSysex[i]); fprintf(stderr, " }\n"); #endif // Don't do anything else if engine // has not been activated... if (m_pAlsaSeq == NULL) return; // Initialize sequencer event... snd_seq_event_t ev; snd_seq_ev_clear(&ev); // Addressing... snd_seq_ev_set_source(&ev, m_iAlsaPort); snd_seq_ev_set_subs(&ev); // The event will be direct... snd_seq_ev_set_direct(&ev); // Just set SYSEX stuff and send it out.. ev.type = SND_SEQ_EVENT_SYSEX; snd_seq_ev_set_sysex(&ev, iSysex, pSysex); snd_seq_event_output_direct(m_pAlsaSeq, &ev); }
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 }
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); } }
/** * \brief queue controls - start/stop/continue * \param seq sequencer handle * \param q queue id to control * \param type event type * \param value event value * \param ev event instance * * This function sets up general queue control event and sends it. * To send at scheduled time, set the schedule in \a ev. * If \a ev is NULL, the event is composed locally and sent immediately * to the specified queue. In any cases, you need to call #snd_seq_drain_output() * appropriately to feed the event. * * \sa snd_seq_alloc_queue() */ int snd_seq_control_queue(snd_seq_t *seq, int q, int type, int value, snd_seq_event_t *ev) { snd_seq_event_t tmpev; if (ev == NULL) { snd_seq_ev_clear(&tmpev); ev = &tmpev; snd_seq_ev_set_direct(ev); } snd_seq_ev_set_queue_control(ev, type, q, value); return snd_seq_event_output(seq, ev); }
void MIDIDevice::feedBack(t_input_channel channel, t_input_value value) { /* MIDI devices can have only 128 notes or controllers */ if (channel < 128) { snd_seq_event_t ev; MIDIInput* plugin; plugin = static_cast<MIDIInput*> (parent()); Q_ASSERT(plugin != NULL); Q_ASSERT(plugin->alsa() != NULL); Q_ASSERT(m_address != NULL); /* Setup an event structure */ snd_seq_ev_clear(&ev); snd_seq_ev_set_dest(&ev, m_address->client, m_address->port); snd_seq_ev_set_subs(&ev); snd_seq_ev_set_direct(&ev); char scaled = static_cast <char> (SCALE(double(value), double(0), double(KInputValueMax), double(0), double(127))); if (m_mode == ControlChange) { /* Send control change */ snd_seq_ev_set_controller(&ev, midiChannel(), channel, scaled); snd_seq_event_output(plugin->alsa(), &ev); snd_seq_drain_output(plugin->alsa()); } else { /* Send note on/off */ if (value == 0) { snd_seq_ev_set_noteoff(&ev, midiChannel(), channel, scaled); } else { snd_seq_ev_set_noteon(&ev, midiChannel(), channel, scaled); } snd_seq_event_output(plugin->alsa(), &ev); snd_seq_drain_output(plugin->alsa()); } } }
void synth_noteStop(synth_t * st,int num, int status) { snd_seq_event_t ev; snd_seq_ev_clear(&ev); snd_seq_ev_set_direct(&ev); snd_seq_ev_set_source(&ev, port_out_id); snd_seq_ev_set_subs(&ev); //usleep(100000); printf("synth_noteStop %d\n", st->runningNote[num]); snd_seq_ev_set_noteoff(&ev, st->channel, st->runningNote[num], st->velocity); snd_seq_event_output_direct(seq, &ev); snd_seq_drain_output(seq); }
void rimshot_alsa_output_play_note (rimshot_alsa_output_t *output, int channel, int note, unsigned int velocity) { snd_seq_event_t ev; snd_seq_ev_clear (&ev); snd_seq_ev_set_source (&ev, output->port); snd_seq_ev_set_subs (&ev); snd_seq_ev_set_direct (&ev); snd_seq_ev_set_noteon (&ev, channel, note, velocity); snd_seq_event_output_direct (output->seq, &ev); }
// change the tempo on the fly int change_tempo(snd_seq_t *handle, int my_client_id, int my_port_id, int q, unsigned int tempo) { snd_seq_event_t ev; snd_seq_ev_clear(&ev); ev.dest.client = SND_SEQ_CLIENT_SYSTEM; ev.dest.port = SND_SEQ_PORT_SYSTEM_TIMER; ev.source.client = my_client_id; ev.source.port = my_port_id; ev.queue = SND_SEQ_QUEUE_DIRECT; // no scheduling ev.data.queue.queue = q; // affected queue id ev.data.queue.param.value = tempo; // new tempo in microsec. return snd_seq_event_output(handle, &ev); }
static PyObject *send_note_on(PyObject *self, PyObject *args) { int channel, note, velocity; if (!PyArg_ParseTuple(args, "iii", &channel, ¬e, &velocity)) return NULL; snd_seq_ev_clear(&ev); snd_seq_ev_set_noteon(&ev, channel, note, velocity); send(); Py_INCREF(Py_None); return Py_None; }
static PyObject *send_control_change(PyObject *self, PyObject *args) { int channel, param, value; if (!PyArg_ParseTuple(args, "iii", &channel, ¶m, &value)) return NULL; snd_seq_ev_clear(&ev); snd_seq_ev_set_controller(&ev, channel, param, value); send(); Py_INCREF(Py_None); return Py_None; }
static gboolean put_click (const DrumClick *click) { snd_seq_event_t ev; snd_seq_ev_clear (&ev); snd_seq_ev_set_source (&ev, out_port_id); snd_seq_ev_set_subs (&ev); snd_seq_ev_schedule_tick (&ev, queue_id, 0, click->tick); snd_seq_ev_set_note (&ev, 10, 24, click->velocity, 48); int err = snd_seq_event_output_direct (seq, &ev); return err >= 0; }