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";