Signed-off-by: falkTX <falktx@falktx.com>pull/452/head
| @@ -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 | |||
| @@ -746,6 +757,13 @@ $(TARGET_DIR)/%/Resources/empty.lproj: $(DPF_PATH)/utils/plugin.bundle/Contents/ | |||
| -@mkdir -p $(shell dirname $@) | |||
| $(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) | |||
| @@ -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 | |||
| @@ -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(); } | |||
| @@ -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 | |||
| @@ -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); | |||
| } | |||
| // -------------------------------------------------------------------------------------------------------------------- | |||
| @@ -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; | |||
| } | |||
| // -------------------------------------------------------------------------------------------------------------------- | |||
| @@ -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 | |||
| @@ -1 +1 @@ | |||
| _PluginAUEntry | |||
| _PluginAUFactory | |||