Пример #1
0
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);
                        }
                  }
            }
      }
Пример #2
0
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);
    }
}
Пример #3
0
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);
}
Пример #4
0
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;
}
Пример #5
0
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;
}
Пример #6
0
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;
}
Пример #7
0
/*
 * 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...");
}
Пример #8
0
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++;
}
Пример #9
0
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;
        }
Пример #10
0
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;
}
Пример #11
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));
    }
}
Пример #12
0
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);
                        }
                  }
            }
      }
Пример #13
0
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));
  }
}
Пример #14
0
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));
  }
}
Пример #15
0
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;
        }
Пример #16
0
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);
        }
    }
}
Пример #17
0
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()
Пример #18
0
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;
			}
		}
	}
Пример #19
0
/* 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
}
Пример #20
0
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 );
				}
			}
		}
	}
}
Пример #21
0
/* 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);
}
Пример #22
0
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;
}
Пример #23
0
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(); 
}
Пример #24
0
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;
}
Пример #25
0
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;
}