void test_breakpoint_remove(void)
{
    int i;
    int break_count = 0;
    CSOUND* csound = csoundCreate(NULL);
    csoundCreateMessageBuffer(csound, 0);
    csoundCompileOrc(csound, "instr 1\nasig oscil 1, p4\nendin\n");
    csoundInputMessage(csound, "i 1.1 0   1 440");
    csoundInputMessage(csound, "i 1.2 0   1 880");
    csoundInputMessage(csound, "i 1.1 0.1 1 440");
    csoundStart(csound);
    csoundDebuggerInit(csound);
    csoundSetBreakpointCallback(csound, brkpt_cb2, (void *) &break_count);
    csoundSetInstrumentBreakpoint(csound, 1.1, 0);

    for (i = 0; i < 10; i++) {
        csoundPerformKsmps(csound);
        csoundDebugContinue(csound);
    }

    csoundRemoveInstrumentBreakpoint(csound, 1.1);
    for (i = 0; i < 10; i++) {
        csoundPerformKsmps(csound);
        csoundDebugContinue(csound);
    }
    CU_ASSERT(break_count == 1);

    csoundDebuggerClean(csound);
    csoundDestroy(csound);
}
void test_line_breakpoint_orc_file(void)
{
    FILE *f = fopen("debug.orc", "w");
    CU_ASSERT_PTR_NOT_NULL(f);

    const char *orc = "\n"
                      "instr 1\n"
                      "Svar init \"hello\"\n"
                      "ksig line 0, p3, 1\n"
                      "ksig2 line 1, p3, 0\n"
                      "asig3 oscils 0.5, 440, 0.5\n"
                      "endin\n";
    fprintf(f, "%s", orc);
    fclose(f);
    f = fopen("debug.sco", "w");
    CU_ASSERT_PTR_NOT_NULL(f);

    const char *sco = "i 1 0 1\n";
    fprintf(f, "%s", sco);
    fclose(f);
    count = 0;
    CSOUND* csound = csoundCreate(NULL);

    csoundCreateMessageBuffer(csound, 0);
    const char* argv[] = {"csound", "debug.orc", "debug.sco"};
    csoundCompile(csound, 3, (char **) argv);

    csoundDebuggerInit(csound);
    int line = 5;
    csoundSetBreakpointCallback(csound, brkpt_cb7, &line);
    csoundSetBreakpoint(csound, line, 0, 0);
    csoundPerformKsmps(csound);
    csoundDebugContinue(csound);
    csoundRemoveBreakpoint(csound, line, 0);
    csoundPerformKsmps(csound);
    csoundDebugContinue(csound);
    csoundPerformKsmps(csound);
    csoundDebugContinue(csound);
    csoundPerformKsmps(csound);
    csoundDebugContinue(csound);

    line = 6;
    csoundSetBreakpoint(csound, line, 0, 0);
    csoundPerformKsmps(csound);
    csoundDebugContinue(csound);
//    csoundPerformKsmps(csound);

    csoundDebuggerClean(csound);
    CU_ASSERT_EQUAL(count, 2);
    csoundDestroy(csound);
}
void test_line_breakpoint_add_remove(void)
{
    CSOUND* csound = csoundCreate(NULL);
    csoundCreateMessageBuffer(csound, 0);
    count = 0;
    csoundCompileOrc(csound, "instr 1\n"
                     "Svar init \"hello\"\n"
                     "ksig line 0, p3, 1\n"
                     "ksig2 line 1, p3, 0\n"
                     "asig3 oscils 0.5, 440, 0.5\n"
                     "endin\n");

    csoundInputMessage(csound, "i 1 0  1.1 440");
    csoundStart(csound);
    csoundDebuggerInit(csound);
    csoundSetBreakpointCallback(csound, brkpt_cb5, NULL);
    csoundSetBreakpoint(csound, 5, 1, 0);
    csoundPerformKsmps(csound);
    csoundDebugContinue(csound);
    csoundPerformKsmps(csound); // This block performs
    csoundPerformKsmps(csound); // This block breaks

    csoundRemoveBreakpoint(csound, 5, 1);
    csoundPerformKsmps(csound);
    csoundPerformKsmps(csound);
    csoundPerformKsmps(csound);
    csoundPerformKsmps(csound);
    csoundPerformKsmps(csound);

    csoundDebuggerClean(csound);
    csoundDestroy(csound);
    CU_ASSERT_EQUAL(count, 2);
}
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;
}
//Stephen Hensley
//shSoundScape
//email: [email protected]
//		: [email protected]
//
//
//functions used in main.
//Seperate file for ease of reading and editing.
///FUNCTIONS: THESE HAVE THEIR OWN FILE AND THIS SHOULD BE REMOVED WHEN DEBUGGING FOR BUILDING HAPPENS  
uintptr_t performance_function(void* data){
  CSOUND* csound = (CSOUND*) data;
  while(csoundPerformKsmps(csound) == 0){
    //as in main: just runs for now. Here for later expansion.
  }
  return 0;
}
Exemple #6
0
void test_pvs_opcodes(void)
{
    csoundSetGlobalEnv("OPCODE6DIR64", "../../");
    CSOUND *csound = csoundCreate(0);
    csoundCreateMessageBuffer(csound, 0);
    csoundSetOption(csound, "--logfile=null");
    int err = csoundCompileOrc(csound, orc5);
    CU_ASSERT(err == CSOUND_SUCCESS);
    err = csoundStart(csound);
    PVSDATEXT pvs_data, pvs_data2;
    memset(&pvs_data,0,sizeof(PVSDATEXT));
    memset(&pvs_data2,0,sizeof(PVSDATEXT));
    pvs_data.N = 16;
    pvs_data.winsize = 32;
    err = csoundSetPvsChannel(csound, &pvs_data, "1");
    err = csoundGetPvsChannel(csound, &pvs_data2, "1");
    CU_ASSERT_EQUAL(pvs_data.N, pvs_data2.N);
    MYFLT pFields[] = {1.0, 0.0, 1.0};
    err = csoundScoreEvent(csound, 'i', pFields, 3);
    err = csoundPerformKsmps(csound);
    CU_ASSERT_EQUAL(32.0, csoundGetControlChannel(csound, "winsize", NULL));
    csoundCleanup(csound);
    csoundDestroyMessageBuffer(csound);
    csoundDestroy(csound);
}
Exemple #7
0
int CsoundObj_process(CsoundObj *self,
		int inNumberFrames,
		double *inputBuffer,
		double *outputBuffer)
{
	int result = csoundPerformKsmps(self->csound);

	if (result == 0) {

		int outputChannelCount = csoundGetNchnls(self->csound);
		int inputChannelCount = csoundGetNchnlsInput(self->csound);

		self->csoundOut = csoundGetSpout(self->csound);
		self->csoundIn = csoundGetSpin(self->csound);

		if (self->useAudioInput == 1) {

			memcpy(self->csoundIn, inputBuffer, sizeof(double) * inNumberFrames);
		}

		memcpy(outputBuffer, self->csoundOut, sizeof(double) * inNumberFrames * outputChannelCount);
//		printf("csoundOut =%f outputBuffer = %f\n", self->csoundOut[0], outputBuffer[0]);
	}

	return result;
}
Exemple #8
0
/* Our performance function for the thread.  This will run Csound to 
 * completion using a while-loop.  For now, our data that we are passing
 * in is just the CSOUND structure, but in later examples we will use
 * a custom data structure so that we can pass in channels and other things
 * to use for processing at runtime. 
 */
