Example #1
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...");
}
Example #2
0
bool inputAvailable()
{
        if(Pm_Poll(in) == 1 || nbEventWaiting > 0)
                return true;
        else if(Pm_Poll(in) == 0)
                return false;
        //else
        //        printf("Error while reading midi input.\r\n");
        return false;
}
Example #3
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);
    }
}
Example #4
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);
}
Example #5
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);
                        }
                  }
            }
      }
Example #6
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;
}
Example #7
0
/*
 * Method:    Pm_Poll
 */
JNIEXPORT jint JNICALL Java_jportmidi_JPortMidiApi_Pm_1Poll
        (JNIEnv *env, jclass cl, jobject jstream)
{
    CLASS(c, jstream);
    ADDRESS_FID(fid, c);
    return Pm_Poll(PMSTREAM(jstream, fid));
}
Example #8
0
bool PortMidiDriver::init()
      {
      inputId = getDeviceIn(preferences.getString(PREF_IO_PORTMIDI_INPUTDEVICE));
      if (inputId == -1)
            inputId  = Pm_GetDefaultInputDeviceID();

      if (inputId == pmNoDevice)
            return false;

      outputId = getDeviceOut(preferences.getString(PREF_IO_PORTMIDI_OUTPUTDEVICE)); // Note: allow init even if outputId == pmNoDevice, since input is more important than output.

      static const int DRIVER_INFO = 0;
      static const int TIME_INFO = 0;

      Pt_Start(20, 0, 0);      // timer started, 20 millisecond accuracy

      PmError error = Pm_OpenInput(&inputStream,
         inputId,
         (void*)DRIVER_INFO,
         preferences.getInt(PREF_IO_PORTMIDI_INPUTBUFFERCOUNT),
         ((PmTimeProcPtr) Pt_Time),
         (void*)TIME_INFO);
      if (error != pmNoError) {
            const char* p = Pm_GetErrorText(error);
            qDebug("PortMidi: open input (id=%d) failed: %s", int(inputId), p);
            Pt_Stop();
            return false;
            }

      Pm_SetFilter(inputStream, PM_FILT_ACTIVE | PM_FILT_CLOCK | PM_FILT_SYSEX);

      PmEvent buffer[1];
      while (Pm_Poll(inputStream))
            Pm_Read(inputStream, buffer, 1);

      if (outputId != pmNoDevice) {
            error = Pm_OpenOutput(&outputStream,
               outputId,
               (void*)DRIVER_INFO,
               preferences.getInt(PREF_IO_PORTMIDI_OUTPUTBUFFERCOUNT),
               ((PmTimeProcPtr) Pt_Time),
               (void*)TIME_INFO,
               preferences.getInt(PREF_IO_PORTMIDI_OUTPUTLATENCYMILLISECONDS));
            if (error != pmNoError) {
                  const char* p = Pm_GetErrorText(error);
                  qDebug("PortMidi: open output (id=%d) failed: %s", int(outputId), p);
                  Pt_Stop();
                  return false;
                  }
            }

      timer = new QTimer();
      timer->setInterval(20);       // 20 msec
      timer->start();
      timer->connect(timer, SIGNAL(timeout()), seq, SLOT(midiInputReady()));
      return true;
      }
Example #9
0
bool osd_poll_midi_channel(osd_midi_device *dev)
{
	#ifndef DISABLE_MIDI
	PmError chk = Pm_Poll(dev->pmStream);

	return (chk == pmGotData) ? true : false;
	#else
	return false;
	#endif
}
Example #10
0
/* callback function for PortTime -- computes histogram */
void pt_callback(PtTimestamp timestamp, void *userData)
{
    PtTimestamp difference = timestamp - previous_callback_time - period;
    previous_callback_time = timestamp;

    /* allow 5 seconds for the system to settle down */
    if (timestamp < 5000) return;

    iteration++;
    /* send a note on/off if user requested it */
    if (test_out && (iteration % output_period == 0)) {
        PmEvent buffer[1];
        buffer[0].timestamp = Pt_Time(NULL);
        if (note_on) {
            /* note off */
            buffer[0].message = Pm_Message(0x90, 60, 0);
            note_on = 0;
        } else {
            /* note on */
            buffer[0].message = Pm_Message(0x90, 60, 100);
            note_on = 1;
        }
        Pm_Write(out, buffer, 1);
        iteration = 0;
    }

    /* read all waiting events (if user requested) */
    if (test_in) {
       PmError status;
       PmEvent buffer[1];
       do {
          status = Pm_Poll(in);
          if (status == TRUE) {
              Pm_Read(in,buffer,1);
          }
       } while (status == TRUE);
    }

    if (difference < 0) return; /* ignore when system is "catching up" */

    /* update the histogram */
    if (difference < HIST_LEN) {
        histogram[difference]++;
    } else {
        out_of_range++;
    }

    if (max_latency < difference) max_latency = difference;
}
Example #11
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));
  }
}
Example #12
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));
  }
}
Example #13
0
int
midibus::poll_for_midi ()
{
    if (m_pm_num)
    {
        PmError err = Pm_Poll(m_pms);
        if (err == FALSE)
        {
            return 0;
        }
        if (err == TRUE)
        {
            return 1;
        }
        errprintf("Pm_Poll: %s\n", Pm_GetErrorText(err));
    }
    return 0;
}
Example #14
0
void portmidiGetEvents(Server *self)
{
    int i;
    PmError result;
    PmEvent buffer;

    PyoPmBackendData *be_data = (PyoPmBackendData *) self->midi_be_data;

    for (i=0; i<self->midiin_count; i++) {
        do {
            result = Pm_Poll(be_data->midiin[i]);
            if (result) {
                if (Pm_Read(be_data->midiin[i], &buffer, 1) == pmBufferOverflow)
                    continue;
                self->midiEvents[self->midi_count++] = PmEventToPyoMidiEvent(buffer);
            }
        } while (result);
    }
}
Example #15
0
bool PortMidiDriver::init()
      {
      inputId = getDeviceIn(preferences.portMidiInput);
      if(inputId == -1)
        inputId  = Pm_GetDefaultInputDeviceID();
      outputId = Pm_GetDefaultOutputDeviceID();

      if (inputId == pmNoDevice)
            return false;

      static const int INPUT_BUFFER_SIZE = 100;
      static const int DRIVER_INFO = 0;
      static const int TIME_INFO = 0;

      Pt_Start(20, 0, 0);      // timer started, 20 millisecond accuracy

      PmError error = Pm_OpenInput(&inputStream,
         inputId,
         (void*)DRIVER_INFO, INPUT_BUFFER_SIZE,
         ((long (*)(void*)) Pt_Time),
         (void*)TIME_INFO);
      if (error != pmNoError) {
            const char* p = Pm_GetErrorText(error);
            qDebug("PortMidi: open input (id=%d) failed: %s", int(inputId), p);
            Pt_Stop();
            return false;
            }

      Pm_SetFilter(inputStream, PM_FILT_ACTIVE | PM_FILT_CLOCK | PM_FILT_SYSEX);

      PmEvent buffer[1];
      while (Pm_Poll(inputStream))
            Pm_Read(inputStream, buffer, 1);

      timer = new QTimer();
      timer->setInterval(20);       // 20 msec
      timer->start();
      timer->connect(timer, SIGNAL(timeout()), seq, SLOT(midiInputReady()));
      return true;
      }
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);
        }
    }
}
Example #17
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);
                        }
                  }
            }
      }
