diff --git a/Makefile b/Makefile index abc689409..9fd4cbdf7 100644 --- a/Makefile +++ b/Makefile @@ -59,6 +59,19 @@ ifeq ($(HAVE_QT5),true) ALL_LIBS += $(MODULEDIR)/theme.qt5.a endif +ifeq ($(USING_JUCE),true) +ALL_LIBS += $(MODULEDIR)/juce_audio_basics.a +ALL_LIBS += $(MODULEDIR)/juce_audio_devices.a +ALL_LIBS += $(MODULEDIR)/juce_audio_formats.a +ALL_LIBS += $(MODULEDIR)/juce_audio_processors.a +ALL_LIBS += $(MODULEDIR)/juce_core.a +ALL_LIBS += $(MODULEDIR)/juce_data_structures.a +ALL_LIBS += $(MODULEDIR)/juce_events.a +ALL_LIBS += $(MODULEDIR)/juce_graphics.a +ALL_LIBS += $(MODULEDIR)/juce_gui_basics.a +# ALL_LIBS += $(MODULEDIR)/juce_gui_extra.a +endif + libs: $(ALL_LIBS) $(MODULEDIR)/carla_engine.a: .FORCE diff --git a/source/Makefile.mk b/source/Makefile.mk index 969a8d697..fd7961c12 100644 --- a/source/Makefile.mk +++ b/source/Makefile.mk @@ -91,6 +91,13 @@ ifeq ($(MACOS),true) UNIX=true endif +# --------------------------------------------------------------------------------------------------------------------- +# Set USING_JUCE + +ifeq ($(MACOS_OR_WIN32),true) +USING_JUCE=true +endif + # --------------------------------------------------------------------------------------------------------------------- # Set build and link flags @@ -334,6 +341,10 @@ ifeq ($(HAVE_X11),true) BASE_FLAGS += -DHAVE_X11 endif +ifeq ($(USING_JUCE),true) +BASE_FLAGS += -DUSING_JUCE +endif + # --------------------------------------------------------------------------------------------------------------------- # Set libs stuff (part 1) diff --git a/source/backend/CarlaBackend.h b/source/backend/CarlaBackend.h index e0e42838a..cb1f888fb 100644 --- a/source/backend/CarlaBackend.h +++ b/source/backend/CarlaBackend.h @@ -494,20 +494,32 @@ typedef enum { */ PLUGIN_VST2 = 5, + /*! + * VST3 plugin. + * @note Windows and MacOS only + */ + PLUGIN_VST3 = 6, + + /*! + * AU plugin. + * @note MacOS only + */ + PLUGIN_AU = 7, + /*! * SF2 file (SoundFont). */ - PLUGIN_SF2 = 6, + PLUGIN_SF2 = 8, /*! * SFZ file. */ - PLUGIN_SFZ = 7, + PLUGIN_SFZ = 9, /*! * JACK application. */ - PLUGIN_JACK = 8 + PLUGIN_JACK = 10 } PluginType; diff --git a/source/backend/CarlaEngine.hpp b/source/backend/CarlaEngine.hpp index f245e00a1..06b63eb21 100644 --- a/source/backend/CarlaEngine.hpp +++ b/source/backend/CarlaEngine.hpp @@ -55,20 +55,25 @@ enum EngineType { */ kEngineTypeJack = 1, + /*! + * Juce engine type, used to provide Native Audio and MIDI support. + */ + kEngineTypeJuce = 2, + /*! * RtAudio engine type, used to provide Native Audio and MIDI support. */ - kEngineTypeRtAudio = 2, + kEngineTypeRtAudio = 3, /*! * Plugin engine type, used to export the engine as a plugin. */ - kEngineTypePlugin = 3, + kEngineTypePlugin = 4, /*! * Bridge engine type, used in BridgePlugin class. */ - kEngineTypeBridge = 4 + kEngineTypeBridge = 5 }; /*! @@ -239,6 +244,7 @@ struct CARLA_API EngineOptions { const char* pathDSSI; const char* pathLV2; const char* pathVST2; + const char* pathVST3; const char* pathSF2; const char* pathSFZ; @@ -1212,12 +1218,21 @@ public: const char* const nonRtClientBaseName, const char* const nonRtServerBaseName); #else +# ifdef USING_JUCE + // Juce + static CarlaEngine* newJuce(const AudioApi api); + static uint getJuceApiCount(); + static const char* getJuceApiName(const uint index); + static const char* const* getJuceApiDeviceNames(const uint index); + static const EngineDriverDeviceInfo* getJuceDeviceInfo(const uint index, const char* const deviceName); +# else // RtAudio static CarlaEngine* newRtAudio(const AudioApi api); static uint getRtAudioApiCount(); static const char* getRtAudioApiName(const uint index); static const char* const* getRtAudioApiDeviceNames(const uint index); static const EngineDriverDeviceInfo* getRtAudioDeviceInfo(const uint index, const char* const deviceName); +# endif #endif #ifndef BUILD_BRIDGE diff --git a/source/backend/CarlaPlugin.hpp b/source/backend/CarlaPlugin.hpp index 25393c4b0..46dab4bab 100644 --- a/source/backend/CarlaPlugin.hpp +++ b/source/backend/CarlaPlugin.hpp @@ -916,7 +916,10 @@ public: static CarlaPlugin* newDSSI(const Initializer& init); static CarlaPlugin* newLV2(const Initializer& init); static CarlaPlugin* newVST2(const Initializer& init); + static CarlaPlugin* newVST3(const Initializer& init); + static CarlaPlugin* newAU(const Initializer& init); + static CarlaPlugin* newJuce(const Initializer& init, const char* const format); static CarlaPlugin* newFluidSynth(const Initializer& init, const bool use16Outs); static CarlaPlugin* newSFZero(const Initializer& init); diff --git a/source/backend/engine/CarlaEngine.cpp b/source/backend/engine/CarlaEngine.cpp index 3c8e7b51d..8798c8ec1 100644 --- a/source/backend/engine/CarlaEngine.cpp +++ b/source/backend/engine/CarlaEngine.cpp @@ -83,7 +83,11 @@ uint CarlaEngine::getDriverCount() count += 1; #ifndef BUILD_BRIDGE +# ifdef USING_JUCE + count += getJuceApiCount(); +# else count += getRtAudioApiCount(); +# endif #endif return count; @@ -93,17 +97,26 @@ const char* CarlaEngine::getDriverName(const uint index2) { carla_debug("CarlaEngine::getDriverName(%i)", index2); - uint index(index2); + uint index = index2; if (jackbridge_is_ok() && index-- == 0) return "JACK"; #ifndef BUILD_BRIDGE +# ifdef USING_JUCE + if (const uint count = getJuceApiCount()) + { + if (index < count) + return getJuceApiName(index); + index -= count; + } +# else if (const uint count = getRtAudioApiCount()) { if (index < count) return getRtAudioApiName(index); } +# endif #endif carla_stderr("CarlaEngine::getDriverName(%i) - invalid index", index2); @@ -114,7 +127,7 @@ const char* const* CarlaEngine::getDriverDeviceNames(const uint index2) { carla_debug("CarlaEngine::getDriverDeviceNames(%i)", index2); - uint index(index2); + uint index = index2; if (jackbridge_is_ok() && index-- == 0) { @@ -123,11 +136,20 @@ const char* const* CarlaEngine::getDriverDeviceNames(const uint index2) } #ifndef BUILD_BRIDGE +# ifdef USING_JUCE + if (const uint count = getJuceApiCount()) + { + if (index < count) + return getJuceApiDeviceNames(index); + index -= count; + } +# else if (const uint count = getRtAudioApiCount()) { if (index < count) return getRtAudioApiDeviceNames(index); } +# endif #endif carla_stderr("CarlaEngine::getDriverDeviceNames(%i) - invalid index", index2); @@ -138,7 +160,7 @@ const EngineDriverDeviceInfo* CarlaEngine::getDriverDeviceInfo(const uint index2 { carla_debug("CarlaEngine::getDriverDeviceInfo(%i, \"%s\")", index2, deviceName); - uint index(index2); + uint index = index2; if (jackbridge_is_ok() && index-- == 0) { @@ -150,11 +172,20 @@ const EngineDriverDeviceInfo* CarlaEngine::getDriverDeviceInfo(const uint index2 } #ifndef BUILD_BRIDGE +# ifdef USING_JUCE + if (const uint count = getJuceApiCount()) + { + if (index < count) + return getJuceDeviceInfo(index, deviceName); + index -= count; + } +# else if (const uint count = getRtAudioApiCount()) { if (index < count) return getRtAudioDeviceInfo(index, deviceName); } +# endif #endif carla_stderr("CarlaEngine::getDriverDeviceNames(%i, \"%s\") - invalid index", index2, deviceName); @@ -170,6 +201,21 @@ CarlaEngine* CarlaEngine::newDriverByName(const char* const driverName) return newJack(); #ifndef BUILD_BRIDGE +# ifdef USING_JUCE + // ------------------------------------------------------------------- + // macos + + if (std::strcmp(driverName, "CoreAudio") == 0) + return newJuce(AUDIO_API_COREAUDIO); + + // ------------------------------------------------------------------- + // windows + + if (std::strcmp(driverName, "ASIO") == 0) + return newJuce(AUDIO_API_ASIO); + if (std::strcmp(driverName, "DirectSound") == 0) + return newJuce(AUDIO_API_DIRECTSOUND); +# else // ------------------------------------------------------------------- // common @@ -203,6 +249,7 @@ CarlaEngine* CarlaEngine::newDriverByName(const char* const driverName) return newRtAudio(AUDIO_API_DIRECTSOUND); if (std::strcmp(driverName, "WASAPI") == 0) return newRtAudio(AUDIO_API_WASAPI); +# endif #endif carla_stderr("CarlaEngine::newDriverByName(\"%s\") - invalid driver name", driverName); @@ -458,6 +505,14 @@ bool CarlaEngine::addPlugin(const BinaryType btype, const PluginType ptype, plugin = CarlaPlugin::newVST2(initializer); break; + case PLUGIN_VST3: + plugin = CarlaPlugin::newVST3(initializer); + break; + + case PLUGIN_AU: + plugin = CarlaPlugin::newAU(initializer); + break; + #ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH case PLUGIN_INTERNAL: plugin = CarlaPlugin::newNative(initializer); @@ -1054,6 +1109,11 @@ bool CarlaEngine::loadFile(const char* const filename) return addPlugin(getBinaryTypeFromFile(filename), PLUGIN_VST2, filename, nullptr, nullptr, 0, nullptr, 0x0); #endif +#ifdef USING_JUCE + if (extension == "vst3") + return addPlugin(getBinaryTypeFromFile(filename), PLUGIN_VST3, filename, nullptr, nullptr, 0, nullptr, 0x0); +#endif + // ------------------------------------------------------------------- setLastError("Unknown file extension"); @@ -1476,6 +1536,14 @@ void CarlaEngine::setOption(const EngineOption option, const int value, const ch else pData->options.pathVST2 = nullptr; break; + case PLUGIN_VST3: + if (pData->options.pathVST3 != nullptr) + delete[] pData->options.pathVST3; + if (valueStr != nullptr) + pData->options.pathVST3 = carla_strdup_safe(valueStr); + else + pData->options.pathVST3 = nullptr; + break; case PLUGIN_SF2: if (pData->options.pathSF2 != nullptr) delete[] pData->options.pathSF2; @@ -1769,6 +1837,7 @@ void CarlaEngine::saveProjectInternal(water::MemoryOutputStream& outStream) cons outSettings << " " << xmlSafeString(options.pathDSSI, true) << "\n"; outSettings << " " << xmlSafeString(options.pathLV2, true) << "\n"; outSettings << " " << xmlSafeString(options.pathVST2, true) << "\n"; + outSettings << " " << xmlSafeString(options.pathVST3, true) << "\n"; outSettings << " " << xmlSafeString(options.pathSF2, true) << "\n"; outSettings << " " << xmlSafeString(options.pathSFZ, true) << "\n"; } @@ -1919,7 +1988,7 @@ static String findBinaryInCustomPath(const char* const searchPath, const char* c int searchFlags = File::findFiles|File::ignoreHiddenFiles; #ifdef CARLA_OS_MAC - if (filename.endsWithIgnoreCase(".vst")) + if (filename.endsWithIgnoreCase(".vst") || filename.endsWithIgnoreCase(".vst3")) searchFlags |= File::findDirectories; #endif @@ -2062,6 +2131,12 @@ bool CarlaEngine::loadProjectInternal(water::XmlDocument& xmlDoc) value = PLUGIN_VST2; valueStr = text.toRawUTF8(); } + else if (tag.equalsIgnoreCase("VST3_PATH")) + { + option = ENGINE_OPTION_PLUGIN_PATH; + value = PLUGIN_VST3; + valueStr = text.toRawUTF8(); + } else if (tag == "SF2_PATH") { option = ENGINE_OPTION_PLUGIN_PATH; @@ -2079,11 +2154,13 @@ bool CarlaEngine::loadProjectInternal(water::XmlDocument& xmlDoc) if (option == -1) { // check old stuff, unhandled now - if (tag == "AU_PATH" || tag == "VST3_PATH" || tag == "GIG_PATH") + if (tag == "GIG_PATH") continue; // ignored tags if (tag == "LADSPA_PATH" || tag == "DSSI_PATH" || tag == "LV2_PATH" || tag == "VST2_PATH") continue; + if (tag == "VST3_PATH" || tag == "AU_PATH") + continue; if (tag == "SF2_PATH" || tag == "SFZ_PATH") continue; @@ -2204,6 +2281,7 @@ bool CarlaEngine::loadProjectInternal(water::XmlDocument& xmlDoc) case PLUGIN_LADSPA: case PLUGIN_DSSI: case PLUGIN_VST2: + case PLUGIN_VST3: case PLUGIN_SFZ: if (stateSave.binary != nullptr && stateSave.binary[0] != '\0' && ! (File::isAbsolutePath(stateSave.binary) && File(stateSave.binary).exists())) @@ -2215,6 +2293,7 @@ bool CarlaEngine::loadProjectInternal(water::XmlDocument& xmlDoc) case PLUGIN_LADSPA: searchPath = pData->options.pathLADSPA; break; case PLUGIN_DSSI: searchPath = pData->options.pathDSSI; break; case PLUGIN_VST2: searchPath = pData->options.pathVST2; break; + case PLUGIN_VST3: searchPath = pData->options.pathVST3; break; case PLUGIN_SF2: searchPath = pData->options.pathSF2; break; case PLUGIN_SFZ: searchPath = pData->options.pathSFZ; break; default: searchPath = nullptr; break; @@ -2234,6 +2313,7 @@ bool CarlaEngine::loadProjectInternal(water::XmlDocument& xmlDoc) case PLUGIN_LADSPA: searchPath = std::getenv("LADSPA_PATH"); break; case PLUGIN_DSSI: searchPath = std::getenv("DSSI_PATH"); break; case PLUGIN_VST2: searchPath = std::getenv("VST_PATH"); break; + case PLUGIN_VST3: searchPath = std::getenv("VST3_PATH"); break; case PLUGIN_SF2: searchPath = std::getenv("SF2_PATH"); break; case PLUGIN_SFZ: searchPath = std::getenv("SFZ_PATH"); break; default: searchPath = nullptr; break; diff --git a/source/backend/engine/CarlaEngineData.cpp b/source/backend/engine/CarlaEngineData.cpp index cd54a9ff8..4c08cb47c 100644 --- a/source/backend/engine/CarlaEngineData.cpp +++ b/source/backend/engine/CarlaEngineData.cpp @@ -201,6 +201,7 @@ EngineOptions::EngineOptions() noexcept pathDSSI(nullptr), pathLV2(nullptr), pathVST2(nullptr), + pathVST3(nullptr), pathSF2(nullptr), pathSFZ(nullptr), binaryDir(nullptr), @@ -245,6 +246,12 @@ EngineOptions::~EngineOptions() noexcept pathVST2 = nullptr; } + if (pathVST3 != nullptr) + { + delete[] pathVST3; + pathVST3 = nullptr; + } + if (pathSF2 != nullptr) { delete[] pathSF2; diff --git a/source/backend/engine/CarlaEngineNative.cpp b/source/backend/engine/CarlaEngineNative.cpp index 664ccac42..daea6f376 100644 --- a/source/backend/engine/CarlaEngineNative.cpp +++ b/source/backend/engine/CarlaEngineNative.cpp @@ -2307,11 +2307,19 @@ CARLA_BACKEND_START_NAMESPACE CarlaEngine* CarlaEngine::newJack() { return nullptr; } +# ifdef USING_JUCE +CarlaEngine* CarlaEngine::newJuce(const AudioApi) { return nullptr; } +uint CarlaEngine::getJuceApiCount() { return 0; } +const char* CarlaEngine::getJuceApiName(const uint) { return nullptr; } +const char* const* CarlaEngine::getJuceApiDeviceNames(const uint) { return nullptr; } +const EngineDriverDeviceInfo* CarlaEngine::getJuceDeviceInfo(const uint, const char* const) { return nullptr; } +# else CarlaEngine* CarlaEngine::newRtAudio(const AudioApi) { return nullptr; } uint CarlaEngine::getRtAudioApiCount() { return 0; } const char* CarlaEngine::getRtAudioApiName(const uint) { return nullptr; } const char* const* CarlaEngine::getRtAudioApiDeviceNames(const uint) { return nullptr; } const EngineDriverDeviceInfo* CarlaEngine::getRtAudioDeviceInfo(const uint, const char* const) { return nullptr; } +# endif CARLA_BACKEND_END_NAMESPACE diff --git a/source/backend/engine/Makefile b/source/backend/engine/Makefile index 4882d0140..680f36d38 100644 --- a/source/backend/engine/Makefile +++ b/source/backend/engine/Makefile @@ -26,8 +26,15 @@ endif OBJSa = $(OBJS) \ $(OBJDIR)/CarlaEngineJack.cpp.o \ - $(OBJDIR)/CarlaEngineNative.cpp.o \ + $(OBJDIR)/CarlaEngineNative.cpp.o + +ifeq ($(USING_JUCE),true) +# OBJSa += \ +# - $(OBJDIR)/CarlaEngineJuce.cpp.o +else +OBJSa += \ $(OBJDIR)/CarlaEngineRtAudio.cpp.o +endif OBJSp = $(OBJS) \ $(OBJDIR)/CarlaEngineNative.cpp.exp.o diff --git a/source/backend/plugin/CarlaPluginBridge.cpp b/source/backend/plugin/CarlaPluginBridge.cpp index 0bfd4d3b5..ae3bb3595 100644 --- a/source/backend/plugin/CarlaPluginBridge.cpp +++ b/source/backend/plugin/CarlaPluginBridge.cpp @@ -237,6 +237,11 @@ protected: else carla_setenv("ENGINE_OPTION_PLUGIN_PATH_VST2", ""); + if (options.pathVST3 != nullptr) + carla_setenv("ENGINE_OPTION_PLUGIN_PATH_VST3", options.pathVST3); + else + carla_setenv("ENGINE_OPTION_PLUGIN_PATH_VST3", ""); + if (options.pathSF2 != nullptr) carla_setenv("ENGINE_OPTION_PLUGIN_PATH_SF2", options.pathSF2); else diff --git a/source/backend/plugin/CarlaPluginVST2.cpp b/source/backend/plugin/CarlaPluginVST2.cpp index 4d6cfebee..3979aeb52 100644 --- a/source/backend/plugin/CarlaPluginVST2.cpp +++ b/source/backend/plugin/CarlaPluginVST2.cpp @@ -18,6 +18,8 @@ #include "CarlaPluginInternal.hpp" #include "CarlaEngine.hpp" +#ifndef USING_JUCE + #include "CarlaVstUtils.hpp" #include "CarlaMathUtils.hpp" @@ -2619,6 +2621,8 @@ CarlaPluginVST2* CarlaPluginVST2::sLastCarlaPluginVST2 = nullptr; CARLA_BACKEND_END_NAMESPACE +#endif // USING_JUCE + // ------------------------------------------------------------------------------------------------------------------- CARLA_BACKEND_START_NAMESPACE @@ -2627,6 +2631,9 @@ CarlaPlugin* CarlaPlugin::newVST2(const Initializer& init) { carla_debug("CarlaPlugin::newVST2({%p, \"%s\", \"%s\", " P_INT64 "})", init.engine, init.filename, init.name, init.uniqueId); +#ifdef USING_JUCE + return newJuce(init, "VST2"); +#else CarlaPluginVST2* const plugin(new CarlaPluginVST2(init.engine, init.id)); if (! plugin->init(init.filename, init.name, init.uniqueId, init.options)) @@ -2636,6 +2643,7 @@ CarlaPlugin* CarlaPlugin::newVST2(const Initializer& init) } return plugin; +#endif } // ------------------------------------------------------------------------------------------------------------------- diff --git a/source/frontend/carla_backend.py b/source/frontend/carla_backend.py index f1de07aa8..bad216b0b 100644 --- a/source/frontend/carla_backend.py +++ b/source/frontend/carla_backend.py @@ -394,14 +394,22 @@ PLUGIN_LV2 = 4 # VST2 plugin. PLUGIN_VST2 = 5 +# VST3 plugin. +# @note Windows and MacOS only +PLUGIN_VST3 = 6 + +# AU plugin. +# @note MacOS only +PLUGIN_AU = 7 + # SF2 file (SoundFont). -PLUGIN_SF2 = 6 +PLUGIN_SF2 = 8 # SFZ file. -PLUGIN_SFZ = 7 +PLUGIN_SFZ = 9 # JACK application. -PLUGIN_JACK = 8 +PLUGIN_JACK = 10 # ------------------------------------------------------------------------------------------------------------ # Plugin Category diff --git a/source/frontend/carla_database.py b/source/frontend/carla_database.py index 3c67878f1..853fc69d9 100755 --- a/source/frontend/carla_database.py +++ b/source/frontend/carla_database.py @@ -83,6 +83,15 @@ def findBinaries(binPath, OS): return binaries +def findVST3Binaries(binPath): + binaries = [] + + for root, dirs, files in os.walk(binPath): + for name in [name for name in files if name.lower().endswith(".vst3")]: + binaries.append(os.path.join(root, name)) + + return binaries + def findLV2Bundles(bundlePath): bundles = [] @@ -93,12 +102,13 @@ def findLV2Bundles(bundlePath): return bundles -def findMacVSTBundles(bundlePath): +def findMacVSTBundles(bundlePath, isVST3): bundles = [] + extension = ".vst3" if isVST3 else ".vst" for root, dirs, files in os.walk(bundlePath, followlinks=True): #if root == bundlePath: continue # FIXME - for name in [name for name in dirs if name.lower().endswith(".vst")]: + for name in [name for name in dirs if name.lower().endswith(extension)]: bundles.append(os.path.join(root, name)) return bundles @@ -341,6 +351,9 @@ def checkPluginLV2(filename, tool, wineSettings=None): def checkPluginVST2(filename, tool, wineSettings=None): return runCarlaDiscovery(PLUGIN_VST2, "VST2", filename, tool, wineSettings) +def checkPluginVST3(filename, tool, wineSettings=None): + return runCarlaDiscovery(PLUGIN_VST3, "VST3", filename, tool, wineSettings) + def checkFileSF2(filename, tool): return runCarlaDiscovery(PLUGIN_SF2, "SF2", filename, tool) @@ -369,6 +382,8 @@ class SearchPluginsThread(QThread): self.fCheckDSSI = False self.fCheckLV2 = False self.fCheckVST2 = False + self.fCheckVST3 = False + self.fCheckAU = False self.fCheckSF2 = False self.fCheckSFZ = False @@ -409,11 +424,13 @@ class SearchPluginsThread(QThread): self.fCheckWin32 = win32 self.fCheckWin64 = win64 - def setSearchPluginTypes(self, ladspa, dssi, lv2, vst2, sf2, sfz): + def setSearchPluginTypes(self, ladspa, dssi, lv2, vst2, vst3, au, sf2, sfz): self.fCheckLADSPA = ladspa self.fCheckDSSI = dssi self.fCheckLV2 = lv2 self.fCheckVST2 = vst2 + self.fCheckVST3 = vst3 and (MACOS or WINDOWS) + self.fCheckAU = au and MACOS self.fCheckSF2 = sf2 self.fCheckSFZ = sfz @@ -432,16 +449,26 @@ class SearchPluginsThread(QThread): if self.fCheckLADSPA: pluginCount += 1 if self.fCheckDSSI: pluginCount += 1 if self.fCheckVST2: pluginCount += 1 + if self.fCheckVST3: pluginCount += 1 # Increase count by the number of externally discoverable plugin types if self.fCheckNative: self.fCurCount += pluginCount + # MacOS and Windows are the only VST3 supported OSes + if self.fCheckVST3 and not (MACOS or WINDOWS): + self.fCurCount -= 1 if self.fCheckPosix32: self.fCurCount += pluginCount + # MacOS is the only VST3 supported posix OS + if self.fCheckVST3 and not MACOS: + self.fCurCount -= 1 if self.fCheckPosix64: self.fCurCount += pluginCount + # MacOS is the only VST3 supported posix OS + if self.fCheckVST3 and not MACOS: + self.fCurCount -= 1 if self.fCheckWin32: self.fCurCount += pluginCount @@ -710,7 +737,7 @@ class SearchPluginsThread(QThread): for iPATH in VST2_PATH: if MACOS and not isWine: - binaries = findMacVSTBundles(iPATH) + binaries = findMacVSTBundles(iPATH, False) else: binaries = findBinaries(iPATH, OS) for binary in binaries: @@ -1128,8 +1155,12 @@ class PluginRefreshW(QDialog): self.ui.ch_lv2.isChecked(), self.ui.ch_vst.isChecked(), self.ui.ch_sf2.isChecked(), self.ui.ch_sfz.isChecked()) + # TODO + vst3 = False + au = False + self.fThread.setSearchBinaryTypes(native, posix32, posix64, win32, win64) - self.fThread.setSearchPluginTypes(ladspa, dssi, lv2, vst, sf2, sfz) + self.fThread.setSearchPluginTypes(ladspa, dssi, lv2, vst, vst3, au, sf2, sfz) self.fThread.start() # ------------------------------------------------------------------------------------------------------------------ diff --git a/source/frontend/carla_host.py b/source/frontend/carla_host.py index 843a2f7db..ec425f556 100644 --- a/source/frontend/carla_host.py +++ b/source/frontend/carla_host.py @@ -2853,6 +2853,7 @@ def setEngineSettings(host): DSSI_PATH = toList(settings.value(CARLA_KEY_PATHS_DSSI, CARLA_DEFAULT_DSSI_PATH)) LV2_PATH = toList(settings.value(CARLA_KEY_PATHS_LV2, CARLA_DEFAULT_LV2_PATH)) VST2_PATH = toList(settings.value(CARLA_KEY_PATHS_VST2, CARLA_DEFAULT_VST2_PATH)) + VST3_PATH = toList(settings.value(CARLA_KEY_PATHS_VST3, CARLA_DEFAULT_VST3_PATH)) SF2_PATH = toList(settings.value(CARLA_KEY_PATHS_SF2, CARLA_DEFAULT_SF2_PATH)) SFZ_PATH = toList(settings.value(CARLA_KEY_PATHS_SFZ, CARLA_DEFAULT_SFZ_PATH)) @@ -2860,6 +2861,7 @@ def setEngineSettings(host): host.set_engine_option(ENGINE_OPTION_PLUGIN_PATH, PLUGIN_DSSI, splitter.join(DSSI_PATH)) host.set_engine_option(ENGINE_OPTION_PLUGIN_PATH, PLUGIN_LV2, splitter.join(LV2_PATH)) host.set_engine_option(ENGINE_OPTION_PLUGIN_PATH, PLUGIN_VST2, splitter.join(VST2_PATH)) + host.set_engine_option(ENGINE_OPTION_PLUGIN_PATH, PLUGIN_VST3, splitter.join(VST3_PATH)) host.set_engine_option(ENGINE_OPTION_PLUGIN_PATH, PLUGIN_SF2, splitter.join(SF2_PATH)) host.set_engine_option(ENGINE_OPTION_PLUGIN_PATH, PLUGIN_SFZ, splitter.join(SFZ_PATH)) diff --git a/source/frontend/carla_shared.py b/source/frontend/carla_shared.py index 752fa20f7..7eba9d0fe 100644 --- a/source/frontend/carla_shared.py +++ b/source/frontend/carla_shared.py @@ -216,6 +216,7 @@ CARLA_KEY_PATHS_LADSPA = "Paths/LADSPA" CARLA_KEY_PATHS_DSSI = "Paths/DSSI" CARLA_KEY_PATHS_LV2 = "Paths/LV2" CARLA_KEY_PATHS_VST2 = "Paths/VST2" +CARLA_KEY_PATHS_VST3 = "Paths/VST3" CARLA_KEY_PATHS_SF2 = "Paths/SF2" CARLA_KEY_PATHS_SFZ = "Paths/SFZ" @@ -312,6 +313,7 @@ DEFAULT_LADSPA_PATH = "" DEFAULT_DSSI_PATH = "" DEFAULT_LV2_PATH = "" DEFAULT_VST2_PATH = "" +DEFAULT_VST3_PATH = "" DEFAULT_SF2_PATH = "" DEFAULT_SFZ_PATH = "" @@ -352,14 +354,19 @@ if WINDOWS: if kIs64bit: DEFAULT_VST2_PATH += ";" + COMMONPROGRAMFILES + "\\VST2" + DEFAULT_VST3_PATH = COMMONPROGRAMFILES + "\\VST3" + DEFAULT_SF2_PATH = APPDATA + "\\SF2" DEFAULT_SFZ_PATH = APPDATA + "\\SFZ" if PROGRAMFILESx86: DEFAULT_LADSPA_PATH += ";" + PROGRAMFILESx86 + "\\LADSPA" DEFAULT_DSSI_PATH += ";" + PROGRAMFILESx86 + "\\DSSI" - DEFAULT_VST2_PATH += ";" + PROGRAMFILESx86 + "\\VstPlugins" - DEFAULT_VST2_PATH += ";" + PROGRAMFILESx86 + "\\Steinberg\\VstPlugins" + DEFAULT_VST2_PATH += ";" + PROGRAMFILESx86 + "\\VstPlugins" + DEFAULT_VST2_PATH += ";" + PROGRAMFILESx86 + "\\Steinberg\\VstPlugins" + + if COMMONPROGRAMFILESx86: + DEFAULT_VST3_PATH += COMMONPROGRAMFILESx86 + "\\VST3" elif HAIKU: splitter = ":" @@ -376,6 +383,9 @@ elif HAIKU: DEFAULT_VST2_PATH = HOME + "/.vst" DEFAULT_VST2_PATH += ":/boot/common/add-ons/vst" + DEFAULT_VST3_PATH = HOME + "/.vst3" + DEFAULT_VST3_PATH += ":/boot/common/add-ons/vst3" + elif MACOS: splitter = ":" @@ -391,6 +401,9 @@ elif MACOS: DEFAULT_VST2_PATH = HOME + "/Library/Audio/Plug-Ins/VST" DEFAULT_VST2_PATH += ":/Library/Audio/Plug-Ins/VST" + DEFAULT_VST3_PATH = HOME + "/Library/Audio/Plug-Ins/VST3" + DEFAULT_VST3_PATH += ":/Library/Audio/Plug-Ins/VST3" + else: splitter = ":" @@ -410,6 +423,10 @@ else: DEFAULT_VST2_PATH += ":/usr/lib/vst" DEFAULT_VST2_PATH += ":/usr/local/lib/vst" + DEFAULT_VST3_PATH = HOME + "/.vst3" + DEFAULT_VST3_PATH += ":/usr/lib/vst3" + DEFAULT_VST3_PATH += ":/usr/local/lib/vst3" + DEFAULT_SF2_PATH = HOME + "/.sounds/sf2" DEFAULT_SF2_PATH += ":/usr/share/sounds/sf2" @@ -424,9 +441,11 @@ if not WINDOWS: if os.path.exists(winePrefix): DEFAULT_VST2_PATH += ":" + winePrefix + "/drive_c/Program Files/VstPlugins" + DEFAULT_VST3_PATH += ":" + winePrefix + "/drive_c/Program Files/Common Files/VST3" if kIs64bit and os.path.exists(winePrefix + "/drive_c/Program Files (x86)"): DEFAULT_VST2_PATH += ":" + winePrefix + "/drive_c/Program Files (x86)/VstPlugins" + DEFAULT_VST3_PATH += ":" + winePrefix + "/drive_c/Program Files (x86)/Common Files/VST3" del winePrefix @@ -456,6 +475,7 @@ if readEnvVars: CARLA_DEFAULT_DSSI_PATH = os.getenv("DSSI_PATH", DEFAULT_DSSI_PATH).split(splitter) CARLA_DEFAULT_LV2_PATH = os.getenv("LV2_PATH", DEFAULT_LV2_PATH).split(splitter) CARLA_DEFAULT_VST2_PATH = os.getenv("VST_PATH", DEFAULT_VST2_PATH).split(splitter) + CARLA_DEFAULT_VST3_PATH = os.getenv("VST3_PATH", DEFAULT_VST3_PATH).split(splitter) CARLA_DEFAULT_SF2_PATH = os.getenv("SF2_PATH", DEFAULT_SF2_PATH).split(splitter) CARLA_DEFAULT_SFZ_PATH = os.getenv("SFZ_PATH", DEFAULT_SFZ_PATH).split(splitter) @@ -464,6 +484,7 @@ else: CARLA_DEFAULT_DSSI_PATH = DEFAULT_DSSI_PATH.split(splitter) CARLA_DEFAULT_LV2_PATH = DEFAULT_LV2_PATH.split(splitter) CARLA_DEFAULT_VST2_PATH = DEFAULT_VST2_PATH.split(splitter) + CARLA_DEFAULT_VST3_PATH = DEFAULT_VST3_PATH.split(splitter) CARLA_DEFAULT_SF2_PATH = DEFAULT_SF2_PATH.split(splitter) CARLA_DEFAULT_SFZ_PATH = DEFAULT_SFZ_PATH.split(splitter) @@ -474,6 +495,7 @@ del DEFAULT_LADSPA_PATH del DEFAULT_DSSI_PATH del DEFAULT_LV2_PATH del DEFAULT_VST2_PATH +del DEFAULT_VST3_PATH del DEFAULT_SF2_PATH del DEFAULT_SFZ_PATH diff --git a/source/frontend/carla_skin.py b/source/frontend/carla_skin.py index 5a511afa0..d44bcd02f 100644 --- a/source/frontend/carla_skin.py +++ b/source/frontend/carla_skin.py @@ -1923,7 +1923,7 @@ def getColorAndSkinStyle(host, pluginId): pluginMaker = pluginInfo['maker'] uniqueId = pluginInfo['uniqueId'] - if pluginInfo['type'] == PLUGIN_VST2: + if pluginInfo['type'] in (PLUGIN_VST2, PLUGIN_VST3, PLUGIN_AU): progCount = host.get_program_count(pluginId) else: progCount = host.get_midi_program_count(pluginId) @@ -1961,7 +1961,7 @@ def getColorAndSkinStyle(host, pluginId): # Presets if progCount > 1 and (pluginInfo['hints'] & PLUGIN_USES_MULTI_PROGS) == 0: - if pluginInfo['type'] == PLUGIN_VST2: + if pluginInfo['type'] in (PLUGIN_VST2, PLUGIN_VST3, PLUGIN_AU): return (color, "presets") return (color, "mpresets") diff --git a/source/frontend/carla_utils.py b/source/frontend/carla_utils.py index de3709d02..88d927ae7 100644 --- a/source/frontend/carla_utils.py +++ b/source/frontend/carla_utils.py @@ -42,6 +42,10 @@ def getPluginTypeAsString(ptype): return "LV2" if ptype == PLUGIN_VST2: return "VST2" + if ptype == PLUGIN_VST3: + return "VST3" + if ptype == PLUGIN_AU: + return "AU" if ptype == PLUGIN_SF2: return "SF2" if ptype == PLUGIN_SFZ: @@ -70,6 +74,10 @@ def getPluginTypeFromString(stype): return PLUGIN_LV2 if stype in ("vst2", "vst"): return PLUGIN_VST2 + if stype == "vst3": + return PLUGIN_VST3 + if stype in ("au", "audiounit"): + return PLUGIN_AU if stype == "sf2": return PLUGIN_SF2 if stype == "sfz": diff --git a/source/modules/Makefile b/source/modules/Makefile index c822c8a51..51ffae8a2 100644 --- a/source/modules/Makefile +++ b/source/modules/Makefile @@ -18,4 +18,15 @@ clean: $(MAKE) clean -C sfzero $(MAKE) clean -C water + $(MAKE) clean -C juce_audio_basics + $(MAKE) clean -C juce_audio_devices + $(MAKE) clean -C juce_audio_formats + $(MAKE) clean -C juce_audio_processors + $(MAKE) clean -C juce_core + $(MAKE) clean -C juce_data_structures + $(MAKE) clean -C juce_events + $(MAKE) clean -C juce_graphics + $(MAKE) clean -C juce_gui_basics + $(MAKE) clean -C juce_gui_extra + # ---------------------------------------------------------------------------------------------------------------------------- diff --git a/source/utils/CarlaBackendUtils.hpp b/source/utils/CarlaBackendUtils.hpp index a557c9060..26ca3af0a 100644 --- a/source/utils/CarlaBackendUtils.hpp +++ b/source/utils/CarlaBackendUtils.hpp @@ -96,6 +96,10 @@ const char* PluginType2Str(const PluginType type) noexcept return "PLUGIN_LV2"; case PLUGIN_VST2: return "PLUGIN_VST2"; + case PLUGIN_VST3: + return "PLUGIN_VST3"; + case PLUGIN_AU: + return "PLUGIN_AU"; case PLUGIN_SF2: return "PLUGIN_SF2"; case PLUGIN_SFZ: @@ -482,6 +486,10 @@ const char* getPluginTypeAsString(const PluginType type) noexcept return "LV2"; case PLUGIN_VST2: return "VST2"; + case PLUGIN_VST3: + return "VST3"; + case PLUGIN_AU: + return "AU";; case PLUGIN_SF2: return "SF2"; case PLUGIN_SFZ: @@ -519,6 +527,10 @@ PluginType getPluginTypeFromString(const char* const ctype) noexcept return PLUGIN_LV2; if (stype == "vst2" || stype == "vst") return PLUGIN_VST2; + if (stype == "vst3") + return PLUGIN_VST3; + if (stype == "au" || stype == "audiounit") + return PLUGIN_AU; if (stype == "sf2") return PLUGIN_SF2; if (stype == "sfz") diff --git a/source/utils/CarlaEngineUtils.hpp b/source/utils/CarlaEngineUtils.hpp index 386e070bc..7a5c06020 100644 --- a/source/utils/CarlaEngineUtils.hpp +++ b/source/utils/CarlaEngineUtils.hpp @@ -42,6 +42,8 @@ const char* EngineType2Str(const EngineType type) noexcept return "kEngineTypeNull"; case kEngineTypeJack: return "kEngineTypeJack"; + case kEngineTypeJuce: + return "kEngineTypeJuce"; case kEngineTypeRtAudio: return "kEngineTypeRtAudio"; case kEngineTypePlugin: diff --git a/source/utils/CarlaStateUtils.cpp b/source/utils/CarlaStateUtils.cpp index fd95c4773..ca3763c7b 100644 --- a/source/utils/CarlaStateUtils.cpp +++ b/source/utils/CarlaStateUtils.cpp @@ -525,6 +525,13 @@ void CarlaStateSave::dumpToMemoryStream(MemoryOutputStream& content) const infoXml << " " << xmlSafeString(binary, true) << "\n"; infoXml << " " << water::int64(uniqueId) << "\n"; break; + case PLUGIN_VST3: + infoXml << " " << xmlSafeString(binary, true) << "\n"; + infoXml << " \n"; + break; + case PLUGIN_AU: + infoXml << " " << xmlSafeString(label, true) << "\n"; + break; case PLUGIN_SF2: infoXml << " " << xmlSafeString(binary, true) << "\n"; infoXml << " \n";