コード例 #1
0
ファイル: rtmidimodule.cpp プロジェクト: DerThorsten/pyrtmidi
static void MidiIn_callback(double timestamp, std::vector<unsigned char> *message, void *opaque)
{
  MidiIn *self = (MidiIn *) opaque;
  
  uint8 *data = (uint8*) malloc(message->size());
  for(size_t i=0; i < message->size(); i++)
    data[i] = (*message)[i];  
  MidiMessage inMidi(data, message->size(), timestamp);
  free(data);

#if PK_WINDOWS
  WaitForSingleObject(self->mutex);
#else
  pthread_mutex_lock(&self->mutex);
#endif
  
  if(self->callback) // called too fast to init?
  {
    PyGILState_STATE gil_state = PyGILState_Ensure();
    
    PyObject *result = NULL;
    PyObject *args = NULL;

    PyMidiMessage *outMidi = (PyMidiMessage *) PyMidiMessage_new();

    (*outMidi->m) = inMidi;  

    args = Py_BuildValue("(O)", outMidi);  
    result = PyEval_CallObject(self->callback, args);
    if(result == NULL)
    {
      PyThreadState_SetAsyncExc(self->calling_thread_id, 0);
    }
    
    Py_XDECREF(result);
    Py_XDECREF(args);
    Py_XDECREF(outMidi);
    
    PyGILState_Release(gil_state);
  }
  else
  {
    self->m_q->push(new MidiMessage(inMidi));
    self->triggered = true;
  }
  
#if PK_WINDOWS
  SetEvent(self->cond);
  ReleaseMutex(self->mutex);
#else
  pthread_cond_signal(&self->cond);
  pthread_mutex_unlock(&self->mutex);
#endif
}
コード例 #2
0
PyObject *PyMidiMessage_FromMidiMessage(const MidiMessage &m)
{
  PyMidiMessage *result = (PyMidiMessage *) PyMidiMessage_new();
  *(result->m) = m;
  return (PyObject *) result;
}
コード例 #3
0
PyObject *PyMidiMessage_new()
{
  return PyMidiMessage_new(getMidiMessageType(), 0, 0);
}
コード例 #4
0
ファイル: rtmidimodule.cpp プロジェクト: DerThorsten/pyrtmidi
static PyObject *
MidiIn_getMessage(MidiIn *self, PyObject *args)
{
  PyObject *timeout = NULL;
  PyObject *result = NULL;
  
  if(!PyArg_ParseTuple(args, "|O:getMessage", &timeout))
    return NULL;

  long ms = -1;
  if(timeout)
  {
    if(PyFloat_CheckExact(timeout))
      ms = (long) PyFloat_AS_DOUBLE(timeout);
#if ! PK_PYTHON3
    else if(PyInt_CheckExact(timeout))
      ms = PyInt_AS_LONG(timeout);
#endif
    else if(PyLong_CheckExact(timeout))
      ms = PyLong_AsLong(timeout);
    else
    {
      PyErr_Format(RtMidiError, "timeout value must be a number, not %s", timeout->ob_type->tp_name);
      return NULL;
    }
    
    if(ms < 0)
    {
      PyErr_SetString(RtMidiError, "timeout value must be a positive number");
      return NULL;
    }
  }
  
#if PK_WINDOWS
  WaitForSingleObject(self->mutex);
#else
  pthread_mutex_lock(&self->mutex);    
#endif
  
  if(ms > -1 && self->triggered == false)
  { 
    PyThreadState *_save = PyEval_SaveThread();

#if PK_WINDOWS
    WaitForSingleObject(self->cond, ms < 0 ? INFINITE : ms);
#else
    if(ms < 0)
    {
      pthread_cond_wait(&self->cond, &self->mutex);
    }
    else
    {              
      struct timeval now;
      gettimeofday(&now, 0);
      
      struct timespec time;
      TIMEVAL_TO_TIMESPEC(&now, &time);
      unsigned long sec = ms / 1000;
      unsigned long nsec = (ms % 1000) * 1000000;
      
      time.tv_sec += sec;
      time.tv_nsec += nsec;
      while(time.tv_nsec >= 1000000000) {
        time.tv_sec++;
        time.tv_nsec -= 1000000000;
      }
      pthread_cond_timedwait(&self->cond, &self->mutex, &time);
    }
#endif
    
    PyEval_RestoreThread(_save);
  }
  
  if(self->m_q->size() > 0)
  {
    result = (PyObject *) PyMidiMessage_new();
    MidiMessage *inMidi = self->m_q->front();
    (*((PyMidiMessage *)result)->m) = (*inMidi);
    self->m_q->pop();
    self->triggered = false;
    delete inMidi;
  }    

#if PK_WINDOWS
  ReleaseMutex(self->mutex);
#else
  pthread_mutex_unlock(&self->mutex);
#endif
  
  if(result)
    return result;

  Py_RETURN_NONE;
}