commit 6d669870db308b61eacb2e932943b20f994e902c
parent dfc9e235c065c4a241d3e230587e6aca813d05f9
Author: falkTX <falktx@falktx.com>
Date: Sun, 18 Feb 2024 22:27:14 +0100
Build a loadable AU object, debug and stubs
Signed-off-by: falkTX <falktx@falktx.com>
Diffstat:
7 files changed, 668 insertions(+), 9 deletions(-)
diff --git a/Makefile.plugins.mk b/Makefile.plugins.mk
@@ -297,7 +297,6 @@ static = $(TARGET_DIR)/$(NAME).a
ifeq ($(MACOS),true)
BUNDLE_RESOURCES = Info.plist PkgInfo Resources/empty.lproj
au = $(TARGET_DIR)/$(NAME).component/Contents/MacOS/$(NAME)
-# aufiles += $(TARGET_DIR)/$(NAME).component/Contents/Resources/$(NAME).rsrc
aufiles += $(BUNDLE_RESOURCES:%=$(TARGET_DIR)/$(NAME).component/Contents/%)
vst2files += $(BUNDLE_RESOURCES:%=$(TARGET_DIR)/$(NAME).vst/Contents/%)
vst3files += $(BUNDLE_RESOURCES:%=$(TARGET_DIR)/$(NAME).vst3/Contents/%)
@@ -696,7 +695,19 @@ $(au): $(OBJS_DSP) $(BUILD_DIR)/DistrhoPluginMain_AU.cpp.o
endif
-@mkdir -p $(shell dirname $@)
@echo "Creating AU component for $(NAME)"
- $(SILENT)$(CXX) $^ $(BUILD_CXX_FLAGS) $(LINK_FLAGS) $(EXTRA_LIBS) $(EXTRA_DSP_LIBS) $(EXTRA_UI_LIBS) $(DGL_LIBS) -framework AudioUnit $(SHARED) $(SYMBOLS_AU) -o $@
+ $(SILENT)$(CXX) $^ $(BUILD_CXX_FLAGS) $(LINK_FLAGS) $(EXTRA_LIBS) $(EXTRA_DSP_LIBS) $(EXTRA_UI_LIBS) $(DGL_LIBS) -framework AudioToolbox -framework AudioUnit $(SHARED) $(SYMBOLS_AU) -o $@
+
+# ---------------------------------------------------------------------------------------------------------------------
+# Export
+
+# ifeq ($(HAVE_DGL),true)
+# $(BUILD_DIR)/export$(APP_EXT): $(OBJS_DSP) $(OBJS_UI) $(BUILD_DIR)/DistrhoPluginMain_EXPORT.cpp.o $(BUILD_DIR)/DistrhoUIMain_EXPORT.cpp.o $(DGL_LIB)
+# else
+$(BUILD_DIR)/export$(APP_EXT): $(OBJS_DSP) $(BUILD_DIR)/DistrhoPluginMain_EXPORT.cpp.o
+# endif
+ -@mkdir -p $(shell dirname $@)
+ @echo "Creating export tool for $(NAME)"
+ $(SILENT)$(CXX) $^ $(BUILD_CXX_FLAGS) $(LINK_FLAGS) $(EXTRA_LIBS) $(EXTRA_DSP_LIBS) $(EXTRA_UI_LIBS) $(DGL_LIBS) -o $@
# ---------------------------------------------------------------------------------------------------------------------
# Shared
@@ -747,6 +758,13 @@ $(TARGET_DIR)/%/Resources/empty.lproj: $(DPF_PATH)/utils/plugin.bundle/Contents/
$(SILENT)cp $< $@
# ---------------------------------------------------------------------------------------------------------------------
+# format-specific files
+
+$(TARGET_DIR)/$(NAME).component/Contents/Info.plist: $(BUILD_DIR)/export$(APP_EXT)
+ -@mkdir -p $(shell dirname $@)
+ cd $(TARGET_DIR)/$(NAME).component/Contents && $(abspath $<) "$(NAME)"
+
+# ---------------------------------------------------------------------------------------------------------------------
-include $(OBJS_DSP:%.o=%.d)
ifneq ($(UI_TYPE),)
@@ -761,6 +779,7 @@ endif
-include $(BUILD_DIR)/DistrhoPluginMain_VST3.cpp.d
-include $(BUILD_DIR)/DistrhoPluginMain_CLAP.cpp.d
-include $(BUILD_DIR)/DistrhoPluginMain_AU.cpp.d
+-include $(BUILD_DIR)/DistrhoPluginMain_Export.cpp.d
-include $(BUILD_DIR)/DistrhoPluginMain_SHARED.cpp.d
-include $(BUILD_DIR)/DistrhoPluginMain_STATIC.cpp.d
diff --git a/distrho/DistrhoPluginMain.cpp b/distrho/DistrhoPluginMain.cpp
@@ -33,6 +33,8 @@
# include "src/DistrhoPluginVST2.cpp"
#elif defined(DISTRHO_PLUGIN_TARGET_VST3)
# include "src/DistrhoPluginVST3.cpp"
+#elif defined(DISTRHO_PLUGIN_TARGET_EXPORT)
+# include "src/DistrhoPluginExport.cpp"
#elif defined(DISTRHO_PLUGIN_TARGET_SHARED)
DISTRHO_PLUGIN_EXPORT DISTRHO_NAMESPACE::Plugin* createSharedPlugin();
DISTRHO_PLUGIN_EXPORT DISTRHO_NAMESPACE::Plugin* createSharedPlugin() { return DISTRHO_NAMESPACE::createPlugin(); }
diff --git a/distrho/DistrhoUIMain.cpp b/distrho/DistrhoUIMain.cpp
@@ -42,6 +42,8 @@
#elif defined(DISTRHO_PLUGIN_TARGET_VST3)
# define DISTRHO_PLUGIN_AND_UI_IN_SINGLE_OBJECT 1
# include "src/DistrhoUIVST3.cpp"
+#elif defined(DISTRHO_PLUGIN_TARGET_EXPORT)
+# define DISTRHO_PLUGIN_AND_UI_IN_SINGLE_OBJECT 0
#elif defined(DISTRHO_PLUGIN_TARGET_SHARED) || defined(DISTRHO_PLUGIN_TARGET_STATIC)
# define DISTRHO_PLUGIN_AND_UI_IN_SINGLE_OBJECT 1
#else
diff --git a/distrho/src/DistrhoPluginAU.cpp b/distrho/src/DistrhoPluginAU.cpp
@@ -16,35 +16,360 @@
#include "DistrhoPluginInternal.hpp"
+// #define CA_NO_AU_UI_FEATURES
+
+#define TRACE d_stderr("////////--------------------------------------------------------------- %s %d", __PRETTY_FUNCTION__, __LINE__);
+
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunused-parameter"
-#include "au/AUBase.h"
+#include "au/MusicDeviceBase.h"
#pragma clang diagnostic pop
+#ifndef TARGET_OS_MAC
+#error TARGET_OS_MAC missing
+#endif
+
START_NAMESPACE_DISTRHO
// --------------------------------------------------------------------------------------------------------------------
-class PluginAU : public AUBase
+#if DISTRHO_PLUGIN_WANT_MIDI_INPUT || DISTRHO_PLUGIN_WANT_MIDI_OUTPUT
+typedef MusicDeviceBase PluginBase;
+#define PluginBaseFactory AUMIDIEffectFactory
+#else
+typedef AUBase PluginBase;
+#define PluginBaseFactory AUBaseFactory
+#endif
+
+// --------------------------------------------------------------------------------------------------------------------
+
+#if ! DISTRHO_PLUGIN_WANT_MIDI_OUTPUT
+static constexpr const writeMidiFunc writeMidiCallback = nullptr;
+#endif
+#if ! DISTRHO_PLUGIN_WANT_PARAMETER_VALUE_CHANGE_REQUEST
+static constexpr const requestParameterValueChangeFunc requestParameterValueChangeCallback = nullptr;
+#endif
+#if ! DISTRHO_PLUGIN_WANT_STATE
+static constexpr const updateStateValueFunc updateStateValueCallback = nullptr;
+#endif
+
+class PluginHolder
+{
+public:
+ PluginExporter fPlugin;
+
+ PluginHolder()
+ : fPlugin(this, writeMidiCallback, requestParameterValueChangeCallback, updateStateValueCallback) {}
+
+ virtual ~PluginHolder() {}
+
+protected:
+ uint32_t getPluginBusCount(const bool isInput) noexcept
+ {
+ return 0;
+ }
+
+private:
+ // ----------------------------------------------------------------------------------------------------------------
+ // DPF callbacks
+
+ #if DISTRHO_PLUGIN_WANT_MIDI_OUTPUT
+ bool writeMidi(const MidiEvent&)
+ {
+ return true;
+ }
+
+ static bool writeMidiCallback(void* const ptr, const MidiEvent& midiEvent)
+ {
+ return static_cast<PluginHolder*>(ptr)->writeMidi(midiEvent);
+ }
+ #endif
+
+
+ #if DISTRHO_PLUGIN_WANT_PARAMETER_VALUE_CHANGE_REQUEST
+ bool requestParameterValueChange(uint32_t, float)
+ {
+ return true;
+ }
+
+ static bool requestParameterValueChangeCallback(void* const ptr, const uint32_t index, const float value)
+ {
+ return static_cast<PluginHolder*>(ptr)->requestParameterValueChange(index, value);
+ }
+ #endif
+
+ #if DISTRHO_PLUGIN_WANT_STATE
+ bool updateState(const char*, const char*)
+ {
+ return true;
+ }
+
+ static bool updateStateValueCallback(void* const ptr, const char* const key, const char* const value)
+ {
+ return static_cast<PluginHolder*>(ptr)->updateState(key, value);
+ }
+ #endif
+};
+
+class PluginAU : public PluginHolder,
+ public PluginBase
{
public:
PluginAU(AudioUnit component)
- : AUBase(component, 0, 0)
- {}
+ : PluginHolder(),
+ PluginBase(component, getPluginBusCount(true), getPluginBusCount(false))
+ {
+ TRACE
+ }
+
+ ~PluginAU() override
+ {
+ TRACE
+ }
protected:
+ ComponentResult Initialize() override
+ {
+ TRACE
+ ComponentResult res;
+
+ res = PluginBase::Initialize();
+ DISTRHO_SAFE_ASSERT_INT_RETURN(res == noErr, res, res);
+
+ setBufferSizeAndSampleRate();
+ return noErr;
+ }
+
+ void Cleanup() override
+ {
+ TRACE
+ PluginBase::Cleanup();
+ fPlugin.deactivate();
+ }
+
+ ComponentResult Reset(AudioUnitScope inScope, AudioUnitElement inElement) override
+ {
+ TRACE
+ fPlugin.deactivateIfNeeded();
+ setBufferSizeAndSampleRate();
+
+ const ComponentResult res = PluginBase::Reset(inScope, inElement);
+
+ if (res == noErr)
+ fPlugin.activate();
+
+ return res;
+ }
+
+ ComponentResult 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,
+ AudioUnitScope inScope,
+ AudioUnitElement inElement,
+ void* outData) override
+ {
+ TRACE
+ return PluginBase::GetProperty(inID, inScope, inElement, outData);
+ }
+
+ ComponentResult SetProperty(AudioUnitPropertyID inID,
+ AudioUnitScope inScope,
+ AudioUnitElement inElement,
+ const void* inData,
+ UInt32 inDataSize) override
+ {
+ TRACE
+ return PluginBase::SetProperty(inID, inScope, inElement, inData, inDataSize);
+ }
+
+ ComponentResult GetParameter(AudioUnitParameterID inID,
+ AudioUnitScope inScope,
+ AudioUnitElement inElement,
+ Float32& outValue) override
+ {
+ TRACE
+ return kAudioUnitErr_InvalidProperty;
+ // return PluginBase::GetParameter(inID, inScope, inElement, outValue);
+ }
+
+ ComponentResult SetParameter(AudioUnitParameterID inID,
+ AudioUnitScope inScope,
+ AudioUnitElement inElement,
+ Float32 inValue,
+ UInt32 inBufferOffsetInFrames) override
+ {
+ TRACE
+ return kAudioUnitErr_InvalidProperty;
+ // return PluginBase::SetParameter(inID, inScope, inElement, inValue, inBufferOffsetInFrames);
+ }
+
bool CanScheduleParameters() const override
{
+ TRACE
+ return false;
+ }
+
+ ComponentResult Render(AudioUnitRenderActionFlags& ioActionFlags,
+ const AudioTimeStamp& inTimeStamp,
+ const UInt32 nFrames) override
+ {
+ TRACE
+ return noErr;
+ }
+
+ bool BusCountWritable(AudioUnitScope scope) override
+ {
+ TRACE
+ return false;
+ }
+
+ OSStatus SetBusCount(AudioUnitScope scope, UInt32 count) override
+ {
+ TRACE
+ return noErr;
+ }
+
+ ComponentResult GetParameterInfo(AudioUnitScope inScope,
+ AudioUnitParameterID inParameterID,
+ AudioUnitParameterInfo& outParameterInfo) override
+ {
+ TRACE
+ return kAudioUnitErr_InvalidProperty;
+ }
+
+ ComponentResult SaveState(CFPropertyListRef* outData) override
+ {
+ TRACE
+ return PluginBase::SaveState(outData);
+ }
+
+ ComponentResult RestoreState(CFPropertyListRef inData) override
+ {
+ TRACE
+ return noErr;
+ }
+
+ ComponentResult GetParameterValueStrings(AudioUnitScope inScope,
+ AudioUnitParameterID inParameterID,
+ CFArrayRef *outStrings) override
+ {
+ TRACE
+ return kAudioUnitErr_InvalidProperty;
+ }
+
+ ComponentResult GetPresets(CFArrayRef* outData) const override
+ {
+ TRACE
+ return noErr;
+ }
+
+ OSStatus NewFactoryPresetSet(const AUPreset& inNewFactoryPreset) override
+ {
+ TRACE
+ return noErr;
+ }
+
+ #if DISTRHO_PLUGIN_WANT_LATENCY
+ Float64 GetLatency() override
+ {
+ TRACE
+ return static_cast<double>(fPlugin.getLatency()) / fPlugin.getSampleRate();
+ }
+ #endif
+
+ bool StreamFormatWritable(AudioUnitScope, AudioUnitElement) override
+ {
+ TRACE
return false;
}
- bool StreamFormatWritable (AudioUnitScope, AudioUnitElement) override
+ UInt32 SupportedNumChannels(const AUChannelInfo** outInfo) override
+ {
+ TRACE
+ return 0;
+ }
+
+ bool ValidFormat(AudioUnitScope scope, AudioUnitElement element, const CAStreamBasicDescription& format) override
{
+ TRACE
return false;
}
+ OSStatus ChangeStreamFormat(AudioUnitScope scope, AudioUnitElement element, const CAStreamBasicDescription& old, const CAStreamBasicDescription& format) override
+ {
+ TRACE
+ return noErr;
+ }
+
+ ComponentResult StartNote(MusicDeviceInstrumentID, MusicDeviceGroupID, NoteInstanceID*, UInt32, const MusicDeviceNoteParams&) override
+ {
+ TRACE
+ return noErr;
+ }
+
+ ComponentResult StopNote(MusicDeviceGroupID, NoteInstanceID, UInt32) override
+ {
+ TRACE
+ return noErr;
+ }
+
+ UInt32 GetChannelLayoutTags(AudioUnitScope scope, AudioUnitElement element, AudioChannelLayoutTag* outLayoutTags) override
+ {
+ TRACE
+ return 0;
+ }
+
+ UInt32 GetAudioChannelLayout(AudioUnitScope scope, AudioUnitElement element,
+ AudioChannelLayout* outLayoutPtr, Boolean& outWritable) override
+ {
+ TRACE
+ return 0;
+ }
+
+ OSStatus SetAudioChannelLayout(AudioUnitScope scope, AudioUnitElement element, const AudioChannelLayout* inLayout) override
+ {
+ TRACE
+ return noErr;
+ }
+
+private:
+ double getSampleRate()
+ {
+ #if DISTRHO_PLUGIN_NUM_OUTPUTS != 0 && 0
+ if (AUOutputElement* const output = GetOutput(0))
+ {
+ const double sampleRate = d_nextSampleRate = output->GetStreamFormat().mSampleRate;
+ return sampleRate;
+ }
+ #endif
+
+ #if DISTRHO_PLUGIN_NUM_INPUTS != 0 && 0
+ if (AUInputElement* const input = GetInput(0))
+ {
+ const double sampleRate = d_nextSampleRate = input->GetStreamFormat().mSampleRate;
+ return sampleRate;
+ }
+ #endif
+
+ return d_nextSampleRate;
+ }
+
+ void setBufferSizeAndSampleRate()
+ {
+ fPlugin.setSampleRate(getSampleRate(), true);
+ fPlugin.setBufferSize(GetMaxFramesPerSlice(), true);
+ }
+
DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(PluginAU)
};
@@ -70,13 +395,13 @@ END_NAMESPACE_DISTRHO
#include "au/AUMIDIBase.cpp"
#include "au/AUOutputBase.cpp"
#include "au/AUOutputElement.cpp"
+#include "au/AUPlugInDispatch.cpp"
#include "au/AUScopeElement.cpp"
#include "au/CAAUParameter.cpp"
#include "au/CAAudioChannelLayout.cpp"
#include "au/CAMutex.cpp"
#include "au/CAStreamBasicDescription.cpp"
#include "au/CAVectorUnit.cpp"
-#include "au/CarbonEventHandler.cpp"
#include "au/ComponentBase.cpp"
#include "au/MusicDeviceBase.cpp"
@@ -87,13 +412,37 @@ END_NAMESPACE_DISTRHO
// --------------------------------------------------------------------------------------------------------------------
+/*
DISTRHO_PLUGIN_EXPORT
OSStatus PluginAUEntry(ComponentParameters*, PluginAU*);
+DISTRHO_PLUGIN_EXPORT
+void* PluginAUFactory(const AudioComponentDescription*);
+
#if DISTRHO_PLUGIN_WANT_MIDI_INPUT || DISTRHO_PLUGIN_WANT_MIDI_OUTPUT
AUDIOCOMPONENT_ENTRY(AUMIDIEffectFactory, PluginAU)
#else
AUDIOCOMPONENT_ENTRY(AUBaseFactory, PluginAU)
#endif
+DISTRHO_PLUGIN_EXPORT
+OSStatus PluginAUEntry(ComponentParameters* const params, PluginAU* const obj)
+{
+ TRACE
+ return ComponentEntryPoint<PluginAU>::Dispatch(params, obj);
+}
+*/
+
+DISTRHO_PLUGIN_EXPORT
+void* PluginAUFactory(const AudioComponentDescription* const inDesc)
+{
+ TRACE
+ if (d_nextBufferSize == 0)
+ d_nextBufferSize = 512;
+ if (d_nextSampleRate == 0)
+ d_nextSampleRate = 44100;
+
+ return PluginBaseFactory<PluginAU>::Factory(inDesc);
+}
+
// --------------------------------------------------------------------------------------------------------------------
diff --git a/distrho/src/DistrhoPluginExport.cpp b/distrho/src/DistrhoPluginExport.cpp
@@ -0,0 +1,280 @@
+/*
+ * DISTRHO Plugin Framework (DPF)
+ * Copyright (C) 2012-2024 Filipe Coelho <falktx@falktx.com>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any purpose with
+ * or without fee is hereby granted, provided that the above copyright notice and this
+ * permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD
+ * TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
+ * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include "DistrhoPluginInternal.hpp"
+#include "../DistrhoPluginUtils.hpp"
+
+#include <fstream>
+#include <iostream>
+
+USE_NAMESPACE_DISTRHO
+
+// --------------------------------------------------------------------------------------------------------------------
+
+void generate_au_plist(const PluginExporter& plugin,
+ const char* const basename,
+ const char* const license)
+{
+ std::cout << "Writing Info.plist..."; std::cout.flush();
+ std::fstream outputFile("Info.plist", std::ios::out);
+
+ const uint32_t version = plugin.getVersion();
+
+ const uint32_t majorVersion = (version & 0xFF0000) >> 16;
+ const uint32_t minorVersion = (version & 0x00FF00) >> 8;
+ const uint32_t microVersion = (version & 0x0000FF) >> 0;
+
+ outputFile << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
+ outputFile << "<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n";
+ outputFile << "<plist>\n";
+ outputFile << " <dict>\n";
+ outputFile << " <key>CFBundleExecutable</key>\n";
+ outputFile << " <string>" << basename << "</string>\n";
+ outputFile << " <key>CFBundleIconFile</key>\n";
+ outputFile << " <string></string>\n";
+ outputFile << " <key>CFBundleIdentifier</key>\n";
+ outputFile << " <string>" DISTRHO_PLUGIN_CLAP_ID "</string>\n";
+ outputFile << " <key>CFBundleName</key>\n";
+ outputFile << " <string>" << basename << "</string>\n";
+ outputFile << " <key>CFBundleDisplayName</key>\n";
+ outputFile << " <string>" << plugin.getName() << "</string>\n";
+ outputFile << " <key>CFBundlePackageType</key>\n";
+ outputFile << " <string>BNDL</string>\n";
+ outputFile << " <key>CFBundleSignature</key>\n";
+ outputFile << " <string>" << "????" << "</string>\n";
+ outputFile << " <key>CFBundleShortVersionString</key>\n";
+ outputFile << " <string>" << majorVersion << "." << minorVersion << "." << microVersion << "</string>\n";
+ outputFile << " <key>CFBundleVersion</key>\n";
+ outputFile << " <string>" << majorVersion << "." << minorVersion << "." << microVersion << "</string>\n";
+ outputFile << " <key>NSHumanReadableCopyright</key>\n";
+ outputFile << " <string>" << license << "</string>\n";
+ outputFile << " <key>NSHighResolutionCapable</key>\n";
+ outputFile << " <true/>\n";
+ outputFile << " <key>AudioComponents</key>\n";
+ outputFile << " <array>\n";
+ outputFile << " <dict>\n";
+ outputFile << " <key>name</key>\n";
+ outputFile << " <string>" << plugin.getMaker() << ": " << plugin.getName() << "</string>\n";
+ outputFile << " <key>description</key>\n";
+ outputFile << " <string>" << plugin.getDescription() << "</string>\n";
+ outputFile << " <key>factoryFunction</key>\n";
+ outputFile << " <string>PluginAUFactory</string>\n";
+ outputFile << " <key>manufacturer</key>\n";
+ outputFile << " <string>Dstr</string>\n";
+ outputFile << " <key>type</key>\n";
+ #if DISTRHO_PLUGIN_IS_SYNTH
+ outputFile << " <string>aumu</string>\n"; // kAudioUnitType_MusicDevice
+ #elif (DISTRHO_PLUGIN_WANT_MIDI_INPUT || DISTRHO_PLUGIN_WANT_MIDI_OUTPUT) && DISTRHO_PLUGIN_NUM_INPUTS != 0 && DISTRHO_PLUGIN_NUM_OUTPUTS != 0
+ outputFile << " <string>aumf</string>\n"; // kAudioUnitType_MusicEffect
+ #elif (DISTRHO_PLUGIN_WANT_MIDI_INPUT || DISTRHO_PLUGIN_WANT_MIDI_OUTPUT) && DISTRHO_PLUGIN_NUM_INPUTS + DISTRHO_PLUGIN_NUM_OUTPUTS != 0
+ outputFile << " <string>aumu</string>\n"; // kAudioUnitType_MusicDevice
+ #elif (DISTRHO_PLUGIN_WANT_MIDI_INPUT || DISTRHO_PLUGIN_WANT_MIDI_OUTPUT) && DISTRHO_PLUGIN_NUM_INPUTS + DISTRHO_PLUGIN_NUM_OUTPUTS != 0
+ outputFile << " <string>aumi</string>\n"; // kAudioUnitType_MIDIProcessor
+ #elif DISTRHO_PLUGIN_NUM_INPUTS == 0 && DISTRHO_PLUGIN_NUM_OUTPUTS != 0
+ outputFile << " <string>augn</string>\n"; // kAudioUnitType_Generator
+ #else
+ outputFile << " <string>aufx</string>\n"; // kAudioUnitType_Effect
+ #endif
+ outputFile << " <key>subtype</key>\n";
+ outputFile << " <string>ParM</string>\n";
+ outputFile << " <key>version</key>\n";
+ outputFile << " <integer>" << version << "</integer>\n";
+ outputFile << " <key>resourceUsage</key>\n";
+ outputFile << " <dict>\n";
+ outputFile << " <key>network.client</key>\n";
+ outputFile << " <true/>\n";
+ outputFile << " <key>temporary-exception.files.all.read-write</key>\n";
+ outputFile << " <true/>\n";
+ outputFile << " </dict>\n";
+ outputFile << " </dict>\n";
+ outputFile << " </array>\n";
+ outputFile << " </dict>\n";
+ outputFile << "</plist>\n";
+
+ outputFile.close();
+ std::cout << " done!" << std::endl;
+}
+
+// --------------------------------------------------------------------------------------------------------------------
+
+int main(int argc, char* argv[])
+{
+ if (argc <= 1)
+ return 1;
+
+ // Dummy plugin to get data from
+ d_nextBufferSize = 512;
+ d_nextSampleRate = 44100.0;
+ d_nextPluginIsDummy = true;
+ PluginExporter plugin(nullptr, nullptr, nullptr, nullptr);
+ d_nextBufferSize = 0;
+ d_nextSampleRate = 0.0;
+ d_nextPluginIsDummy = false;
+
+ String license(plugin.getLicense());
+
+ // License as URL, use as-is
+ if (license.contains("://"))
+ {}
+ // License contains quotes, use as-is
+ else if (license.contains('"'))
+ {}
+ // Regular license string, convert to URL as much as we can
+ else
+ {
+ const String uplicense(license.asUpper());
+
+ // for reference, see https://spdx.org/licenses/
+
+ // common licenses
+ /**/ if (uplicense == "AGPL-1.0-ONLY" ||
+ uplicense == "AGPL1" ||
+ uplicense == "AGPLV1")
+ {
+ license = "http://spdx.org/licenses/AGPL-1.0-only.html";
+ }
+ else if (uplicense == "AGPL-1.0-OR-LATER" ||
+ uplicense == "AGPL1+" ||
+ uplicense == "AGPLV1+")
+ {
+ license = "http://spdx.org/licenses/AGPL-1.0-or-later.html";
+ }
+ else if (uplicense == "AGPL-3.0-ONLY" ||
+ uplicense == "AGPL3" ||
+ uplicense == "AGPLV3")
+ {
+ license = "http://spdx.org/licenses/AGPL-3.0-only.html";
+ }
+ else if (uplicense == "AGPL-3.0-OR-LATER" ||
+ uplicense == "AGPL3+" ||
+ uplicense == "AGPLV3+")
+ {
+ license = "http://spdx.org/licenses/AGPL-3.0-or-later.html";
+ }
+ else if (uplicense == "APACHE-2.0" ||
+ uplicense == "APACHE2" ||
+ uplicense == "APACHE-2")
+ {
+ license = "http://spdx.org/licenses/Apache-2.0.html";
+ }
+ else if (uplicense == "BSD-2-CLAUSE" ||
+ uplicense == "BSD2" ||
+ uplicense == "BSD-2")
+ {
+ license = "http://spdx.org/licenses/BSD-2-Clause.html";
+ }
+ else if (uplicense == "BSD-3-CLAUSE" ||
+ uplicense == "BSD3" ||
+ uplicense == "BSD-3")
+ {
+ license = "http://spdx.org/licenses/BSD-3-Clause.html";
+ }
+ else if (uplicense == "GPL-2.0-ONLY" ||
+ uplicense == "GPL2" ||
+ uplicense == "GPLV2")
+ {
+ license = "http://spdx.org/licenses/GPL-2.0-only.html";
+ }
+ else if (uplicense == "GPL-2.0-OR-LATER" ||
+ uplicense == "GPL2+" ||
+ uplicense == "GPLV2+" ||
+ uplicense == "GPLV2.0+" ||
+ uplicense == "GPL V2+")
+ {
+ license = "http://spdx.org/licenses/GPL-2.0-or-later.html";
+ }
+ else if (uplicense == "GPL-3.0-ONLY" ||
+ uplicense == "GPL3" ||
+ uplicense == "GPLV3")
+ {
+ license = "http://spdx.org/licenses/GPL-3.0-only.html";
+ }
+ else if (uplicense == "GPL-3.0-OR-LATER" ||
+ uplicense == "GPL3+" ||
+ uplicense == "GPLV3+" ||
+ uplicense == "GPLV3.0+" ||
+ uplicense == "GPL V3+")
+ {
+ license = "http://spdx.org/licenses/GPL-3.0-or-later.html";
+ }
+ else if (uplicense == "ISC")
+ {
+ license = "http://spdx.org/licenses/ISC.html";
+ }
+ else if (uplicense == "LGPL-2.0-ONLY" ||
+ uplicense == "LGPL2" ||
+ uplicense == "LGPLV2")
+ {
+ license = "http://spdx.org/licenses/LGPL-2.0-only.html";
+ }
+ else if (uplicense == "LGPL-2.0-OR-LATER" ||
+ uplicense == "LGPL2+" ||
+ uplicense == "LGPLV2+")
+ {
+ license = "http://spdx.org/licenses/LGPL-2.0-or-later.html";
+ }
+ else if (uplicense == "LGPL-2.1-ONLY" ||
+ uplicense == "LGPL2.1" ||
+ uplicense == "LGPLV2.1")
+ {
+ license = "http://spdx.org/licenses/LGPL-2.1-only.html";
+ }
+ else if (uplicense == "LGPL-2.1-OR-LATER" ||
+ uplicense == "LGPL2.1+" ||
+ uplicense == "LGPLV2.1+")
+ {
+ license = "http://spdx.org/licenses/LGPL-2.1-or-later.html";
+ }
+ else if (uplicense == "LGPL-3.0-ONLY" ||
+ uplicense == "LGPL3" ||
+ uplicense == "LGPLV3")
+ {
+ license = "http://spdx.org/licenses/LGPL-2.0-only.html";
+ }
+ else if (uplicense == "LGPL-3.0-OR-LATER" ||
+ uplicense == "LGPL3+" ||
+ uplicense == "LGPLV3+")
+ {
+ license = "http://spdx.org/licenses/LGPL-3.0-or-later.html";
+ }
+ else if (uplicense == "MIT")
+ {
+ license = "http://spdx.org/licenses/MIT.html";
+ }
+
+ // generic fallbacks
+ else if (uplicense.startsWith("GPL"))
+ {
+ license = "http://opensource.org/licenses/gpl-license";
+ }
+ else if (uplicense.startsWith("LGPL"))
+ {
+ license = "http://opensource.org/licenses/lgpl-license";
+ }
+
+ // unknown or not handled yet, log a warning
+ else
+ {
+ d_stderr("Unknown license string '%s'", license.buffer());
+ }
+ }
+
+ generate_au_plist(plugin, argv[1], license);
+
+ return 0;
+}
+
+// --------------------------------------------------------------------------------------------------------------------
diff --git a/utils/au-services-restart.sh b/utils/au-services-restart.sh
@@ -0,0 +1,7 @@
+#!/bin/bash
+
+rm -f "~/Library/Application Support/AU Lab/com.apple.audio.aulab_componentcache.plist"
+rm -rf "~/Library/Caches/AudioUnitCache"
+killall -9 AudioComponentRegistrar
+sudo killall -9 AudioComponentRegistrar
+exit 0
diff --git a/utils/symbols/au.exp b/utils/symbols/au.exp
@@ -1 +1 @@
-_PluginAUEntry
+_PluginAUFactory