Browse Source

Deal with more AU audio rendering details

Signed-off-by: falkTX <falktx@falktx.com>
pull/452/head
falkTX 1 year ago
parent
commit
19cb24186b
Signed by: falkTX <falktx@falktx.com> GPG Key ID: CDBAA37ABC74FBA0
1 changed files with 248 additions and 68 deletions
  1. +248
    -68
      distrho/src/DistrhoPluginAU.cpp

+ 248
- 68
distrho/src/DistrhoPluginAU.cpp View File

@@ -200,14 +200,33 @@ struct PropertyListener {
void* userData; void* userData;
}; };


struct RenderListener {
AURenderCallback proc;
void* userData;
};

typedef std::vector<PropertyListener> PropertyListeners; 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 { typedef struct {
UInt32 numPackets; UInt32 numPackets;
MIDIPacket packets[kMaxMidiEvents]; MIDIPacket packets[kMaxMidiEvents];
} MIDIPacketList;
} d_MIDIPacketList;


// -------------------------------------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------------------------------------


@@ -233,6 +252,7 @@ public:
fComponent(component), fComponent(component),
fLastRenderError(noErr), fLastRenderError(noErr),
fPropertyListeners(), fPropertyListeners(),
fRenderListeners(),
fSampleRateForInput(d_nextSampleRate), fSampleRateForInput(d_nextSampleRate),
#if DISTRHO_PLUGIN_NUM_OUTPUTS != 0 #if DISTRHO_PLUGIN_NUM_OUTPUTS != 0
fSampleRateForOutput(d_nextSampleRate), fSampleRateForOutput(d_nextSampleRate),
@@ -240,6 +260,7 @@ public:
#if DISTRHO_PLUGIN_NUM_INPUTS + DISTRHO_PLUGIN_NUM_OUTPUTS == 0 #if DISTRHO_PLUGIN_NUM_INPUTS + DISTRHO_PLUGIN_NUM_OUTPUTS == 0
fHasWorkingAudio(false), fHasWorkingAudio(false),
#endif #endif
fUsingRenderListeners(false),
fParameterCount(fPlugin.getParameterCount()), fParameterCount(fPlugin.getParameterCount()),
fLastParameterValues(nullptr), fLastParameterValues(nullptr),
fBypassParameterIndex(UINT32_MAX) fBypassParameterIndex(UINT32_MAX)
@@ -256,6 +277,8 @@ public:
, fStateCount(fPlugin.getStateCount()) , fStateCount(fPlugin.getStateCount())
#endif #endif
{ {
const uint32_t bufferSize = fPlugin.getBufferSize();

if (fParameterCount != 0) if (fParameterCount != 0)
{ {
fLastParameterValues = new float[fParameterCount]; fLastParameterValues = new float[fParameterCount];
@@ -274,6 +297,15 @@ public:
fInputRenderCallback.inputProc = nullptr; fInputRenderCallback.inputProc = nullptr;
fInputRenderCallback.inputProcRefCon = 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 #if DISTRHO_PLUGIN_WANT_MIDI_INPUT
std::memset(&fMidiEvents, 0, sizeof(fMidiEvents)); std::memset(&fMidiEvents, 0, sizeof(fMidiEvents));
#endif #endif
@@ -331,6 +363,9 @@ public:
delete[] fLastParameterValues; delete[] fLastParameterValues;
CFRelease(fUserPresetData.presetName); 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 #if DISTRHO_PLUGIN_WANT_PROGRAMS
for (uint32_t i=0; i<fProgramCount; ++i) for (uint32_t i=0; i<fProgramCount; ++i)
CFRelease(fFactoryPresetsData[i].presetName); CFRelease(fFactoryPresetsData[i].presetName);
@@ -1037,7 +1072,7 @@ public:
fPlugin.setSampleRate(sampleRate, true); fPlugin.setSampleRate(sampleRate, true);
} }


notifyListeners(inProp, inScope, inElement);
notifyPropertyListeners(inProp, inScope, inElement);
} }
return noErr; return noErr;
} }
@@ -1055,7 +1090,7 @@ public:
fPlugin.setSampleRate(sampleRate, true); fPlugin.setSampleRate(sampleRate, true);
} }


