src/effects/RealtimeEffectManager.cpp
//
// This will be called in a different thread than the main GUI thread.
//
This will be called in a different thread than the main GUI thread.
This will be called in a different thread than the main GUI thread .
size_t RealtimeEffectManager::RealtimeProcess(int group, unsigned chans, float **buffers, size_t numSamples)
{
   std::lock_guard<std::mutex> guard(mLock);
   if (mSuspended || mStates.empty())
   {
      return numSamples;
   }
   auto start = std::chrono::steady_clock::now();
   float **ibuf = (float **) alloca(chans * sizeof(float *));
   float **obuf = (float **) alloca(chans * sizeof(float *));
   for (unsigned int i = 0; i < chans; i++)
   {
      ibuf[i] = buffers[i];
      obuf[i] = (float *) alloca(numSamples * sizeof(float));
   }
   size_t called = 0;
   for (auto &state : mStates)
   {
      if (state->IsRealtimeActive())
      {
         state->RealtimeProcess(group, chans, ibuf, obuf, numSamples);
         called++;
      }
      for (unsigned int j = 0; j < chans; j++)
      {
         float *temp;
         temp = ibuf[j];
         ibuf[j] = obuf[j];
         obuf[j] = temp;
      }
   }
   if (called & 1)
   {
      for (unsigned int i = 0; i < chans; i++)
      {
         memcpy(buffers[i], ibuf[i], numSamples * sizeof(float));
      }
   }
   auto end = std::chrono::steady_clock::now();
   mLatency = std::chrono::duration_cast<std::chrono::microseconds>(end - start);
    This is wrong...needs to handle tails
   return numSamples;
}
size_t RealtimeEffectManager :: RealtimeProcess ( int group , unsigned chans , float * * buffers , size_t numSamples ) { std :: lock_guard < std :: mutex > guard ( mLock ) ; if ( mSuspended || mStates . empty ( ) ) { return numSamples ; } auto start = std :: chrono :: steady_clock :: now ( ) ; float * * ibuf = ( float * * ) alloca ( chans * sizeof ( float * ) ) ; float * * obuf = ( float * * ) alloca ( chans * sizeof ( float * ) ) ; for ( unsigned int i = 0 ; i < chans ; i ++ ) { ibuf [ i ] = buffers [ i ] ; obuf [ i ] = ( float * ) alloca ( numSamples * sizeof ( float ) ) ; } size_t called = 0 ; for ( auto & state : mStates ) { if ( state -> IsRealtimeActive ( ) ) { state -> RealtimeProcess ( group , chans , ibuf , obuf , numSamples ) ; called ++ ; } for ( unsigned int j = 0 ; j < chans ; j ++ ) { float * temp ; temp = ibuf [ j ] ; ibuf [ j ] = obuf [ j ] ; obuf [ j ] = temp ; } } if ( called & 1 ) { for ( unsigned int i = 0 ; i < chans ; i ++ ) { memcpy ( buffers [ i ] , ibuf [ i ] , numSamples * sizeof ( float ) ) ; } } auto end = std :: chrono :: steady_clock :: now ( ) ; mLatency = std :: chrono :: duration_cast < std :: chrono :: microseconds > ( end - start ) ; return numSamples ; }
This will be called in a different thread than the main GUI thread.
This will be called in a different thread than the main GUI thread .
// Protect... // Can be suspended because of the audio stream being paused or because effects // have been suspended, so allow the samples to pass as-is. // Remember when we started so we can calculate the amount of latency we // are introducing // Allocate the in/out buffer arrays // And populate the input with the buffers we've been given while allocating // NEW output buffers // Now call each effect in the chain while swapping buffer pointers to feed the // output of one effect as the input to the next effect // Once we're done, we might wind up with the last effect storing its results // in the temporary buffers.  If that's the case, we need to copy it over to // the caller's buffers.  This happens when the number of effects processed // is odd. // Remember the latency // // This is wrong...needs to handle tails //