diff --git a/resources/ui/carla_settings.ui b/resources/ui/carla_settings.ui
index e499be796..224d66a0b 100644
--- a/resources/ui/carla_settings.ui
+++ b/resources/ui/carla_settings.ui
@@ -2159,6 +2159,11 @@
JSFX
+ -
+
+ CLAP
+
+
-
@@ -2385,6 +2390,28 @@
+
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+ -
+
+
+
+
-
diff --git a/source/backend/CarlaBackend.h b/source/backend/CarlaBackend.h
index e286c285f..45b560635 100644
--- a/source/backend/CarlaBackend.h
+++ b/source/backend/CarlaBackend.h
@@ -681,7 +681,12 @@ typedef enum {
/*!
* CLAP plugin.
*/
- PLUGIN_CLAP = 14
+ PLUGIN_CLAP = 14,
+
+ /*!
+ * Terminator/count, not a plugin type.
+ */
+ PLUGIN_TYPE_COUNT = 15
} PluginType;
diff --git a/source/backend/CarlaEngine.hpp b/source/backend/CarlaEngine.hpp
index b9f16a479..e5811cc6e 100644
--- a/source/backend/CarlaEngine.hpp
+++ b/source/backend/CarlaEngine.hpp
@@ -277,6 +277,7 @@ struct CARLA_API EngineOptions {
const char* pathSF2;
const char* pathSFZ;
const char* pathJSFX;
+ const char* pathCLAP;
const char* binaryDir;
const char* resourceDir;
diff --git a/source/backend/CarlaStandalone.cpp b/source/backend/CarlaStandalone.cpp
index a4ef3df73..d9151ff04 100644
--- a/source/backend/CarlaStandalone.cpp
+++ b/source/backend/CarlaStandalone.cpp
@@ -272,6 +272,9 @@ static void carla_engine_init_common(const CarlaHostStandalone& standalone, Carl
if (const char* const pathJSFX = std::getenv("ENGINE_OPTION_PLUGIN_PATH_JSFX"))
engine->setOption(CB::ENGINE_OPTION_PLUGIN_PATH, CB::PLUGIN_JSFX, pathJSFX);
+ if (const char* const pathCLAP = std::getenv("ENGINE_OPTION_PLUGIN_PATH_CLAP"))
+ engine->setOption(CB::ENGINE_OPTION_PLUGIN_PATH, CB::PLUGIN_CLAP, pathCLAP);
+
if (const char* const binaryDir = std::getenv("ENGINE_OPTION_PATH_BINARIES"))
engine->setOption(CB::ENGINE_OPTION_PATH_BINARIES, 0, binaryDir);
else
@@ -339,6 +342,9 @@ static void carla_engine_init_common(const CarlaHostStandalone& standalone, Carl
if (standalone.engineOptions.pathJSFX != nullptr)
engine->setOption(CB::ENGINE_OPTION_PLUGIN_PATH, CB::PLUGIN_JSFX, standalone.engineOptions.pathJSFX);
+ if (standalone.engineOptions.pathCLAP != nullptr)
+ engine->setOption(CB::ENGINE_OPTION_PLUGIN_PATH, CB::PLUGIN_CLAP, standalone.engineOptions.pathCLAP);
+
if (standalone.engineOptions.binaryDir != nullptr && standalone.engineOptions.binaryDir[0] != '\0')
engine->setOption(CB::ENGINE_OPTION_PATH_BINARIES, 0, standalone.engineOptions.binaryDir);
else
@@ -843,7 +849,7 @@ void carla_set_engine_option(CarlaHostHandle handle, EngineOption option, int va
case CB::ENGINE_OPTION_PLUGIN_PATH:
CARLA_SAFE_ASSERT_RETURN(value > CB::PLUGIN_NONE,);
- CARLA_SAFE_ASSERT_RETURN(value <= CB::PLUGIN_JSFX,);
+ CARLA_SAFE_ASSERT_RETURN(value <= CB::PLUGIN_TYPE_COUNT,);
CARLA_SAFE_ASSERT_RETURN(valueStr != nullptr,);
switch (value)
@@ -888,6 +894,11 @@ void carla_set_engine_option(CarlaHostHandle handle, EngineOption option, int va
delete[] shandle.engineOptions.pathJSFX;
shandle.engineOptions.pathJSFX = carla_strdup_safe(valueStr);
break;
+ case CB::PLUGIN_CLAP:
+ if (shandle.engineOptions.pathCLAP != nullptr)
+ delete[] shandle.engineOptions.pathCLAP;
+ shandle.engineOptions.pathCLAP = carla_strdup_safe(valueStr);
+ break;
}
break;
diff --git a/source/backend/engine/CarlaEngine.cpp b/source/backend/engine/CarlaEngine.cpp
index cc4876acd..a9149fa73 100644
--- a/source/backend/engine/CarlaEngine.cpp
+++ b/source/backend/engine/CarlaEngine.cpp
@@ -737,6 +737,7 @@ bool CarlaEngine::addPlugin(const BinaryType btype,
switch (ptype)
{
case PLUGIN_NONE:
+ case PLUGIN_TYPE_COUNT:
break;
case PLUGIN_LADSPA:
@@ -1424,6 +1425,9 @@ bool CarlaEngine::loadFile(const char* const filename)
if (extension == "vst3")
return addPlugin(getBinaryTypeFromFile(filename), PLUGIN_VST3, filename, nullptr, nullptr, 0, nullptr);
+ if (extension == "clap")
+ return addPlugin(getBinaryTypeFromFile(filename), PLUGIN_CLAP, filename, nullptr, nullptr, 0, nullptr);
+
// -------------------------------------------------------------------
setLastError("Unknown file extension");
@@ -2048,7 +2052,7 @@ void CarlaEngine::setOption(const EngineOption option, const int value, const ch
break;
case ENGINE_OPTION_PLUGIN_PATH:
CARLA_SAFE_ASSERT_RETURN(value > PLUGIN_NONE,);
- CARLA_SAFE_ASSERT_RETURN(value <= PLUGIN_JSFX,);
+ CARLA_SAFE_ASSERT_RETURN(value <= PLUGIN_TYPE_COUNT,);
switch (value)
{
@@ -2116,6 +2120,14 @@ void CarlaEngine::setOption(const EngineOption option, const int value, const ch
else
pData->options.pathJSFX = nullptr;
break;
+ case PLUGIN_CLAP:
+ if (pData->options.pathCLAP != nullptr)
+ delete[] pData->options.pathCLAP;
+ if (valueStr != nullptr)
+ pData->options.pathCLAP = carla_strdup_safe(valueStr);
+ else
+ pData->options.pathCLAP = nullptr;
+ break;
default:
return carla_stderr("CarlaEngine::setOption(%i:%s, %i, \"%s\") - Invalid plugin type",
option, EngineOption2Str(option), value, valueStr);
@@ -2419,6 +2431,7 @@ void CarlaEngine::saveProjectInternal(water::MemoryOutputStream& outStream) cons
outSettings << " " << xmlSafeString(options.pathSF2, true) << "\n";
outSettings << " " << xmlSafeString(options.pathSFZ, true) << "\n";
outSettings << " " << xmlSafeString(options.pathJSFX, true) << "\n";
+ outSettings << " " << xmlSafeString(options.pathCLAP, true) << "\n";
}
outSettings << " \n";
@@ -2841,6 +2854,12 @@ bool CarlaEngine::loadProjectInternal(water::XmlDocument& xmlDoc, const bool alw
value = PLUGIN_JSFX;
valueStr = text.toRawUTF8();
}
+ else if (tag == "CLAP_PATH")
+ {
+ option = ENGINE_OPTION_PLUGIN_PATH;
+ value = PLUGIN_CLAP;
+ valueStr = text.toRawUTF8();
+ }
}
if (option == -1)
@@ -2853,7 +2872,7 @@ bool CarlaEngine::loadProjectInternal(water::XmlDocument& xmlDoc, const bool alw
continue;
if (tag == "VST3_PATH" || tag == "AU_PATH")
continue;
- if (tag == "SF2_PATH" || tag == "SFZ_PATH" || tag == "JSFX_PATH")
+ if (tag == "SF2_PATH" || tag == "SFZ_PATH" || tag == "JSFX_PATH" || tag == "CLAP_PATH")
continue;
// hmm something is wrong..
@@ -3040,7 +3059,7 @@ bool CarlaEngine::loadProjectInternal(water::XmlDocument& xmlDoc, const bool alw
const void* extraStuff = nullptr;
static const char kTrue[] = "true";
- const PluginType ptype(getPluginTypeFromString(stateSave.type));
+ const PluginType ptype = getPluginTypeFromString(stateSave.type);
switch (ptype)
{
@@ -3054,6 +3073,7 @@ bool CarlaEngine::loadProjectInternal(water::XmlDocument& xmlDoc, const bool alw
case PLUGIN_VST3:
case PLUGIN_SFZ:
case PLUGIN_JSFX:
+ case PLUGIN_CLAP:
if (stateSave.binary != nullptr && stateSave.binary[0] != '\0' &&
! (File::isAbsolutePath(stateSave.binary) && File(stateSave.binary).exists()))
{
@@ -3068,6 +3088,7 @@ bool CarlaEngine::loadProjectInternal(water::XmlDocument& xmlDoc, const bool alw
case PLUGIN_SF2: searchPath = pData->options.pathSF2; break;
case PLUGIN_SFZ: searchPath = pData->options.pathSFZ; break;
case PLUGIN_JSFX: searchPath = pData->options.pathJSFX; break;
+ case PLUGIN_CLAP: searchPath = pData->options.pathCLAP; break;
default: searchPath = nullptr; break;
}
@@ -3089,6 +3110,7 @@ bool CarlaEngine::loadProjectInternal(water::XmlDocument& xmlDoc, const bool alw
case PLUGIN_SF2: searchPath = std::getenv("SF2_PATH"); break;
case PLUGIN_SFZ: searchPath = std::getenv("SFZ_PATH"); break;
case PLUGIN_JSFX: searchPath = std::getenv("JSFX_PATH"); break;
+ case PLUGIN_CLAP: searchPath = std::getenv("CLAP_PATH"); break;
default: searchPath = nullptr; break;
}
diff --git a/source/backend/engine/CarlaEngineData.cpp b/source/backend/engine/CarlaEngineData.cpp
index 9af889c9f..a2fb54608 100644
--- a/source/backend/engine/CarlaEngineData.cpp
+++ b/source/backend/engine/CarlaEngineData.cpp
@@ -239,6 +239,7 @@ EngineOptions::EngineOptions() noexcept
pathSF2(nullptr),
pathSFZ(nullptr),
pathJSFX(nullptr),
+ pathCLAP(nullptr),
binaryDir(nullptr),
resourceDir(nullptr),
clientNamePrefix(nullptr),
@@ -312,6 +313,11 @@ EngineOptions::~EngineOptions() noexcept
delete[] pathJSFX;
pathJSFX = nullptr;
}
+ if (pathCLAP != nullptr)
+ {
+ delete[] pathCLAP;
+ pathCLAP = nullptr;
+ }
if (binaryDir != nullptr)
{
delete[] binaryDir;
diff --git a/source/frontend/carla_host.py b/source/frontend/carla_host.py
index 4ea7db76f..12ba51a44 100644
--- a/source/frontend/carla_host.py
+++ b/source/frontend/carla_host.py
@@ -3421,6 +3421,7 @@ def setEngineSettings(host, oscPort = None):
SF2_PATH = settings.value(CARLA_KEY_PATHS_SF2, CARLA_DEFAULT_SF2_PATH, list)
SFZ_PATH = settings.value(CARLA_KEY_PATHS_SFZ, CARLA_DEFAULT_SFZ_PATH, list)
JSFX_PATH = settings.value(CARLA_KEY_PATHS_JSFX, CARLA_DEFAULT_JSFX_PATH, list)
+ CLAP_PATH = settings.value(CARLA_KEY_PATHS_CLAP, CARLA_DEFAULT_CLAP_PATH, list)
host.set_engine_option(ENGINE_OPTION_PLUGIN_PATH, PLUGIN_LADSPA, splitter.join(LADSPA_PATH))
host.set_engine_option(ENGINE_OPTION_PLUGIN_PATH, PLUGIN_DSSI, splitter.join(DSSI_PATH))
@@ -3430,6 +3431,7 @@ def setEngineSettings(host, oscPort = None):
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))
host.set_engine_option(ENGINE_OPTION_PLUGIN_PATH, PLUGIN_JSFX, splitter.join(JSFX_PATH))
+ host.set_engine_option(ENGINE_OPTION_PLUGIN_PATH, PLUGIN_CLAP, splitter.join(CLAP_PATH))
# --------------------------------------------------------------------------------------------------------
# don't continue if plugin
diff --git a/source/frontend/carla_settings.py b/source/frontend/carla_settings.py
index 76a2c7fd2..4038d3e5b 100755
--- a/source/frontend/carla_settings.py
+++ b/source/frontend/carla_settings.py
@@ -46,7 +46,8 @@ from carla_backend import (
PLUGIN_VST3,
PLUGIN_SF2,
PLUGIN_SFZ,
- PLUGIN_JSFX
+ PLUGIN_JSFX,
+ PLUGIN_CLAP,
)
from carla_shared import (
@@ -99,6 +100,7 @@ from carla_shared import (
CARLA_KEY_PATHS_SF2,
CARLA_KEY_PATHS_SFZ,
CARLA_KEY_PATHS_JSFX,
+ CARLA_KEY_PATHS_CLAP,
CARLA_KEY_WINE_EXECUTABLE,
CARLA_KEY_WINE_AUTO_PREFIX,
CARLA_KEY_WINE_FALLBACK_PREFIX,
@@ -174,6 +176,7 @@ from carla_shared import (
CARLA_DEFAULT_SF2_PATH,
CARLA_DEFAULT_SFZ_PATH,
CARLA_DEFAULT_JSFX_PATH,
+ CARLA_DEFAULT_CLAP_PATH,
getAndSetPath,
getIcon,
fontMetricsHorizontalAdvance,
@@ -511,6 +514,7 @@ class CarlaSettingsW(QDialog):
PLUGINPATH_INDEX_SF2 = 5
PLUGINPATH_INDEX_SFZ = 6
PLUGINPATH_INDEX_JSFX = 7
+ PLUGINPATH_INDEX_CLAP = 8
# Single and Multiple client mode is only for JACK,
# but we still want to match QComboBox index to backend defines,
@@ -640,6 +644,7 @@ class CarlaSettingsW(QDialog):
self.ui.lw_sf2.currentRowChanged.connect(self.slot_pluginPathRowChanged)
self.ui.lw_sfz.currentRowChanged.connect(self.slot_pluginPathRowChanged)
self.ui.lw_jsfx.currentRowChanged.connect(self.slot_pluginPathRowChanged)
+ self.ui.lw_clap.currentRowChanged.connect(self.slot_pluginPathRowChanged)
self.ui.b_filepaths_add.clicked.connect(self.slot_addFilePath)
self.ui.b_filepaths_remove.clicked.connect(self.slot_removeFilePath)
@@ -666,6 +671,7 @@ class CarlaSettingsW(QDialog):
self.ui.lw_sf2.setCurrentRow(0)
self.ui.lw_sfz.setCurrentRow(0)
self.ui.lw_jsfx.setCurrentRow(0)
+ self.ui.lw_clap.setCurrentRow(0)
self.ui.lw_files_audio.setCurrentRow(0)
self.ui.lw_files_midi.setCurrentRow(0)
@@ -877,6 +883,7 @@ class CarlaSettingsW(QDialog):
sf2s = settings.value(CARLA_KEY_PATHS_SF2, CARLA_DEFAULT_SF2_PATH, list)
sfzs = settings.value(CARLA_KEY_PATHS_SFZ, CARLA_DEFAULT_SFZ_PATH, list)
jsfxs = settings.value(CARLA_KEY_PATHS_JSFX, CARLA_DEFAULT_JSFX_PATH, list)
+ claps = settings.value(CARLA_KEY_PATHS_CLAP, CARLA_DEFAULT_CLAP_PATH, list)
ladspas.sort()
dssis.sort()
@@ -886,6 +893,7 @@ class CarlaSettingsW(QDialog):
sf2s.sort()
sfzs.sort()
jsfxs.sort()
+ claps.sort()
for ladspa in ladspas:
if not ladspa:
@@ -927,6 +935,11 @@ class CarlaSettingsW(QDialog):
continue
self.ui.lw_jsfx.addItem(jsfx)
+ for clap in claps:
+ if not clap:
+ continue
+ self.ui.lw_clap.addItem(clap)
+
# -------------------------------------------------------------------------------------------------------------
# Wine
@@ -1098,6 +1111,7 @@ class CarlaSettingsW(QDialog):
sf2s = []
sfzs = []
jsfxs = []
+ claps = []
for i in range(self.ui.lw_ladspa.count()):
ladspas.append(self.ui.lw_ladspa.item(i).text())
@@ -1123,6 +1137,9 @@ class CarlaSettingsW(QDialog):
for i in range(self.ui.lw_jsfx.count()):
jsfxs.append(self.ui.lw_jsfx.item(i).text())
+ for i in range(self.ui.lw_clap.count()):
+ claps.append(self.ui.lw_clap.item(i).text())
+
self.host.set_engine_option(ENGINE_OPTION_PLUGIN_PATH, PLUGIN_LADSPA, splitter.join(ladspas))
self.host.set_engine_option(ENGINE_OPTION_PLUGIN_PATH, PLUGIN_DSSI, splitter.join(dssis))
self.host.set_engine_option(ENGINE_OPTION_PLUGIN_PATH, PLUGIN_LV2, splitter.join(lv2s))
@@ -1131,6 +1148,7 @@ class CarlaSettingsW(QDialog):
self.host.set_engine_option(ENGINE_OPTION_PLUGIN_PATH, PLUGIN_SF2, splitter.join(sf2s))
self.host.set_engine_option(ENGINE_OPTION_PLUGIN_PATH, PLUGIN_SFZ, splitter.join(sfzs))
self.host.set_engine_option(ENGINE_OPTION_PLUGIN_PATH, PLUGIN_JSFX, splitter.join(jsfxs))
+ self.host.set_engine_option(ENGINE_OPTION_PLUGIN_PATH, PLUGIN_CLAP, splitter.join(claps))
settings.setValue(CARLA_KEY_PATHS_LADSPA, ladspas)
settings.setValue(CARLA_KEY_PATHS_DSSI, dssis)
@@ -1140,6 +1158,7 @@ class CarlaSettingsW(QDialog):
settings.setValue(CARLA_KEY_PATHS_SF2, sf2s)
settings.setValue(CARLA_KEY_PATHS_SFZ, sfzs)
settings.setValue(CARLA_KEY_PATHS_JSFX, jsfxs)
+ settings.setValue(CARLA_KEY_PATHS_CLAP, claps)
# -------------------------------------------------------------------------------------------------------------
# Wine
@@ -1337,6 +1356,16 @@ class CarlaSettingsW(QDialog):
continue
self.ui.lw_jsfx.addItem(path)
+ elif curIndex == self.PLUGINPATH_INDEX_CLAP:
+ paths = CARLA_DEFAULT_CLAP_PATH
+ paths.sort()
+ self.ui.lw_clap.clear()
+
+ for path in paths:
+ if not path:
+ continue
+ self.ui.lw_clap.addItem(path)
+
# -------------------------------------------------------------------------------------------------------------
# Wine
@@ -1467,6 +1496,8 @@ class CarlaSettingsW(QDialog):
self.ui.lw_sfz.addItem(newPath)
elif curIndex == self.PLUGINPATH_INDEX_JSFX:
self.ui.lw_jsfx.addItem(newPath)
+ elif curIndex == self.PLUGINPATH_INDEX_CLAP:
+ self.ui.lw_clap.addItem(newPath)
@pyqtSlot()
def slot_removePluginPath(self):
@@ -1488,6 +1519,8 @@ class CarlaSettingsW(QDialog):
self.ui.lw_sfz.takeItem(self.ui.lw_sfz.currentRow())
elif curIndex == self.PLUGINPATH_INDEX_JSFX:
self.ui.lw_jsfx.takeItem(self.ui.lw_jsfx.currentRow())
+ elif curIndex == self.PLUGINPATH_INDEX_CLAP:
+ self.ui.lw_clap.takeItem(self.ui.lw_clap.currentRow())
@pyqtSlot()
def slot_changePluginPath(self):
@@ -1509,6 +1542,8 @@ class CarlaSettingsW(QDialog):
currentPath = self.ui.lw_sfz.currentItem().text()
elif curIndex == self.PLUGINPATH_INDEX_JSFX:
currentPath = self.ui.lw_jsfx.currentItem().text()
+ elif curIndex == self.PLUGINPATH_INDEX_CLAP:
+ currentPath = self.ui.lw_clap.currentItem().text()
else:
currentPath = ""
@@ -1533,6 +1568,8 @@ class CarlaSettingsW(QDialog):
self.ui.lw_sfz.currentItem().setText(newPath)
elif curIndex == self.PLUGINPATH_INDEX_JSFX:
self.ui.lw_jsfx.currentItem().setText(newPath)
+ elif curIndex == self.PLUGINPATH_INDEX_CLAP:
+ self.ui.lw_clap.currentItem().setText(newPath)
# -----------------------------------------------------------------------------------------------------------------
@@ -1554,6 +1591,8 @@ class CarlaSettingsW(QDialog):
row = self.ui.lw_sfz.currentRow()
elif index == self.PLUGINPATH_INDEX_JSFX:
row = self.ui.lw_jsfx.currentRow()
+ elif index == self.PLUGINPATH_INDEX_CLAP:
+ row = self.ui.lw_clap.currentRow()
else:
row = -1
diff --git a/source/utils/CarlaBackendUtils.hpp b/source/utils/CarlaBackendUtils.hpp
index 22784a015..f71c12c8b 100644
--- a/source/utils/CarlaBackendUtils.hpp
+++ b/source/utils/CarlaBackendUtils.hpp
@@ -131,6 +131,8 @@ const char* PluginType2Str(const PluginType type) noexcept
return "PLUGIN_JSFX";
case PLUGIN_CLAP:
return "PLUGIN_CLAP";
+ case PLUGIN_TYPE_COUNT:
+ break;
}
carla_stderr("CarlaBackend::PluginType2Str(%i) - invalid type", type);
@@ -604,6 +606,8 @@ const char* getPluginTypeAsString(const PluginType type) noexcept
return "JSFX";
case PLUGIN_CLAP:
return "CLAP";
+ case PLUGIN_TYPE_COUNT:
+ break;
}
carla_stderr("CarlaBackend::getPluginTypeAsString(%i) - invalid type", type);
diff --git a/source/utils/CarlaStateUtils.cpp b/source/utils/CarlaStateUtils.cpp
index 12ba80faa..071662f2a 100644
--- a/source/utils/CarlaStateUtils.cpp
+++ b/source/utils/CarlaStateUtils.cpp
@@ -594,9 +594,12 @@ void CarlaStateSave::dumpToMemoryStream(MemoryOutputStream& content) const
infoXml << " \n";
break;
case PLUGIN_AU:
- case PLUGIN_CLAP:
infoXml << " " << xmlSafeString(label, true) << "\n";
break;
+ case PLUGIN_CLAP:
+ infoXml << " " << xmlSafeString(binary, true) << "\n";
+ infoXml << " " << xmlSafeString(label, true) << "\n";
+ break;
case PLUGIN_DLS:
case PLUGIN_GIG:
case PLUGIN_SF2:
@@ -611,6 +614,8 @@ void CarlaStateSave::dumpToMemoryStream(MemoryOutputStream& content) const
infoXml << " " << xmlSafeString(binary, true) << "\n";
infoXml << " " << xmlSafeString(label, true) << "\n";
break;
+ case PLUGIN_TYPE_COUNT:
+ break;
}
infoXml << " \n\n";