notifyListeners(inProp, inScope, inElement);
notifyPropertyListeners(inProp, inScope, inElement);
} }
return noErr; return noErr;
} }
@@ -1111,8 +1146,8 @@ public:
fPlugin.setSampleRate(desc->mSampleRate, true); 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 #if DISTRHO_PLUGIN_NUM_INPUTS + DISTRHO_PLUGIN_NUM_OUTPUTS == 0
fHasWorkingAudio = true; fHasWorkingAudio = true;
@@ -1132,8 +1167,8 @@ public:
fPlugin.setSampleRate(desc->mSampleRate, true); 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; return noErr;
} }
@@ -1145,10 +1180,23 @@ public:
DISTRHO_SAFE_ASSERT_UINT_RETURN(inScope == kAudioUnitScope_Global, inScope, kAudioUnitErr_InvalidScope); 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(inElement == 0, inElement, kAudioUnitErr_InvalidElement);
DISTRHO_SAFE_ASSERT_UINT_RETURN(inDataSize == sizeof(UInt32), inDataSize, kAudioUnitErr_InvalidPropertyValue); 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; return noErr;


case kAudioUnitProperty_BypassEffect: case kAudioUnitProperty_BypassEffect:
@@ -1164,7 +1212,7 @@ public:
const float value = bypass ? 1.f : 0.f; const float value = bypass ? 1.f : 0.f;
fLastParameterValues[fBypassParameterIndex] = value; fLastParameterValues[fBypassParameterIndex] = value;
fPlugin.setParameterValue(fBypassParameterIndex, value); fPlugin.setParameterValue(fBypassParameterIndex, value);
notifyListeners(inProp, inScope, inElement);
notifyPropertyListeners(inProp, inScope, inElement);
} }
} }
return noErr; return noErr;
@@ -1190,7 +1238,7 @@ public:
std::memset(&fHostCallbackInfo + usableDataSize, 0, sizeof(HostCallbackInfo) - usableDataSize); std::memset(&fHostCallbackInfo + usableDataSize, 0, sizeof(HostCallbackInfo) - usableDataSize);


if (changed) if (changed)
notifyListeners(inProp, inScope, inElement);
notifyPropertyListeners(inProp, inScope, inElement);
} }
return noErr; return noErr;
#else #else
@@ -1212,7 +1260,7 @@ public:
fCurrentProgram = presetNumber; fCurrentProgram = presetNumber;
fLastFactoryProgram = presetNumber; fLastFactoryProgram = presetNumber;
fPlugin.loadProgram(fLastFactoryProgram); fPlugin.loadProgram(fLastFactoryProgram);
notifyListeners('DPFo', kAudioUnitScope_Global, 0);
notifyPropertyListeners('DPFo', kAudioUnitScope_Global, 0);
} }
} }
else else
@@ -1251,16 +1299,16 @@ public:
return noErr; return noErr;


#if DISTRHO_PLUGIN_WANT_PROGRAMS #if DISTRHO_PLUGIN_WANT_PROGRAMS
notifyListeners('DPFo', kAudioUnitScope_Global, 0);
notifyPropertyListeners('DPFo', kAudioUnitScope_Global, 0);
#endif #endif


#if DISTRHO_PLUGIN_WANT_STATE #if DISTRHO_PLUGIN_WANT_STATE
for (uint32_t i=0; i<fStateCount; ++i) for (uint32_t i=0; i<fStateCount; ++i)
notifyListeners('DPFs', kAudioUnitScope_Global, i);
notifyPropertyListeners('DPFs', kAudioUnitScope_Global, i);
#endif #endif


for (uint32_t i=0; i<fParameterCount; ++i) for (uint32_t i=0; i<fParameterCount; ++i)
notifyListeners('DPFp', kAudioUnitScope_Global, i);
notifyPropertyListeners('DPFp', kAudioUnitScope_Global, i);
} }
return noErr; return noErr;


@@ -1310,7 +1358,7 @@ public:
AUEventListenerNotify(NULL, NULL, &event); AUEventListenerNotify(NULL, NULL, &event);


