void PortMidiDriver::read() { if (!inputStream) return; PmEvent buffer[1]; while (Pm_Poll(inputStream)) { int n = Pm_Read(inputStream, buffer, 1); if (n > 0) { int status = Pm_MessageStatus(buffer[0].message); int type = status & 0xF0; int channel = status & 0x0F; if (type == ME_NOTEON) { int pitch = Pm_MessageData1(buffer[0].message); int velo = Pm_MessageData2(buffer[0].message); mscore->midiNoteReceived(channel, pitch, velo); } else if (type == ME_NOTEOFF) { int pitch = Pm_MessageData1(buffer[0].message); (void)Pm_MessageData2(buffer[0].message); // read but ignore mscore->midiNoteReceived(channel, pitch, 0); } else if (type == ME_CONTROLLER) { int param = Pm_MessageData1(buffer[0].message); int value = Pm_MessageData2(buffer[0].message); mscore->midiCtrlReceived(param, value); } } } }
void QMidiSequencer::run() { while(true) { if (Pm_Poll(m_midi) == TRUE) { int size = Pm_Read(m_midi,m_buffer, 256); for(int i=0; i<size; i++) { int type = Pm_MessageStatus(m_buffer[i].message); int chan = Pm_MessageData1(m_buffer[i].message); int value = Pm_MessageData2(m_buffer[i].message); //std::cout << "midi : " << QString::number(type).toStdString() << " | " << QString::number(chan).toStdString() << " | " << QString::number(value).toStdString() << std::endl; /*qDebug(QString::number(type).toStdString().c_str()); qDebug(QString::number(chan).toStdString().c_str()); qDebug(QString::number(value).toStdString().c_str()); qDebug("\n");*/ if( chan == 74 || chan == 10 || chan == 7 ) emit controllerValueChanged(type*chan,value); else if( (chan == 72 || chan == 73) ) emit noteOn(type,type+chan,value); /*else if( type == 144 && value == 0 ) emit noteOff(type, chan);*/ } } this->msleep(10); } }
void process_midi(PtTimestamp timestamp, void *userData) { PmError result; PmEvent buffer; /* just one message at a time */ int i, status, data1, data2; PyObject *tup = NULL; MidiListener *server = (MidiListener *)userData; if (server->active == 0) return; PyGILState_STATE s = PyGILState_Ensure(); do { for (i=0; i<server->midicount; i++) { result = Pm_Poll(server->midiin[i]); if (result) { if (Pm_Read(server->midiin[i], &buffer, 1) == pmBufferOverflow) continue; status = Pm_MessageStatus(buffer.message); data1 = Pm_MessageData1(buffer.message); data2 = Pm_MessageData2(buffer.message); tup = PyTuple_New(3); PyTuple_SetItem(tup, 0, PyInt_FromLong(status)); PyTuple_SetItem(tup, 1, PyInt_FromLong(data1)); PyTuple_SetItem(tup, 2, PyInt_FromLong(data2)); PyObject_Call((PyObject *)server->midicallable, tup, NULL); } } } while (result); PyGILState_Release(s); Py_XDECREF(tup); }
void* MIDIInputPoll(MIDIInput* self) { PmEvent buffer[64]; int result; while (self->mRunning) { if (Pm_Poll(self->mStream)) { result = Pm_Read(self->mStream, buffer, 64); // result is an error number if (result < 0) { TTLogError("MidiPoll error\n"); } // result is the number of midi events else { MIDIParserFrom parser; for (TTInt32 i = 0; i < result; i++) { // if the parsing is done : pass address and value if (parser.parse(Pm_MessageStatus(buffer[i].message), Pm_MessageData1(buffer[i].message), Pm_MessageData2(buffer[i].message))) self->mProtocol->receivedMessage(self->mApplication, parser.address, parser.value); } } } self->mPollingThread->sleep(1); } return NULL; }
void mk_addNote(mk_State* state, PmMessage message) { static const char *noteNames[12] = {"c", "db", "d", "eb", "e", "f", "gb", "g", "ab", "a", "bb", "b"}; static const char *octaveNames[11] = {"_____", "____", "___", "__", "_", "", "'", "''", "'''", "''''", "'''''"}; long status = Pm_MessageStatus(message); long data1 = Pm_MessageData1(message); long data2 = Pm_MessageData2(message); mk_Note* note = malloc(sizeof(mk_Note)); note->name = (char*) noteNames[data1 % 12]; note->octave = (char*) octaveNames[data1 / 12 % 11]; note->next = NULL; if (state->notes.first == NULL) { state->notes.first = note; } state->notes.length++; if (state->notes.last != NULL) { state->notes.last->next = note; } state->notes.last = note; }
bool mastermidibus::get_midi_event (event *a_in) { automutex locker(m_mutex); bool result = false; PmEvent event; PmError err; for (int i = 0; i < m_num_in_buses; i++) { if (m_buses_in[i]->poll_for_midi()) { err = Pm_Read(m_buses_in[i]->m_pms, &event, 1); if (err < 0) printf("Pm_Read: %s\n", Pm_GetErrorText(err)); if (m_buses_in[i]->m_inputing) result = true; } } if (! result) return false; a_in->set_status(Pm_MessageStatus(event.message)); a_in->set_size(3); a_in->set_data(Pm_MessageData1(event.message), Pm_MessageData2(event.message)); /* some keyboards send Note On with velocity 0 for Note Off */ if (a_in->get_status() == EVENT_NOTE_ON && a_in->get_note_velocity() == 0x00) a_in->set_status(EVENT_NOTE_OFF); // Why no "sysex = false" here, like in Linux version? return true; }
/* * the somethingStupid parameter can be set to simulate a program crash. * We want PortMidi to close Midi ports automatically in the event of a * crash because Windows does not (and this may cause an OS crash) */ void main_test_input(unsigned int somethingStupid) { PmStream * midi; PmError status, length; PmEvent buffer[1]; int num = 10; int i = get_number("Type input number: "); /* It is recommended to start timer before Midi; otherwise, PortMidi may start the timer with its (default) parameters */ TIME_START; /* open input device */ Pm_OpenInput(&midi, i, DRIVER_INFO, INPUT_BUFFER_SIZE, TIME_PROC, TIME_INFO); printf("Midi Input opened. Reading %d Midi messages...\n", num); Pm_SetFilter(midi, PM_FILT_ACTIVE | PM_FILT_CLOCK | PM_FILT_SYSEX); /* empty the buffer after setting filter, just in case anything got through */ while (Pm_Poll(midi)) { Pm_Read(midi, buffer, 1); } /* now start paying attention to messages */ i = 0; /* count messages as they arrive */ while (i < num) { status = Pm_Poll(midi); if (status == TRUE) { length = Pm_Read(midi,buffer, 1); if (length > 0) { printf("Got message %d: time %ld, %2lx %2lx %2lx\n", i, (long) buffer[0].timestamp, (long) Pm_MessageStatus(buffer[0].message), (long) Pm_MessageData1(buffer[0].message), (long) Pm_MessageData2(buffer[0].message)); i++; } else { assert(0); } } /* simulate crash if somethingStupid is 1 or 2 */ if ((i > (num/2)) && (somethingStupid == 1)) { doSomethingStupid(); } else if ((i > (num/2)) && (somethingStupid == 2)) { doSomethingReallyStupid(); } } /* close device (this not explicitly needed in most implementations) */ printf("ready to close..."); Pm_Close(midi); printf("done closing..."); }
void midiReadLast(struct Note *note) { if(nbEventWaiting == 0) { iEventWaiting = 0; nbEventWaiting = Pm_Read(in, inBuffer, 1); } note->t = inBuffer[iEventWaiting].timestamp; note->note = Pm_MessageData1(inBuffer[iEventWaiting].message); note->vol = Pm_MessageData2(inBuffer[iEventWaiting].message); note->status = Pm_MessageStatus(inBuffer[iEventWaiting].message); nbEventWaiting--; iEventWaiting++; }
void sys_poll_midi(void) { int i, nmess, throttle = 100; PmEvent buffer; for (i = 0; i < mac_nmidiindev; i++) { while (1) { if (!throttle--) goto overload; nmess = Pm_Read(mac_midiindevlist[i], &buffer, 1); if (nmess > 0) { int status = Pm_MessageStatus(buffer.message); int data1 = Pm_MessageData1(buffer.message); int data2 = Pm_MessageData2(buffer.message); int data3 = ((buffer.message >> 24) & 0xff); int msgtype = ((status & 0xf0) == 0xf0 ? status : (status & 0xf0)); if (nd_sysex_mode) nd_sysex_inword(i, status, data1, data2, data3); else switch (msgtype) { case MIDINOTEOFF: case MIDINOTEON: case MIDIPOLYTOUCH: case MIDICONTROLCHANGE: case MIDIPITCHBEND: case MIDISONGPOS: sys_midibytein(i, status); sys_midibytein(i, data1); sys_midibytein(i, data2); break; case MIDIPROGRAMCHANGE: case MIDICHANNELTOUCH: case MIDITIMECODE: case MIDISONGSELECT: sys_midibytein(i, status); sys_midibytein(i, data1); break; case MIDISTARTSYSEX: nd_sysex_mode=1; nd_sysex_inword(i, status, data1, data2, data3); break; default: sys_midibytein(i, status); break; } } else break; }
int main(int argc, char **argv) { FILE *f; PmError perr; MfFile *pf; int ti; MfTrack *track; MfEvent *cur; int redux; if (argc < 4) { fprintf(stderr, "Use: hreducevel <file> <output file> <range reduction>\n"); return 1; } redux = atoi(argv[3]); PSF(perr, Mf_Initialize, ()); /* open it for input */ SF(f, fopen, NULL, (argv[1], "rb")); /* and read it */ PSF(perr, Mf_ReadMidiFile, (&pf, f)); fclose(f); /* redux it */ for (ti = 0; ti < pf->trackCt; ti++) { track = pf->tracks[ti]; cur = track->head; while (cur) { if (Pm_MessageType(cur->e.message) == MIDI_NOTE_ON) { uint8_t vel = Pm_MessageData2(cur->e.message); vel = 127 - (127-vel)/redux; cur->e.message = Pm_Message( Pm_MessageStatus(cur->e.message), Pm_MessageData1(cur->e.message), vel); } cur = cur->next; } } /* write it out */ SF(f, fopen, NULL, (argv[2], "wb")); PSF(perr, Mf_WriteMidiFile, (f, pf)); fclose(f); return 0; }
void dump(PtTimestamp ts, void *ignore) { PmEvent ev; while (Pm_Read(stream, &ev, 1) > 0) { switch (Pm_MessageType(ev.message)) { case MIDI_CONTROLLER: printf("CC: "); break; default: printf("??" "(%X): ", Pm_MessageType(ev.message)); } printf("ch%d %d %d\n", (int) Pm_MessageChannel(ev.message), (int) Pm_MessageData1(ev.message), (int) Pm_MessageData2(ev.message)); } }
void PortMidiDriver::read() { static const int THRESHOLD = 3; // iterations required before consecutive drum notes are not considered part of a chord static int active = 0; static int iter = 0; //for some reason, some users could have "active" blocked in < 0 if (active < 0) active = 0; if (!inputStream) return; PmEvent buffer[1]; iter = (iter >= THRESHOLD) ? iter : (iter+1); while (Pm_Poll(inputStream)) { int n = Pm_Read(inputStream, buffer, 1); if (n > 0) { int status = Pm_MessageStatus(buffer[0].message); int type = status & 0xF0; int channel = status & 0x0F; if (type == ME_NOTEON) { int pitch = Pm_MessageData1(buffer[0].message); int velo = Pm_MessageData2(buffer[0].message); mscore->midiNoteReceived(channel, pitch, velo); } else if (type == ME_NOTEOFF) { int pitch = Pm_MessageData1(buffer[0].message); (void)Pm_MessageData2(buffer[0].message); // read but ignore mscore->midiNoteReceived(channel, pitch, 0); } else if (type == ME_CONTROLLER) { int param = Pm_MessageData1(buffer[0].message); int value = Pm_MessageData2(buffer[0].message); mscore->midiCtrlReceived(param, value); } } } }
void receive_poll(PtTimestamp ts, void *userData) { int count, command; PmEvent event; if (inStream==NULL) return; if (Pm_Poll(inStream)!=TRUE) return; while ((count = Pm_Read(inStream, &event, 1))) { if (count == 1) { /* there seems to be a constant stream of MIDI events, not all of which are interesting */ /* the status has the command in the highest 4 bits and the channel in the lowest 4 bits */ command = Pm_MessageStatus(event.message) & MIDI_CODE_MASK; if ((command == MIDI_ON_NOTE) || (command == MIDI_OFF_NOTE ) || (command == MIDI_CH_PROGRAM ) || (command == MIDI_CTRL) || (command == MIDI_POLY_TOUCH ) || (command == MIDI_TOUCH ) || (command == MIDI_BEND )) { MUTEX_LOCK; channel [numReceived] = (Pm_MessageStatus(event.message) & MIDI_CHN_MASK); note [numReceived] = Pm_MessageData1(event.message); velocity [numReceived] = Pm_MessageData2(event.message); timestamp [numReceived] = event.timestamp; if (verbose) { mexPrintf("channel = %2d, note = %3d, velocity = %3d, timestamp = %d\n", channel[numReceived], note[numReceived], velocity[numReceived], timestamp[numReceived]); mexEvalString("try, drawnow limitrate nocallbacks; end"); } if (numReceived==INPUT_BUFFER_SIZE) mexWarnMsgTxt("midi buffer overrun"); else numReceived++; MUTEX_UNLOCK; } } else mexWarnMsgTxt(Pm_GetErrorText(count)); } }
void receive_poll(PtTimestamp ts, void *userData) { int count, command; unsigned int latest; PmEvent event; if (inStream==NULL) return; if (Pm_Poll(inStream)!=TRUE) return; while ((count = Pm_Read(inStream, &event, 1))) { if (count == 1) { /* there seems to be a constant stream of MIDI events, not all of which are interesting */ /* the status has the command in the highest 4 bits and the channel in the lowest 4 bits */ command = Pm_MessageStatus(event.message) & MIDI_CODE_MASK; if ((command == MIDI_ON_NOTE) || (command == MIDI_OFF_NOTE ) || (command == MIDI_CH_PROGRAM ) || (command == MIDI_CTRL) || (command == MIDI_POLY_TOUCH ) || (command == MIDI_TOUCH ) || (command == MIDI_BEND )) { /* store the latest event at the end of the ring buffer */ latest = WRAP(numReceived, INPUT_BUFFER_SIZE); numReceived++; channel [latest] = (double)(Pm_MessageStatus(event.message) & MIDI_CHN_MASK); note [latest] = (double)Pm_MessageData1(event.message); velocity [latest] = (double)Pm_MessageData2(event.message); timestamp [latest] = (double)event.timestamp; if (verbose) { mexPrintf("channel = %2d, note = %3d, velocity = %3d, timestamp = %g\n", (int)channel[latest], (int)note[latest], (int)velocity[latest], timestamp[latest]); mexEvalString("try, drawnow limitrate nocallbacks; end"); } } } else mexWarnMsgTxt(Pm_GetErrorText(count)); } }
void sys_poll_midi(void) { int i, nmess, throttle = 100; PmEvent buffer; for (i = 0; i < mac_nmidiindev; i++) { while (1) { if (!throttle--) goto overload; nmess = Pm_Read(mac_midiindevlist[i], &buffer, 1); if (nmess > 0) { int status = Pm_MessageStatus(buffer.message); int data1 = Pm_MessageData1(buffer.message); int data2 = Pm_MessageData2(buffer.message); int data3 = ((buffer.message >> 24) & 0xFF); int msgtype = (status >> 4) - 8; switch (msgtype) { case 0: case 1: case 2: case 3: case 6: sys_midibytein(i, status); sys_midibytein(i, data1); sys_midibytein(i, data2); break; case 4: case 5: sys_midibytein(i, status); sys_midibytein(i, data1); break; case 7: nd_sysex_mode=1; nd_sysex_inword(i, status, data1, data2, data3); break; default: if (nd_sysex_mode) nd_sysex_inword(i, status, data1, data2, data3); } } else break; }
void MidiSession::read() { while(active) { auto available = Pm_Poll(midiStream); if(available) { numEvents = Pm_Read(midiStream, events, 1); buffer.events.resize(numEvents); for(auto i = 0; i < numEvents; i++) { write(&events[i]); MidiEvent event; event.status = Pm_MessageStatus(events[i].message); event.note = Pm_MessageData1(events[i].message); event.velocity = Pm_MessageData2(events[i].message); event.timeStamp = events[i].timestamp; if(event.isNoteOff()) { event.channel = event.status - 127; } if(event.isNoteOn()) event.channel = event.status - 143; if (event.isPolyAftertouch()) event.channel = event.status = 159; buffer.events[i] = event; } for(auto& listener: listeners) listener->addBuffer(buffer); } } }
static Scheme_Object *read_event(int argc, Scheme_Object **argv) { PmEvent event; bool event_read; unsigned char cmd,channel,data1,data2; Scheme_Object *resultvector[4]; event_read=midi_io.read_event(event); // event is passed by reference if(event_read){ cmd=Pm_MessageStatus(event.message)&0xf0; channel=Pm_MessageStatus(event.message)&0xf; data1=Pm_MessageData1(event.message); data2=Pm_MessageData2(event.message); resultvector[0]=scheme_make_integer((int)cmd); resultvector[1]=scheme_make_integer((int)channel); resultvector[2]=scheme_make_integer((int)data1); resultvector[3]=scheme_make_integer((int)data2); return scheme_build_list(4,resultvector); } // if event read else { resultvector[0]=resultvector[1]=resultvector[2]=resultvector[3]=scheme_make_integer(0); return scheme_build_list(4,resultvector); } } // read_event()
int osd_midi_device_pm::read(UINT8 *pOut) { int msgsRead = Pm_Read(pmStream, rx_evBuf, RX_EVENT_BUF_SIZE); int bytesOut = 0; if (msgsRead <= 0) { return 0; } for (int msg = 0; msg < msgsRead; msg++) { UINT8 status = Pm_MessageStatus(rx_evBuf[msg].message); if (rx_sysex) { if (status & 0x80) // sys real-time imposing on us? { if ((status == 0xf2) || (status == 0xf3)) { *pOut++ = status; *pOut++ = Pm_MessageData1(rx_evBuf[msg].message); *pOut++ = Pm_MessageData2(rx_evBuf[msg].message); bytesOut += 3; } else { *pOut++ = status; bytesOut++; if (status == MIDI_EOX) { rx_sysex = false; } } } else // shift out the sysex bytes { for (int i = 0; i < 4; i++) { UINT8 byte = rx_evBuf[msg].message & 0xff; *pOut++ = byte; bytesOut++; if (byte == MIDI_EOX) { rx_sysex = false; break; } rx_evBuf[msg].message >>= 8; } } } else { switch ((status>>4) & 0xf) { case 0xc: // 2-byte messages case 0xd: *pOut++ = status; *pOut++ = Pm_MessageData1(rx_evBuf[msg].message); bytesOut += 2; break; case 0xf: // system common switch (status & 0xf) { case 0: // System Exclusive { *pOut++ = status; // this should be OK: the shortest legal sysex is F0 tt dd F7, I believe *pOut++ = (rx_evBuf[msg].message>>8) & 0xff; *pOut++ = (rx_evBuf[msg].message>>16) & 0xff; UINT8 last = *pOut++ = (rx_evBuf[msg].message>>24) & 0xff; bytesOut += 4; rx_sysex = (last != MIDI_EOX); break; } case 7: // End of System Exclusive *pOut++ = status; bytesOut += 1; rx_sysex = false; break; case 2: // song pos case 3: // song select *pOut++ = status; *pOut++ = Pm_MessageData1(rx_evBuf[msg].message); *pOut++ = Pm_MessageData2(rx_evBuf[msg].message); bytesOut += 3; break; default: // all other defined Fx messages are 1 byte break; } break; default: *pOut++ = status; *pOut++ = Pm_MessageData1(rx_evBuf[msg].message); *pOut++ = Pm_MessageData2(rx_evBuf[msg].message); bytesOut += 3; break; } } }
/* timer "interrupt" for processing midi data */ static void PMProcessMidi(PtTimestamp timestamp, void *userData) { ScopeMutexLock mulo(&gPmStreamMutex); PmError result; PmEvent buffer; /* just one message at a time */ for( int i = 0 ; i < gNumMIDIInPorts; ++i ) { int pmdid = gMidiInputIndexToPmDevIndex[i]; PmStream* midi_in = gMIDIInStreams[i]; if( midi_in ) { while(result = Pm_Poll(midi_in)) { long Tstatus, data1, data2; if (Pm_Read(midi_in, &buffer, 1) == pmBufferOverflow) continue; // unless there was overflow, we should have a message now Tstatus = Pm_MessageStatus(buffer.message); data1 = Pm_MessageData1(buffer.message); data2 = Pm_MessageData2(buffer.message); // +---------------------------------------------+ // | Lock the interp. mutex and dispatch message | // +---------------------------------------------+ pthread_mutex_lock (&gLangMutex); // it is needed -jamesmcc if (compiledOK) { VMGlobals *g = gMainVMGlobals; uint8 status = static_cast<uint8>(Tstatus & 0xF0); uint8 chan = static_cast<uint8>(Tstatus & 0x0F); g->canCallOS = false; // cannot call the OS ++g->sp; SetObject(g->sp, s_midiin->u.classobj); // Set the class MIDIIn //set arguments: ++g->sp; SetInt(g->sp, pmdid); //src // ++g->sp; SetInt(g->sp, status); //status ++g->sp; SetInt(g->sp, chan); //chan //if(status & 0x80) // set the running status for voice messages //gRunningStatus = ((status >> 4) == 0xF) ? 0 : pkt->data[i]; // keep also additional info switch (status) { case 0x80 : //noteOff ++g->sp; SetInt(g->sp, data1); ++g->sp; SetInt(g->sp, data2); runInterpreter(g, s_midiNoteOffAction, 5); break; case 0x90 : //noteOn ++g->sp; SetInt(g->sp, data1); ++g->sp; SetInt(g->sp, data2); runInterpreter(g, data2 ? s_midiNoteOnAction : s_midiNoteOffAction, 5); break; case 0xA0 : //polytouch ++g->sp; SetInt(g->sp, data1); ++g->sp; SetInt(g->sp, data2); runInterpreter(g, s_midiPolyTouchAction, 5); break; case 0xB0 : //control ++g->sp; SetInt(g->sp, data1); ++g->sp; SetInt(g->sp, data2); runInterpreter(g, s_midiControlAction, 5); break; case 0xC0 : //program ++g->sp; SetInt(g->sp, data1); runInterpreter(g, s_midiProgramAction, 4); break; case 0xD0 : //touch ++g->sp; SetInt(g->sp, data1); runInterpreter(g, s_midiTouchAction, 4); break; case 0xE0 : //bend ++g->sp; SetInt(g->sp, (data2 << 7) | data1); runInterpreter(g, s_midiBendAction, 4); break; /*case 0xF0 : // only the first Pm_Event will carry the 0xF0 byte // sysex message will be terminated by the EOX status byte 0xF7 midiProcessSystemPacket(data1, data2, chan); break; default : // data byte => continuing sysex message if(gRunningStatus && !gSysexFlag) { // handle running status status = gRunningStatus & 0xF0; // accept running status only inside a packet beginning chan = gRunningStatus & 0x0F; // with a valid status byte SetInt(g->sp, chan); --i; //goto L; // parse again with running status set // mv - get next byte } chan = 0; i += midiProcessSystemPacket(pkt, chan); // process sysex packet break; */ } g->canCallOS = false; } pthread_mutex_unlock (&gLangMutex); } } // if (midi_in) } // for loop until numMIDIInPorts }
void MidiTimelineNode::drawBackground( const KeyFramesWidgetInterface *pTrackWidget, const QRect &pUpdateRect, QImage &pBackImage ) const { QPainter Painter( &pBackImage ); Painter.drawImage( pUpdateRect, pTrackWidget->viewImage(), pUpdateRect ); if( !mEvents.isEmpty() ) { Painter.setPen( Qt::red ); QList<quint8> Notes; int j = 0; for( int i = pUpdateRect.left() ; i <= pUpdateRect.right() ; i++ ) { const qint64 t1 = qint64( mKF->time( pTrackWidget->viewToTimestamp( i ) ) * 1000.0 ); QList<quint8> SliceNotes = Notes; while( j > 0 ) { if( j < mEvents.size() ) { fugio::MidiEvent ME = mEvents[ j ]; if( ME.timestamp <= t1 ) { break; } } j--; } while( j < mEvents.size() ) { fugio::MidiEvent ME = mEvents[ j ]; if( ME.timestamp > t1 ) { break; } quint8 Status = Pm_MessageStatus( ME.message ) & 0xf0; quint8 Data1 = Pm_MessageData1( ME.message ); quint8 Data2 = Pm_MessageData2( ME.message ); if( Status == MIDI_NOTE_ON && Data2 > 0 ) { Notes.removeAll( Data1 ); Notes.append( Data1 ); SliceNotes.removeAll( Data1 ); SliceNotes.append( Data1 ); } else if( Status == MIDI_NOTE_OFF || ( Status == MIDI_NOTE_ON && Data2 == 0 ) ) { Notes.removeAll( Data1 ); } j++; } if( i > pUpdateRect.left() ) { for( quint8 n : SliceNotes ) { qint32 y1 = pTrackWidget->valueToView( qreal( n ) / 127.0 ); Painter.drawPoint( i, y1 ); } } else { for( quint8 n : Notes ) { qint32 y1 = pTrackWidget->valueToView( qreal( n ) / 127.0 ); Painter.drawPoint( i, y1 ); } } } } }
/* timer interrupt for processing midi data */ void process_midi(PtTimestamp timestamp, void *userData) { PmError result; PmEvent buffer; /* just one message at a time */ long msg; /* do nothing until initialization completes */ if (!active) return; /* check for messages */ do { result = Pm_Dequeue(main_to_midi, &msg); if (result) { if (msg >= -127 && msg <= 127) transpose = msg; else if (msg == QUIT_MSG) { /* acknowledge receipt of quit message */ Pm_Enqueue(midi_to_main, &msg); active = FALSE; return; } else if (msg == MONITOR_MSG) { /* main has requested a pitch. monitor is a flag that * records the request: */ monitor = TRUE; } else if (msg == THRU_MSG) { /* toggle Thru on or off */ midi_thru = !midi_thru; } } } while (result); /* see if there is any midi input to process */ do { result = Pm_Poll(midi_in); if (result) { long status, data1, data2; if (Pm_Read(midi_in, &buffer, 1) == pmBufferOverflow) continue; if (midi_thru) Pm_Write(midi_out, &buffer, 1); /* unless there was overflow, we should have a message now */ status = Pm_MessageStatus(buffer.message); data1 = Pm_MessageData1(buffer.message); data2 = Pm_MessageData2(buffer.message); if ((status & 0xF0) == 0x90 || (status & 0xF0) == 0x80) { /* this is a note-on or note-off, so transpose and send */ data1 += transpose; /* keep within midi pitch range, keep proper pitch class */ while (data1 > 127) data1 -= 12; while (data1 < 0) data1 += 12; /* send the message */ buffer.message = Pm_Message(status, data1, data2); Pm_Write(midi_out, &buffer, 1); /* if monitor is set, send the pitch to the main thread */ if (monitor) { Pm_Enqueue(midi_to_main, &data1); monitor = FALSE; /* only send one pitch per request */ } } } } while (result); }
static int ReadMidiData_(CSOUND *csound, void *userData, unsigned char *mbuf, int nbytes) { int n, retval, st, d1, d2; PmEvent mev; pmall_data *data; /* * Reads from MIDI input device linked list. */ n = 0; data = (pmall_data *)userData; while (data) { retval = Pm_Poll(data->midistream); if (retval != FALSE) { if (UNLIKELY(retval < 0)) return portMidiErrMsg(csound, Str("error polling input device")); while ((retval = Pm_Read(data->midistream, &mev, 1L)) > 0) { st = (int)Pm_MessageStatus(mev.message); d1 = (int)Pm_MessageData1(mev.message); d2 = (int)Pm_MessageData2(mev.message); /* unknown message or sysex data: ignore */ if (UNLIKELY(st < 0x80)) continue; /* ignore most system messages */ if (UNLIKELY(st >= 0xF0 && !(st == 0xF8 || st == 0xFA || st == 0xFB || st == 0xFC || st == 0xFF))) continue; nbytes -= (datbyts[(st - 0x80) >> 4] + 1); if (UNLIKELY(nbytes < 0)) { portMidiErrMsg(csound, Str("buffer overflow in MIDI input")); break; } /* channel messages */ n += (datbyts[(st - 0x80) >> 4] + 1); switch (datbyts[(st - 0x80) >> 4]) { case 0: *mbuf++ = (unsigned char) st; break; case 1: *mbuf++ = (unsigned char) st; *mbuf++ = (unsigned char) d1; break; case 2: *mbuf++ = (unsigned char) st; *mbuf++ = (unsigned char) d1; *mbuf++ = (unsigned char) d2; break; } } if (UNLIKELY(retval < 0)) { portMidiErrMsg(csound, Str("read error %d"), retval); if (n < 1) n = -1; } } data = data->next; } /* return the number of bytes read */ return n; }
void main_test_both() { int i = 0; int in, out; PmStream * midi, * midiOut; PmEvent buffer[1]; PmError status, length; int num = 10; in = get_number("Type input number: "); out = get_number("Type output number: "); /* In is recommended to start timer before PortMidi */ TIME_START; Pm_OpenOutput(&midiOut, out, DRIVER_INFO, OUTPUT_BUFFER_SIZE, TIME_PROC, TIME_INFO, latency); printf("Midi Output opened with %ld ms latency.\n", (long) latency); /* open input device */ Pm_OpenInput(&midi, in, DRIVER_INFO, INPUT_BUFFER_SIZE, TIME_PROC, TIME_INFO); printf("Midi Input opened. Reading %d Midi messages...\n",num); Pm_SetFilter(midi, PM_FILT_ACTIVE | PM_FILT_CLOCK); /* empty the buffer after setting filter, just in case anything got through */ while (Pm_Poll(midi)) { Pm_Read(midi, buffer, 1); } i = 0; while (i < num) { status = Pm_Poll(midi); if (status == TRUE) { length = Pm_Read(midi,buffer,1); if (length > 0) { Pm_Write(midiOut, buffer, 1); printf("Got message %d: time %ld, %2lx %2lx %2lx\n", i, (long) buffer[0].timestamp, (long) Pm_MessageStatus(buffer[0].message), (long) Pm_MessageData1(buffer[0].message), (long) Pm_MessageData2(buffer[0].message)); i++; } else { assert(0); } } } /* close midi devices */ Pm_Close(midi); Pm_Close(midiOut); Pm_Terminate(); }
void FLiveEditorManager::Tick(float DeltaTime) { //avoid multiple tick DOOM ( FTickableGameObject's get ticked once per UWorld that is active and Ticking ) float CurTime = GWorld->GetRealTimeSeconds(); if ( LastUpdateTime == CurTime ) { return; } LastUpdateTime = CurTime; if ( LiveEditorWorld == NULL ) { CreateLiveEditorWorld(); } RealWorld = GWorld; check( LiveEditorWorld != NULL ); GWorld = LiveEditorWorld; if ( ActiveBlueprints.Num() > 0 ) LiveEditorWorld->Tick( ELevelTick::LEVELTICK_All, DeltaTime ); // //update our ActiveBlueprints // int32 i = 0; while ( i < ActiveBlueprints.Num() ) { FActiveBlueprintRecord record = ActiveBlueprints[i]; ULiveEditorBlueprint *Instance = record.Blueprint.Get(); if ( Instance == NULL ) { ActiveBlueprints.RemoveAtSwap(i); //clean out the dead entry Activate( record.Name ); //try to ressurect the Blueprint (user has likely just recompiled it) continue; } Instance->Tick( DeltaTime ); ++i; } // // handle the actual MIDI messages // for( TMap< PmDeviceID, FLiveEditorDeviceInstance >::TIterator It(InputConnections); It; ++It ) { PmDeviceID DeviceID = (*It).Key; FLiveEditorDeviceInstance &DeviceInstance = (*It).Value; int NumRead = Pm_Read( DeviceInstance.Connection.MIDIStream, MIDIBuffer, DEFAULT_BUFFER_SIZE ); //needs to remain int (instead of int32) since numbers are derived from TPL that uses int if ( NumRead < 0 ) { continue; //error occurred, portmidi should handle this silently behind the scenes } else if ( NumRead > 0 ) { DeviceInstance.Data.LastInputTime = GWorld->GetTimeSeconds(); } //dispatch for ( int32 BufferIndex = 0; BufferIndex < NumRead; BufferIndex++ ) { PmMessage Msg = MIDIBuffer[BufferIndex].message; int Status = Pm_MessageStatus(Msg); //needs to remain int (instead of int32) since numbers are derived from TPL that uses int int Data1 = Pm_MessageData1(Msg); //needs to remain int (instead of int32) since numbers are derived from TPL that uses int int Data2 = Pm_MessageData2(Msg); //needs to remain int (instead of int32) since numbers are derived from TPL that uses int if ( ActiveWizard != NULL ) { ActiveWizard->ProcessMIDI( Status, Data1, Data2, DeviceID, DeviceInstance.Data ); } else { switch ( DeviceInstance.Data.ConfigState ) { case FLiveEditorDeviceData::UNCONFIGURED: break; case FLiveEditorDeviceData::CONFIGURED: Dispatch( Status, Data1, Data2, DeviceInstance.Data ); break; default: break; } } } } PieObjectCache.EvaluatePendingCreations(); GWorld = RealWorld; RealWorld = NULL; }
int main(int argc, const char * argv[]) { int i, numDevices, selectedDeviceIndex = 3; long channel; const PmDeviceInfo *info; PortMidiStream *stream; PmEvent event; Pm_Initialize(); numDevices = Pm_CountDevices(); if (numDevices == 0) { return 0; } for (i = 0; i < numDevices; i++) { info = Pm_GetDeviceInfo(i); if (info->input) { } } info = Pm_GetDeviceInfo(selectedDeviceIndex); channel = 1; channel--; Pm_OpenInput(&stream, selectedDeviceIndex, NULL, 8192, NULL, NULL); printf("Setup complete! Waiting for MIDI data...\n"); system("setterm -blank force");//kills all display. to bring back call: setterm -blank poke while (1) { long status, data1, data2; int length, person, audioFile; length = Pm_Read(stream, &event, sizeof(long)); if (length > 0) { status = Pm_MessageStatus(event.message); data1 = Pm_MessageData1(event.message); data2 = Pm_MessageData2(event.message); if (status == (0x80 + channel)) { printf("Note off: %ld, %ld\n", data1, data2); } else if (status == (0x90 + channel)) { printf("Note on: %ld, %ld\n", data1, data2); } else if (status == (0xB0 + channel)) { printf("CC: %ld, %ld\n", data1, data2); } } if (data1 == 25) { if (data2 == 127) { system("clear"); system("playMovie"); } } if(data1 == 26) { if(data2 == 127) { system("setterm -blank force"); } if(data2 == 0) { system("setterm -blank poke"); } } } Pm_Close(stream); Pm_Terminate(); return 0; }