bool OfflineAudioDestinationHandler::renderIfNotSuspended(AudioBus* sourceBus, AudioBus* destinationBus, size_t numberOfFrames) { // We don't want denormals slowing down any of the audio processing // since they can very seriously hurt performance. // This will take care of all AudioNodes because they all process within this scope. DenormalDisabler denormalDisabler; context()->deferredTaskHandler().setAudioThread(currentThread()); if (!context()->isDestinationInitialized()) { destinationBus->zero(); return false; } // Take care pre-render tasks at the beginning of each render quantum. Then // it will stop the rendering loop if the context needs to be suspended // at the beginning of the next render quantum. if (context()->handlePreOfflineRenderTasks()) { suspendOfflineRendering(); return true; } // Prepare the local audio input provider for this render quantum. if (sourceBus) m_localAudioInputProvider.set(sourceBus); ASSERT(numberOfInputs() >= 1); if (numberOfInputs() < 1) { destinationBus->zero(); return false; } // This will cause the node(s) connected to us to process, which in turn will pull on their input(s), // all the way backwards through the rendering graph. AudioBus* renderedBus = input(0).pull(destinationBus, numberOfFrames); if (!renderedBus) { destinationBus->zero(); } else if (renderedBus != destinationBus) { // in-place processing was not possible - so copy destinationBus->copyFrom(*renderedBus); } // Process nodes which need a little extra help because they are not connected to anything, but still need to process. context()->deferredTaskHandler().processAutomaticPullNodes(numberOfFrames); // Let the context take care of any business at the end of each render quantum. context()->handlePostOfflineRenderTasks(); // Advance current sample-frame. size_t newSampleFrame = m_currentSampleFrame + numberOfFrames; releaseStore(&m_currentSampleFrame, newSampleFrame); return false; }
bool OfflineAudioDestinationHandler::renderIfNotSuspended(AudioBus* sourceBus, AudioBus* destinationBus, size_t numberOfFrames) { // We don't want denormals slowing down any of the audio processing // since they can very seriously hurt performance. // This will take care of all AudioNodes because they all process within this scope. DenormalDisabler denormalDisabler; // Need to check if the context actually alive. Otherwise the subsequent // steps will fail. If the context is not alive somehow, return immediately // and do nothing. // // TODO(hongchan): because the context can go away while rendering, so this // check cannot guarantee the safe execution of the following steps. ASSERT(context()); if (!context()) return false; context()->deferredTaskHandler().setAudioThread(currentThread()); // If the destination node is not initialized, pass the silence to the final // audio destination (one step before the FIFO). This check is for the case // where the destination is in the middle of tearing down process. if (!isInitialized()) { destinationBus->zero(); return false; } // Take care pre-render tasks at the beginning of each render quantum. Then // it will stop the rendering loop if the context needs to be suspended // at the beginning of the next render quantum. if (context()->handlePreOfflineRenderTasks()) { suspendOfflineRendering(); return true; } // Prepare the local audio input provider for this render quantum. if (sourceBus) m_localAudioInputProvider.set(sourceBus); ASSERT(numberOfInputs() >= 1); if (numberOfInputs() < 1) { destinationBus->zero(); return false; } // This will cause the node(s) connected to us to process, which in turn will pull on their input(s), // all the way backwards through the rendering graph. AudioBus* renderedBus = input(0).pull(destinationBus, numberOfFrames); if (!renderedBus) { destinationBus->zero(); } else if (renderedBus != destinationBus) { // in-place processing was not possible - so copy destinationBus->copyFrom(*renderedBus); } // Process nodes which need a little extra help because they are not connected to anything, but still need to process. context()->deferredTaskHandler().processAutomaticPullNodes(numberOfFrames); // Let the context take care of any business at the end of each render quantum. context()->handlePostOfflineRenderTasks(); // Advance current sample-frame. size_t newSampleFrame = m_currentSampleFrame + numberOfFrames; releaseStore(&m_currentSampleFrame, newSampleFrame); return false; }