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; }
int csoundReadScore(CSOUND *csound, const char *message){ int res; csoundLockMutex(csound->API_lock); res = csoundReadScoreInternal(csound, message); csoundUnlockMutex(csound->API_lock); return res; }
/** allocate a new loop, and return its index */ loopIdx_t alloc() { csoundLockMutex(mutex); //find a loop_nextIdx that isn't in loop map already while ( loop.find( loop_nextIdx) != loop.end()) ++loop_nextIdx; loop[loop_nextIdx] = new Loop(); csoundUnlockMutex(mutex); return loop_nextIdx; }
int csoundScoreEventAbsolute(CSOUND *csound, char type, const MYFLT *pfields, long numFields, double time_ofs) { csoundLockMutex(csound->API_lock); csoundScoreEventAbsoluteInternal(csound, type, pfields, numFields, time_ofs); csoundUnlockMutex(csound->API_lock); return OK; }
void step(MYFLT amt, MYFLT secs_per_tick, CSOUND * csound) { csoundLockMutex(mutex); for (eventMap_t::iterator i = loop.begin(); i != loop.end(); ++i) { i->second->step(amt, secs_per_tick, csound); } csoundUnlockMutex(mutex); }
int csoundScoreEvent(CSOUND *csound, char type, const MYFLT *pfields, long numFields) { csoundLockMutex(csound->API_lock); csoundScoreEventInternal(csound, type, pfields, numFields); csoundUnlockMutex(csound->API_lock); return OK; }
/** set the playing flag of the given loop */ void playing(loopIdx_t loopIdx, int tf) { if (loop.find(loopIdx) != loop.end()) { csoundLockMutex(mutex); loop[loopIdx]->setPlaying(tf); csoundUnlockMutex(mutex); } else { g_log->printf(1, "%s() called on non-existant loop %i\n", __FUNCTION__ , loopIdx); } }
/** set the playing flag of the given loop */ void addEvent(loopIdx_t loopIdx, int eventId, char type, MYFLT * p, int np, bool in_ticks, bool active) { if (loop.find(loopIdx) != loop.end()) { csoundLockMutex(mutex); loop[loopIdx]->addEvent(eventId, type, p, np, in_ticks, active); csoundUnlockMutex(mutex); } else { g_log->printf(1, "%s() called on non-existant loop %i\n", __FUNCTION__ , loopIdx); } }
void delEvent(loopIdx_t loopIdx, int eventId) { if (loop.find(loopIdx) != loop.end()) { csoundLockMutex(mutex); loop[loopIdx]->delEvent(eventId); csoundUnlockMutex(mutex); } else { g_log->printf(1, "%s() called on non-existant loop %i\n", __FUNCTION__ , loopIdx); } }
void updateEvent(loopIdx_t loopIdx, int eventId, int pIdx, float pVal, int activate_cmd) { if (loop.find(loopIdx) != loop.end()) { csoundLockMutex(mutex); loop[loopIdx]->updateEvent(eventId, pIdx, pVal, activate_cmd); csoundUnlockMutex(mutex); } else { g_log->printf(1, "%s() called on non-existant loop %i\n", __FUNCTION__ , loopIdx); } }
/** de-allocate a loop */ void destroy(loopIdx_t loopIdx) { if (loop.find(loopIdx) != loop.end()) { csoundLockMutex(mutex); //TODO: save the note events to a cache for recycling delete loop[loopIdx]; loop.erase(loopIdx); csoundUnlockMutex(mutex); } else { g_log->printf(1, "%s() called on non-existant loop %i\n", __FUNCTION__ , loopIdx); } }
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); }
PUBLIC int csoundCompileCsd(CSOUND *csound, char *str) { if((csound->engineStatus & CS_STATE_COMP) == 0) { char *argv[2] = { "csound", (char *) str }; int argc = 2; return csoundCompile(csound, argc, argv); } else { int res = read_unified_file2(csound, (char *) str); if(res) { res = csoundCompileOrc(csound, NULL); if(res == CSOUND_SUCCESS){ csoundLockMutex(csound->API_lock); char *sc = scsortstr(csound, csound->scorestr); csoundInputMessageInternal(csound, (const char *) sc); free(sc); csoundUnlockMutex(csound->API_lock); return CSOUND_SUCCESS; } } return res; } }
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; }
/* VL: These functions are slated to be converted to message enqueueing in the next API revision. */ void csoundInputMessage(CSOUND *csound, const char *message){ csoundLockMutex(csound->API_lock); csoundInputMessageInternal(csound, message); csoundUnlockMutex(csound->API_lock); }
void csoundTableCopyIn(CSOUND *csound, int table, MYFLT *ptable){ csoundLockMutex(csound->API_lock); csoundTableCopyInInternal(csound, table, ptable); csoundUnlockMutex(csound->API_lock); }
void csoundTableSet(CSOUND *csound, int table, int index, MYFLT value) { csoundLockMutex(csound->API_lock); csoundTableSetInternal(csound, table, index, value); csoundUnlockMutex(csound->API_lock); }
void unlockRecord() { csoundUnlockMutex(pt_->recordLock); }