commit 47c62517069b1d11297c52674377413e522d7fb9
parent 2980483e3a439083631792cdd6bfad4850763cca
Author: falkTX <falktx@falktx.com>
Date: Sun, 25 Feb 2024 10:28:23 +0100
Deal with AU hosts that require 1 input element
Signed-off-by: falkTX <falktx@falktx.com>
Diffstat:
4 files changed, 43 insertions(+), 61 deletions(-)
diff --git a/distrho/src/DistrhoPluginAU.cpp b/distrho/src/DistrhoPluginAU.cpp
@@ -214,12 +214,13 @@ public:
fComponent(component),
fLastRenderError(noErr),
fPropertyListeners(),
- #if DISTRHO_PLUGIN_NUM_INPUTS != 0
fSampleRateForInput(d_nextSampleRate),
- #endif
#if DISTRHO_PLUGIN_NUM_OUTPUTS != 0
fSampleRateForOutput(d_nextSampleRate),
#endif
+ #if DISTRHO_PLUGIN_NUM_INPUTS + DISTRHO_PLUGIN_NUM_OUTPUTS == 0
+ fHasWorkingAudio(false),
+ #endif
fParameterCount(fPlugin.getParameterCount()),
fLastParameterValues(nullptr),
fBypassParameterIndex(UINT32_MAX)
@@ -325,20 +326,16 @@ public:
outWritable = true;
return noErr;
- #if DISTRHO_PLUGIN_NUM_INPUTS + DISTRHO_PLUGIN_NUM_OUTPUTS != 0
case kAudioUnitProperty_SampleRate:
- #if DISTRHO_PLUGIN_NUM_INPUTS != 0 && DISTRHO_PLUGIN_NUM_OUTPUTS != 0
- DISTRHO_SAFE_ASSERT_UINT_RETURN(inScope == kAudioUnitScope_Input || inScope == kAudioUnitScope_Output, inScope, kAudioUnitErr_InvalidScope);
- #elif DISTRHO_PLUGIN_NUM_INPUTS != 0
- DISTRHO_SAFE_ASSERT_UINT_RETURN(inScope == kAudioUnitScope_Input, inScope, kAudioUnitErr_InvalidScope);
- #else
+ #if DISTRHO_PLUGIN_NUM_INPUTS == 0 && DISTRHO_PLUGIN_NUM_OUTPUTS != 0
DISTRHO_SAFE_ASSERT_UINT_RETURN(inScope == kAudioUnitScope_Output, inScope, kAudioUnitErr_InvalidScope);
+ #else
+ DISTRHO_SAFE_ASSERT_UINT_RETURN(inScope == kAudioUnitScope_Input || inScope == kAudioUnitScope_Output, inScope, kAudioUnitErr_InvalidScope);
#endif
DISTRHO_SAFE_ASSERT_UINT_RETURN(inElement == 0, inElement, kAudioUnitErr_InvalidElement);
outDataSize = sizeof(Float64);
outWritable = true;
return noErr;
- #endif
case kAudioUnitProperty_ParameterList:
DISTRHO_SAFE_ASSERT_UINT_RETURN(inElement == 0, inElement, kAudioUnitErr_InvalidElement);
@@ -353,17 +350,14 @@ public:
outWritable = false;
return noErr;
- #if DISTRHO_PLUGIN_NUM_INPUTS + DISTRHO_PLUGIN_NUM_OUTPUTS != 0
case kAudioUnitProperty_StreamFormat:
DISTRHO_SAFE_ASSERT_UINT_RETURN(inElement == 0, inElement, kAudioUnitErr_InvalidElement);
- #if DISTRHO_PLUGIN_NUM_INPUTS != 0
if (inScope == kAudioUnitScope_Input)
{
outDataSize = sizeof(AudioStreamBasicDescription);
outWritable = true;
return noErr;
}
- #endif
#if DISTRHO_PLUGIN_NUM_OUTPUTS != 0
if (inScope == kAudioUnitScope_Output)
{
@@ -373,7 +367,6 @@ public:
}
#endif
return kAudioUnitErr_InvalidScope;
- #endif
case kAudioUnitProperty_ElementCount:
DISTRHO_SAFE_ASSERT_UINT_RETURN(inElement == 0, inElement, kAudioUnitErr_InvalidElement);
@@ -569,10 +562,6 @@ public:
case kAudioUnitProperty_CPULoad:
case kAudioUnitProperty_RenderContextObserver:
case kAudioUnitProperty_TailTime:
- #if DISTRHO_PLUGIN_NUM_INPUTS + DISTRHO_PLUGIN_NUM_OUTPUTS == 0
- case kAudioUnitProperty_SampleRate:
- case kAudioUnitProperty_StreamFormat:
- #endif
DISTRHO_SAFE_ASSERT_UINT_RETURN(inElement == 0, inElement, kAudioUnitErr_InvalidElement);
return kAudioUnitErr_InvalidProperty;
}
@@ -592,15 +581,12 @@ public:
*static_cast<CFPropertyListRef*>(outData) = retrieveClassInfo();
return noErr;
- #if DISTRHO_PLUGIN_NUM_INPUTS + DISTRHO_PLUGIN_NUM_OUTPUTS != 0
case kAudioUnitProperty_SampleRate:
- #if DISTRHO_PLUGIN_NUM_INPUTS != 0
if (inScope == kAudioUnitScope_Input)
{
*static_cast<Float64*>(outData) = fSampleRateForInput;
}
else
- #endif
#if DISTRHO_PLUGIN_NUM_OUTPUTS != 0
if (inScope == kAudioUnitScope_Output)
{
@@ -612,7 +598,6 @@ public:
return kAudioUnitErr_InvalidScope;
}
return noErr;
- #endif
case kAudioUnitProperty_ParameterList:
{
@@ -680,7 +665,6 @@ public:
}
return noErr;
- #if DISTRHO_PLUGIN_NUM_INPUTS + DISTRHO_PLUGIN_NUM_OUTPUTS != 0
case kAudioUnitProperty_StreamFormat:
{
AudioStreamBasicDescription* const desc = static_cast<AudioStreamBasicDescription*>(outData);
@@ -689,13 +673,11 @@ public:
if (inElement != 0)
return kAudioUnitErr_InvalidElement;
- #if DISTRHO_PLUGIN_NUM_INPUTS != 0
if (inScope == kAudioUnitScope_Input)
{
desc->mChannelsPerFrame = DISTRHO_PLUGIN_NUM_INPUTS;
}
else
- #endif
#if DISTRHO_PLUGIN_NUM_OUTPUTS != 0
if (inScope == kAudioUnitScope_Output)
{
@@ -716,7 +698,6 @@ public:
desc->mFramesPerPacket = 1;
}
return noErr;
- #endif
case kAudioUnitProperty_ElementCount:
switch (inScope)
@@ -725,7 +706,8 @@ public:
*static_cast<UInt32*>(outData) = 1;
break;
case kAudioUnitScope_Input:
- *static_cast<UInt32*>(outData) = DISTRHO_PLUGIN_NUM_INPUTS != 0 ? 1 : 0;
+ // FIXME seems to be mandatory for Logic Pro
+ *static_cast<UInt32*>(outData) = 1; // DISTRHO_PLUGIN_NUM_INPUTS != 0 ? 1 : 0;
break;
case kAudioUnitScope_Output:
*static_cast<UInt32*>(outData) = DISTRHO_PLUGIN_NUM_OUTPUTS != 0 ? 1 : 0;
@@ -911,21 +893,17 @@ public:
// TODO
return noErr;
- #if DISTRHO_PLUGIN_NUM_INPUTS + DISTRHO_PLUGIN_NUM_OUTPUTS != 0
case kAudioUnitProperty_SampleRate:
- #if DISTRHO_PLUGIN_NUM_INPUTS != 0 && DISTRHO_PLUGIN_NUM_OUTPUTS != 0
- DISTRHO_SAFE_ASSERT_UINT_RETURN(inScope == kAudioUnitScope_Input || inScope == kAudioUnitScope_Output, inScope, kAudioUnitErr_InvalidScope);
- #elif DISTRHO_PLUGIN_NUM_INPUTS != 0
- DISTRHO_SAFE_ASSERT_UINT_RETURN(inScope == kAudioUnitScope_Input, inScope, kAudioUnitErr_InvalidScope);
- #else
+ #if DISTRHO_PLUGIN_NUM_INPUTS == 0 && DISTRHO_PLUGIN_NUM_OUTPUTS != 0
DISTRHO_SAFE_ASSERT_UINT_RETURN(inScope == kAudioUnitScope_Output, inScope, kAudioUnitErr_InvalidScope);
+ #else
+ DISTRHO_SAFE_ASSERT_UINT_RETURN(inScope == kAudioUnitScope_Input || inScope == kAudioUnitScope_Output, inScope, kAudioUnitErr_InvalidScope);
#endif
DISTRHO_SAFE_ASSERT_UINT_RETURN(inElement == 0, inElement, kAudioUnitErr_InvalidElement);
DISTRHO_SAFE_ASSERT_UINT_RETURN(inDataSize == sizeof(Float64), inDataSize, kAudioUnitErr_InvalidPropertyValue);
{
const Float64 sampleRate = *static_cast<const Float64*>(inData);
- #if DISTRHO_PLUGIN_NUM_INPUTS != 0
if (inScope == kAudioUnitScope_Input)
{
if (d_isNotEqual(fSampleRateForInput, sampleRate))
@@ -944,7 +922,6 @@ public:
}
return noErr;
}
- #endif
#if DISTRHO_PLUGIN_NUM_OUTPUTS != 0
if (inScope == kAudioUnitScope_Output)
@@ -954,9 +931,7 @@ public:
fSampleRateForOutput = sampleRate;
d_nextSampleRate = sampleRate;
- #if DISTRHO_PLUGIN_NUM_INPUTS != 0
if (d_isEqual(fSampleRateForInput, sampleRate))
- #endif
{
fPlugin.setSampleRate(sampleRate, true);
}
@@ -968,16 +943,12 @@ public:
#endif
}
return kAudioUnitErr_InvalidScope;
- #endif
- #if DISTRHO_PLUGIN_NUM_INPUTS + DISTRHO_PLUGIN_NUM_OUTPUTS != 0
case kAudioUnitProperty_StreamFormat:
- #if DISTRHO_PLUGIN_NUM_INPUTS != 0 && DISTRHO_PLUGIN_NUM_OUTPUTS != 0
- DISTRHO_SAFE_ASSERT_UINT_RETURN(inScope == kAudioUnitScope_Input || inScope == kAudioUnitScope_Output, inScope, kAudioUnitErr_InvalidScope);
- #elif DISTRHO_PLUGIN_NUM_INPUTS != 0
- DISTRHO_SAFE_ASSERT_UINT_RETURN(inScope == kAudioUnitScope_Input, inScope, kAudioUnitErr_InvalidScope);
- #else
+ #if DISTRHO_PLUGIN_NUM_INPUTS == 0 && DISTRHO_PLUGIN_NUM_OUTPUTS != 0
DISTRHO_SAFE_ASSERT_UINT_RETURN(inScope == kAudioUnitScope_Output, inScope, kAudioUnitErr_InvalidScope);
+ #else
+ DISTRHO_SAFE_ASSERT_UINT_RETURN(inScope == kAudioUnitScope_Input || inScope == kAudioUnitScope_Output, inScope, kAudioUnitErr_InvalidScope);
#endif
DISTRHO_SAFE_ASSERT_UINT_RETURN(inElement == 0, inElement, kAudioUnitErr_InvalidElement);
DISTRHO_SAFE_ASSERT_UINT_RETURN(inDataSize == sizeof(AudioStreamBasicDescription), inDataSize, kAudioUnitErr_InvalidPropertyValue);
@@ -1008,7 +979,6 @@ public:
: DISTRHO_PLUGIN_NUM_OUTPUTS))
return kAudioUnitErr_FormatNotSupported;
- #if DISTRHO_PLUGIN_NUM_INPUTS != 0
if (inScope == kAudioUnitScope_Input)
{
if (d_isNotEqual(fSampleRateForInput, desc->mSampleRate))
@@ -1025,9 +995,11 @@ public:
notifyListeners(inProp, inScope, inElement);
notifyListeners(kAudioUnitProperty_SampleRate, inScope, inElement);
}
+ #if DISTRHO_PLUGIN_NUM_INPUTS + DISTRHO_PLUGIN_NUM_OUTPUTS == 0
+ fHasWorkingAudio = true;
+ #endif
return noErr;
}
- #endif
#if DISTRHO_PLUGIN_NUM_OUTPUTS != 0
if (inScope == kAudioUnitScope_Output)
@@ -1036,9 +1008,7 @@ public:
{
fSampleRateForOutput = desc->mSampleRate;
- #if DISTRHO_PLUGIN_NUM_INPUTS != 0
if (d_isEqual(fSampleRateForInput, desc->mSampleRate))
- #endif
{
fPlugin.setSampleRate(desc->mSampleRate, true);
}
@@ -1051,7 +1021,6 @@ public:
#endif
}
return kAudioUnitErr_InvalidScope;
- #endif
case kAudioUnitProperty_MaximumFramesPerSlice:
DISTRHO_SAFE_ASSERT_UINT_RETURN(inScope == kAudioUnitScope_Global, inScope, kAudioUnitErr_InvalidScope);
@@ -1499,8 +1468,9 @@ public:
}
#if DISTRHO_PLUGIN_NUM_INPUTS + DISTRHO_PLUGIN_NUM_OUTPUTS == 0
- // if plugin has no audio, assume render function is not going to be called
- run(nullptr, nullptr, std::max(1u, inOffsetSampleFrame), nullptr);
+ // handle case of plugin having no working audio, simulate audio-side processing
+ if (! fHasWorkingAudio)
+ run(nullptr, nullptr, std::max(1u, inOffsetSampleFrame), nullptr);
#endif
return noErr;
@@ -1527,8 +1497,9 @@ public:
}
#if DISTRHO_PLUGIN_NUM_INPUTS + DISTRHO_PLUGIN_NUM_OUTPUTS == 0
- // if plugin has no audio, assume render function is not going to be called
- run(nullptr, nullptr, 1, nullptr);
+ // handle case of plugin having no working audio, simulate audio-side processing
+ if (! fHasWorkingAudio)
+ run(nullptr, nullptr, 1, nullptr);
#endif
return noErr;
@@ -1547,12 +1518,13 @@ private:
AUPreset fCurrentPreset;
OSStatus fLastRenderError;
PropertyListeners fPropertyListeners;
- #if DISTRHO_PLUGIN_NUM_INPUTS != 0
Float64 fSampleRateForInput;
- #endif
#if DISTRHO_PLUGIN_NUM_OUTPUTS != 0
Float64 fSampleRateForOutput;
#endif
+ #if DISTRHO_PLUGIN_NUM_INPUTS + DISTRHO_PLUGIN_NUM_OUTPUTS == 0
+ bool fHasWorkingAudio;
+ #endif
// Caching
const uint32_t fParameterCount;
diff --git a/distrho/src/DistrhoUIAU.mm b/distrho/src/DistrhoUIAU.mm
@@ -448,21 +448,25 @@ END_NAMESPACE_DISTRHO
{
Float64 sampleRate = d_nextSampleRate;
void* instancePointer = nullptr;
+ AudioUnitScope scope;
UInt32 dataSize;
+ // fetch direct access pointer
#if DISTRHO_PLUGIN_WANT_DIRECT_ACCESS
dataSize = sizeof(void*);
AudioUnitGetProperty(component, 'DPFa', kAudioUnitScope_Global, 0, &instancePointer, &dataSize);
#endif
- #if DISTRHO_PLUGIN_NUM_INPUTS != 0
- dataSize = sizeof(Float64);
- AudioUnitGetProperty(component, kAudioUnitProperty_SampleRate, kAudioUnitScope_Input, 0, &sampleRate, &dataSize);
- #elif DISTRHO_PLUGIN_NUM_INPUTS != 0
+ // fetch current sample rate
+ #if DISTRHO_PLUGIN_NUM_OUTPUTS != 0
+ scope = kAudioUnitScope_Output;
+ #else
+ scope = kAudioUnitScope_Input;
+ #endif
dataSize = sizeof(Float64);
AudioUnitGetProperty(component, kAudioUnitProperty_SampleRate, kAudioUnitScope_Output, 0, &sampleRate, &dataSize);
- #endif
+ // create view
view = [[[COCOA_VIEW_CLASS_NAME alloc] initWithPreferredSize:inPreferredSize] autorelease];
view->ui = new DPF_UI_AU(component, view, sampleRate, instancePointer);
view->ui->postSetup();
diff --git a/distrho/src/DistrhoUIDSSI.cpp b/distrho/src/DistrhoUIDSSI.cpp
@@ -32,6 +32,9 @@ START_NAMESPACE_DISTRHO
static constexpr const sendNoteFunc sendNoteCallback = nullptr;
#endif
+// unused in DSSI, we only use external and standalone UIs
+static constexpr const setSizeFunc setSizeCallback = nullptr;
+
// unsupported in DSSI
static constexpr const fileRequestFunc fileRequestCallback = nullptr;
@@ -104,7 +107,7 @@ class UIDssi : public DGL_NAMESPACE::IdleCallback
public:
UIDssi(const OscData& oscData, const char* const uiTitle, const double sampleRate)
: fUI(this, 0, sampleRate, nullptr,
- setParameterCallback, setStateCallback, sendNoteCallback, fileRequestCallback, nullptr),
+ setParameterCallback, setStateCallback, sendNoteCallback, setSizeCallback, fileRequestCallback),
fHostClosed(false),
fOscData(oscData)
{
diff --git a/distrho/src/DistrhoUILV2.cpp b/distrho/src/DistrhoUILV2.cpp
@@ -49,6 +49,9 @@ static constexpr const setStateFunc setStateCallback = nullptr;
static constexpr const sendNoteFunc sendNoteCallback = nullptr;
#endif
+// unwanted in LV2, resize extension is deprecated and hosts can do it without extensions
+static constexpr const setSizeFunc setSizeCallback = nullptr;
+
// -----------------------------------------------------------------------
template <class LV2F>
@@ -96,7 +99,7 @@ public:
setParameterCallback,
setStateCallback,
sendNoteCallback,
- nullptr, // resize is very messy, hosts can do it without extensions
+ setSizeCallback,
fileRequestCallback,
bundlePath, dspPtr, scaleFactor, bgColor, fgColor, appClassName)
{