OSStatus AUEffectBase::Render()

in Source/AUEffectBase.cpp [286:358]


OSStatus AUEffectBase::Render(
	AudioUnitRenderActionFlags& ioActionFlags, const AudioTimeStamp& inTimeStamp, UInt32 nFrames)
{
	if (!HasInput(0)) {
		return kAudioUnitErr_NoConnection;
	}

	OSStatus result = noErr;

	result = mMainInput->PullInput(ioActionFlags, inTimeStamp, 0 /* element */, nFrames);

	if (result == noErr) {
		if (ProcessesInPlace() && mMainOutput->WillAllocateBuffer()) {
			mMainOutput->SetBufferList(mMainInput->GetBufferList());
		}

		if (ShouldBypassEffect()) {
			// leave silence bit alone

			if (!ProcessesInPlace()) {
				mMainInput->CopyBufferContentsTo(mMainOutput->GetBufferList());
			}
		} else {
			auto& paramEventList = GetParamEventList();

			if (paramEventList.empty()) {
				// this will read/write silence bit
				result = ProcessBufferLists(ioActionFlags, mMainInput->GetBufferList(),
					mMainOutput->GetBufferList(), nFrames);
			} else {
				// deal with scheduled parameters...

				AudioBufferList& inputBufferList = mMainInput->GetBufferList();
				AudioBufferList& outputBufferList = mMainOutput->GetBufferList();

				ScheduledProcessParams processParams{ .actionFlags = &ioActionFlags,
					.inputBufferList = &inputBufferList,
					.outputBufferList = &outputBufferList };

				// divide up the buffer into slices according to scheduled params then
				// do the DSP for each slice (ProcessScheduledSlice() called for each slice)
				result = ProcessForScheduledParams(paramEventList, nFrames, &processParams);


				// fixup the buffer pointers to how they were before we started
				const UInt32 channelSize = nFrames * mBytesPerFrame;
				for (UInt32 i = 0; i < inputBufferList.mNumberBuffers; i++) {
					const UInt32 size =
						inputBufferList.mBuffers[i].mNumberChannels * channelSize;         // NOLINT
					inputBufferList.mBuffers[i].mData =                                    // NOLINT
						static_cast<std::byte*>(inputBufferList.mBuffers[i].mData) - size; // NOLINT
					inputBufferList.mBuffers[i].mDataByteSize = size;                      // NOLINT
				}

				for (UInt32 i = 0; i < outputBufferList.mNumberBuffers; i++) {
					const UInt32 size =
						outputBufferList.mBuffers[i].mNumberChannels * channelSize; // NOLINT
					outputBufferList.mBuffers[i].mData =                            // NOLINT
						static_cast<std::byte*>(outputBufferList.mBuffers[i].mData) -
						size;                                          // NOLINT
					outputBufferList.mBuffers[i].mDataByteSize = size; // NOLINT
				}
			}
		}

		if (((ioActionFlags & kAudioUnitRenderAction_OutputIsSilence) != 0u) &&
			!ProcessesInPlace()) {
			AUBufferList::ZeroBuffer(mMainOutput->GetBufferList());
		}
	}

	return result;
}