Пример #1
0
int CsoundPerformanceThread::Perform()
{
    int retval = 0;
    do {
      while (firstMessage) {
        csoundLockMutex(queueLock);
        do {
          CsoundPerformanceThreadMessage *msg;
          // get oldest message
          msg = (CsoundPerformanceThreadMessage*) firstMessage;
          if (!msg)
            break;
          // unlink from FIFO
          firstMessage = msg->nxt;
          if (!msg->nxt)
            lastMessage = (CsoundPerformanceThreadMessage*) 0;
          // process and destroy message
          retval = msg->run();
          delete msg;
        } while (!retval);
        if (paused)
          csoundWaitThreadLock(pauseLock, (size_t) 0);
        // mark queue as empty
        csoundNotifyThreadLock(flushLock);
        csoundUnlockMutex(queueLock);
        // if error or end of score, return now
        if (retval)
          goto endOfPerf;
        // if paused, wait until a new message is received, then loop back
        if (!paused)
          break;
        // VL: if this is paused, then it will double lock.
        csoundWaitThreadLockNoTimeout(pauseLock);
        csoundNotifyThreadLock(pauseLock);
      }
      if(processcallback != NULL)
           processcallback(cdata);
      retval = csoundPerformKsmps(csound);
    } while (!retval);
 endOfPerf:
    status = retval;
    csoundCleanup(csound);
    // delete any pending messages
    csoundLockMutex(queueLock);
    {
      CsoundPerformanceThreadMessage *msg;
      msg = (CsoundPerformanceThreadMessage*) firstMessage;
      firstMessage = (CsoundPerformanceThreadMessage*) 0;
      lastMessage = (CsoundPerformanceThreadMessage*) 0;
      while (msg) {
        CsoundPerformanceThreadMessage *nxt = msg->nxt;
        delete msg;
        msg = nxt;
      }
    }
    csoundNotifyThreadLock(flushLock);
    csoundUnlockMutex(queueLock);
    running = 1;
    return retval;
}
Пример #2
0
void CsoundPerformanceThread::QueueMessage(CsoundPerformanceThreadMessage *msg)
{
    if (status) {
      delete msg;
      return;
    }
    csoundLockMutex(queueLock);
    // link message into FIFO
    if (!lastMessage)
      firstMessage = msg;
    else
      lastMessage->nxt = msg;
    lastMessage = msg;
    // mark queue as non-empty
    csoundWaitThreadLock(flushLock, (size_t) 0);
    // wake up from pause
    csoundNotifyThreadLock(pauseLock);
    csoundUnlockMutex(queueLock);
}
Пример #3
0
int CsoundPerformanceThread::Perform()
{
    int retval = 0;
    do {
      while (firstMessage) {
        csoundLockMutex(queueLock);
        do {
          CsoundPerformanceThreadMessage *msg;
          // get oldest message
          msg = (CsoundPerformanceThreadMessage*) firstMessage;
          if (!msg)
            break;
          // unlink from FIFO
          firstMessage = msg->nxt;
          if (!msg->nxt)
            lastMessage = (CsoundPerformanceThreadMessage*) 0;
          // process and destroy message
          retval = msg->run();
          delete msg; // TODO: This should be moved out of the Perform function
        } while (!retval);
        if (paused)
          csoundWaitThreadLock(pauseLock, (size_t) 0);
        // mark queue as empty
        csoundNotifyThreadLock(flushLock);
        csoundUnlockMutex(queueLock);
        // if error or end of score, return now
        if (retval)
          goto endOfPerf;
        // if paused, wait until a new message is received, then loop back
        if (!paused)
          break;
        // VL: if this is paused, then it will double lock.
        csoundWaitThreadLockNoTimeout(pauseLock);
        csoundNotifyThreadLock(pauseLock);
      }
      if(processcallback != NULL)
           processcallback(cdata);
      retval = csoundPerformKsmps(csound);
      if (recordData.running) {
          MYFLT *spout = csoundGetSpout(csound);
          int len = csoundGetKsmps(csound) * csoundGetNchnls(csound);
          if (csoundGet0dBFS(csound) != 1.0) {
              MYFLT zdbfs = csoundGet0dBFS(csound);
              MYFLT *modspout = spout;
              for (int i = 0; i < len; i++) {
                  *modspout /= zdbfs;
                  modspout++;
              }
          }
          int written = csoundWriteCircularBuffer(NULL, recordData.cbuf, spout, len);
          if (written != len) {
              csoundMessage(csound, "perfThread record buffer overrun.");
          }
      }
      pthread_cond_signal(&recordData.condvar); // Needs to be outside the if for the case where stop record was requested
    } while (!retval);
 endOfPerf:
    status = retval;
    csoundCleanup(csound);
    // delete any pending messages
    csoundLockMutex(queueLock);
    {
      CsoundPerformanceThreadMessage *msg;
      msg = (CsoundPerformanceThreadMessage*) firstMessage;
      firstMessage = (CsoundPerformanceThreadMessage*) 0;
      lastMessage = (CsoundPerformanceThreadMessage*) 0;
      while (msg) {
        CsoundPerformanceThreadMessage *nxt = msg->nxt;
        delete msg;
        msg = nxt;
      }
    }
    csoundNotifyThreadLock(flushLock);
    csoundUnlockMutex(queueLock);
    running = 1;
    return retval;
}