if (fBypassParameterIndex == inElement) if (fBypassParameterIndex == inElement)
notifyListeners(kAudioUnitProperty_BypassEffect, kAudioUnitScope_Global, 0);
notifyPropertyListeners(kAudioUnitProperty_BypassEffect, kAudioUnitScope_Global, 0);
} }
return noErr; return noErr;


@@ -1382,9 +1430,6 @@ public:
prop, proc, userData prop, proc, userData
}; };


if (fPropertyListeners.empty())
fPropertyListeners.reserve(32);

fPropertyListeners.push_back(pl); fPropertyListeners.push_back(pl);
return noErr; return noErr;
} }
@@ -1425,15 +1470,29 @@ public:


OSStatus auAddRenderNotify(const AURenderCallback proc, void* const userData) 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; return noErr;
} }


OSStatus auRemoveRenderNotify(const AURenderCallback proc, void* const userData) 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; return noErr;
} }


@@ -1468,10 +1527,10 @@ public:
fPlugin.setParameterValue(param, value); fPlugin.setParameterValue(param, value);


// TODO flag param only, notify listeners later on bg thread (sem_post etc) // 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) if (fBypassParameterIndex == elem)
notifyListeners(kAudioUnitProperty_BypassEffect, kAudioUnitScope_Global, 0);
notifyPropertyListeners(kAudioUnitProperty_BypassEffect, kAudioUnitScope_Global, 0);
} }


return noErr; return noErr;
@@ -1523,61 +1582,158 @@ public:
return noErr; return noErr;
} }


OSStatus auRender(AudioUnitRenderActionFlags* const ioActionFlags,
OSStatus auRender(const AudioUnitRenderActionFlags actionFlags,
const AudioTimeStamp* const inTimeStamp, const AudioTimeStamp* const inTimeStamp,
const UInt32 inBusNumber, const UInt32 inBusNumber,
const UInt32 inFramesToProcess, 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 #if DISTRHO_PLUGIN_NUM_INPUTS != 0
const float* inputs[DISTRHO_PLUGIN_NUM_INPUTS]; 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 #else
constexpr const float** inputs = nullptr; constexpr const float** inputs = nullptr;
#endif #endif


#if DISTRHO_PLUGIN_NUM_OUTPUTS != 0 #if DISTRHO_PLUGIN_NUM_OUTPUTS != 0
float* outputs[DISTRHO_PLUGIN_NUM_OUTPUTS]; 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 #else
constexpr float** outputs = nullptr; constexpr float** outputs = nullptr;
#endif #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); 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; return noErr;
@@ -1667,14 +1823,17 @@ private:
// AUv2 related fields // AUv2 related fields
OSStatus fLastRenderError; OSStatus fLastRenderError;
PropertyListeners fPropertyListeners; PropertyListeners fPropertyListeners;
RenderListeners fRenderListeners;
AURenderCallbackStruct fInputRenderCallback; AURenderCallbackStruct fInputRenderCallback;
Float64 fSampleRateForInput; Float64 fSampleRateForInput;
#if DISTRHO_PLUGIN_NUM_OUTPUTS != 0 #if DISTRHO_PLUGIN_NUM_OUTPUTS != 0
Float64 fSampleRateForOutput; Float64 fSampleRateForOutput;
#endif #endif
d_AudioBufferList fAudioBufferList;
#if DISTRHO_PLUGIN_NUM_INPUTS + DISTRHO_PLUGIN_NUM_OUTPUTS == 0 #if DISTRHO_PLUGIN_NUM_INPUTS + DISTRHO_PLUGIN_NUM_OUTPUTS == 0
bool fHasWorkingAudio; bool fHasWorkingAudio;
#endif #endif
bool fUsingRenderListeners;


// Caching // Caching
const uint32_t fParameterCount; const uint32_t fParameterCount;
@@ -1689,7 +1848,7 @@ private:


#if DISTRHO_PLUGIN_WANT_MIDI_OUTPUT #if DISTRHO_PLUGIN_WANT_MIDI_OUTPUT
AUMIDIOutputCallbackStruct fMidiOutput; AUMIDIOutputCallbackStruct fMidiOutput;
MIDIPacketList fMidiOutputPackets;
d_MIDIPacketList fMidiOutputPackets;
#endif #endif


#if DISTRHO_PLUGIN_WANT_PROGRAMS #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) 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) void run(const float** inputs, float** outputs, const uint32_t frames, const AudioTimeStamp* const inTimeStamp)
{ {
#if DISTRHO_PLUGIN_WANT_MIDI_INPUT #if DISTRHO_PLUGIN_WANT_MIDI_INPUT
@@ -1862,7 +2037,7 @@ private:
// TODO flag param only, notify listeners later on bg thread (sem_post etc) // TODO flag param only, notify listeners later on bg thread (sem_post etc)
event.mArgument.mParameter.mParameterID = i; event.mArgument.mParameter.mParameterID = i;
AUEventListenerNotify(NULL, NULL, &event); AUEventListenerNotify(NULL, NULL, &event);
notifyListeners('DPFp', kAudioUnitScope_Global, i);
notifyPropertyListeners('DPFp', kAudioUnitScope_Global, i);
} }
} }
} }
@@ -1873,7 +2048,7 @@ private:
return; return;


