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