|  |  | @@ -200,14 +200,33 @@ struct PropertyListener { | 
		
	
		
			
			|  |  |  | void* userData; | 
		
	
		
			
			|  |  |  | }; | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | struct RenderListener { | 
		
	
		
			
			|  |  |  | AURenderCallback proc; | 
		
	
		
			
			|  |  |  | void* userData; | 
		
	
		
			
			|  |  |  | }; | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | typedef std::vector<PropertyListener> PropertyListeners; | 
		
	
		
			
			|  |  |  | typedef std::vector<RenderListener> RenderListeners; | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | // -------------------------------------------------------------------------------------------------------------------- | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | #if DISTRHO_PLUGIN_NUM_INPUTS + DISTRHO_PLUGIN_NUM_OUTPUTS == 0 | 
		
	
		
			
			|  |  |  | # define DPF_AU_NUM_BUFFERS 1 | 
		
	
		
			
			|  |  |  | #elif DISTRHO_PLUGIN_NUM_INPUTS > DISTRHO_PLUGIN_NUM_OUTPUTS | 
		
	
		
			
			|  |  |  | # define DPF_AU_NUM_BUFFERS DISTRHO_PLUGIN_NUM_INPUTS | 
		
	
		
			
			|  |  |  | #else | 
		
	
		
			
			|  |  |  | # define DPF_AU_NUM_BUFFERS DISTRHO_PLUGIN_NUM_OUTPUTS | 
		
	
		
			
			|  |  |  | #endif | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | typedef struct { | 
		
	
		
			
			|  |  |  | UInt32 mNumberBuffers; | 
		
	
		
			
			|  |  |  | AudioBuffer mBuffers[DPF_AU_NUM_BUFFERS]; | 
		
	
		
			
			|  |  |  | } d_AudioBufferList; | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | typedef struct { | 
		
	
		
			
			|  |  |  | UInt32 numPackets; | 
		
	
		
			
			|  |  |  | MIDIPacket packets[kMaxMidiEvents]; | 
		
	
		
			
			|  |  |  | } MIDIPacketList; | 
		
	
		
			
			|  |  |  | } d_MIDIPacketList; | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | // -------------------------------------------------------------------------------------------------------------------- | 
		
	
		
			
			|  |  |  | 
 | 
		
	
	
		
			
				|  |  | @@ -233,6 +252,7 @@ public: | 
		
	
		
			
			|  |  |  | fComponent(component), | 
		
	
		
			
			|  |  |  | fLastRenderError(noErr), | 
		
	
		
			
			|  |  |  | fPropertyListeners(), | 
		
	
		
			
			|  |  |  | fRenderListeners(), | 
		
	
		
			
			|  |  |  | fSampleRateForInput(d_nextSampleRate), | 
		
	
		
			
			|  |  |  | #if DISTRHO_PLUGIN_NUM_OUTPUTS != 0 | 
		
	
		
			
			|  |  |  | fSampleRateForOutput(d_nextSampleRate), | 
		
	
	
		
			
				|  |  | @@ -240,6 +260,7 @@ public: | 
		
	
		
			
			|  |  |  | #if DISTRHO_PLUGIN_NUM_INPUTS + DISTRHO_PLUGIN_NUM_OUTPUTS == 0 | 
		
	
		
			
			|  |  |  | fHasWorkingAudio(false), | 
		
	
		
			
			|  |  |  | #endif | 
		
	
		
			
			|  |  |  | fUsingRenderListeners(false), | 
		
	
		
			
			|  |  |  | fParameterCount(fPlugin.getParameterCount()), | 
		
	
		
			
			|  |  |  | fLastParameterValues(nullptr), | 
		
	
		
			
			|  |  |  | fBypassParameterIndex(UINT32_MAX) | 
		
	
	
		
			
				|  |  | @@ -256,6 +277,8 @@ public: | 
		
	
		
			
			|  |  |  | , fStateCount(fPlugin.getStateCount()) | 
		
	
		
			
			|  |  |  | #endif | 
		
	
		
			
			|  |  |  | { | 
		
	
		
			
			|  |  |  | const uint32_t bufferSize = fPlugin.getBufferSize(); | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | if (fParameterCount != 0) | 
		
	
		
			
			|  |  |  | { | 
		
	
		
			
			|  |  |  | fLastParameterValues = new float[fParameterCount]; | 
		
	
	
		
			
				|  |  | @@ -274,6 +297,15 @@ public: | 
		
	
		
			
			|  |  |  | fInputRenderCallback.inputProc = nullptr; | 
		
	
		
			
			|  |  |  | fInputRenderCallback.inputProcRefCon = nullptr; | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | fAudioBufferList.mNumberBuffers = DPF_AU_NUM_BUFFERS; | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | for (uint16_t i=0; i<DPF_AU_NUM_BUFFERS; ++i) | 
		
	
		
			
			|  |  |  | { | 
		
	
		
			
			|  |  |  | fAudioBufferList.mBuffers[i].mNumberChannels = 1; | 
		
	
		
			
			|  |  |  | fAudioBufferList.mBuffers[i].mData = new float[bufferSize]; | 
		
	
		
			
			|  |  |  | fAudioBufferList.mBuffers[i].mDataByteSize = sizeof(float) * bufferSize; | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | #if DISTRHO_PLUGIN_WANT_MIDI_INPUT | 
		
	
		
			
			|  |  |  | std::memset(&fMidiEvents, 0, sizeof(fMidiEvents)); | 
		
	
		
			
			|  |  |  | #endif | 
		
	
	
		
			
				|  |  | @@ -331,6 +363,9 @@ public: | 
		
	
		
			
			|  |  |  | delete[] fLastParameterValues; | 
		
	
		
			
			|  |  |  | CFRelease(fUserPresetData.presetName); | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | for (uint16_t i=0; i<DPF_AU_NUM_BUFFERS; ++i) | 
		
	
		
			
			|  |  |  | delete[] static_cast<float*>(fAudioBufferList.mBuffers[i].mData); | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | #if DISTRHO_PLUGIN_WANT_PROGRAMS | 
		
	
		
			
			|  |  |  | for (uint32_t i=0; i<fProgramCount; ++i) | 
		
	
		
			
			|  |  |  | CFRelease(fFactoryPresetsData[i].presetName); | 
		
	
	
		
			
				|  |  | @@ -1037,7 +1072,7 @@ public: | 
		
	
		
			
			|  |  |  | fPlugin.setSampleRate(sampleRate, true); | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | notifyListeners(inProp, inScope, inElement); | 
		
	
		
			
			|  |  |  | notifyPropertyListeners(inProp, inScope, inElement); | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | return noErr; | 
		
	
		
			
			|  |  |  | } | 
		
	
	
		
			
				|  |  | @@ -1055,7 +1090,7 @@ public: | 
		
	
		
			
			|  |  |  | fPlugin.setSampleRate(sampleRate, true); | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | notifyListeners(inProp, inScope, inElement); | 
		
	
		
			
			|  |  |  | notifyPropertyListeners(inProp, inScope, inElement); | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | return noErr; | 
		
	
		
			
			|  |  |  | } | 
		
	
	
		
			
				|  |  | @@ -1111,8 +1146,8 @@ public: | 
		
	
		
			
			|  |  |  | fPlugin.setSampleRate(desc->mSampleRate, true); | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | notifyListeners(inProp, inScope, inElement); | 
		
	
		
			
			|  |  |  | notifyListeners(kAudioUnitProperty_SampleRate, inScope, inElement); | 
		
	
		
			
			|  |  |  | notifyPropertyListeners(inProp, inScope, inElement); | 
		
	
		
			
			|  |  |  | notifyPropertyListeners(kAudioUnitProperty_SampleRate, inScope, inElement); | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | #if DISTRHO_PLUGIN_NUM_INPUTS + DISTRHO_PLUGIN_NUM_OUTPUTS == 0 | 
		
	
		
			
			|  |  |  | fHasWorkingAudio = true; | 
		
	
	
		
			
				|  |  | @@ -1132,8 +1167,8 @@ public: | 
		
	
		
			
			|  |  |  | fPlugin.setSampleRate(desc->mSampleRate, true); | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | notifyListeners(inProp, inScope, inElement); | 
		
	
		
			
			|  |  |  | notifyListeners(kAudioUnitProperty_SampleRate, inScope, inElement); | 
		
	
		
			
			|  |  |  | notifyPropertyListeners(inProp, inScope, inElement); | 
		
	
		
			
			|  |  |  | notifyPropertyListeners(kAudioUnitProperty_SampleRate, inScope, inElement); | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | return noErr; | 
		
	
		
			
			|  |  |  | } | 
		
	
	
		
			
				|  |  | @@ -1145,10 +1180,23 @@ public: | 
		
	
		
			
			|  |  |  | DISTRHO_SAFE_ASSERT_UINT_RETURN(inScope == kAudioUnitScope_Global, inScope, kAudioUnitErr_InvalidScope); | 
		
	
		
			
			|  |  |  | DISTRHO_SAFE_ASSERT_UINT_RETURN(inElement == 0, inElement, kAudioUnitErr_InvalidElement); | 
		
	
		
			
			|  |  |  | DISTRHO_SAFE_ASSERT_UINT_RETURN(inDataSize == sizeof(UInt32), inDataSize, kAudioUnitErr_InvalidPropertyValue); | 
		
	
		
			
			|  |  |  | { | 
		
	
		
			
			|  |  |  | const UInt32 bufferSize = *static_cast<const UInt32*>(inData); | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | if (fPlugin.setBufferSize(*static_cast<const UInt32*>(inData), true)) | 
		
	
		
			
			|  |  |  | notifyListeners(inProp, inScope, inElement); | 
		
	
		
			
			|  |  |  | if (fPlugin.setBufferSize(bufferSize, true)) | 
		
	
		
			
			|  |  |  | { | 
		
	
		
			
			|  |  |  | notifyPropertyListeners(inProp, inScope, inElement); | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | #if DISTRHO_PLUGIN_NUM_INPUTS + DISTRHO_PLUGIN_NUM_OUTPUTS != 0 | 
		
	
		
			
			|  |  |  | for (uint16_t i=0; i<DPF_AU_NUM_BUFFERS; ++i) | 
		
	
		
			
			|  |  |  | { | 
		
	
		
			
			|  |  |  | delete[] static_cast<float*>(fAudioBufferList.mBuffers[i].mData); | 
		
	
		
			
			|  |  |  | fAudioBufferList.mBuffers[i].mData = new float[bufferSize]; | 
		
	
		
			
			|  |  |  | fAudioBufferList.mBuffers[i].mDataByteSize = sizeof(float) * bufferSize; | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | #endif | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | return noErr; | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | case kAudioUnitProperty_BypassEffect: | 
		
	
	
		
			
				|  |  | @@ -1164,7 +1212,7 @@ public: | 
		
	
		
			
			|  |  |  | const float value = bypass ? 1.f : 0.f; | 
		
	
		
			
			|  |  |  | fLastParameterValues[fBypassParameterIndex] = value; | 
		
	
		
			
			|  |  |  | fPlugin.setParameterValue(fBypassParameterIndex, value); | 
		
	
		
			
			|  |  |  | notifyListeners(inProp, inScope, inElement); | 
		
	
		
			
			|  |  |  | notifyPropertyListeners(inProp, inScope, inElement); | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | return noErr; | 
		
	
	
		
			
				|  |  | @@ -1190,7 +1238,7 @@ public: | 
		
	
		
			
			|  |  |  | std::memset(&fHostCallbackInfo + usableDataSize, 0, sizeof(HostCallbackInfo) - usableDataSize); | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | if (changed) | 
		
	
		
			
			|  |  |  | notifyListeners(inProp, inScope, inElement); | 
		
	
		
			
			|  |  |  | notifyPropertyListeners(inProp, inScope, inElement); | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | return noErr; | 
		
	
		
			
			|  |  |  | #else | 
		
	
	
		
			
				|  |  | @@ -1212,7 +1260,7 @@ public: | 
		
	
		
			
			|  |  |  | fCurrentProgram = presetNumber; | 
		
	
		
			
			|  |  |  | fLastFactoryProgram = presetNumber; | 
		
	
		
			
			|  |  |  | fPlugin.loadProgram(fLastFactoryProgram); | 
		
	
		
			
			|  |  |  | notifyListeners('DPFo', kAudioUnitScope_Global, 0); | 
		
	
		
			
			|  |  |  | notifyPropertyListeners('DPFo', kAudioUnitScope_Global, 0); | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | else | 
		
	
	
		
			
				|  |  | @@ -1251,16 +1299,16 @@ public: | 
		
	
		
			
			|  |  |  | return noErr; | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | #if DISTRHO_PLUGIN_WANT_PROGRAMS | 
		
	
		
			
			|  |  |  | notifyListeners('DPFo', kAudioUnitScope_Global, 0); | 
		
	
		
			
			|  |  |  | notifyPropertyListeners('DPFo', kAudioUnitScope_Global, 0); | 
		
	
		
			
			|  |  |  | #endif | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | #if DISTRHO_PLUGIN_WANT_STATE | 
		
	
		
			
			|  |  |  | for (uint32_t i=0; i<fStateCount; ++i) | 
		
	
		
			
			|  |  |  | notifyListeners('DPFs', kAudioUnitScope_Global, i); | 
		
	
		
			
			|  |  |  | notifyPropertyListeners('DPFs', kAudioUnitScope_Global, i); | 
		
	
		
			
			|  |  |  | #endif | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | for (uint32_t i=0; i<fParameterCount; ++i) | 
		
	
		
			
			|  |  |  | notifyListeners('DPFp', kAudioUnitScope_Global, i); | 
		
	
		
			
			|  |  |  | notifyPropertyListeners('DPFp', kAudioUnitScope_Global, i); | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | return noErr; | 
		
	
		
			
			|  |  |  | 
 | 
		
	
	
		
			
				|  |  | @@ -1310,7 +1358,7 @@ public: | 
		
	
		
			
			|  |  |  | AUEventListenerNotify(NULL, NULL, &event); | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | if (fBypassParameterIndex == inElement) | 
		
	
		
			
			|  |  |  | notifyListeners(kAudioUnitProperty_BypassEffect, kAudioUnitScope_Global, 0); | 
		
	
		
			
			|  |  |  | notifyPropertyListeners(kAudioUnitProperty_BypassEffect, kAudioUnitScope_Global, 0); | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | return noErr; | 
		
	
		
			
			|  |  |  | 
 | 
		
	
	
		
			
				|  |  | @@ -1382,9 +1430,6 @@ public: | 
		
	
		
			
			|  |  |  | prop, proc, userData | 
		
	
		
			
			|  |  |  | }; | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | if (fPropertyListeners.empty()) | 
		
	
		
			
			|  |  |  | fPropertyListeners.reserve(32); | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | fPropertyListeners.push_back(pl); | 
		
	
		
			
			|  |  |  | return noErr; | 
		
	
		
			
			|  |  |  | } | 
		
	
	
		
			
				|  |  | @@ -1425,15 +1470,29 @@ public: | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | OSStatus auAddRenderNotify(const AURenderCallback proc, void* const userData) | 
		
	
		
			
			|  |  |  | { | 
		
	
		
			
			|  |  |  | d_stdout("WIP AddRenderNotify(%p, %p)", proc, userData); | 
		
	
		
			
			|  |  |  | // TODO | 
		
	
		
			
			|  |  |  | fUsingRenderListeners = true; | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | const RenderListener rl = { | 
		
	
		
			
			|  |  |  | proc, userData | 
		
	
		
			
			|  |  |  | }; | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | fRenderListeners.push_back(rl); | 
		
	
		
			
			|  |  |  | return noErr; | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | OSStatus auRemoveRenderNotify(const AURenderCallback proc, void* const userData) | 
		
	
		
			
			|  |  |  | { | 
		
	
		
			
			|  |  |  | d_stdout("WIP RemoveRenderNotify(%p, %p)", proc, userData); | 
		
	
		
			
			|  |  |  | // TODO | 
		
	
		
			
			|  |  |  | for (RenderListeners::iterator it = fRenderListeners.begin(); it != fRenderListeners.end(); ++it) | 
		
	
		
			
			|  |  |  | { | 
		
	
		
			
			|  |  |  | const RenderListener& rl(*it); | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | if (rl.proc == proc && rl.userData == userData) | 
		
	
		
			
			|  |  |  | { | 
		
	
		
			
			|  |  |  | fRenderListeners.erase(it); | 
		
	
		
			
			|  |  |  | return auRemoveRenderNotify(proc, userData); | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | return noErr; | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | 
 | 
		
	
	
		
			
				|  |  | @@ -1468,10 +1527,10 @@ public: | 
		
	
		
			
			|  |  |  | fPlugin.setParameterValue(param, value); | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | // TODO flag param only, notify listeners later on bg thread (sem_post etc) | 
		
	
		
			
			|  |  |  | notifyListeners('DPFp', kAudioUnitScope_Global, param); | 
		
	
		
			
			|  |  |  | notifyPropertyListeners('DPFp', kAudioUnitScope_Global, param); | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | if (fBypassParameterIndex == elem) | 
		
	
		
			
			|  |  |  | notifyListeners(kAudioUnitProperty_BypassEffect, kAudioUnitScope_Global, 0); | 
		
	
		
			
			|  |  |  | notifyPropertyListeners(kAudioUnitProperty_BypassEffect, kAudioUnitScope_Global, 0); | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | return noErr; | 
		
	
	
		
			
				|  |  | @@ -1523,61 +1582,158 @@ public: | 
		
	
		
			
			|  |  |  | return noErr; | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | OSStatus auRender(AudioUnitRenderActionFlags* const ioActionFlags, | 
		
	
		
			
			|  |  |  | OSStatus auRender(const AudioUnitRenderActionFlags actionFlags, | 
		
	
		
			
			|  |  |  | const AudioTimeStamp* const inTimeStamp, | 
		
	
		
			
			|  |  |  | const UInt32 inBusNumber, | 
		
	
		
			
			|  |  |  | const UInt32 inFramesToProcess, | 
		
	
		
			
			|  |  |  | AudioBufferList& ioData) | 
		
	
		
			
			|  |  |  | AudioBufferList* const ioData) | 
		
	
		
			
			|  |  |  | { | 
		
	
		
			
			|  |  |  | DISTRHO_SAFE_ASSERT_UINT_RETURN(inBusNumber == 0, inBusNumber, kAudioUnitErr_InvalidElement); | 
		
	
		
			
			|  |  |  | DISTRHO_SAFE_ASSERT_UINT_RETURN(ioData.mNumberBuffers == std::max<uint>(DISTRHO_PLUGIN_NUM_INPUTS, DISTRHO_PLUGIN_NUM_OUTPUTS), ioData.mNumberBuffers, kAudio_ParamError); | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | if (inFramesToProcess > fPlugin.getBufferSize()) | 
		
	
		
			
			|  |  |  | { | 
		
	
		
			
			|  |  |  | setLastRenderError(kAudioUnitErr_TooManyFramesToProcess); | 
		
	
		
			
			|  |  |  | return kAudioUnitErr_TooManyFramesToProcess; | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | for (uint i=0; i<ioData.mNumberBuffers; ++i) | 
		
	
		
			
			|  |  |  | if ((actionFlags & kAudioUnitRenderAction_DoNotCheckRenderArgs) == 0x0) | 
		
	
		
			
			|  |  |  | { | 
		
	
		
			
			|  |  |  | AudioBuffer& buffer(ioData.mBuffers[i]); | 
		
	
		
			
			|  |  |  | DISTRHO_SAFE_ASSERT_UINT_RETURN(inBusNumber == 0, inBusNumber, kAudioUnitErr_InvalidElement); | 
		
	
		
			
			|  |  |  | DISTRHO_SAFE_ASSERT_UINT_RETURN(ioData->mNumberBuffers == DPF_AU_NUM_BUFFERS, | 
		
	
		
			
			|  |  |  | ioData->mNumberBuffers, kAudio_ParamError); | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | // TODO there must be something more to this... | 
		
	
		
			
			|  |  |  | if (buffer.mData == nullptr) | 
		
	
		
			
			|  |  |  | if (inFramesToProcess > fPlugin.getBufferSize()) | 
		
	
		
			
			|  |  |  | { | 
		
	
		
			
			|  |  |  | return noErr; | 
		
	
		
			
			|  |  |  | setLastRenderError(kAudioUnitErr_TooManyFramesToProcess); | 
		
	
		
			
			|  |  |  | return kAudioUnitErr_TooManyFramesToProcess; | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | DISTRHO_SAFE_ASSERT_UINT_RETURN(buffer.mDataByteSize == inFramesToProcess * sizeof(float), buffer.mDataByteSize, kAudio_ParamError); | 
		
	
		
			
			|  |  |  | for (uint16_t i=0; i<DPF_AU_NUM_BUFFERS; ++i) | 
		
	
		
			
			|  |  |  | { | 
		
	
		
			
			|  |  |  | if (ioData->mBuffers[i].mDataByteSize != sizeof(float) * inFramesToProcess) | 
		
	
		
			
			|  |  |  | { | 
		
	
		
			
			|  |  |  | setLastRenderError(kAudio_ParamError); | 
		
	
		
			
			|  |  |  | return kAudio_ParamError; | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | #if DISTRHO_PLUGIN_NUM_INPUTS != 0 | 
		
	
		
			
			|  |  |  | const float* inputs[DISTRHO_PLUGIN_NUM_INPUTS]; | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | for (uint16_t i=0; i<DISTRHO_PLUGIN_NUM_INPUTS; ++i) | 
		
	
		
			
			|  |  |  | { | 
		
	
		
			
			|  |  |  | inputs[i] = static_cast<const float*>(ioData.mBuffers[i].mData); | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | #else | 
		
	
		
			
			|  |  |  | constexpr const float** inputs = nullptr; | 
		
	
		
			
			|  |  |  | #endif | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | #if DISTRHO_PLUGIN_NUM_OUTPUTS != 0 | 
		
	
		
			
			|  |  |  | float* outputs[DISTRHO_PLUGIN_NUM_OUTPUTS]; | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | for (uint16_t i=0; i<DISTRHO_PLUGIN_NUM_OUTPUTS; ++i) | 
		
	
		
			
			|  |  |  | { | 
		
	
		
			
			|  |  |  | outputs[i] = static_cast<float*>(ioData.mBuffers[i].mData); | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | #else | 
		
	
		
			
			|  |  |  | constexpr float** outputs = nullptr; | 
		
	
		
			
			|  |  |  | #endif | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | if (fInputRenderCallback.inputProc != nullptr) | 
		
	
		
			
			|  |  |  | { | 
		
	
		
			
			|  |  |  | bool adjustDataByteSize, usingHostBuffer = true; | 
		
	
		
			
			|  |  |  | UInt32 prevDataByteSize; | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | for (uint16_t i=0; i<DPF_AU_NUM_BUFFERS; ++i) | 
		
	
		
			
			|  |  |  | { | 
		
	
		
			
			|  |  |  | if (ioData->mBuffers[i].mData == nullptr) | 
		
	
		
			
			|  |  |  | { | 
		
	
		
			
			|  |  |  | usingHostBuffer = false; | 
		
	
		
			
			|  |  |  | ioData->mBuffers[i].mData = fAudioBufferList.mBuffers[i].mData; | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | if (! usingHostBuffer) | 
		
	
		
			
			|  |  |  | { | 
		
	
		
			
			|  |  |  | prevDataByteSize = fAudioBufferList.mBuffers[0].mDataByteSize; | 
		
	
		
			
			|  |  |  | adjustDataByteSize = prevDataByteSize != sizeof(float) * inFramesToProcess; | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | if (adjustDataByteSize) | 
		
	
		
			
			|  |  |  | { | 
		
	
		
			
			|  |  |  | for (uint16_t i=0; i<DPF_AU_NUM_BUFFERS; ++i) | 
		
	
		
			
			|  |  |  | fAudioBufferList.mBuffers[i].mDataByteSize = sizeof(float) * inFramesToProcess; | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | else | 
		
	
		
			
			|  |  |  | { | 
		
	
		
			
			|  |  |  | adjustDataByteSize = false; | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | AudioUnitRenderActionFlags rActionFlags = 0; | 
		
	
		
			
			|  |  |  | AudioBufferList* const rData = usingHostBuffer ? ioData : reinterpret_cast<AudioBufferList*>(&fAudioBufferList); | 
		
	
		
			
			|  |  |  | const OSStatus err = fInputRenderCallback.inputProc(fInputRenderCallback.inputProcRefCon, | 
		
	
		
			
			|  |  |  | &rActionFlags, | 
		
	
		
			
			|  |  |  | inTimeStamp, | 
		
	
		
			
			|  |  |  | inBusNumber, | 
		
	
		
			
			|  |  |  | inFramesToProcess, | 
		
	
		
			
			|  |  |  | rData); | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | if (err != noErr) | 
		
	
		
			
			|  |  |  | { | 
		
	
		
			
			|  |  |  | if (adjustDataByteSize) | 
		
	
		
			
			|  |  |  | { | 
		
	
		
			
			|  |  |  | for (uint16_t i=0; i<DPF_AU_NUM_BUFFERS; ++i) | 
		
	
		
			
			|  |  |  | fAudioBufferList.mBuffers[i].mDataByteSize = prevDataByteSize; | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | setLastRenderError(err); | 
		
	
		
			
			|  |  |  | return err; | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | if (usingHostBuffer) | 
		
	
		
			
			|  |  |  | { | 
		
	
		
			
			|  |  |  | #if DISTRHO_PLUGIN_NUM_INPUTS != 0 | 
		
	
		
			
			|  |  |  | for (uint16_t i=0; i<DISTRHO_PLUGIN_NUM_INPUTS; ++i) | 
		
	
		
			
			|  |  |  | inputs[i] = static_cast<const float*>(ioData->mBuffers[i].mData); | 
		
	
		
			
			|  |  |  | #endif | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | #if DISTRHO_PLUGIN_NUM_OUTPUTS != 0 | 
		
	
		
			
			|  |  |  | for (uint16_t i=0; i<DISTRHO_PLUGIN_NUM_OUTPUTS; ++i) | 
		
	
		
			
			|  |  |  | outputs[i] = static_cast<float*>(ioData->mBuffers[i].mData); | 
		
	
		
			
			|  |  |  | #endif | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | else | 
		
	
		
			
			|  |  |  | { | 
		
	
		
			
			|  |  |  | #if DISTRHO_PLUGIN_NUM_INPUTS != 0 | 
		
	
		
			
			|  |  |  | for (uint16_t i=0; i<DISTRHO_PLUGIN_NUM_INPUTS; ++i) | 
		
	
		
			
			|  |  |  | inputs[i] = static_cast<const float*>(fAudioBufferList.mBuffers[i].mData); | 
		
	
		
			
			|  |  |  | #endif | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | #if DISTRHO_PLUGIN_NUM_OUTPUTS != 0 | 
		
	
		
			
			|  |  |  | for (uint16_t i=0; i<DISTRHO_PLUGIN_NUM_OUTPUTS; ++i) | 
		
	
		
			
			|  |  |  | outputs[i] = static_cast<float*>(ioData->mBuffers[i].mData); | 
		
	
		
			
			|  |  |  | #endif | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | else | 
		
	
		
			
			|  |  |  | { | 
		
	
		
			
			|  |  |  | #if DISTRHO_PLUGIN_NUM_INPUTS != 0 | 
		
	
		
			
			|  |  |  | for (uint16_t i=0; i<DISTRHO_PLUGIN_NUM_INPUTS; ++i) | 
		
	
		
			
			|  |  |  | { | 
		
	
		
			
			|  |  |  | if (ioData->mBuffers[i].mData == nullptr) | 
		
	
		
			
			|  |  |  | ioData->mBuffers[i].mData = fAudioBufferList.mBuffers[i].mData; | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | inputs[i] = static_cast<const float*>(ioData->mBuffers[i].mData); | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | #endif | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | #if DISTRHO_PLUGIN_NUM_OUTPUTS != 0 | 
		
	
		
			
			|  |  |  | for (uint16_t i=0; i<DISTRHO_PLUGIN_NUM_OUTPUTS; ++i) | 
		
	
		
			
			|  |  |  | { | 
		
	
		
			
			|  |  |  | if (ioData->mBuffers[i].mData == nullptr) | 
		
	
		
			
			|  |  |  | ioData->mBuffers[i].mData = fAudioBufferList.mBuffers[i].mData; | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | outputs[i] = static_cast<float*>(ioData->mBuffers[i].mData); | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | #endif | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | if (fUsingRenderListeners) | 
		
	
		
			
			|  |  |  | { | 
		
	
		
			
			|  |  |  | AudioUnitRenderActionFlags ioActionFlags = actionFlags | kAudioUnitRenderAction_PreRender; | 
		
	
		
			
			|  |  |  | notifyRenderListeners(&ioActionFlags, inTimeStamp, inBusNumber, inFramesToProcess, ioData); | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | run(inputs, outputs, inFramesToProcess, inTimeStamp); | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | if (ioActionFlags != nullptr) | 
		
	
		
			
			|  |  |  | if (fUsingRenderListeners) | 
		
	
		
			
			|  |  |  | { | 
		
	
		
			
			|  |  |  | // TODO what now? | 
		
	
		
			
			|  |  |  | AudioUnitRenderActionFlags ioActionFlags = actionFlags | kAudioUnitRenderAction_PostRender; | 
		
	
		
			
			|  |  |  | notifyRenderListeners(&ioActionFlags, inTimeStamp, inBusNumber, inFramesToProcess, ioData); | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | return noErr; | 
		
	
	
		
			
				|  |  | @@ -1667,14 +1823,17 @@ private: | 
		
	
		
			
			|  |  |  | // AUv2 related fields | 
		
	
		
			
			|  |  |  | OSStatus fLastRenderError; | 
		
	
		
			
			|  |  |  | PropertyListeners fPropertyListeners; | 
		
	
		
			
			|  |  |  | RenderListeners fRenderListeners; | 
		
	
		
			
			|  |  |  | AURenderCallbackStruct fInputRenderCallback; | 
		
	
		
			
			|  |  |  | Float64 fSampleRateForInput; | 
		
	
		
			
			|  |  |  | #if DISTRHO_PLUGIN_NUM_OUTPUTS != 0 | 
		
	
		
			
			|  |  |  | Float64 fSampleRateForOutput; | 
		
	
		
			
			|  |  |  | #endif | 
		
	
		
			
			|  |  |  | d_AudioBufferList fAudioBufferList; | 
		
	
		
			
			|  |  |  | #if DISTRHO_PLUGIN_NUM_INPUTS + DISTRHO_PLUGIN_NUM_OUTPUTS == 0 | 
		
	
		
			
			|  |  |  | bool fHasWorkingAudio; | 
		
	
		
			
			|  |  |  | #endif | 
		
	
		
			
			|  |  |  | bool fUsingRenderListeners; | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | // Caching | 
		
	
		
			
			|  |  |  | const uint32_t fParameterCount; | 
		
	
	
		
			
				|  |  | @@ -1689,7 +1848,7 @@ private: | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | #if DISTRHO_PLUGIN_WANT_MIDI_OUTPUT | 
		
	
		
			
			|  |  |  | AUMIDIOutputCallbackStruct fMidiOutput; | 
		
	
		
			
			|  |  |  | MIDIPacketList fMidiOutputPackets; | 
		
	
		
			
			|  |  |  | d_MIDIPacketList fMidiOutputPackets; | 
		
	
		
			
			|  |  |  | #endif | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | #if DISTRHO_PLUGIN_WANT_PROGRAMS | 
		
	
	
		
			
				|  |  | @@ -1712,7 +1871,7 @@ private: | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | // ---------------------------------------------------------------------------------------------------------------- | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | void notifyListeners(const AudioUnitPropertyID prop, const AudioUnitScope scope, const AudioUnitElement elem) | 
		
	
		
			
			|  |  |  | void notifyPropertyListeners(const AudioUnitPropertyID prop, const AudioUnitScope scope, const AudioUnitElement elem) | 
		
	
		
			
			|  |  |  | { | 
		
	
		
			
			|  |  |  | for (PropertyListeners::iterator it = fPropertyListeners.begin(); it != fPropertyListeners.end(); ++it) | 
		
	
		
			
			|  |  |  | { | 
		
	
	
		
			
				|  |  | @@ -1723,6 +1882,22 @@ private: | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | void notifyRenderListeners(AudioUnitRenderActionFlags* const ioActionFlags, | 
		
	
		
			
			|  |  |  | const AudioTimeStamp* const inTimeStamp, | 
		
	
		
			
			|  |  |  | const UInt32 inBusNumber, | 
		
	
		
			
			|  |  |  | const UInt32 inNumberFrames, | 
		
	
		
			
			|  |  |  | AudioBufferList* const ioData) | 
		
	
		
			
			|  |  |  | { | 
		
	
		
			
			|  |  |  | for (RenderListeners::iterator it = fRenderListeners.begin(); it != fRenderListeners.end(); ++it) | 
		
	
		
			
			|  |  |  | { | 
		
	
		
			
			|  |  |  | const RenderListener& rl(*it); | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | rl.proc(rl.userData, ioActionFlags, inTimeStamp, inBusNumber, inNumberFrames, ioData); | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | // ---------------------------------------------------------------------------------------------------------------- | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | void run(const float** inputs, float** outputs, const uint32_t frames, const AudioTimeStamp* const inTimeStamp) | 
		
	
		
			
			|  |  |  | { | 
		
	
		
			
			|  |  |  | #if DISTRHO_PLUGIN_WANT_MIDI_INPUT | 
		
	
	
		
			
				|  |  | @@ -1862,7 +2037,7 @@ private: | 
		
	
		
			
			|  |  |  | // TODO flag param only, notify listeners later on bg thread (sem_post etc) | 
		
	
		
			
			|  |  |  | event.mArgument.mParameter.mParameterID = i; | 
		
	
		
			
			|  |  |  | AUEventListenerNotify(NULL, NULL, &event); | 
		
	
		
			
			|  |  |  | notifyListeners('DPFp', kAudioUnitScope_Global, i); | 
		
	
		
			
			|  |  |  | notifyPropertyListeners('DPFp', kAudioUnitScope_Global, i); | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | } | 
		
	
	
		
			
				|  |  | @@ -1873,7 +2048,7 @@ private: | 
		
	
		
			
			|  |  |  | return; | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | fLastRenderError = err; | 
		
	
		
			
			|  |  |  | notifyListeners(kAudioUnitProperty_LastRenderError, kAudioUnitScope_Global, 0); | 
		
	
		
			
			|  |  |  | notifyPropertyListeners(kAudioUnitProperty_LastRenderError, kAudioUnitScope_Global, 0); | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | // ---------------------------------------------------------------------------------------------------------------- | 
		
	
	
		
			
				|  |  | @@ -2063,10 +2238,10 @@ private: | 
		
	
		
			
			|  |  |  | { | 
		
	
		
			
			|  |  |  | fLastFactoryProgram = program; | 
		
	
		
			
			|  |  |  | fPlugin.loadProgram(fLastFactoryProgram); | 
		
	
		
			
			|  |  |  | notifyListeners('DPFo', kAudioUnitScope_Global, 0); | 
		
	
		
			
			|  |  |  | notifyPropertyListeners('DPFo', kAudioUnitScope_Global, 0); | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | notifyListeners(kAudioUnitProperty_PresentPreset, kAudioUnitScope_Global, 0); | 
		
	
		
			
			|  |  |  | notifyPropertyListeners(kAudioUnitProperty_PresentPreset, kAudioUnitScope_Global, 0); | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | #endif | 
		
	
	
		
			
				|  |  | @@ -2124,7 +2299,7 @@ private: | 
		
	
		
			
			|  |  |  | if (fPlugin.getStateKey(j) == key) | 
		
	
		
			
			|  |  |  | { | 
		
	
		
			
			|  |  |  | if ((fPlugin.getStateHints(i) & kStateIsOnlyForDSP) == 0x0) | 
		
	
		
			
			|  |  |  | notifyListeners('DPFs', kAudioUnitScope_Global, j); | 
		
	
		
			
			|  |  |  | notifyPropertyListeners('DPFs', kAudioUnitScope_Global, j); | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | break; | 
		
	
		
			
			|  |  |  | } | 
		
	
	
		
			
				|  |  | @@ -2178,10 +2353,10 @@ private: | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | fLastParameterValues[j] = value; | 
		
	
		
			
			|  |  |  | fPlugin.setParameterValue(j, value); | 
		
	
		
			
			|  |  |  | notifyListeners('DPFp', kAudioUnitScope_Global, j); | 
		
	
		
			
			|  |  |  | notifyPropertyListeners('DPFp', kAudioUnitScope_Global, j); | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | if (fBypassParameterIndex == j) | 
		
	
		
			
			|  |  |  | notifyListeners(kAudioUnitProperty_BypassEffect, kAudioUnitScope_Global, 0); | 
		
	
		
			
			|  |  |  | notifyPropertyListeners(kAudioUnitProperty_BypassEffect, kAudioUnitScope_Global, 0); | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | break; | 
		
	
		
			
			|  |  |  | } | 
		
	
	
		
			
				|  |  | @@ -2230,7 +2405,7 @@ private: | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | fLastParameterValues[index] = value; | 
		
	
		
			
			|  |  |  | AUEventListenerNotify(NULL, NULL, &event); | 
		
	
		
			
			|  |  |  | notifyListeners('DPFp', kAudioUnitScope_Global, index); | 
		
	
		
			
			|  |  |  | notifyPropertyListeners('DPFp', kAudioUnitScope_Global, index); | 
		
	
		
			
			|  |  |  | return true; | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | 
 | 
		
	
	
		
			
				|  |  | @@ -2253,7 +2428,7 @@ private: | 
		
	
		
			
			|  |  |  | fStateMap[dkey] = newValue; | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | if ((fPlugin.getStateHints(i) & kStateIsOnlyForDSP) == 0x0) | 
		
	
		
			
			|  |  |  | notifyListeners('DPFs', kAudioUnitScope_Global, i); | 
		
	
		
			
			|  |  |  | notifyPropertyListeners('DPFs', kAudioUnitScope_Global, i); | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | return true; | 
		
	
		
			
			|  |  |  | } | 
		
	
	
		
			
				|  |  | @@ -2571,10 +2746,15 @@ struct AudioComponentPlugInInstance { | 
		
	
		
			
			|  |  |  | const UInt32 inNumberFrames, | 
		
	
		
			
			|  |  |  | AudioBufferList* const ioData) | 
		
	
		
			
			|  |  |  | { | 
		
	
		
			
			|  |  |  | DISTRHO_SAFE_ASSERT_RETURN(inTimeStamp != nullptr, kAudio_ParamError); | 
		
	
		
			
			|  |  |  | DISTRHO_SAFE_ASSERT_RETURN(ioData != nullptr, kAudio_ParamError); | 
		
	
		
			
			|  |  |  | const AudioUnitRenderActionFlags actionFlags = ioActionFlags != nullptr ? *ioActionFlags : 0; | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | // if ((actionFlags & kAudioUnitRenderAction_DoNotCheckRenderArgs) == 0x0) | 
		
	
		
			
			|  |  |  | { | 
		
	
		
			
			|  |  |  | DISTRHO_SAFE_ASSERT_RETURN(inTimeStamp != nullptr, kAudio_ParamError); | 
		
	
		
			
			|  |  |  | DISTRHO_SAFE_ASSERT_RETURN(ioData != nullptr, kAudio_ParamError); | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | return self->plugin->auRender(ioActionFlags, inTimeStamp, inOutputBusNumber, inNumberFrames, *ioData); | 
		
	
		
			
			|  |  |  | return self->plugin->auRender(actionFlags, inTimeStamp, inOutputBusNumber, inNumberFrames, ioData); | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | #if DISTRHO_PLUGIN_WANT_MIDI_INPUT | 
		
	
	
		
			
				|  |  | 
 |