fLastRenderError = err; fLastRenderError = err;
notifyListeners(kAudioUnitProperty_LastRenderError, kAudioUnitScope_Global, 0);
notifyPropertyListeners(kAudioUnitProperty_LastRenderError, kAudioUnitScope_Global, 0);
} }


// ---------------------------------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------------------------------
@@ -2063,10 +2238,10 @@ private:
{ {
fLastFactoryProgram = program; fLastFactoryProgram = program;
fPlugin.loadProgram(fLastFactoryProgram); 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 #endif
@@ -2124,7 +2299,7 @@ private:
if (fPlugin.getStateKey(j) == key) if (fPlugin.getStateKey(j) == key)
{ {
if ((fPlugin.getStateHints(i) & kStateIsOnlyForDSP) == 0x0) if ((fPlugin.getStateHints(i) & kStateIsOnlyForDSP) == 0x0)
notifyListeners('DPFs', kAudioUnitScope_Global, j);
notifyPropertyListeners('DPFs', kAudioUnitScope_Global, j);


break; break;
} }
@@ -2178,10 +2353,10 @@ private:


fLastParameterValues[j] = value; fLastParameterValues[j] = value;
fPlugin.setParameterValue(j, value); fPlugin.setParameterValue(j, value);
notifyListeners('DPFp', kAudioUnitScope_Global, j);
notifyPropertyListeners('DPFp', kAudioUnitScope_Global, j);


if (fBypassParameterIndex == j) if (fBypassParameterIndex == j)
notifyListeners(kAudioUnitProperty_BypassEffect, kAudioUnitScope_Global, 0);
notifyPropertyListeners(kAudioUnitProperty_BypassEffect, kAudioUnitScope_Global, 0);


break; break;
} }
@@ -2230,7 +2405,7 @@ private:


fLastParameterValues[index] = value; fLastParameterValues[index] = value;
AUEventListenerNotify(NULL, NULL, &event); AUEventListenerNotify(NULL, NULL, &event);
notifyListeners('DPFp', kAudioUnitScope_Global, index);
notifyPropertyListeners('DPFp', kAudioUnitScope_Global, index);
return true; return true;
} }


@@ -2253,7 +2428,7 @@ private:
fStateMap[dkey] = newValue; fStateMap[dkey] = newValue;


if ((fPlugin.getStateHints(i) & kStateIsOnlyForDSP) == 0x0) if ((fPlugin.getStateHints(i) & kStateIsOnlyForDSP) == 0x0)
notifyListeners('DPFs', kAudioUnitScope_Global, i);
notifyPropertyListeners('DPFs', kAudioUnitScope_Global, i);


return true; return true;
} }
@@ -2571,10 +2746,15 @@ struct AudioComponentPlugInInstance {
const UInt32 inNumberFrames, const UInt32 inNumberFrames,
AudioBufferList* const ioData) 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 #if DISTRHO_PLUGIN_WANT_MIDI_INPUT


Loading…
Cancel
Save