Example #18
0
bool osd_poll_midi_channel(osd_midi_device *dev)
{
    PmError chk = Pm_Poll(dev->pmStream);

    return (chk == pmGotData) ? true : false;
}
Example #19
0
static int OpenMidiInDevice_(CSOUND *csound, void **userData, const char *dev)
{
    int         cntdev, devnum, opendevs, i;
    PmEvent     buffer;
    PmError     retval;
    PmDeviceInfo *info;
//     PortMidiStream *midistream;
    pmall_data *data = NULL;
    pmall_data *next = NULL;


    if (start_portmidi(csound) != 0)
      return -1;
    /* check if there are any devices available */
    cntdev = portMidi_getDeviceCount(0);
    portMidi_listDevices(csound, 0);
    /* look up device in list */
    if (dev == NULL || dev[0] == '\0')
      devnum =
        portMidi_getPackedDeviceID((int)Pm_GetDefaultInputDeviceID(), 0);
    else if (UNLIKELY((dev[0] < '0' || dev[0] > '9') && dev[0] != 'a')) {
      portMidiErrMsg(csound,
                     Str("error: must specify a device number (>=0) or"
                         " 'a' for all, not a name"));
      return -1;
    }
    else if (dev[0] != 'a') {
      devnum = (int)atoi(dev);
      if (UNLIKELY(devnum < 0 || devnum >= cntdev)) {
        portMidiErrMsg(csound, Str("error: device number is out of range"));
        return -1;
      }
    }
    else {
    // allow to proceed if 'a' is given even if there are no MIDI devices
      devnum = -1;
    }

    if (UNLIKELY(cntdev < 1 && (dev==NULL || dev[0] != 'a'))) {
      return portMidiErrMsg(csound, Str("no input devices are available"));
    }
    opendevs = 0;
    for (i = 0; i < cntdev; i++) {
      if (devnum == i || devnum == -1) {
        if (opendevs == 0) {
          data = (pmall_data *) malloc(sizeof(pmall_data));
          next = data;
          data->next = NULL;
          opendevs++;
        }
        else {
          next->next = (pmall_data *) malloc(sizeof(pmall_data));
          next = next->next;
          next->next = NULL;
          opendevs++;
        }
        info = portMidi_getDeviceInfo(i, 0);
        if (info->interf != NULL)
          csound->Message(csound,
                          Str("PortMIDI: Activated input device %d: '%s' (%s)\n"),
                          i, info->name, info->interf);
        else
          csound->Message(csound,
                          Str("PortMIDI: Activated input device %d: '%s'\n"),
                          i, info->name);
        retval = Pm_OpenInput(&next->midistream,
                 (PmDeviceID) portMidi_getRealDeviceID(i, 0),
                         NULL, 512L, (PmTimeProcPtr) NULL, NULL);
        if (UNLIKELY(retval != pmNoError)) {
          // Prevent leaking memory from "data"
          if (data) {
            next = data->next;
            free(data);
          }
          return portMidiErrMsg(csound, Str("error opening input device %d: %s"),
                                          i, Pm_GetErrorText(retval));
        }
          /* only interested in channel messages (note on, control change, etc.) */
        /* GAB: fixed for portmidi v.23Aug06 */
        Pm_SetFilter(next->midistream, (PM_FILT_ACTIVE | PM_FILT_SYSEX));
        /* empty the buffer after setting filter */
        while (Pm_Poll(next->midistream) == TRUE) {
          Pm_Read(next->midistream, &buffer, 1);
        }
      }
    }
    *userData = (void*) data;
    /* report success */
    return 0;
}
Example #20
0
bool osd_midi_device_pm::poll()
{
	PmError chk = Pm_Poll(pmStream);

	return (chk == pmGotData) ? true : false;
}
Example #21
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
}
Example #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;
}
Example #23
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);
}
Example #24
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(); 
}