DPF

DISTRHO Plugin Framework
Log | Files | Refs | Submodules | README | LICENSE

commit cff94b659c5e8de0f2ff8fd59d53663e3d46cfa2
parent 6d669870db308b61eacb2e932943b20f994e902c
Author: falkTX <falktx@falktx.com>
Date:   Mon, 19 Feb 2024 12:12:23 +0100

Setup more stubs, pass early validation

Signed-off-by: falkTX <falktx@falktx.com>

Diffstat:
Mdistrho/src/DistrhoPluginAU.cpp | 278+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----------
1 file changed, 243 insertions(+), 35 deletions(-)

diff --git a/distrho/src/DistrhoPluginAU.cpp b/distrho/src/DistrhoPluginAU.cpp @@ -16,7 +16,12 @@ #include "DistrhoPluginInternal.hpp" -// #define CA_NO_AU_UI_FEATURES +// #define CA_BASIC_AU_FEATURES 1 +#define CA_NO_AU_UI_FEATURES 1 +#define CA_USE_AUDIO_PLUGIN_ONLY 1 +#define TARGET_OS_MAC 1 + +#include <AudioUnit/AudioUnit.h> #define TRACE d_stderr("////////--------------------------------------------------------------- %s %d", __PRETTY_FUNCTION__, __LINE__); @@ -60,22 +65,208 @@ class PluginHolder public: PluginExporter fPlugin; + #if DISTRHO_PLUGIN_NUM_INPUTS+DISTRHO_PLUGIN_NUM_OUTPUTS != 0 + struct BusInfo { + char name[32]; + uint32_t numChannels; + bool hasPair; + bool isCV; + bool isMain; + uint32_t groupId; + }; + std::vector<BusInfo> fAudioInputBuses, fAudioOutputBuses; + bool fUsingCV; + #endif + PluginHolder() - : fPlugin(this, writeMidiCallback, requestParameterValueChangeCallback, updateStateValueCallback) {} + : fPlugin(this, writeMidiCallback, requestParameterValueChangeCallback, updateStateValueCallback) + #if DISTRHO_PLUGIN_NUM_INPUTS+DISTRHO_PLUGIN_NUM_OUTPUTS != 0 + , fAudioInputBuses() + , fAudioOutputBuses() + , fUsingCV(false) + #endif + { + #if DISTRHO_PLUGIN_NUM_INPUTS != 0 + fillInBusInfoDetails<true>(); + #endif + #if DISTRHO_PLUGIN_NUM_OUTPUTS != 0 + fillInBusInfoDetails<false>(); + #endif + #if DISTRHO_PLUGIN_NUM_INPUTS != 0 && DISTRHO_PLUGIN_NUM_OUTPUTS != 0 + fillInBusInfoPairs(); + #endif + } - virtual ~PluginHolder() {} + // virtual ~PluginHolder() {} protected: uint32_t getPluginBusCount(const bool isInput) noexcept { + #if DISTRHO_PLUGIN_NUM_INPUTS != 0 + if (isInput) + return fAudioInputBuses.size(); + #endif + #if DISTRHO_PLUGIN_NUM_OUTPUTS != 0 + if (!isInput) + return fAudioOutputBuses.size(); + #endif return 0; } private: + #if DISTRHO_PLUGIN_NUM_INPUTS+DISTRHO_PLUGIN_NUM_OUTPUTS != 0 + template<bool isInput> + void fillInBusInfoDetails() + { + constexpr const uint32_t numPorts = isInput ? DISTRHO_PLUGIN_NUM_INPUTS : DISTRHO_PLUGIN_NUM_OUTPUTS; + std::vector<BusInfo>& busInfos(isInput ? fAudioInputBuses : fAudioOutputBuses); + + enum { + kPortTypeNull, + kPortTypeAudio, + kPortTypeSidechain, + kPortTypeCV, + kPortTypeGroup + } lastSeenPortType = kPortTypeNull; + uint32_t lastSeenGroupId = kPortGroupNone; + uint32_t nonGroupAudioId = 0; + uint32_t nonGroupSidechainId = 0x20000000; + + for (uint32_t i=0; i<numPorts; ++i) + { + const AudioPortWithBusId& port(fPlugin.getAudioPort(isInput, i)); + + if (port.groupId != kPortGroupNone) + { + if (lastSeenPortType != kPortTypeGroup || lastSeenGroupId != port.groupId) + { + lastSeenPortType = kPortTypeGroup; + lastSeenGroupId = port.groupId; + + BusInfo busInfo = { + {}, 1, false, false, + // if this is the first port, set it as main + busInfos.empty(), + // user given group id with extra safety offset + port.groupId + 0x80000000 + }; + + const PortGroupWithId& group(fPlugin.getPortGroupById(port.groupId)); + + switch (port.groupId) + { + case kPortGroupStereo: + case kPortGroupMono: + if (busInfo.isMain) + { + d_strncpy(busInfo.name, isInput ? "Audio Input" : "Audio Output", 32); + break; + } + // fall-through + default: + if (group.name.isNotEmpty()) + d_strncpy(busInfo.name, group.name, 32); + else + d_strncpy(busInfo.name, port.name, 32); + break; + } + + busInfos.push_back(busInfo); + } + else + { + ++busInfos.back().numChannels; + } + } + else if (port.hints & kAudioPortIsCV) + { + // TODO + lastSeenPortType = kPortTypeCV; + lastSeenGroupId = kPortGroupNone; + fUsingCV = true; + } + else if (port.hints & kAudioPortIsSidechain) + { + if (lastSeenPortType != kPortTypeSidechain) + { + lastSeenPortType = kPortTypeSidechain; + lastSeenGroupId = kPortGroupNone; + + BusInfo busInfo = { + {}, 1, false, false, + // not main + false, + // give unique id + nonGroupSidechainId++ + }; + + d_strncpy(busInfo.name, port.name, 32); + + busInfos.push_back(busInfo); + } + else + { + ++busInfos.back().numChannels; + } + } + else + { + if (lastSeenPortType != kPortTypeAudio) + { + lastSeenPortType = kPortTypeAudio; + lastSeenGroupId = kPortGroupNone; + + BusInfo busInfo = { + {}, 1, false, false, + // if this is the first port, set it as main + busInfos.empty(), + // give unique id + nonGroupAudioId++ + }; + + if (busInfo.isMain) + { + d_strncpy(busInfo.name, isInput ? "Audio Input" : "Audio Output", 32); + } + else + { + d_strncpy(busInfo.name, port.name, 32); + } + + busInfos.push_back(busInfo); + } + else + { + ++busInfos.back().numChannels; + } + } + } + } + #endif + + #if DISTRHO_PLUGIN_NUM_INPUTS != 0 && DISTRHO_PLUGIN_NUM_OUTPUTS != 0 + void fillInBusInfoPairs() + { + const size_t numSharedBuses = std::min(fAudioInputBuses.size(), fAudioOutputBuses.size()); + + for (size_t i=0; i<numSharedBuses; ++i) + { + if (fAudioInputBuses[i].groupId != fAudioOutputBuses[i].groupId) + break; + if (fAudioInputBuses[i].numChannels != fAudioOutputBuses[i].numChannels) + break; + if (fAudioInputBuses[i].isMain != fAudioOutputBuses[i].isMain) + break; + + fAudioInputBuses[i].hasPair = fAudioOutputBuses[i].hasPair = true; + } + } + #endif + // ---------------------------------------------------------------------------------------------------------------- // DPF callbacks - #if DISTRHO_PLUGIN_WANT_MIDI_OUTPUT + #if DISTRHO_PLUGIN_WANT_MIDI_OUTPUT && 0 bool writeMidi(const MidiEvent&) { return true; @@ -88,7 +279,7 @@ private: #endif - #if DISTRHO_PLUGIN_WANT_PARAMETER_VALUE_CHANGE_REQUEST + #if DISTRHO_PLUGIN_WANT_PARAMETER_VALUE_CHANGE_REQUEST && 0 bool requestParameterValueChange(uint32_t, float) { return true; @@ -100,7 +291,7 @@ private: } #endif - #if DISTRHO_PLUGIN_WANT_STATE + #if DISTRHO_PLUGIN_WANT_STATE && 0 bool updateState(const char*, const char*) { return true; @@ -130,7 +321,8 @@ public: } protected: - ComponentResult Initialize() override +#if 0 + OSStatus Initialize() override { TRACE ComponentResult res; @@ -145,17 +337,18 @@ protected: void Cleanup() override { TRACE - PluginBase::Cleanup(); fPlugin.deactivate(); + PluginBase::Cleanup(); } +#endif - ComponentResult Reset(AudioUnitScope inScope, AudioUnitElement inElement) override + OSStatus Reset(AudioUnitScope inScope, AudioUnitElement inElement) override { TRACE fPlugin.deactivateIfNeeded(); setBufferSizeAndSampleRate(); - const ComponentResult res = PluginBase::Reset(inScope, inElement); + const OSStatus res = PluginBase::Reset(inScope, inElement); if (res == noErr) fPlugin.activate(); @@ -163,17 +356,18 @@ protected: return res; } - ComponentResult GetPropertyInfo(AudioUnitPropertyID inID, - AudioUnitScope inScope, - AudioUnitElement inElement, - UInt32& outDataSize, - Boolean& outWritable) override +#if 0 + OSStatus GetPropertyInfo(AudioUnitPropertyID inID, + AudioUnitScope inScope, + AudioUnitElement inElement, + UInt32& outDataSize, + Boolean& outWritable) override { TRACE return PluginBase::GetPropertyInfo(inID, inScope, inElement, outDataSize, outWritable); } - ComponentResult GetProperty(AudioUnitPropertyID inID, + OSStatus GetProperty(AudioUnitPropertyID inID, AudioUnitScope inScope, AudioUnitElement inElement, void* outData) override @@ -182,7 +376,7 @@ protected: return PluginBase::GetProperty(inID, inScope, inElement, outData); } - ComponentResult SetProperty(AudioUnitPropertyID inID, + OSStatus SetProperty(AudioUnitPropertyID inID, AudioUnitScope inScope, AudioUnitElement inElement, const void* inData, @@ -192,7 +386,7 @@ protected: return PluginBase::SetProperty(inID, inScope, inElement, inData, inDataSize); } - ComponentResult GetParameter(AudioUnitParameterID inID, + OSStatus GetParameter(AudioUnitParameterID inID, AudioUnitScope inScope, AudioUnitElement inElement, Float32& outValue) override @@ -202,7 +396,7 @@ protected: // return PluginBase::GetParameter(inID, inScope, inElement, outValue); } - ComponentResult SetParameter(AudioUnitParameterID inID, + OSStatus SetParameter(AudioUnitParameterID inID, AudioUnitScope inScope, AudioUnitElement inElement, Float32 inValue, @@ -212,6 +406,7 @@ protected: return kAudioUnitErr_InvalidProperty; // return PluginBase::SetParameter(inID, inScope, inElement, inValue, inBufferOffsetInFrames); } +#endif bool CanScheduleParameters() const override { @@ -219,14 +414,15 @@ protected: return false; } - ComponentResult Render(AudioUnitRenderActionFlags& ioActionFlags, - const AudioTimeStamp& inTimeStamp, - const UInt32 nFrames) override + OSStatus Render(AudioUnitRenderActionFlags& ioActionFlags, + const AudioTimeStamp& inTimeStamp, + const UInt32 nFrames) override { TRACE return noErr; } +#if 0 bool BusCountWritable(AudioUnitScope scope) override { TRACE @@ -239,7 +435,7 @@ protected: return noErr; } - ComponentResult GetParameterInfo(AudioUnitScope inScope, + OSStatus GetParameterInfo(AudioUnitScope inScope, AudioUnitParameterID inParameterID, AudioUnitParameterInfo& outParameterInfo) override { @@ -247,19 +443,19 @@ protected: return kAudioUnitErr_InvalidProperty; } - ComponentResult SaveState(CFPropertyListRef* outData) override + OSStatus SaveState(CFPropertyListRef* outData) override { TRACE return PluginBase::SaveState(outData); } - ComponentResult RestoreState(CFPropertyListRef inData) override + OSStatus RestoreState(CFPropertyListRef inData) override { TRACE return noErr; } - ComponentResult GetParameterValueStrings(AudioUnitScope inScope, + OSStatus GetParameterValueStrings(AudioUnitScope inScope, AudioUnitParameterID inParameterID, CFArrayRef *outStrings) override { @@ -267,7 +463,7 @@ protected: return kAudioUnitErr_InvalidProperty; } - ComponentResult GetPresets(CFArrayRef* outData) const override + OSStatus GetPresets(CFArrayRef* outData) const override { TRACE return noErr; @@ -278,6 +474,7 @@ protected: TRACE return noErr; } +#endif #if DISTRHO_PLUGIN_WANT_LATENCY Float64 GetLatency() override @@ -293,12 +490,18 @@ protected: return false; } - UInt32 SupportedNumChannels(const AUChannelInfo** outInfo) override + UInt32 SupportedNumChannels(const AUChannelInfo** const outInfo) override { TRACE - return 0; + static const AUChannelInfo sChannels[1] = {{ DISTRHO_PLUGIN_NUM_INPUTS, DISTRHO_PLUGIN_NUM_OUTPUTS }}; + + if (outInfo != nullptr) + *outInfo = sChannels; + + return 1; } +#if 0 bool ValidFormat(AudioUnitScope scope, AudioUnitElement element, const CAStreamBasicDescription& format) override { TRACE @@ -311,19 +514,21 @@ protected: return noErr; } - ComponentResult StartNote(MusicDeviceInstrumentID, MusicDeviceGroupID, NoteInstanceID*, UInt32, const MusicDeviceNoteParams&) override + OSStatus StartNote(MusicDeviceInstrumentID, MusicDeviceGroupID, NoteInstanceID*, UInt32, const MusicDeviceNoteParams&) override { TRACE return noErr; } - ComponentResult StopNote(MusicDeviceGroupID, NoteInstanceID, UInt32) override + OSStatus StopNote(MusicDeviceGroupID, NoteInstanceID, UInt32) override { TRACE return noErr; } - UInt32 GetChannelLayoutTags(AudioUnitScope scope, AudioUnitElement element, AudioChannelLayoutTag* outLayoutTags) override + UInt32 GetChannelLayoutTags(const AudioUnitScope scope, + const AudioUnitElement element, + AudioChannelLayoutTag* const outLayoutTags) override { TRACE return 0; @@ -341,6 +546,7 @@ protected: TRACE return noErr; } +#endif private: double getSampleRate() @@ -390,7 +596,9 @@ END_NAMESPACE_DISTRHO #include "au/AUBase.cpp" #include "au/AUBuffer.cpp" +#if !CA_USE_AUDIO_PLUGIN_ONLY #include "au/AUDispatch.cpp" +#endif #include "au/AUInputElement.cpp" #include "au/AUMIDIBase.cpp" #include "au/AUOutputBase.cpp" @@ -438,9 +646,9 @@ void* PluginAUFactory(const AudioComponentDescription* const inDesc) { TRACE if (d_nextBufferSize == 0) - d_nextBufferSize = 512; - if (d_nextSampleRate == 0) - d_nextSampleRate = 44100; + d_nextBufferSize = kAUDefaultMaxFramesPerSlice; + if (d_isZero(d_nextSampleRate)) + d_nextSampleRate = kAUDefaultSampleRate; return PluginBaseFactory<PluginAU>::Factory(inDesc); }