diff --git a/resources/ui/carla_database.ui b/resources/ui/carla_database.ui
index 0fe170c11..782759c80 100644
--- a/resources/ui/carla_database.ui
+++ b/resources/ui/carla_database.ui
@@ -692,6 +692,13 @@
+ -
+
+
+ JSFX
+
+
+
-
diff --git a/resources/ui/carla_refresh.ui b/resources/ui/carla_refresh.ui
index ff9e4071f..024d0e204 100644
--- a/resources/ui/carla_refresh.ui
+++ b/resources/ui/carla_refresh.ui
@@ -85,6 +85,13 @@
+ -
+
+
+ JSFX
+
+
+
-
diff --git a/resources/ui/carla_settings.ui b/resources/ui/carla_settings.ui
index 15f52ee03..e499be796 100644
--- a/resources/ui/carla_settings.ui
+++ b/resources/ui/carla_settings.ui
@@ -2154,6 +2154,11 @@
SFZ
+ -
+
+ JSFX
+
+
-
@@ -2358,6 +2363,28 @@
+
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+ -
+
+
+
+
-
diff --git a/source/frontend/C++/carla_database.cpp b/source/frontend/C++/carla_database.cpp
index 913451444..3396233b4 100644
--- a/source/frontend/C++/carla_database.cpp
+++ b/source/frontend/C++/carla_database.cpp
@@ -209,6 +209,7 @@ PluginRefreshW::PluginRefreshW(QWidget* const parent, const CarlaHost& host)
connect(self->ui.ch_au, SIGNAL(clicked()), SLOT(slot_checkTools()));
connect(self->ui.ch_sf2, SIGNAL(clicked()), SLOT(slot_checkTools()));
connect(self->ui.ch_sfz, SIGNAL(clicked()), SLOT(slot_checkTools()));
+ connect(self->ui.ch_jsfx, SIGNAL(clicked()), SLOT(slot_checkTools()));
connect(&self->fThread, SIGNAL(pluginLook(float, QString)), SLOT(slot_handlePluginLook(float, QString)));
connect(&self->fThread, SIGNAL(finished(int)), SLOT(slot_handlePluginThreadFinished()));
diff --git a/source/frontend/C++/carla_host.cpp b/source/frontend/C++/carla_host.cpp
index 013e2433c..9a39ddae0 100644
--- a/source/frontend/C++/carla_host.cpp
+++ b/source/frontend/C++/carla_host.cpp
@@ -2676,6 +2676,7 @@ QString setEngineSettings(CarlaHost& host)
QStringList VST3_PATH = settings.valueStringList(CARLA_KEY_PATHS_VST3, CARLA_DEFAULT_VST3_PATH);
QStringList SF2_PATH = settings.valueStringList(CARLA_KEY_PATHS_SF2, CARLA_DEFAULT_SF2_PATH);
QStringList SFZ_PATH = settings.valueStringList(CARLA_KEY_PATHS_SFZ, CARLA_DEFAULT_SFZ_PATH);
+ QStringList JSFX_PATH = settings.valueStringList(CARLA_KEY_PATHS_JSFX, CARLA_DEFAULT_JSFX_PATH);
/*
// TODO
@@ -2686,6 +2687,7 @@ QString setEngineSettings(CarlaHost& host)
carla_set_engine_option(ENGINE_OPTION_PLUGIN_PATH, PLUGIN_VST3, splitter.join(VST3_PATH))
carla_set_engine_option(ENGINE_OPTION_PLUGIN_PATH, PLUGIN_SF2, splitter.join(SF2_PATH))
carla_set_engine_option(ENGINE_OPTION_PLUGIN_PATH, PLUGIN_SFZ, splitter.join(SFZ_PATH))
+ carla_set_engine_option(ENGINE_OPTION_PLUGIN_PATH, PLUGIN_JSFX, splitter.join(JSFX_PATH))
*/
//-----------------------------------------------------------------------------------------------------------------
diff --git a/source/frontend/C++/carla_settings.cpp b/source/frontend/C++/carla_settings.cpp
index 7c7f77e44..f0f3778ea 100644
--- a/source/frontend/C++/carla_settings.cpp
+++ b/source/frontend/C++/carla_settings.cpp
@@ -426,7 +426,8 @@ enum PluginPathIndexes {
PLUGINPATH_INDEX_VST2,
PLUGINPATH_INDEX_VST3,
PLUGINPATH_INDEX_SF2,
- PLUGINPATH_INDEX_SFZ
+ PLUGINPATH_INDEX_SFZ,
+ PLUGINPATH_INDEX_JSFX
};
/*
@@ -662,6 +663,7 @@ struct CarlaSettingsW::PrivateData {
QStringList vst3s = settings.valueStringList(CARLA_KEY_PATHS_VST3, CARLA_DEFAULT_VST3_PATH);
QStringList sf2s = settings.valueStringList(CARLA_KEY_PATHS_SF2, CARLA_DEFAULT_SF2_PATH);
QStringList sfzs = settings.valueStringList(CARLA_KEY_PATHS_SFZ, CARLA_DEFAULT_SFZ_PATH);
+ QStringList jsfxs = settings.valueStringList(CARLA_KEY_PATHS_JSFX, CARLA_DEFAULT_JSFX_PATH);
ladspas.sort();
dssis.sort();
@@ -670,6 +672,7 @@ struct CarlaSettingsW::PrivateData {
vst3s.sort();
sf2s.sort();
sfzs.sort();
+ jsfxs.sort();
for (const QString& ladspa : ladspas)
{
@@ -713,6 +716,12 @@ struct CarlaSettingsW::PrivateData {
ui.lw_sfz->addItem(sfz);
}
+ for (const QString& jsfx : jsfxs)
+ {
+ if (jsfx.isEmpty()) continue;
+ ui.lw_jsfx->addItem(jsfx);
+ }
+
// ------------------------------------------------------------------------------------------------------------
// Wine
@@ -883,6 +892,7 @@ struct CarlaSettingsW::PrivateData {
QStringList vst3s;
QStringList sf2s;
QStringList sfzs;
+ QStringList jsfxs;
for (int i=0; i < ui.lw_ladspa->count(); ++i)
ladspas.append(ui.lw_ladspa->item(i)->text());
@@ -905,6 +915,9 @@ struct CarlaSettingsW::PrivateData {
for (int i=0; i < ui.lw_sfz->count(); ++i)
sfzs.append(ui.lw_sfz->item(i)->text());
+ for (int i=0; i < ui.lw_jsfx->count(); ++i)
+ jsfxs.append(ui.lw_jsfx->item(i)->text());
+
/* TODO
host.set_engine_option(ENGINE_OPTION_PLUGIN_PATH, PLUGIN_LADSPA, splitter.join(ladspas));
host.set_engine_option(ENGINE_OPTION_PLUGIN_PATH, PLUGIN_DSSI, splitter.join(dssis));
@@ -913,6 +926,7 @@ struct CarlaSettingsW::PrivateData {
host.set_engine_option(ENGINE_OPTION_PLUGIN_PATH, PLUGIN_VST3, splitter.join(vst3s));
host.set_engine_option(ENGINE_OPTION_PLUGIN_PATH, PLUGIN_SF2, splitter.join(sf2s));
host.set_engine_option(ENGINE_OPTION_PLUGIN_PATH, PLUGIN_SFZ, splitter.join(sfzs));
+ host.set_engine_option(ENGINE_OPTION_PLUGIN_PATH, PLUGIN_JSFX, splitter.join(jsfxs));
*/
settings.setValue(CARLA_KEY_PATHS_LADSPA, ladspas);
@@ -922,6 +936,7 @@ struct CarlaSettingsW::PrivateData {
settings.setValue(CARLA_KEY_PATHS_VST3, vst3s);
settings.setValue(CARLA_KEY_PATHS_SF2, sf2s);
settings.setValue(CARLA_KEY_PATHS_SFZ, sfzs);
+ settings.setValue(CARLA_KEY_PATHS_JSFX, jsfxs);
// ------------------------------------------------------------------------------------------------------------
// Wine
@@ -1147,6 +1162,19 @@ struct CarlaSettingsW::PrivateData {
ui.lw_sfz->addItem(path);
}
break;
+
+ case PLUGINPATH_INDEX_JSFX:
+ paths = CARLA_DEFAULT_JSFX_PATH;
+ paths.sort();
+ ui.lw_jsfx->clear();
+
+ for (const auto& path : paths)
+ {
+ if (path.isEmpty())
+ continue;
+ ui.lw_jsfx->addItem(path);
+ }
+ break;
}
break;
}
@@ -1310,6 +1338,7 @@ CarlaSettingsW::CarlaSettingsW(QWidget* const parent, CarlaHost& host, const boo
connect(self->ui.lw_vst3, SIGNAL(currentRowChanged(int)), SLOT(slot_pluginPathRowChanged(int)));
connect(self->ui.lw_sf2, SIGNAL(currentRowChanged(int)), SLOT(slot_pluginPathRowChanged(int)));
connect(self->ui.lw_sfz, SIGNAL(currentRowChanged(int)), SLOT(slot_pluginPathRowChanged(int)));
+ connect(self->ui.lw_jsfx, SIGNAL(currentRowChanged(int)), SLOT(slot_pluginPathRowChanged(int)));
connect(self->ui.b_filepaths_add, SIGNAL(clicked()), SLOT(slot_addFilePath()));
connect(self->ui.b_filepaths_remove, SIGNAL(clicked()), SLOT(slot_removeFilePath()));
@@ -1335,6 +1364,7 @@ CarlaSettingsW::CarlaSettingsW(QWidget* const parent, CarlaHost& host, const boo
self->ui.lw_vst3->setCurrentRow(0);
self->ui.lw_sf2->setCurrentRow(0);
self->ui.lw_sfz->setCurrentRow(0);
+ self->ui.lw_jsfx->setCurrentRow(0);
self->ui.lw_files_audio->setCurrentRow(0);
self->ui.lw_files_midi->setCurrentRow(0);
@@ -1485,6 +1515,9 @@ void CarlaSettingsW::slot_addPluginPath()
case PLUGINPATH_INDEX_SFZ:
self->ui.lw_sfz->addItem(newPath);
break;
+ case PLUGINPATH_INDEX_JSFX:
+ self->ui.lw_jsfx->addItem(newPath);
+ break;
}
}
@@ -1513,6 +1546,9 @@ void CarlaSettingsW::slot_removePluginPath()
case PLUGINPATH_INDEX_SFZ:
self->ui.lw_sfz->takeItem(self->ui.lw_sfz->currentRow());
break;
+ case PLUGINPATH_INDEX_JSFX:
+ self->ui.lw_jsfx->takeItem(self->ui.lw_jsfx->currentRow());
+ break;
}
}
@@ -1545,6 +1581,9 @@ void CarlaSettingsW::slot_changePluginPath()
case PLUGINPATH_INDEX_SFZ:
currentPath = self->ui.lw_sfz->currentItem()->text();
break;
+ case PLUGINPATH_INDEX_JSFX:
+ currentPath = self->ui.lw_jsfx->currentItem()->text();
+ break;
}
const QString newPath = QFileDialog::getExistingDirectory(this, tr("Add Path"), currentPath, QFileDialog::ShowDirsOnly);
@@ -1575,6 +1614,9 @@ void CarlaSettingsW::slot_changePluginPath()
case PLUGINPATH_INDEX_SFZ:
self->ui.lw_sfz->currentItem()->setText(newPath);
break;
+ case PLUGINPATH_INDEX_JSFX:
+ self->ui.lw_jsfx->currentItem()->setText(newPath);
+ break;
}
}
@@ -1607,6 +1649,9 @@ void CarlaSettingsW::slot_pluginPathTabChanged(const int index)
case PLUGINPATH_INDEX_SFZ:
row = self->ui.lw_sfz->currentRow();
break;
+ case PLUGINPATH_INDEX_JSFX:
+ row = self->ui.lw_jsfx->currentRow();
+ break;
default:
row = -1;
break;
diff --git a/source/frontend/C++/carla_shared.hpp b/source/frontend/C++/carla_shared.hpp
index c283782f0..b53d4de5d 100644
--- a/source/frontend/C++/carla_shared.hpp
+++ b/source/frontend/C++/carla_shared.hpp
@@ -172,6 +172,7 @@ static const char* const* const MIDI_CC_LIST = {
#define CARLA_KEY_PATHS_VST3 "Paths/VST3"
#define CARLA_KEY_PATHS_SF2 "Paths/SF2"
#define CARLA_KEY_PATHS_SFZ "Paths/SFZ"
+#define CARLA_KEY_PATHS_JSFX "Paths/JSFX"
#define CARLA_KEY_WINE_EXECUTABLE "Wine/Executable" /* str */
#define CARLA_KEY_WINE_AUTO_PREFIX "Wine/AutoPrefix" /* bool */
@@ -299,6 +300,7 @@ static const char* const* const MIDI_CC_LIST = {
#define DEFAULT_VST3_PATH ""
#define DEFAULT_SF2_PATH ""
#define DEFAULT_SFZ_PATH ""
+#define DEFAULT_JSFX_PATH ""
#ifdef CARLA_OS_WIN
# define CARLA_PATH_SPLITTER ";"
@@ -338,6 +340,7 @@ if WINDOWS:
# define CARLA_DEFAULT_VST3_PATH = std::getenv("VST3_PATH", DEFAULT_VST3_PATH).split(CARLA_PATH_SPLITTER)
# define CARLA_DEFAULT_SF2_PATH = std::getenv("SF2_PATH", DEFAULT_SF2_PATH).split(CARLA_PATH_SPLITTER)
# define CARLA_DEFAULT_SFZ_PATH = std::getenv("SFZ_PATH", DEFAULT_SFZ_PATH).split(CARLA_PATH_SPLITTER)
+# define CARLA_DEFAULT_JSFX_PATH = std::getenv("JSFX_PATH", DEFAULT_JSFX_PATH).split(CARLA_PATH_SPLITTER)
#else
*/
# define CARLA_DEFAULT_LADSPA_PATH QString(DEFAULT_LADSPA_PATH).split(CARLA_PATH_SPLITTER)
@@ -347,6 +350,7 @@ if WINDOWS:
# define CARLA_DEFAULT_VST3_PATH QString(DEFAULT_VST3_PATH).split(CARLA_PATH_SPLITTER)
# define CARLA_DEFAULT_SF2_PATH QString(DEFAULT_SF2_PATH).split(CARLA_PATH_SPLITTER)
# define CARLA_DEFAULT_SFZ_PATH QString(DEFAULT_SFZ_PATH).split(CARLA_PATH_SPLITTER)
+# define CARLA_DEFAULT_JSFX_PATH QString(DEFAULT_JSFX_PATH).split(CARLA_PATH_SPLITTER)
/*
#endif
*/
diff --git a/source/frontend/carla_database.py b/source/frontend/carla_database.py
index a31d6b3ef..ad89bda09 100755
--- a/source/frontend/carla_database.py
+++ b/source/frontend/carla_database.py
@@ -410,6 +410,7 @@ class SearchPluginsThread(QThread):
self.fCheckAU = False
self.fCheckSF2 = False
self.fCheckSFZ = False
+ self.fCheckJSFX = False
if WINDOWS:
toolNative = "carla-discovery-native.exe"
@@ -447,7 +448,7 @@ class SearchPluginsThread(QThread):
self.fCheckWin32 = win32
self.fCheckWin64 = win64
- def setSearchPluginTypes(self, ladspa, dssi, lv2, vst2, vst3, au, sf2, sfz):
+ def setSearchPluginTypes(self, ladspa, dssi, lv2, vst2, vst3, au, sf2, sfz, jsfx):
self.fCheckLADSPA = ladspa
self.fCheckDSSI = dssi
self.fCheckLV2 = lv2
@@ -456,6 +457,7 @@ class SearchPluginsThread(QThread):
self.fCheckAU = au and MACOS
self.fCheckSF2 = sf2
self.fCheckSFZ = sfz
+ self.fCheckJSFX = jsfx
def stop(self):
self.fContinueChecking = False
@@ -522,6 +524,12 @@ class SearchPluginsThread(QThread):
else:
self.fCheckSF2 = False
+ if self.fCheckJSFX:
+ if self.fCheckNative:
+ self.fCurCount += 1
+ else:
+ self.fCheckJSFX = False
+
if self.fCurCount == 0:
return
@@ -721,6 +729,11 @@ class SearchPluginsThread(QThread):
settingsDB.setValue("Plugins/SFZ", kits)
settingsDB.sync()
+ if self.fCheckJSFX:
+ kits = self._checkJsfxCached()
+ settingsDB.setValue("Plugins/JSFX", kits)
+ settingsDB.sync()
+
def _checkLADSPA(self, OS, tool, isWine=False):
ladspaBinaries = []
ladspaPlugins = []
@@ -994,6 +1007,36 @@ class SearchPluginsThread(QThread):
self.fLastCheckValue += self.fCurPercentValue
return sfzKits
+ def _checkJsfxCached(self):
+ settings = QSafeSettings("falkTX", "Carla2")
+ PLUG_PATH = splitter.join(settings.value(CARLA_KEY_PATHS_JSFX, CARLA_DEFAULT_JSFX_PATH, list))
+ del settings
+
+ jsfxPlugins = []
+ self._pluginLook(self.fLastCheckValue, "JSFX plugins...")
+
+ count = gCarla.utils.get_cached_plugin_count(PLUGIN_JSFX, PLUG_PATH)
+
+ if not self.fContinueChecking:
+ return jsfxPlugins
+
+ for i in range(count):
+ descInfo = gCarla.utils.get_cached_plugin_info(PLUGIN_JSFX, i)
+
+ percent = ( float(i) / count ) * self.fCurPercentValue
+ self._pluginLook(self.fLastCheckValue + percent, descInfo['label'])
+
+ if not descInfo['valid']:
+ continue
+
+ jsfxPlugins.append(checkPluginCached(descInfo, PLUGIN_JSFX))
+
+ if not self.fContinueChecking:
+ break
+
+ self.fLastCheckValue += self.fCurPercentValue
+ return jsfxPlugins
+
def _pluginLook(self, percent, plugin):
self.pluginLook.emit(percent, plugin)
@@ -1224,6 +1267,7 @@ class PluginRefreshW(QDialog):
self.ui.ch_au.clicked.connect(self.slot_checkTools)
self.ui.ch_sf2.clicked.connect(self.slot_checkTools)
self.ui.ch_sfz.clicked.connect(self.slot_checkTools)
+ self.ui.ch_jsfx.clicked.connect(self.slot_checkTools)
self.fThread.pluginLook.connect(self.slot_handlePluginLook)
self.fThread.finished.connect(self.slot_handlePluginThreadFinished)
@@ -1264,6 +1308,9 @@ class PluginRefreshW(QDialog):
check = settings.value("PluginDatabase/SearchSFZ", False, bool) and self.ui.ch_sfz.isEnabled()
self.ui.ch_sfz.setChecked(check)
+ check = settings.value("PluginDatabase/SearchJSFX", True, bool) and self.ui.ch_jsfx.isEnabled()
+ self.ui.ch_jsfx.setChecked(check)
+
check = settings.value("PluginDatabase/SearchNative", True, bool) and self.ui.ch_native.isEnabled()
self.ui.ch_native.setChecked(check)
@@ -1294,6 +1341,7 @@ class PluginRefreshW(QDialog):
settings.setValue("PluginDatabase/SearchAU", self.ui.ch_au.isChecked())
settings.setValue("PluginDatabase/SearchSF2", self.ui.ch_sf2.isChecked())
settings.setValue("PluginDatabase/SearchSFZ", self.ui.ch_sfz.isChecked())
+ settings.setValue("PluginDatabase/SearchJSFX", self.ui.ch_jsfx.isChecked())
settings.setValue("PluginDatabase/SearchNative", self.ui.ch_native.isChecked())
settings.setValue("PluginDatabase/SearchPOSIX32", self.ui.ch_posix32.isChecked())
settings.setValue("PluginDatabase/SearchPOSIX64", self.ui.ch_posix64.isChecked())
@@ -1323,13 +1371,14 @@ class PluginRefreshW(QDialog):
self.ui.ch_posix32.isChecked(), self.ui.ch_posix64.isChecked(),
self.ui.ch_win32.isChecked(), self.ui.ch_win64.isChecked())
- ladspa, dssi, lv2, vst, vst3, au, sf2, sfz = (self.ui.ch_ladspa.isChecked(), self.ui.ch_dssi.isChecked(),
- self.ui.ch_lv2.isChecked(), self.ui.ch_vst.isChecked(),
- self.ui.ch_vst3.isChecked(), self.ui.ch_au.isChecked(),
- self.ui.ch_sf2.isChecked(), self.ui.ch_sfz.isChecked())
+ ladspa, dssi, lv2, vst, vst3, au, sf2, sfz, jsfx = (self.ui.ch_ladspa.isChecked(), self.ui.ch_dssi.isChecked(),
+ self.ui.ch_lv2.isChecked(), self.ui.ch_vst.isChecked(),
+ self.ui.ch_vst3.isChecked(), self.ui.ch_au.isChecked(),
+ self.ui.ch_sf2.isChecked(), self.ui.ch_sfz.isChecked(),
+ self.ui.ch_jsfx.isChecked())
self.fThread.setSearchBinaryTypes(native, posix32, posix64, win32, win64)
- self.fThread.setSearchPluginTypes(ladspa, dssi, lv2, vst, vst3, au, sf2, sfz)
+ self.fThread.setSearchPluginTypes(ladspa, dssi, lv2, vst, vst3, au, sf2, sfz, jsfx)
self.fThread.start()
# -----------------------------------------------------------------------------------------------------------------
@@ -1349,7 +1398,8 @@ class PluginRefreshW(QDialog):
enabled2 = bool(self.ui.ch_ladspa.isChecked() or self.ui.ch_dssi.isChecked() or
self.ui.ch_lv2.isChecked() or self.ui.ch_vst.isChecked() or
self.ui.ch_vst3.isChecked() or self.ui.ch_au.isChecked() or
- self.ui.ch_sf2.isChecked() or self.ui.ch_sfz.isChecked())
+ self.ui.ch_sf2.isChecked() or self.ui.ch_sfz.isChecked() or
+ self.ui.ch_jsfx.isChecked())
self.ui.b_start.setEnabled(enabled1 and enabled2)
@@ -1506,6 +1556,7 @@ class PluginDatabaseW(QDialog):
self.ui.ch_vst.clicked.connect(self.slot_checkFilters)
self.ui.ch_vst3.clicked.connect(self.slot_checkFilters)
self.ui.ch_au.clicked.connect(self.slot_checkFilters)
+ self.ui.ch_jsfx.clicked.connect(self.slot_checkFilters)
self.ui.ch_kits.clicked.connect(self.slot_checkFilters)
self.ui.ch_effects.clicked.connect(self.slot_checkFilters)
self.ui.ch_instruments.clicked.connect(self.slot_checkFilters)
@@ -1698,6 +1749,7 @@ class PluginDatabaseW(QDialog):
self.ui.ch_dssi.setChecked(True)
self.ui.ch_lv2.setChecked(True)
self.ui.ch_vst.setChecked(True)
+ self.ui.ch_jsfx.setChecked(True)
self.ui.ch_kits.setChecked(True)
self.ui.ch_instruments.setChecked(True)
@@ -1756,6 +1808,7 @@ class PluginDatabaseW(QDialog):
settings.setValue("PluginDatabase/ShowVST2", self.ui.ch_vst.isChecked())
settings.setValue("PluginDatabase/ShowVST3", self.ui.ch_vst3.isChecked())
settings.setValue("PluginDatabase/ShowAU", self.ui.ch_au.isChecked())
+ settings.setValue("PluginDatabase/ShowJSFX", self.ui.ch_jsfx.isChecked())
settings.setValue("PluginDatabase/ShowKits", self.ui.ch_kits.isChecked())
settings.setValue("PluginDatabase/ShowNative", self.ui.ch_native.isChecked())
settings.setValue("PluginDatabase/ShowBridged", self.ui.ch_bridged.isChecked())
@@ -1816,6 +1869,7 @@ class PluginDatabaseW(QDialog):
self.ui.ch_vst.setChecked(settings.value("PluginDatabase/ShowVST2", True, bool))
self.ui.ch_vst3.setChecked(settings.value("PluginDatabase/ShowVST3", (MACOS or WINDOWS), bool))
self.ui.ch_au.setChecked(settings.value("PluginDatabase/ShowAU", MACOS, bool))
+ self.ui.ch_jsfx.setChecked(settings.value("PluginDatabase/ShowJSFX", True, bool))
self.ui.ch_kits.setChecked(settings.value("PluginDatabase/ShowKits", True, bool))
self.ui.ch_native.setChecked(settings.value("PluginDatabase/ShowNative", True, bool))
self.ui.ch_bridged.setChecked(settings.value("PluginDatabase/ShowBridged", True, bool))
@@ -1891,6 +1945,7 @@ class PluginDatabaseW(QDialog):
hideVST2 = not self.ui.ch_vst.isChecked()
hideVST3 = not self.ui.ch_vst3.isChecked()
hideAU = not self.ui.ch_au.isChecked()
+ hideJSFX = not self.ui.ch_jsfx.isChecked()
hideKits = not self.ui.ch_kits.isChecked()
hideNative = not self.ui.ch_native.isChecked()
@@ -1967,6 +2022,8 @@ class PluginDatabaseW(QDialog):
self.ui.tableWidget.hideRow(i)
elif hideAU and ptype == PLUGIN_AU:
self.ui.tableWidget.hideRow(i)
+ elif hideJSFX and ptype == PLUGIN_JSFX:
+ self.ui.tableWidget.hideRow(i)
elif hideNative and isNative:
self.ui.tableWidget.hideRow(i)
elif hideBridged and isBridged:
@@ -2006,7 +2063,7 @@ class PluginDatabaseW(QDialog):
def _addPluginToTable(self, plugin, ptype):
if plugin['API'] != PLUGIN_QUERY_API_VERSION:
return
- if ptype in (self.tr("Internal"), "LV2", "SF2", "SFZ"):
+ if ptype in (self.tr("Internal"), "LV2", "SF2", "SFZ", "JSFX"):
plugin['build'] = BINARY_NATIVE
index = self.fLastTableIndex
@@ -2042,6 +2099,7 @@ class PluginDatabaseW(QDialog):
#elif ptype == PLUGIN_SFZ:
#ptypeStr = "SFZ"
#ptypeStrTr = ptypeStr
+ # TODO(jsfx) what to do here?
else:
return 0
@@ -2153,6 +2211,11 @@ class PluginDatabaseW(QDialog):
auPlugins32 = settingsDB.value("Plugins/AU_posix32", [], list) if MACOS else []
+ # ----------------------------------------------------------------------------------------------------
+ # JSFX
+
+ jsfxPlugins = settingsDB.value("Plugins/JSFX", [], list)
+
# ----------------------------------------------------------------------------------------------------
# Kits
@@ -2167,6 +2230,7 @@ class PluginDatabaseW(QDialog):
vstCount = 0
vst3Count = 0
au32Count = 0
+ jsfxCount = len(jsfxPlugins)
sf2Count = 0
sfzCount = len(sfzs)
@@ -2189,15 +2253,15 @@ class PluginDatabaseW(QDialog):
sf2Count += len(plugins)
self.ui.tableWidget.setRowCount(self.fLastTableIndex +
- ladspaCount + dssiCount + vstCount + vst3Count + au32Count +
+ ladspaCount + dssiCount + vstCount + vst3Count + au32Count + jsfxCount +
sf2Count + sfzCount)
if MACOS:
- self.ui.label.setText(self.tr("Have %i Internal, %i LADSPA, %i DSSI, %i LV2, %i VST2, %i VST3 and %i AudioUnit plugins, plus %i Sound Kits" % (
- internalCount, ladspaCount, dssiCount, lv2Count, vstCount, vst3Count, auCount+au32Count, sf2Count+sfzCount)))
+ self.ui.label.setText(self.tr("Have %i Internal, %i LADSPA, %i DSSI, %i LV2, %i VST2, %i VST3, %i AudioUnit plugins and %i JSFX plugins, plus %i Sound Kits" % (
+ internalCount, ladspaCount, dssiCount, lv2Count, vstCount, vst3Count, auCount+au32Count, jsfxCount, sf2Count+sfzCount)))
else:
- self.ui.label.setText(self.tr("Have %i Internal, %i LADSPA, %i DSSI, %i LV2, %i VST2 and %i VST3 plugins, plus %i Sound Kits" % (
- internalCount, ladspaCount, dssiCount, lv2Count, vstCount, vst3Count, sf2Count+sfzCount)))
+ self.ui.label.setText(self.tr("Have %i Internal, %i LADSPA, %i DSSI, %i LV2, %i VST2, %i VST3 plugins and %i JSFX plugins, plus %i Sound Kits" % (
+ internalCount, ladspaCount, dssiCount, lv2Count, vstCount, vst3Count, jsfxCount, sf2Count+sfzCount)))
# ----------------------------------------------------------------------------------------------------
# now add all plugins to the table
@@ -2222,6 +2286,9 @@ class PluginDatabaseW(QDialog):
for plugin in plugins:
self._addPluginToTable(plugin, "AU")
+ for plugin in jsfxPlugins:
+ self._addPluginToTable(plugin, "JSFX")
+
for sf2 in sf2s:
for sf2_i in sf2:
self._addPluginToTable(sf2_i, "SF2")
diff --git a/source/frontend/carla_host.py b/source/frontend/carla_host.py
index a2abe5f23..f95f4c43f 100644
--- a/source/frontend/carla_host.py
+++ b/source/frontend/carla_host.py
@@ -3376,6 +3376,7 @@ def setEngineSettings(host, oscPort = None):
VST3_PATH = settings.value(CARLA_KEY_PATHS_VST3, CARLA_DEFAULT_VST3_PATH, list)
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)
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))
@@ -3384,6 +3385,7 @@ def setEngineSettings(host, oscPort = None):
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))
+ host.set_engine_option(ENGINE_OPTION_PLUGIN_PATH, PLUGIN_JSFX, splitter.join(JSFX_PATH))
# --------------------------------------------------------------------------------------------------------
# don't continue if plugin
diff --git a/source/frontend/carla_settings.py b/source/frontend/carla_settings.py
index cb39e98ac..e76859874 100755
--- a/source/frontend/carla_settings.py
+++ b/source/frontend/carla_settings.py
@@ -45,7 +45,8 @@ from carla_backend import (
PLUGIN_VST2,
PLUGIN_VST3,
PLUGIN_SF2,
- PLUGIN_SFZ
+ PLUGIN_SFZ,
+ PLUGIN_JSFX
)
from carla_shared import (
@@ -97,6 +98,7 @@ from carla_shared import (
CARLA_KEY_PATHS_VST3,
CARLA_KEY_PATHS_SF2,
CARLA_KEY_PATHS_SFZ,
+ CARLA_KEY_PATHS_JSFX,
CARLA_KEY_WINE_EXECUTABLE,
CARLA_KEY_WINE_AUTO_PREFIX,
CARLA_KEY_WINE_FALLBACK_PREFIX,
@@ -171,6 +173,7 @@ from carla_shared import (
CARLA_DEFAULT_VST3_PATH,
CARLA_DEFAULT_SF2_PATH,
CARLA_DEFAULT_SFZ_PATH,
+ CARLA_DEFAULT_JSFX_PATH,
getAndSetPath,
getIcon,
fontMetricsHorizontalAdvance,
@@ -476,6 +479,7 @@ class CarlaSettingsW(QDialog):
PLUGINPATH_INDEX_VST3 = 4
PLUGINPATH_INDEX_SF2 = 5
PLUGINPATH_INDEX_SFZ = 6
+ PLUGINPATH_INDEX_JSFX = 7
# Single and Multiple client mode is only for JACK,
# but we still want to match QComboBox index to backend defines,
@@ -604,6 +608,7 @@ class CarlaSettingsW(QDialog):
self.ui.lw_vst3.currentRowChanged.connect(self.slot_pluginPathRowChanged)
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.b_filepaths_add.clicked.connect(self.slot_addFilePath)
self.ui.b_filepaths_remove.clicked.connect(self.slot_removeFilePath)
@@ -629,6 +634,7 @@ class CarlaSettingsW(QDialog):
self.ui.lw_vst3.setCurrentRow(0)
self.ui.lw_sf2.setCurrentRow(0)
self.ui.lw_sfz.setCurrentRow(0)
+ self.ui.lw_jsfx.setCurrentRow(0)
self.ui.lw_files_audio.setCurrentRow(0)
self.ui.lw_files_midi.setCurrentRow(0)
@@ -839,6 +845,7 @@ class CarlaSettingsW(QDialog):
vst3s = settings.value(CARLA_KEY_PATHS_VST3, CARLA_DEFAULT_VST3_PATH, list)
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)
ladspas.sort()
dssis.sort()
@@ -847,6 +854,7 @@ class CarlaSettingsW(QDialog):
vst3s.sort()
sf2s.sort()
sfzs.sort()
+ jsfxs.sort()
for ladspa in ladspas:
if not ladspa:
@@ -883,6 +891,11 @@ class CarlaSettingsW(QDialog):
continue
self.ui.lw_sfz.addItem(sfz)
+ for jsfx in jsfxs:
+ if not jsfx:
+ continue
+ self.ui.lw_jsfx.addItem(jsfx)
+
# -------------------------------------------------------------------------------------------------------------
# Wine
@@ -1053,6 +1066,7 @@ class CarlaSettingsW(QDialog):
vst3s = []
sf2s = []
sfzs = []
+ jsfxs = []
for i in range(self.ui.lw_ladspa.count()):
ladspas.append(self.ui.lw_ladspa.item(i).text())
@@ -1075,6 +1089,9 @@ class CarlaSettingsW(QDialog):
for i in range(self.ui.lw_sfz.count()):
sfzs.append(self.ui.lw_sfz.item(i).text())
+ for i in range(self.ui.lw_jsfx.count()):
+ jsfxs.append(self.ui.lw_jsfx.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))
@@ -1082,6 +1099,7 @@ class CarlaSettingsW(QDialog):
self.host.set_engine_option(ENGINE_OPTION_PLUGIN_PATH, PLUGIN_VST3, splitter.join(vst3s))
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))
settings.setValue(CARLA_KEY_PATHS_LADSPA, ladspas)
settings.setValue(CARLA_KEY_PATHS_DSSI, dssis)
@@ -1090,6 +1108,7 @@ class CarlaSettingsW(QDialog):
settings.setValue(CARLA_KEY_PATHS_VST3, vst3s)
settings.setValue(CARLA_KEY_PATHS_SF2, sf2s)
settings.setValue(CARLA_KEY_PATHS_SFZ, sfzs)
+ settings.setValue(CARLA_KEY_PATHS_JSFX, jsfxs)
# -------------------------------------------------------------------------------------------------------------
# Wine
@@ -1277,6 +1296,16 @@ class CarlaSettingsW(QDialog):
continue
self.ui.lw_sfz.addItem(path)
+ elif curIndex == self.PLUGINPATH_INDEX_JSFX:
+ paths = CARLA_DEFAULT_JSFX_PATH
+ paths.sort()
+ self.ui.lw_jsfx.clear()
+
+ for path in paths:
+ if not path:
+ continue
+ self.ui.lw_jsfx.addItem(path)
+
# -------------------------------------------------------------------------------------------------------------
# Wine
@@ -1405,6 +1434,8 @@ class CarlaSettingsW(QDialog):
self.ui.lw_sf2.addItem(newPath)
elif curIndex == self.PLUGINPATH_INDEX_SFZ:
self.ui.lw_sfz.addItem(newPath)
+ elif curIndex == self.PLUGINPATH_INDEX_JSFX:
+ self.ui.lw_jsfx.addItem(newPath)
@pyqtSlot()
def slot_removePluginPath(self):
@@ -1424,6 +1455,8 @@ class CarlaSettingsW(QDialog):
self.ui.lw_sf2.takeItem(self.ui.lw_sf2.currentRow())
elif curIndex == self.PLUGINPATH_INDEX_SFZ:
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())
@pyqtSlot()
def slot_changePluginPath(self):
@@ -1443,6 +1476,8 @@ class CarlaSettingsW(QDialog):
currentPath = self.ui.lw_sf2.currentItem().text()
elif curIndex == self.PLUGINPATH_INDEX_SFZ:
currentPath = self.ui.lw_sfz.currentItem().text()
+ elif curIndex == self.PLUGINPATH_INDEX_JSFX:
+ currentPath = self.ui.lw_jsfx.currentItem().text()
else:
currentPath = ""
@@ -1465,6 +1500,8 @@ class CarlaSettingsW(QDialog):
self.ui.lw_sf2.currentItem().setText(newPath)
elif curIndex == self.PLUGINPATH_INDEX_SFZ:
self.ui.lw_sfz.currentItem().setText(newPath)
+ elif curIndex == self.PLUGINPATH_INDEX_JSFX:
+ self.ui.lw_jsfx.currentItem().setText(newPath)
# -----------------------------------------------------------------------------------------------------------------
@@ -1484,6 +1521,8 @@ class CarlaSettingsW(QDialog):
row = self.ui.lw_sf2.currentRow()
elif index == self.PLUGINPATH_INDEX_SFZ:
row = self.ui.lw_sfz.currentRow()
+ elif index == self.PLUGINPATH_INDEX_JSFX:
+ row = self.ui.lw_jsfx.currentRow()
else:
row = -1
diff --git a/source/frontend/carla_shared.py b/source/frontend/carla_shared.py
index 0cd2e352b..2810f5753 100644
--- a/source/frontend/carla_shared.py
+++ b/source/frontend/carla_shared.py
@@ -233,6 +233,7 @@ CARLA_KEY_PATHS_VST2 = "Paths/VST2"
CARLA_KEY_PATHS_VST3 = "Paths/VST3"
CARLA_KEY_PATHS_SF2 = "Paths/SF2"
CARLA_KEY_PATHS_SFZ = "Paths/SFZ"
+CARLA_KEY_PATHS_JSFX = "Paths/JSFX"
CARLA_KEY_WINE_EXECUTABLE = "Wine/Executable" # str
CARLA_KEY_WINE_AUTO_PREFIX = "Wine/AutoPrefix" # bool
@@ -352,6 +353,7 @@ DEFAULT_VST2_PATH = ""
DEFAULT_VST3_PATH = ""
DEFAULT_SF2_PATH = ""
DEFAULT_SFZ_PATH = ""
+DEFAULT_JSFX_PATH = ""
if WINDOWS:
splitter = ";"
@@ -388,6 +390,9 @@ if WINDOWS:
DEFAULT_VST2_PATH = PROGRAMFILES + "\\VstPlugins"
DEFAULT_VST2_PATH += ";" + PROGRAMFILES + "\\Steinberg\\VstPlugins"
+ DEFAULT_JSFX_PATH = APPDATA + "\\REAPER\Effects"
+ #DEFAULT_JSFX_PATH += ";" + PROGRAMFILES + "\\REAPER\\InstallData\\Effects"
+
if kIs64bit:
DEFAULT_VST2_PATH += ";" + COMMONPROGRAMFILES + "\\VST2"
@@ -402,6 +407,7 @@ if WINDOWS:
DEFAULT_DSSI_PATH += ";" + PROGRAMFILESx86 + "\\DSSI"
DEFAULT_VST2_PATH += ";" + PROGRAMFILESx86 + "\\VstPlugins"
DEFAULT_VST2_PATH += ";" + PROGRAMFILESx86 + "\\Steinberg\\VstPlugins"
+ #DEFAULT_JSFX_PATH += ";" + PROGRAMFILESx86 + "\\REAPER\\InstallData\\Effects"
if COMMONPROGRAMFILESx86:
DEFAULT_VST3_PATH += COMMONPROGRAMFILESx86 + "\\VST3"
@@ -444,7 +450,12 @@ elif MACOS:
DEFAULT_VST3_PATH = HOME + "/Library/Audio/Plug-Ins/VST3"
DEFAULT_VST3_PATH += ":/Library/Audio/Plug-Ins/VST3"
+ DEFAULT_JSFX_PATH = HOME + "/Library/Application Support/REAPER/Effects"
+ #DEFAULT_JSFX_PATH += ":/Applications/REAPER.app/Contents/InstallFiles/Effects"
+
else:
+ CONFIG_HOME = os.getenv("XDG_CONFIG_HOME", HOME + "/.config")
+
splitter = ":"
DEFAULT_LADSPA_PATH = HOME + "/.ladspa"
@@ -480,6 +491,9 @@ else:
DEFAULT_SFZ_PATH = HOME + "/.sounds/sfz"
DEFAULT_SFZ_PATH += ":/usr/share/sounds/sfz"
+ DEFAULT_JSFX_PATH = CONFIG_HOME + "/REAPER/Effects"
+ #DEFAULT_JSFX_PATH += ":" + "/opt/REAPER/InstallData/Effects"
+
if not WINDOWS:
winePrefix = os.getenv("WINEPREFIX")
@@ -527,6 +541,7 @@ if readEnvVars:
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)
+ CARLA_DEFAULT_JSFX_PATH = os.getenv("JSFX_PATH", DEFAULT_JSFX_PATH).split(splitter)
else:
CARLA_DEFAULT_LADSPA_PATH = DEFAULT_LADSPA_PATH.split(splitter)
@@ -536,6 +551,7 @@ else:
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)
+ CARLA_DEFAULT_JSFX_PATH = DEFAULT_JSFX_PATH.split(splitter)
# ------------------------------------------------------------------------------------------------------------
# Default Plugin Folders (cleanup)
diff --git a/source/frontend/carla_utils.py b/source/frontend/carla_utils.py
index a430f9456..ea1079f19 100644
--- a/source/frontend/carla_utils.py
+++ b/source/frontend/carla_utils.py
@@ -43,6 +43,7 @@ from carla_backend import (
PLUGIN_VST2,
PLUGIN_VST3,
PLUGIN_AU,
+ PLUGIN_JSFX,
PLUGIN_DLS,
PLUGIN_GIG,
PLUGIN_SF2,
@@ -85,6 +86,8 @@ def getPluginTypeAsString(ptype):
return "VST3"
if ptype == PLUGIN_AU:
return "AU"
+ if ptype == PLUGIN_JSFX:
+ return "JSFX"
if ptype == PLUGIN_DLS:
return "DLS"
if ptype == PLUGIN_GIG:
@@ -123,6 +126,8 @@ def getPluginTypeFromString(stype):
return PLUGIN_VST3
if stype in ("au", "audiounit"):
return PLUGIN_AU
+ if stype == "jsfx":
+ return PLUGIN_JSFX
if stype == "dls":
return PLUGIN_DLS
if stype == "gig":