int AlsaSeqMidiInDriver::read(unsigned char* buf, int max) { if (!this->is_open()) throw std::logic_error("Device not open"); int bytes_read= 0; int err; snd_seq_event_t *ev; do { if (snd_seq_event_input(m_impl->seq, &ev) > 0 ) { err = snd_midi_event_decode (m_impl->decoder, buf, max, ev); //snd_seq_free_event( ev ); if (err > 0) { buf += err; bytes_read += err; max -= err; } else { // error or buffer full -> drop midi event } } } while (snd_seq_event_input_pending(m_impl->seq, 0) > 0); return bytes_read; }
static GstFlowReturn gst_amidisrc_create (GstPushSrc * psrc, GstBuffer ** outbuf) { //GstaMIDISrc *src = GST_AMIDISRC (psrc); /** *outbuf = gst_buffer_new (); GST_BUFFER_SIZE (*outbuf) = buffer->len; GST_BUFFER_MALLOCDATA (*outbuf) = buffer->data; GST_BUFFER_DATA (*outbuf) = GST_BUFFER_MALLOCDATA (*outbuf); GST_BUFFER_OFFSET (*outbuf) = src->read_offset; GST_BUFFER_OFFSET_END (*outbuf) = src->read_offset + GST_BUFFER_SIZE (*outbuf); **/ //TODO: printf("***Here: %s:%d\n",__FILE__,__LINE__); #if 0 snd_seq_event_t *a_event=NULL; snd_seq_event_input(src->a_seq,&a_event); if(a_event){ // convert to audio/x-gst-midi format and push on psrc. } #endif return GST_FLOW_OK; }
static PyObject * alsaseq_input(PyObject *self, PyObject *args) { snd_seq_event_t *ev; if (!PyArg_ParseTuple(args, "" )) return NULL; Py_BEGIN_ALLOW_THREADS snd_seq_event_input( seq_handle, &ev ); Py_END_ALLOW_THREADS switch( ev->type ) { case SND_SEQ_EVENT_NOTE: case SND_SEQ_EVENT_NOTEON: case SND_SEQ_EVENT_NOTEOFF: case SND_SEQ_EVENT_KEYPRESS: return Py_BuildValue( "(bbbb(ii)(bb)(bb)(bbbbi))", ev->type, ev->flags, ev->tag, ev->queue, ev->time.time.tv_sec, ev->time.time.tv_nsec, ev->source.client, ev->source.port, ev->dest.client, ev->dest.port, ev->data.note.channel, ev->data.note.note, ev->data.note.velocity, ev->data.note.off_velocity, ev->data.note.duration ); break; case SND_SEQ_EVENT_CONTROLLER: case SND_SEQ_EVENT_PGMCHANGE: case SND_SEQ_EVENT_CHANPRESS: case SND_SEQ_EVENT_PITCHBEND: return Py_BuildValue( "(bbbb(ii)(bb)(bb)(bbbbii))", ev->type, ev->flags, ev->tag, ev->queue, ev->time.time.tv_sec, ev->time.time.tv_nsec, ev->source.client, ev->source.port, ev->dest.client, ev->dest.port, ev->data.control.channel, ev->data.control.unused[0], ev->data.control.unused[1], ev->data.control.unused[2], ev->data.control.param, ev->data.control.value ); break; default: return Py_BuildValue( "(bbbb(ii)(bb)(bb)(bbbbi))", ev->type, ev->flags, ev->tag, ev->queue, ev->time.time.tv_sec, ev->time.time.tv_nsec, ev->source.client, ev->source.port, ev->dest.client, ev->dest.port, ev->data.note.channel, ev->data.note.note, ev->data.note.velocity, ev->data.note.off_velocity, ev->data.note.duration ); } }
// This splits the Midi events from one channel to another two channels void Spliter::midievents(){ snd_seq_event_t *midievent; midievent=NULL; snd_seq_event_input(midi_in,&midievent); if (midievent==NULL) return; if ((midievent->type==SND_SEQ_EVENT_NOTEON)||(midievent->type==SND_SEQ_EVENT_NOTEOFF)){ int cmdchan=midievent->data.note.channel; if (cmdchan==Pchin){ snd_seq_ev_set_subs(midievent); snd_seq_ev_set_direct(midievent); if (midievent->data.note.note<Psplitpoint) { midievent->data.note.channel=Pchout1; int tmp=midievent->data.note.note; tmp+=Poct1*12;if (tmp>127) tmp=127;if (tmp<0) tmp=0; midievent->data.note.note=tmp; } else { midievent->data.note.channel=Pchout2; int tmp=midievent->data.note.note; tmp+=Poct2*12;if (tmp>127) tmp=127;if (tmp<0) tmp=0; midievent->data.note.note=tmp; }; snd_seq_event_output_direct(midi_out,midievent); } else { snd_seq_ev_set_subs(midievent); snd_seq_ev_set_direct(midievent); snd_seq_event_output_direct(midi_out,midievent); }; }; snd_seq_free_event(midievent); };
void DeviceManager::loop() { struct pollfd *pfds; int npfds; int c, err; npfds = snd_seq_poll_descriptors_count(handle, POLLIN); D("npfds: %d", npfds); pfds = (struct pollfd *)alloca(sizeof(*pfds) * npfds); for (;;) { snd_seq_poll_descriptors(handle, pfds, npfds, POLLIN); if (poll(pfds, npfds, -1) < 0) break; do { snd_seq_event_t *event; err = snd_seq_event_input(handle, &event); if (err < 0) break; if (event){ list[0]->processEvent(event); } } while (err > 0); fflush(stdout); // if (stop) // break; } snd_seq_close(handle); }
/* TODO: ADD MIDI PANIC/ALL NOTES OFF */ int midi_callback() { snd_seq_event_t *ev; int l1; do { snd_seq_event_input(seq_handle, &ev); switch (ev->type) { case SND_SEQ_EVENT_NOTEON: for (l1 = 0; l1 < POLY; l1++) { if (!note_active[l1]) { note[l1] = ev->data.note.note; printf("Note ON %d FREQ %d\n", note[l1] ,(note[l1])*FREQ_CHANNEL_WIDTH+FREQ_START); velocity[l1] = ev->data.note.velocity / 127.0; env_time[l1] = 0; gate[l1] = 1; note_active[l1] = 1; break; } } break; case SND_SEQ_EVENT_NOTEOFF: for (l1 = 0; l1 < POLY; l1++) { if (gate[l1] && note_active[l1] && (note[l1] == ev->data.note.note)) { printf("Note OFF %d \n", note[l1]); env_time[l1] = 0; gate[l1] = 0; } } break; } snd_seq_free_event(ev); } while (snd_seq_event_input_pending(seq_handle, 0) > 0); return (0); }
static PyObject *get_event(PyObject *self, PyObject *args) { if (!PyArg_ParseTuple(args, "")) /* no args */ return NULL; Py_BEGIN_ALLOW_THREADS err = snd_seq_event_input(seq, &in_event); Py_END_ALLOW_THREADS if (err < 0) return NULL; if (in_event->type == SND_SEQ_EVENT_NOTEON || in_event->type == SND_SEQ_EVENT_NOTEOFF) { return Py_BuildValue("iiii", in_event->type, in_event->data.note.channel, in_event->data.note.note, in_event->data.note.velocity); } else if (in_event->type == SND_SEQ_EVENT_CONTROLLER) { return Py_BuildValue("iiii", in_event->type, in_event->data.control.channel, in_event->data.control.param, in_event->data.control.value); } Py_INCREF(Py_None); return Py_None; }
void run() { snd_seq_t *seq = m_sampl->alsa_seq(); if (seq == NULL) return; m_running = true; int nfds; struct pollfd *pfds; nfds = snd_seq_poll_descriptors_count(seq, POLLIN); pfds = (struct pollfd *) alloca(nfds * sizeof(struct pollfd)); snd_seq_poll_descriptors(seq, pfds, nfds, POLLIN); int poll_rc = 0; while (m_running && poll_rc >= 0) { poll_rc = ::poll(pfds, nfds, 200); while (poll_rc > 0) { snd_seq_event_t *ev = NULL; snd_seq_event_input(seq, &ev); m_sampl->alsa_capture(ev); // snd_seq_free_event(ev); poll_rc = snd_seq_event_input_pending(seq, 0); } } m_running = false; }
int MidiInputDeviceAlsa::Main() { int npfd; struct pollfd* pfd; snd_seq_event_t* ev; npfd = snd_seq_poll_descriptors_count(hAlsaSeq, POLLIN); pfd = (struct pollfd*) alloca(npfd * sizeof(struct pollfd)); snd_seq_poll_descriptors(hAlsaSeq, pfd, npfd, POLLIN); while (true) { if (poll(pfd, npfd, 100000) > 0) { do { snd_seq_event_input(hAlsaSeq, &ev); int port = (int) ev->dest.port; MidiInputPort* pMidiInputPort = Ports[port]; switch (ev->type) { case SND_SEQ_EVENT_CONTROLLER: if (ev->data.control.param == 0) pMidiInputPort->DispatchBankSelectMsb(ev->data.control.value, ev->data.control.channel); else if (ev->data.control.param == 32) pMidiInputPort->DispatchBankSelectLsb(ev->data.control.value, ev->data.control.channel); pMidiInputPort->DispatchControlChange(ev->data.control.param, ev->data.control.value, ev->data.control.channel); break; case SND_SEQ_EVENT_CHANPRESS: pMidiInputPort->DispatchControlChange(128, ev->data.control.value, ev->data.control.channel); break; case SND_SEQ_EVENT_PITCHBEND: pMidiInputPort->DispatchPitchbend(ev->data.control.value, ev->data.control.channel); break; case SND_SEQ_EVENT_NOTEON: if (ev->data.note.velocity != 0) { pMidiInputPort->DispatchNoteOn(ev->data.note.note, ev->data.note.velocity, ev->data.control.channel); } else { pMidiInputPort->DispatchNoteOff(ev->data.note.note, 0, ev->data.control.channel); } break; case SND_SEQ_EVENT_NOTEOFF: pMidiInputPort->DispatchNoteOff(ev->data.note.note, ev->data.note.velocity, ev->data.control.channel); break; case SND_SEQ_EVENT_SYSEX: pMidiInputPort->DispatchSysex(ev->data.ext.ptr, ev->data.ext.len); break; case SND_SEQ_EVENT_PGMCHANGE: pMidiInputPort->DispatchProgramChange(ev->data.control.value, ev->data.control.channel); break; } snd_seq_free_event(ev); } while (snd_seq_event_input_pending(hAlsaSeq, 0) > 0); } } // just to avoid a compiler warning return EXIT_FAILURE; }
int main() { snd_seq_t *handle; int err; err = snd_seq_open(&handle, "default", SND_SEQ_OPEN_INPUT, 0); if (err < 0) { fprintf(stderr, "%s\n", snd_strerror(-err)); exit(1); } snd_seq_set_client_name(handle, "Yo!"); int port_number = snd_seq_create_simple_port(handle, "my port", SND_SEQ_PORT_CAP_WRITE|SND_SEQ_PORT_CAP_SUBS_WRITE, SND_SEQ_PORT_TYPE_MIDI_GENERIC); snd_seq_event_t *event; for (;;){ snd_seq_event_input(handle, &event); printf("Type: %d\n", event->type); if (snd_seq_ev_is_note_type(event)){ printf("Note: %d\n", event->data.note.note); printf("Velocity: %d\n", event->data.note.velocity); } printf("Source: %d:%d\n", event->source.client, event->source.port); printf("Destination: %d:%d\n", event->dest.client, event->dest.port); } return 0; }
void* midi2lp(void* nothing) { printf("waiting for midi events\n"); snd_seq_event_t *ev; while (1) { // get a new event. if there aren't any, wait for one snd_seq_event_input(midi_client, &ev); // copy the data to send switch (ev->type) { case SND_SEQ_EVENT_NOTEON: lp_send3(lp, NOTE_ON, ev->data.note.note, ev->data.note.velocity); break; case SND_SEQ_EVENT_NOTEOFF: lp_send3(lp, NOTE_OFF, ev->data.note.note, ev->data.note.velocity); break; case SND_SEQ_EVENT_CONTROLLER: lp_send3(lp, CTRL, ev->data.control.param, ev->data.control.value); break; } // free the midi event snd_seq_free_event(ev); } }
void SeqDriver::procEvents() { int l1; snd_seq_event_t *evIn, evOut; bool outOfRange = false; bool unmatched = false; MidiMap* mm; do { snd_seq_event_input(seq_handle, &evIn); emit midiEvent(evIn); unmatched = true; for(l1 = 0; l1 < midiMapList->count(); l1++) { mm = midiMapList->at(l1); if (mm->isMap(evIn)) { unmatched = false; mm->doMap(evIn, &evOut, &outOfRange); if (!outOfRange) { snd_seq_ev_set_subs(&evOut); snd_seq_ev_set_direct(&evOut); snd_seq_ev_set_source(&evOut, portid_out[mm->portOut]); snd_seq_event_output_direct(seq_handle, &evOut); } } } if (!discardUnmatched && unmatched) { snd_seq_ev_set_subs(evIn); snd_seq_ev_set_direct(evIn); snd_seq_ev_set_source(evIn, portid_out[portUnmatched]); snd_seq_event_output_direct(seq_handle, evIn); } } while (snd_seq_event_input_pending(seq_handle, 0) > 0); }
/* handles all the midi calls */ void midi_action(snd_seq_t *seq_handle) { snd_seq_event_t *ev; do { snd_seq_event_input(seq_handle, &ev); printf( "%i \n", ev->data.control.channel, ev->data.control.value); switch (ev->type) { case SND_SEQ_EVENT_CONTROLLER: printf("Control event on Channel %2d: %5d \n", ev->data.control.channel, ev->data.control.value); midi_set(ev, 2); pedal_set(ev); break; case SND_SEQ_EVENT_PITCHBEND: printf("Pitchbender event on Channel %2d: %5d \n", ev->data.control.channel, ev->data.control.value); break; case SND_SEQ_EVENT_NOTEON: printf("Note On event on Channel %2d: %5d \n", ev->data.control.channel, ev->data.note.note); break; case SND_SEQ_EVENT_NOTEOFF: printf("Note Off event on Channel %2d: %5d \n", ev->data.control.channel, ev->data.note.note); break; case SND_SEQ_EVENT_PGMCHANGE: printf("PGM event on Channel %2d: %5d \n", ev->data.control.channel, ev->data.control.value); midi_set(ev, 1); break; } snd_seq_free_event(ev); } while (snd_seq_event_input_pending(seq_handle, 0) > 0); }
void *midireceiver(void *arg) { snd_seq_event_t *event; JackVST *jvst = (JackVST* )arg; int val; struct sched_param scp; scp.sched_priority = 50; // Try to set fifo priority... // this works, if we are root or newe sched-cap manegment is used... pthread_setschedparam( pthread_self(), SCHED_FIFO, &scp ); while (1) { snd_seq_event_input (jvst->seq, &event); if (jvst->midiquit) { break; } switch(event->type){ case SND_SEQ_EVENT_NOTEON: queue_midi(jvst,0x90+event->data.note.channel,event->data.note.note,event->data.note.velocity); //printf("Noteon, channel: %d note: %d vol: %d\n",event->data.note.channel,event->data.note.note,event->data.note.velocity); break; case SND_SEQ_EVENT_NOTEOFF: queue_midi(jvst,0x80+event->data.note.channel,event->data.note.note,0); //printf("Noteoff, channel: %d note: %d vol: %d\n",event->data.note.channel,event->data.note.note,event->data.note.velocity); break; case SND_SEQ_EVENT_KEYPRESS: //printf("Keypress, channel: %d note: %d vol: %d\n",event->data.note.channel,event->data.note.note,event->data.note.velocity); queue_midi(jvst,0xa0+event->data.note.channel,event->data.note.note,event->data.note.velocity); break; case SND_SEQ_EVENT_CONTROLLER: queue_midi(jvst,0xb0+event->data.control.channel,event->data.control.param,event->data.control.value); //printf("Control: %d %d %d\n",event->data.control.channel,event->data.control.param,event->data.control.value); break; case SND_SEQ_EVENT_PITCHBEND: val=event->data.control.value + 0x2000; queue_midi(jvst,0xe0+event->data.control.channel,val&127,val>>7); //printf("Pitch: %d %d %d\n",event->data.control.channel,event->data.control.param,event->data.control.value); break; case SND_SEQ_EVENT_CHANPRESS: //printf("chanpress: %d %d %d\n",event->data.control.channel,event->data.control.param,event->data.control.value); queue_midi(jvst,0xd0+event->data.control.channel,event->data.control.value,0); break; case SND_SEQ_EVENT_PGMCHANGE: //printf("pgmchange: %d %d %d\n",event->data.control.channel,event->data.control.param,event->data.control.value); queue_midi(jvst,0xc0+event->data.control.channel,event->data.control.value,0); break; default: //printf("Unknown type: %d\n",event->type); break; } } return NULL; }
void* alsa_input_thread(void * arg) { struct a2j * self = arg; int npfd; struct pollfd * pfd; snd_seq_addr_t addr; snd_seq_client_info_t * client_info; snd_seq_port_info_t * port_info; bool initial; snd_seq_event_t * event; int ret; npfd = snd_seq_poll_descriptors_count(self->seq, POLLIN); pfd = (struct pollfd *)alloca(npfd * sizeof(struct pollfd)); snd_seq_poll_descriptors(self->seq, pfd, npfd, POLLIN); initial = true; while (g_keep_alsa_walking) { if ((ret = poll(pfd, npfd, 1000)) > 0) { while (snd_seq_event_input (self->seq, &event) > 0) { if (initial) { snd_seq_client_info_alloca(&client_info); snd_seq_port_info_alloca(&port_info); snd_seq_client_info_set_client(client_info, -1); while (snd_seq_query_next_client(self->seq, client_info) >= 0) { addr.client = snd_seq_client_info_get_client(client_info); if (addr.client == SND_SEQ_CLIENT_SYSTEM || addr.client == self->client_id) { continue; } snd_seq_port_info_set_client(port_info, addr.client); snd_seq_port_info_set_port(port_info, -1); while (snd_seq_query_next_port(self->seq, port_info) >= 0) { addr.port = snd_seq_port_info_get_port(port_info); a2j_update_port(self, addr, port_info); } } initial = false; } if (event->source.client == SND_SEQ_CLIENT_SYSTEM) { a2j_port_event(self, event); } else { a2j_input_event(self, event); } snd_seq_free_event (event); } } } return (void*) 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 void *midireceiver(void *arg){ struct Data *data=(struct Data*)arg; AEffect *effect=data->effect; snd_seq_event_t *event; for(;;){ snd_seq_event_input(data->seq, &event); if(data->toquit==true) break; switch(event->type){ case SND_SEQ_EVENT_NOTEON: sendmidi(effect,0x90+event->data.note.channel,event->data.note.note,event->data.note.velocity); //printf("Noteon, channel: %d note: %d vol: %d\n",event->data.note.channel,event->data.note.note,event->data.note.velocity); break; case SND_SEQ_EVENT_NOTEOFF: sendmidi(effect,0x90+event->data.note.channel,event->data.note.note,0); //printf("Noteoff, channel: %d note: %d vol: %d\n",event->data.note.channel,event->data.note.note,event->data.note.velocity); break; case SND_SEQ_EVENT_KEYPRESS: //printf("Keypress, channel: %d note: %d vol: %d\n",event->data.note.channel,event->data.note.note,event->data.note.velocity); sendmidi(effect,0xa0+event->data.note.channel,event->data.note.note,event->data.note.velocity); break; case SND_SEQ_EVENT_CONTROLLER: sendmidi(effect,0xb0+event->data.control.channel,event->data.control.param,event->data.control.value); //printf("Control: %d %d %d\n",event->data.control.channel,event->data.control.param,event->data.control.value); break; case SND_SEQ_EVENT_PITCHBEND: { int val=event->data.control.value + 0x2000; sendmidi(effect,0xe0+event->data.control.channel,val&127,val>>7); } //printf("Pitch: %d %d %d\n",event->data.control.channel,event->data.control.param,event->data.control.value); break; case SND_SEQ_EVENT_CHANPRESS: //printf("chanpress: %d %d %d\n",event->data.control.channel,event->data.control.param,event->data.control.value); sendmidi(effect,0xc0+event->data.control.channel,event->data.control.value,0); break; case SND_SEQ_EVENT_PGMCHANGE: //printf("pgmchange: %d %d %d\n",event->data.control.channel,event->data.control.param,event->data.control.value); sendmidi(effect,0xc0+event->data.control.channel,event->data.control.value,0); break; default: //printf("Unknown type: %d\n",event->type); break; } } return NULL; }
void Midi2UdpThread::run() { QUdpSocket *udpSocket; udpSocket = new QUdpSocket(0); forever { if (abort) { delete udpSocket; return; } if (poll(pfd, npfd, 250) > 0) { // Get MIDI event snd_seq_event_input(seq_handle, &midi_event); long len = snd_midi_event_decode(eventparser, midimsg, MAX_MIDI_MESSAGE_LENGTH, midi_event); if( len < 0 ) { printf("midi2udp: Error decoding midi event!\n"); } else { printf("midi2udp: got midi event: "); for(int i=0; i<len; ++i) { printf("0x%x ", midimsg[i]); } printf("\n"); // Send it over UDP for(set<string>::iterator ip_it = ds_ips.begin(); ip_it != ds_ips.end(); ++ip_it) { QString to_((*ip_it).c_str()); printf("sending to %s\n", (*ip_it).c_str()); QHostAddress to(to_); udpSocket->writeDatagram((char*)midimsg, len, to, DS_PORT); } } snd_seq_free_event(midi_event); snd_midi_event_reset_decode(eventparser); } } }
/* * Get the midi command,channel and parameters */ void ALSAMidiIn::getmidicmd(MidiCmdType &cmdtype, unsigned char &cmdchan, int *cmdparams) { snd_seq_event_t *midievent = NULL; cmdtype = MidiNull; if(inputok == false) { /* The input is broken. We need to block for a while anyway so other non-RT threads get a chance to run. */ sleep(1); return; } snd_seq_event_input(midi_handle, &midievent); if(midievent == NULL) return; switch(midievent->type) { case SND_SEQ_EVENT_NOTEON: cmdtype = MidiNoteON; cmdchan = midievent->data.note.channel; cmdparams[0] = midievent->data.note.note; cmdparams[1] = midievent->data.note.velocity; break; case SND_SEQ_EVENT_NOTEOFF: cmdtype = MidiNoteOFF; cmdchan = midievent->data.note.channel; cmdparams[0] = midievent->data.note.note; break; case SND_SEQ_EVENT_PITCHBEND: cmdtype = MidiController; cmdchan = midievent->data.control.channel; cmdparams[0] = C_pitchwheel; //Pitch Bend cmdparams[1] = midievent->data.control.value; break; case SND_SEQ_EVENT_CONTROLLER: cmdtype = MidiController; cmdchan = midievent->data.control.channel; cmdparams[0] = getcontroller(midievent->data.control.param); cmdparams[1] = midievent->data.control.value; //fprintf(stderr,"t=%d val=%d\n",midievent->data.control.param,midievent->data.control.value); break; } }
static ssize_t snd_rawmidi_virtual_read(snd_rawmidi_t *rmidi, void *buffer, size_t size) { snd_rawmidi_virtual_t *virt = rmidi->private_data; ssize_t result = 0; int size1, err; while (size > 0) { if (! virt->in_buf_ofs) { err = snd_seq_event_input_pending(virt->handle, 1); if (err <= 0 && result > 0) return result; err = snd_seq_event_input(virt->handle, &virt->in_event); if (err < 0) return result > 0 ? result : err; if (virt->in_event->type == SND_SEQ_EVENT_SYSEX) { virt->in_buf_ptr = virt->in_event->data.ext.ptr; virt->in_buf_size = virt->in_event->data.ext.len; } else { virt->in_buf_ptr = virt->in_tmp_buf; virt->in_buf_size = snd_midi_event_decode(virt->midi_event, (unsigned char *)virt->in_tmp_buf, sizeof(virt->in_tmp_buf), virt->in_event); } if (virt->in_buf_size <= 0) continue; } size1 = virt->in_buf_size - virt->in_buf_ofs; if ((size_t)size1 > size) { memcpy(buffer, virt->in_buf_ptr + virt->in_buf_ofs, size); virt->in_buf_ofs += size; result += size; break; } memcpy(buffer, virt->in_buf_ptr + virt->in_buf_ofs, size1); size -= size1; result += size1; buffer += size1; virt->in_buf_ofs = 0; } return result; }
// The main thread executive. void run() { snd_seq_t *pAlsaSeq = m_pMidiDevice->alsaSeq(); if (pAlsaSeq == NULL) return; int nfds; struct pollfd *pfds; nfds = snd_seq_poll_descriptors_count(pAlsaSeq, POLLIN); pfds = (struct pollfd *) alloca(nfds * sizeof(struct pollfd)); snd_seq_poll_descriptors(pAlsaSeq, pfds, nfds, POLLIN); qxgeditMidiInputRpn xrpn; m_bRunState = true; int iPoll = 0; while (m_bRunState && iPoll >= 0) { // Wait for events... iPoll = poll(pfds, nfds, 200); // Timeout? if (iPoll == 0) xrpn.flush(); while (iPoll > 0) { snd_seq_event_t *pEv = NULL; snd_seq_event_input(pAlsaSeq, &pEv); // Process input event - ... // - enqueue to input track mapping; if (!xrpn.process(pEv)) m_pMidiDevice->capture(pEv); // snd_seq_free_event(pEv); iPoll = snd_seq_event_input_pending(pAlsaSeq, 0); } // Process pending events... while (xrpn.isPending()) { snd_seq_event_t ev; if (xrpn.dequeue(&ev)) m_pMidiDevice->capture(&ev); } } }
/* TODO: ADD MIDI PANIC/ALL NOTES OFF */ int midi_callback() { snd_seq_event_t *ev; int l1; do { snd_seq_event_input(seq_handle, &ev); switch (ev->type) { case SND_SEQ_EVENT_NOTEON: for (l1 = 0; l1 < POLY; l1++) { if (!note_active[l1]) { note[l1] = ev->data.note.note; midichannel[l1] = ev->data.note.channel; velocity[l1] = ev->data.note.velocity / 127; attron(COLOR_PAIR(1)); printw("CH %2.0f ", midichannel[l1]+1); printw("Note %3d ", note[l1]); printw("Velocity %3.0f ", velocity[l1] * 127); printw("Frequency %3.1f \n", ((note[l1]*FREQ_CHANNEL_WIDTH)+((128*FREQ_CHANNEL_WIDTH*midichannel[l1])+FREQ_START)) ); refresh(); attroff(COLOR_PAIR(1)); env_time[l1] = 0; gate[l1] = 1; note_active[l1] = 1; break; } } break; case SND_SEQ_EVENT_NOTEOFF: for (l1 = 0; l1 < POLY; l1++) { if (gate[l1] && note_active[l1] && (note[l1] == ev->data.note.note)) { printw("Note OFF %3d \n", note[l1]); env_time[l1] = 0; gate[l1] = 0; } } break; } snd_seq_free_event(ev); } while (snd_seq_event_input_pending(seq_handle, 0) > 0); return (0); }
int midi_action(snd_seq_t *seq_handle) { snd_seq_event_t *ev; int cnt = 0; do { snd_seq_event_input(seq_handle, &ev); switch (ev->type) { case SND_SEQ_EVENT_NOTEON: if (channels && !(channels & (1<<ev->data.note.channel))) break; if (ev->data.note.velocity != 0) { note_on(ev->data.note.note, ev->data.note.velocity); cnt++; } } snd_seq_free_event(ev); } while (snd_seq_event_input_pending(seq_handle, 0) > 0); return cnt; }
int midi_callback() { snd_seq_event_t *ev; int l1; do { snd_seq_event_input(seq_handle, &ev); switch (ev->type) { case SND_SEQ_EVENT_PITCHBEND: pitch = (double)ev->data.control.value / 8192.0; break; case SND_SEQ_EVENT_CONTROLLER: if (ev->data.control.param == 1) { modulation = (double)ev->data.control.value / 10.0; } break; case SND_SEQ_EVENT_NOTEON: for (l1 = 0; l1 < POLY; l1++) { if (!note_active[l1]) { note[l1] = ev->data.note.note; velocity[l1] = ev->data.note.velocity / 127.0; env_time[l1] = 0; gate[l1] = 1; note_active[l1] = 1; break; } } break; case SND_SEQ_EVENT_NOTEOFF: for (l1 = 0; l1 < POLY; l1++) { if (gate[l1] && note_active[l1] && (note[l1] == ev->data.note.note)) { env_time[l1] = 0; gate[l1] = 0; } } break; } snd_seq_free_event(ev); } while (snd_seq_event_input_pending(seq_handle, 0) > 0); return (0); }
static void alsa_seqmidi_read(alsa_midi_t *m, jack_nframes_t nframes) { alsa_seqmidi_t *self = (alsa_seqmidi_t*) m; int res; snd_seq_event_t *event; struct process_info info; if (!self->keep_walking) return; set_process_info(&info, self, PORT_INPUT, nframes); jack_process(self, &info); while ((res = snd_seq_event_input(self->seq, &event))>0) { if (event->source.client == SND_SEQ_CLIENT_SYSTEM) port_event(self, event); else input_event(self, event, &info); } }
static void midi_thread(void *userdata) { MidiHardware *midi_hardware = reinterpret_cast<MidiHardware*>(userdata); for (;;) { snd_seq_event_t *event; int err = snd_seq_event_input(midi_hardware->seq, &event); if (midi_hardware->quit_flag) return; if (err < 0) { if (err == ENOSPC) { midi_hardware->on_buffer_overrun(midi_hardware); } else { // docs say ENOSPC is the only error that can occur in // blocking mode. panic("unexpected ALSA MIDI error: %s", snd_strerror(err)); } continue; } if (event->source.client == midi_hardware->system_announce_device->client_id && event->source.port == midi_hardware->system_announce_device->port_id) { if (event->type == SND_SEQ_EVENT_PORT_START || event->type == SND_SEQ_EVENT_PORT_EXIT) { midi_hardware_refresh(midi_hardware); } } else { for (int i = 0; i < midi_hardware->open_devices.length(); i += 1) { GenesisMidiDevice *device = midi_hardware->open_devices.at(i); if (device->client_id == event->source.client && device->port_id == event->source.port) { dispatch_event(device, event); break; } } } } }
static DrumNote* get_note (void) { #if !MIDI_NOP snd_seq_event_t *ev; int err; err = snd_seq_event_input (seq, &ev); assert (err >= 0); if (ev->type == SND_SEQ_EVENT_NOTEON) { DrumNote *note = g_malloc (sizeof (DrumNote)); note->drum = midi_note_to_drum (ev->data.note.note); note->tick = ev->time.tick; note->velocity = ev->data.note.velocity << (32 - 7); return note; } #endif return NULL; }
int midi_read() { snd_seq_event_t *ev; int channel,value,note,velocity,param; do { snd_seq_event_input(seq_handle, &ev); switch (ev->type) { case SND_SEQ_EVENT_NOTEON: channel = ev->data.note.channel; note = ev->data.note.note & 0x7f; velocity = ev->data.note.velocity; note_on_action(channel,note,velocity); break; case SND_SEQ_EVENT_NOTEOFF: channel = ev->data.note.channel; note = ev->data.note.note; velocity = ev->data.note.velocity; note_off_action(channel,note,velocity); break; case SND_SEQ_EVENT_PGMCHANGE: channel = ev->data.control.channel; value = ev->data.control.value; program_change_action(channel,value); break; case SND_SEQ_EVENT_CONTROLLER: channel = ev->data.control.channel; param = ev->data.control.param; value = ev->data.control.value; control_change_action(channel,param,value); break; } snd_seq_free_event(ev); } while (snd_seq_event_input_pending(seq_handle, 0) > 0); return (0); }
/* Handle MIDI input. To be called when poll() call in main loop indicates * that data is available on our fd(s). */ void midi_input(void) { int midi_status; snd_seq_event_t *ev; ssize_t evlen; while (1) { midi_status = snd_seq_event_input(seq, &ev); dprintf("MIDI input status : %d\n", midi_status); if (midi_status < 0) break; evlen = snd_seq_event_length(ev); dprintf("MIDI event length %d\n", evlen); switch (ev->type) { case SND_SEQ_EVENT_SYSEX: dprintf("Sysex: length %d\n", ev->data.ext.len); sysex_in(ev); break; case SND_SEQ_EVENT_CONTROLLER: dprintf("CC: dest cli:port %d:%d, ch %d, param %d, val %d\n", ev->dest.client, ev->dest.port, ev->data.control.channel + 1, ev->data.control.param, ev->data.control.value); int port = myport(ev->dest.port); if (port < 0) break; /* port not found */ if (cc_receivers[port].cc_receiver) { cc_receivers[port].cc_receiver(ev->data.control.channel, ev->data.control.param, ev->data.control.value); } break; default: break; } } }
void midi_action(snd_seq_t *seq_handle) { snd_seq_event_t *ev; do { snd_seq_event_input(seq_handle, &ev); switch (ev->type) { case SND_SEQ_EVENT_CONTROLLER: printf(MIDI_FORMAT, MIDI_CONTROL, ev->data.control.channel, ev->data.control.value); break; case SND_SEQ_EVENT_PITCHBEND: printf(MIDI_FORMAT, MIDI_PITCH_BEND, ev->data.control.channel, ev->data.control.value); break; case SND_SEQ_EVENT_NOTEON: printf(MIDI_FORMAT, MIDI_NOTE_ON, ev->data.control.channel, ev->data.note.note); break; case SND_SEQ_EVENT_NOTEOFF: printf(MIDI_FORMAT, MIDI_NOTE_OFF, ev->data.control.channel, ev->data.note.note); break; } fflush(stdout); fflush(stderr); snd_seq_free_event(ev); } while (snd_seq_event_input_pending(seq_handle, 0) > 0); }