uintptr_t performance_function(void* data) {
    CSOUND* csound = (CSOUND*) data;
    while (csoundPerformKsmps(csound) == 0) {
        /* pass for now */
    }
    return 0;
}
void CsoundObject_readCallback(void *inRefCon, UInt32 inNumberFrames, Float32 **audioData)
{
    CsoundObject *self = (CsoundObject *) inRefCon;
    MYFLT *csoundOut = csoundGetSpout(self->csound);
    csoundPerformKsmps(self->csound);
    
    for (size_t channel = 0; channel < self->channelsCount; ++channel) {
        
        cblas_scopy((SInt32)inNumberFrames, &csoundOut[channel], 2, audioData[channel], 1);
    }
}
void CsoundObject_turnOnPhaseVocoder(CsoundObject *self, size_t phaseVocoderInstances)
{
    self->csoundScore[0] = 1;
    self->csoundScore[1] = 0;
    self->csoundScore[2] = -1;
    self->csoundScore[3] = phaseVocoderInstances;
    self->csoundScore[4] = self->analysisSegmentFramesCount;
    
    csoundScoreEvent(self->csound, 'i', self->csoundScore, 5);
    csoundPerformKsmps(self->csound);
}
void test_no_callback(void)
{
    CSOUND* csound = csoundCreate(NULL);
    csoundCreateMessageBuffer(csound, 0);
    csoundStart(csound);
    csoundDebuggerInit(csound);
    csoundSetInstrumentBreakpoint(csound, 1, 0);

    csoundPerformKsmps(csound);

    csoundDebuggerClean(csound);
    csoundDestroy(csound);
}
Exemple #12
0
void test_channel_opcodes(void)
{
    csoundSetGlobalEnv("OPCODE6DIR64", "../../");
    CSOUND *csound = csoundCreate(0);
    csoundCreateMessageBuffer(csound, 0);
    csoundSetOption(csound, "--logfile=null");
    csoundCompileOrc(csound, orc4);
    csoundSetInputChannelCallback(csound, (channelCallback_t) inputCallback2);
    csoundSetOutputChannelCallback(csound, (channelCallback_t) outputCallback2);
    int err = csoundStart(csound);
    CU_ASSERT(err == CSOUND_SUCCESS);
    csoundGetControlChannel(csound, "1", &err);
    CU_ASSERT(err == CSOUND_SUCCESS)
    csoundSetControlChannel(csound, "1", 5.0);
    MYFLT pFields[] = {1.0, 0.0, 1.0};
    err = csoundScoreEvent(csound, 'i', pFields, 3);
    err = csoundPerformKsmps(csound);
    CU_ASSERT(err == CSOUND_SUCCESS);
    CU_ASSERT_EQUAL(5.0, csoundGetControlChannel(csound, "2", NULL));
    MYFLT pFields2[] = {2.0, 0.0, 1.0};
    err = csoundScoreEvent(csound, 'i', pFields2, 3);
    CU_ASSERT(err == CSOUND_SUCCESS);
    err = csoundPerformKsmps(csound);
    CU_ASSERT(err == CSOUND_SUCCESS);
    CU_ASSERT_EQUAL(6.0, csoundGetControlChannel(csound, "3", NULL));
    MYFLT pFields3[] = {3.0, 0.0, 1.0};
    err = csoundScoreEvent(csound, 'i', pFields3, 3);
    CU_ASSERT(err == CSOUND_SUCCESS);
    err = csoundPerformKsmps(csound);
    CU_ASSERT(err == CSOUND_SUCCESS);
    CU_ASSERT_EQUAL(7.0, csoundGetControlChannel(csound, "4", NULL));

    csoundCleanup(csound);
    csoundDestroyMessageBuffer(csound);
    csoundDestroy(csound);
}
Exemple #13
0
int main(int arg, char** argv) {
    random_line *amp, *freq;

    /* initialize random seed: */
    srand (time(NULL));

    csoundInitialize(CSOUNDINIT_NO_ATEXIT);

    CSOUND* csound = csoundCreate(NULL);

    /* Using SetOption() to configure Csound 
    Note: use only one commandline flag at a time */
    csoundSetOption(csound, "-odac");

    /* Compile the Csound Orchestra string */
    csoundCompileOrc(csound, orc);

    /* Read in the Score from loop-generated String */
    csoundReadScore(csound, "i1 0 60");

    /* When compiling from strings, this call is necessary 
    * before doing any performing */
    csoundStart(csound);

    /* Create a random_line for use with Amplitude */
    amp = random_line_create(0.4, 0.2);

    /* Create a random_line for use with Frequency */
    freq = random_line_create(400.0, 80.0);

    
    /* Initialize channel values before running Csound */
    csoundSetControlChannel(csound, "amp", random_line_tick(amp));
    csoundSetControlChannel(csound, "freq", random_line_tick(freq));

    /* The following is our main performance loop. We will perform one 
    * block of sound at a time and continue to do so while it returns 0, 
    * which signifies to keep processing.  
    */
    while (csoundPerformKsmps(csound) == 0) {
        /* Update Channel Values */
        csoundSetControlChannel(csound, "amp", random_line_tick(amp));
        csoundSetControlChannel(csound, "freq", random_line_tick(freq));
    }

    csoundStop(csound);
    return 0;
}
void test_bkpt_instrument(void)
{
    CSOUND* csound = csoundCreate(NULL);
    csoundCreateMessageBuffer(csound, 0);
    csoundCompileOrc(csound, "instr 1\n Svar init \"hello\"\n endin\n");
    csoundInputMessage(csound, "i 1 0  1.1 440");
    csoundStart(csound);
    csoundDebuggerInit(csound);
    csoundSetBreakpointCallback(csound, brkpt_cb4, NULL);
    csoundSetInstrumentBreakpoint(csound, 1, 0);

    csoundPerformKsmps(csound);

    csoundDebuggerClean(csound);
    csoundDestroy(csound);
}
void CsoundObject_writeDataToTable(CsoundObject *self, UInt32 tableNumber, Float32 *data, UInt32 dataCount)
{
    self->csoundScore[0] = tableNumber;
    self->csoundScore[1] = 0;
    self->csoundScore[2] = -((Float32)dataCount);
    self->csoundScore[3] = 2;
    self->csoundScore[4] = 0;
    
    csoundScoreEvent(self->csound, 'f', self->csoundScore, 5);
    csoundPerformKsmps(self->csound);
    
    Float32 *tablePointer;
    
    csoundGetTable(self->csound, &tablePointer, tableNumber);
    
    cblas_scopy((UInt32)dataCount, data, 1, tablePointer, 1);
    
}
Exemple #16
0
int main(int argc, char **argv)
{
    CSOUND  *csound;
    char    *fname = NULL;
    int     k, result;
    PVSDATEXT dataout, datain;

    /* initialise PVSATEXT data */
    datain.N = 1024;
    datain.format = 0;
    datain.overlap = 256;
    datain.winsize = 1024;
    datain.frame = (float *) calloc(sizeof(float),(datain.N+2));

    dataout.N = 1024;
    dataout.format = 0;
    dataout.overlap = 256;
    dataout.winsize = 1024;
    dataout.frame = (float *) calloc(sizeof(float),(dataout.N+2));

    /*  Create Csound. */
    csound = csoundCreate(NULL);

    /*  One complete performance cycle. */
    result = csoundCompile(csound, argc, argv);
    while (!result){

      /* copy data from pvs out to pvs in bus */
      for(k=0; k < 1026; k++)
          datain.frame[k] = dataout.frame[k];
      datain.framecount = dataout.framecount;
      /* send in the pvs in bus data */
      csoundSetPvsChannel(csound, &datain, "0");
      /* one ksmps pass */
      result = csoundPerformKsmps(csound);
      /* receive the pvs out bus data */
      csoundGetPvsChannel(csound, &dataout, "0");
    }
    /* delete Csound instance */
    csoundDestroy(csound);
    free(datain.frame);
    free(dataout.frame);
    return (result >= 0 ? 0 : result);
}
Exemple #17
0
int main(int arg, char** argv) {

    /* initialize random seed: */
    srand (time(NULL));

    csoundInitialize(CSOUNDINIT_NO_ATEXIT);

    CSOUND* csound = csoundCreate(NULL);

    /* Using SetOption() to configure Csound 
    Note: use only one commandline flag at a time */
    csoundSetOption(csound, "-odac");

    /* Compile the Csound Orchestra string */
    csoundCompileOrc(csound, orc);

    /* Read in the Score from pre-written String */
    /*csoundReadScore(csound, (char*)sco);*/

    /* Read in the Score from loop-generated String */
    /*csoundReadScore(csound, generate_example2());*/

    /* Read in the Score from loop-generated String */
    csoundReadScore(csound, generate_example3());

    /* When compiling from strings, this call is necessary 
    * before doing any performing */
    csoundStart(csound);

    /* The following is our main performance loop. We will perform one 
    * block of sound at a time and continue to do so while it returns 0, 
    * which signifies to keep processing.  We will explore this loop 
    * technique in further examples. 
    */

    while (csoundPerformKsmps(csound) == 0) {
      /* pass for now */
    }

    csoundStop(csound);

    return 0;
}
void test_line_breakpoint(void)
{
    CSOUND* csound = csoundCreate(NULL);
    csoundCreateMessageBuffer(csound, 0);
    count = 0;
    csoundCompileOrc(csound, "instr 1\n"
                     "Svar init \"hello\"\n"
                     "ksig line 0, p3, 1\n"
                     "ksig2 line 1, p3, 0\n"
                     "asig3 oscils 0.5, 440, 0.5\n"
                     "endin\n");

    csoundInputMessage(csound, "i 1 0  1.1 440");
    csoundStart(csound);
    csoundDebuggerInit(csound);
    csoundSetBreakpointCallback(csound, brkpt_cb6, NULL);
    csoundSetBreakpoint(csound, 5, 1, 0);
    csoundPerformKsmps(csound);

    csoundDebugContinue(csound);
    csoundPerformKsmps(csound);
    csoundSetBreakpoint(csound, 4, 1, 0);
    csoundPerformKsmps(csound);

    csoundDebugContinue(csound);
    csoundPerformKsmps(csound);
    csoundRemoveBreakpoint(csound, 4, 1);
    csoundPerformKsmps(csound);

    csoundDebugContinue(csound);
    csoundSetBreakpoint(csound, 1, 1, 0); // This breakpoint shouldn't be triggered as it's an init opcode
    csoundPerformKsmps(csound);

    csoundDebugContinue(csound);
    csoundSetBreakpoint(csound, 2, 2, 0); // This breakpoint shouldn't be triggered as instr 2 is not defined
    csoundPerformKsmps(csound);

    csoundDebuggerClean(csound);

    csoundDestroy(csound);

    CU_ASSERT_EQUAL(count, 2);
}
Exemple #19
0
void test_channel_callbacks(void)
{
    csoundSetGlobalEnv("OPCODE6DIR64", "../../");
    CSOUND *csound = csoundCreate(0);
    csoundCreateMessageBuffer(csound, 0);
    csoundSetOption(csound, "--logfile=null");
    csoundCompileOrc(csound, orc3);
    csoundSetInputChannelCallback(csound, (channelCallback_t) inputCallback);
    csoundSetOutputChannelCallback(csound, (channelCallback_t) outputCallback);
    int err = csoundStart(csound);
    CU_ASSERT(err == CSOUND_SUCCESS);
    MYFLT pFields[] = {1.0, 0.0, 1.0};
    err = csoundScoreEvent(csound, 'i', pFields, 3);
    MYFLT pFields2[] = {2.0, 0.0, 1.0};
    err += csoundScoreEvent(csound, 'i', pFields2, 3);
    CU_ASSERT(err == CSOUND_SUCCESS);
    err = csoundPerformKsmps(csound);
    CU_ASSERT(err == CSOUND_SUCCESS);
    csoundCleanup(csound);
    csoundDestroyMessageBuffer(csound);
    csoundDestroy(csound);
}
Exemple #20
0
int CsoundObj_performKsmps(CsoundObj *self)
{
    return csoundPerformKsmps(self->csound);
}
Exemple #21
0
void CsoundObj_render(CsoundObj *self)
{
    while(csoundPerformKsmps(self->csound) == 0);
    csoundCleanup(self->csound);
}
void test_next(void)
{
    CSOUND* csound = csoundCreate(NULL);
    csoundCreateMessageBuffer(csound, 0);
    count = 0;
    csoundCompileOrc(csound, "instr 1\n"
                             "Svar init \"hello\"\n"
                             "ksig line 0, p3, 1\n"
                             "ksig2 line 1, p3, 0\n"
                             "asig3 oscils 0.5, 440, 0.5\n"
                             "endin\n"
                             "instr 30\n"
                             "kvar init 10\n"
                             "kvar = kvar + 1\n"
                             "ksig2 line 1, p3, 0\n"
                             "kvar = kvar + 1\n"
                             "endin\n");

    csoundInputMessage(csound, "i 1 0  0.1");
    csoundInputMessage(csound, "i 1.2 0  0.1");
    csoundInputMessage(csound, "i 30.1 0  0.01");
    csoundInputMessage(csound, "i 30 0  0.01");
    csoundInputMessage(csound, "i 30 1  0.11");
    csoundInputMessage(csound, "i 1.3 0  0.1");

    csoundStart(csound);
    csoundDebuggerInit(csound);
    csoundSetBreakpointCallback(csound, brkpt_cb8, NULL);
    csoundSetInstrumentBreakpoint(csound, 1.2, 0);
    csoundPerformKsmps(csound);
    csoundPerformKsmps(csound);
    csoundPerformKsmps(csound);  // Only the first call should have effect as we have already stopped

    csoundDebugNext(csound);
    csoundPerformKsmps(csound);
    csoundPerformKsmps(csound); // Ignored
    csoundDebugNext(csound);
    csoundPerformKsmps(csound);
    csoundPerformKsmps(csound); // Ignored
    csoundDebugNext(csound);
    csoundPerformKsmps(csound);
    csoundPerformKsmps(csound); // Ignored
    csoundDebugNext(csound);
    csoundPerformKsmps(csound);
    csoundPerformKsmps(csound); // Ignored
    csoundRemoveInstrumentBreakpoint(csound, 1.2);
    csoundDebugContinue(csound);

    int i;
    for (i = 0; i < 200; i++) {
        csoundPerformKsmps(csound);
    }

    csoundSetBreakpointCallback(csound, brkpt_cb9, NULL);
    csoundSetInstrumentBreakpoint(csound, 30.1, 0);
    for (i = 0; i < 1000; i++) {
        csoundPerformKsmps(csound);
    }

    /* step to next line */
    csoundDebugNext(csound);
    csoundPerformKsmps(csound);
    /* step to next line */
    csoundDebugNext(csound);
    csoundPerformKsmps(csound);
    /* step to next line */
    csoundDebugNext(csound);
    csoundPerformKsmps(csound);

    csoundDebuggerClean(csound);
    csoundDestroy(csound);
    CU_ASSERT_EQUAL(count, 5);
}
Exemple #23
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;
}