diff --git a/source/backend/CarlaEngine.hpp b/source/backend/CarlaEngine.hpp index 4af67518e..abe60456d 100644 --- a/source/backend/CarlaEngine.hpp +++ b/source/backend/CarlaEngine.hpp @@ -730,7 +730,7 @@ public: * Rename plugin with id \a id to \a newName.\n * Returns the new name, or nullptr if the operation failed. */ - const char* renamePlugin(const unsigned int id, const char* const newName); + virtual const char* renamePlugin(const unsigned int id, const char* const newName); /*! * Clone plugin with id \a id. @@ -764,7 +764,7 @@ public: * Get a unique plugin name within the engine.\n * Returned variable must NOT be free'd. */ - const char* getNewUniquePluginName(const char* const name); + const char* getUniquePluginName(const char* const name); // ------------------------------------------------------------------- // Project management diff --git a/source/backend/CarlaPlugin.hpp b/source/backend/CarlaPlugin.hpp index 9cb034727..8284f8952 100644 --- a/source/backend/CarlaPlugin.hpp +++ b/source/backend/CarlaPlugin.hpp @@ -422,11 +422,18 @@ public: // Set data (internal stuff) /*! - * Set the plugin's id to \a id. + * Set the plugin's id to \a newId. * * \see id() */ - void setId(const unsigned int id); + void setId(const unsigned int newId); + + /*! + * Set the plugin's name to \a newName. + * + * \see name() + */ + void setName(const char* const newName); /*! * Set a plugin's option. diff --git a/source/backend/engine/CarlaEngine.cpp b/source/backend/engine/CarlaEngine.cpp index 2e24b6cc4..8c08d5ae6 100644 --- a/source/backend/engine/CarlaEngine.cpp +++ b/source/backend/engine/CarlaEngine.cpp @@ -403,6 +403,23 @@ void doPluginRemove(CarlaEngineProtectedData* const kData, const bool unlock) kData->nextAction.mutex.unlock(); } +void doPluginsSwitch(CarlaEngineProtectedData* const kData, const bool unlock) +{ + CARLA_ASSERT(kData->curPluginCount >= 2); + + const unsigned int idA = kData->nextAction.pluginId; + const unsigned int idB = kData->nextAction.value; + + CarlaPlugin* const tmp = kData->plugins[idA].plugin; + kData->plugins[idA].plugin = kData->plugins[idB].plugin; + kData->plugins[idB].plugin = tmp; + + kData->nextAction.opcode = EnginePostActionNull; + + if (unlock) + kData->nextAction.mutex.unlock(); +} + const char* findDSSIGUI(const char* const filename, const char* const label) { QString guiFilename; @@ -796,7 +813,6 @@ bool CarlaEngine::removePlugin(const unsigned int id) if (plugin == nullptr) { - carla_stderr("CarlaEngine::removePlugin(%i) - could not find plugin", id); setLastError("Could not find plugin to remove"); return false; } @@ -877,7 +893,34 @@ void CarlaEngine::removeAllPlugins() const char* CarlaEngine::renamePlugin(const unsigned int id, const char* const newName) { - setLastError("Not implemented yet"); + CARLA_ASSERT(kData->curPluginCount > 0); + CARLA_ASSERT(id < kData->curPluginCount); + CARLA_ASSERT(kData->plugins != nullptr); + CARLA_ASSERT(newName != nullptr); + + if (kData->plugins == nullptr) + { + setLastError("Critical error: no plugins are currently loaded!"); + return nullptr; + } + + CarlaPlugin* const plugin = kData->plugins[id].plugin; + + if (plugin == nullptr) + { + carla_stderr("CarlaEngine::clonePlugin(%i) - could not find plugin", id); + return nullptr; + } + + CARLA_ASSERT(plugin->id() == id); + + if (const char* const name = getUniquePluginName(newName)) + { + plugin->setName(name); + + return name; + } + return nullptr; } @@ -896,43 +939,40 @@ bool CarlaEngine::clonePlugin(const unsigned int id) CarlaPlugin* const plugin = kData->plugins[id].plugin; - CARLA_ASSERT(plugin != nullptr); - - if (plugin != nullptr) + if (plugin == nullptr) { - CARLA_ASSERT(plugin->id() == id); + carla_stderr("CarlaEngine::clonePlugin(%i) - could not find plugin", id); + return false; + } + + CARLA_ASSERT(plugin->id() == id); - const SaveState& saveState(plugin->getSaveState()); + const SaveState& saveState(plugin->getSaveState()); - char label[STR_MAX+1] = { '\0' }; - plugin->getLabel(label); + char label[STR_MAX+1] = { '\0' }; + plugin->getLabel(label); - BinaryType binaryType = BINARY_NATIVE; + BinaryType binaryType = BINARY_NATIVE; #ifndef BUILD_BRIDGE - if (plugin->hints() & PLUGIN_IS_BRIDGE) - binaryType = CarlaPluginGetBridgeBinaryType(plugin); + if (plugin->hints() & PLUGIN_IS_BRIDGE) + binaryType = CarlaPluginGetBridgeBinaryType(plugin); #endif - const unsigned int pluginsBefore(kData->curPluginCount); + const unsigned int pluginsBefore(kData->curPluginCount); - if (! addPlugin(binaryType, plugin->type(), plugin->filename(), plugin->name(), label, plugin->getExtraStuff())) - return false; - - CARLA_ASSERT(pluginsBefore+1 == kData->curPluginCount); + if (! addPlugin(binaryType, plugin->type(), plugin->filename(), plugin->name(), label, plugin->getExtraStuff())) + return false; - CarlaPlugin* const newPlugin = kData->plugins[kData->curPluginCount-1].plugin; + CARLA_ASSERT(pluginsBefore+1 == kData->curPluginCount); - CARLA_ASSERT(newPlugin != nullptr); + CarlaPlugin* const newPlugin = kData->plugins[kData->curPluginCount-1].plugin; - newPlugin->loadSaveState(saveState); + CARLA_ASSERT(newPlugin != nullptr); - return true; - } + newPlugin->loadSaveState(saveState); - carla_stderr("CarlaEngine::clonePlugin(%i) - could not find plugin", id); - setLastError("Could not find plugin to clone"); - return false; + return true; } bool CarlaEngine::replacePlugin(const unsigned int id) @@ -943,8 +983,48 @@ bool CarlaEngine::replacePlugin(const unsigned int id) bool CarlaEngine::switchPlugins(const unsigned int idA, const unsigned int idB) { - setLastError("Not implemented yet"); - return false; + CARLA_ASSERT(kData->curPluginCount > 0); + CARLA_ASSERT(idA < kData->curPluginCount); + CARLA_ASSERT(idB < kData->curPluginCount); + CARLA_ASSERT(kData->plugins != nullptr); + + if (kData->plugins == nullptr) + { + setLastError("Critical error: no plugins are currently loaded!"); + return false; + } + + kData->thread.stopNow(); + + kData->nextAction.pluginId = idA; + kData->nextAction.value = idB; + kData->nextAction.opcode = EnginePostActionSwitchPlugins; + + kData->nextAction.mutex.lock(); + + if (isRunning()) + { + carla_stderr("CarlaEngine::switchPlugins(%i, %i) - switch blocking START", idA, idB); + // block wait for unlock on proccessing side + kData->nextAction.mutex.lock(); + carla_stderr("CarlaEngine::switchPlugins(%i, %i) - switch blocking DONE", idA, idB); + } + else + { + doPluginsSwitch(kData, false); + } + +#ifndef BUILD_BRIDGE // TODO + //if (isOscControlRegistered()) + // osc_send_control_remove_plugin(id); +#endif + + kData->nextAction.mutex.unlock(); + + if (isRunning() && ! kData->aboutToClose) + kData->thread.startNow(); + + return true; } CarlaPlugin* CarlaEngine::getPlugin(const unsigned int id) const @@ -965,9 +1045,9 @@ CarlaPlugin* CarlaEngine::getPluginUnchecked(const unsigned int id) const return kData->plugins[id].plugin; } -const char* CarlaEngine::getNewUniquePluginName(const char* const name) +const char* CarlaEngine::getUniquePluginName(const char* const name) { - carla_debug("CarlaEngine::getNewUniquePluginName(\"%s\")", name); + carla_debug("CarlaEngine::getUniquePluginName(\"%s\")", name); CARLA_ASSERT(kData->maxPluginNumber > 0); CARLA_ASSERT(kData->plugins != nullptr); CARLA_ASSERT(name != nullptr); @@ -1486,6 +1566,9 @@ void CarlaEngine::proccessPendingEvents() case EnginePostActionRemovePlugin: doPluginRemove(kData, true); break; + case EnginePostActionSwitchPlugins: + doPluginsSwitch(kData, true); + break; } if (kData->time.playing) diff --git a/source/backend/engine/CarlaEngineInternal.hpp b/source/backend/engine/CarlaEngineInternal.hpp index c94b7a45c..a01fa24cc 100644 --- a/source/backend/engine/CarlaEngineInternal.hpp +++ b/source/backend/engine/CarlaEngineInternal.hpp @@ -116,7 +116,8 @@ const unsigned short RACK_EVENT_COUNT = 512; enum EnginePostAction { EnginePostActionNull, - EnginePostActionRemovePlugin + EnginePostActionRemovePlugin, + EnginePostActionSwitchPlugins }; struct EnginePluginData { @@ -151,11 +152,18 @@ struct CarlaEngineProtectedData { struct NextAction { EnginePostAction opcode; unsigned int pluginId; + unsigned int value; CarlaMutex mutex; NextAction() : opcode(EnginePostActionNull), - pluginId(0) {} + pluginId(0), + value(0) {} + + ~NextAction() + { + CARLA_ASSERT(opcode == EnginePostActionNull); + } void ready() { diff --git a/source/backend/engine/CarlaEngineJack.cpp b/source/backend/engine/CarlaEngineJack.cpp index e237e2ce1..20075ee4f 100644 --- a/source/backend/engine/CarlaEngineJack.cpp +++ b/source/backend/engine/CarlaEngineJack.cpp @@ -38,6 +38,7 @@ CARLA_BACKEND_START_NAMESPACE // Plugin Helpers, defined in CarlaPlugin.cpp extern CarlaEngine* CarlaPluginGetEngine(CarlaPlugin* const plugin); +extern CarlaEngineClient* CarlaPluginGetEngineClient(CarlaPlugin* const plugin); extern CarlaEngineAudioPort* CarlaPluginGetAudioInPort(CarlaPlugin* const plugin, uint32_t index); extern CarlaEngineAudioPort* CarlaPluginGetAudioOutPort(CarlaPlugin* const plugin, uint32_t index); @@ -485,6 +486,7 @@ private: jack_client_t* const kClient; const bool kUseClient; + friend class CarlaEngineJack; CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(CarlaEngineJackClient) }; @@ -737,6 +739,64 @@ public: return new CarlaEngineJackClient(kEngineTypeJack, fOptions.processMode, client); } + const char* renamePlugin(const unsigned int id, const char* const newName) override + { + CARLA_ASSERT(kData->curPluginCount > 0); + CARLA_ASSERT(id < kData->curPluginCount); + CARLA_ASSERT(kData->plugins != nullptr); + CARLA_ASSERT(newName != nullptr); + + if (kData->plugins == nullptr) + { + setLastError("Critical error: no plugins are currently loaded!"); + return nullptr; + } + + CarlaPlugin* const plugin = kData->plugins[id].plugin; + + if (plugin == nullptr) + { + carla_stderr("CarlaEngine::clonePlugin(%i) - could not find plugin", id); + return nullptr; + } + + CARLA_ASSERT(plugin->id() == id); + + const char* name = getUniquePluginName(newName); + + // JACK client rename + if (fOptions.processMode == PROCESS_MODE_MULTIPLE_CLIENTS) + { + // not supported yet in the JACK API + if (bridge.client_rename_ptr != nullptr) + { + jack_client_t* const client = ((CarlaEngineJackClient*)CarlaPluginGetEngineClient(plugin))->kClient; + name = bridge.client_rename_ptr(client, name); + } + else + { + setLastError("Your current JACK version does not allow renaming of clients"); + return nullptr; + } + } + + if (name == nullptr) + return nullptr; + + // Rename + plugin->setName(name); + + if (fOptions.processMode == PROCESS_MODE_SINGLE_CLIENT) + { + // reload plugin to recreate its ports + const SaveState& saveState(plugin->getSaveState()); + plugin->reload(); + plugin->loadSaveState(saveState); + } + + return name; + } + #ifndef BUILD_BRIDGE // ------------------------------------------------------------------- // Patchbay diff --git a/source/backend/plugin/BridgePlugin.cpp b/source/backend/plugin/BridgePlugin.cpp index b13034ea1..dc2c3d33a 100644 --- a/source/backend/plugin/BridgePlugin.cpp +++ b/source/backend/plugin/BridgePlugin.cpp @@ -449,7 +449,7 @@ public: fInfo.copyright = copyright; if (fName.isEmpty()) - fName = kData->engine->getNewUniquePluginName(name); + fName = kData->engine->getUniquePluginName(name); break; } @@ -1140,7 +1140,7 @@ public: // set info if (name != nullptr) - fName = kData->engine->getNewUniquePluginName(name); + fName = kData->engine->getUniquePluginName(name); fFilename = filename; diff --git a/source/backend/plugin/CarlaPlugin.cpp b/source/backend/plugin/CarlaPlugin.cpp index 365e3cabf..6457a799b 100644 --- a/source/backend/plugin/CarlaPlugin.cpp +++ b/source/backend/plugin/CarlaPlugin.cpp @@ -235,6 +235,11 @@ CarlaEngine* CarlaPluginGetEngine(CarlaPlugin* const plugin) return CarlaPluginProtectedData::getEngine(plugin); } +CarlaEngineClient* CarlaPluginGetEngineClient(CarlaPlugin* const plugin) +{ + return CarlaPluginProtectedData::getEngineClient(plugin); +} + CarlaEngineAudioPort* CarlaPluginGetAudioInPort(CarlaPlugin* const plugin, const uint32_t index) { return CarlaPluginProtectedData::getAudioInPort(plugin, index); @@ -977,9 +982,14 @@ bool CarlaPlugin::loadStateFromFile(const char* const filename) // ------------------------------------------------------------------- // Set data (internal stuff) -void CarlaPlugin::setId(const unsigned int id) +void CarlaPlugin::setId(const unsigned int newId) +{ + fId = newId; +} + +void CarlaPlugin::setName(const char* const newName) { - fId = id; + fName = newName; } void CarlaPlugin::setOption(const unsigned int option, const bool yesNo) diff --git a/source/backend/plugin/CarlaPluginInternal.hpp b/source/backend/plugin/CarlaPluginInternal.hpp index 4de6fc7a2..9b5ecb579 100644 --- a/source/backend/plugin/CarlaPluginInternal.hpp +++ b/source/backend/plugin/CarlaPluginInternal.hpp @@ -670,6 +670,11 @@ struct CarlaPluginProtectedData { return plugin->kData->engine; } + static CarlaEngineClient* getEngineClient(CarlaPlugin* const plugin) + { + return plugin->kData->client; + } + static CarlaEngineAudioPort* getAudioInPort(CarlaPlugin* const plugin, const uint32_t index) { return plugin->kData->audioIn.ports[index].port; diff --git a/source/backend/plugin/DssiPlugin.cpp b/source/backend/plugin/DssiPlugin.cpp index f1e831165..4a1e80ceb 100644 --- a/source/backend/plugin/DssiPlugin.cpp +++ b/source/backend/plugin/DssiPlugin.cpp @@ -1812,11 +1812,11 @@ public: // get info if (name != nullptr) - fName = kData->engine->getNewUniquePluginName(name); + fName = kData->engine->getUniquePluginName(name); else if (fDescriptor->Name != nullptr) - fName = kData->engine->getNewUniquePluginName(fDescriptor->Name); + fName = kData->engine->getUniquePluginName(fDescriptor->Name); else - fName = kData->engine->getNewUniquePluginName(fDescriptor->Label); + fName = kData->engine->getUniquePluginName(fDescriptor->Label); fFilename = filename; diff --git a/source/backend/plugin/FluidSynthPlugin.cpp b/source/backend/plugin/FluidSynthPlugin.cpp index 529be1a67..79a0829e2 100644 --- a/source/backend/plugin/FluidSynthPlugin.cpp +++ b/source/backend/plugin/FluidSynthPlugin.cpp @@ -1447,9 +1447,9 @@ public: fLabel = label; if (name != nullptr) - fName = kData->engine->getNewUniquePluginName(name); + fName = kData->engine->getUniquePluginName(name); else - fName = kData->engine->getNewUniquePluginName(label); + fName = kData->engine->getUniquePluginName(label); // --------------------------------------------------------------- // register client diff --git a/source/backend/plugin/LadspaPlugin.cpp b/source/backend/plugin/LadspaPlugin.cpp index 932cfec9a..aa8832e6c 100644 --- a/source/backend/plugin/LadspaPlugin.cpp +++ b/source/backend/plugin/LadspaPlugin.cpp @@ -1392,13 +1392,13 @@ public: fRdfDescriptor = ladspa_rdf_dup(rdfDescriptor); if (name != nullptr) - fName = kData->engine->getNewUniquePluginName(name); + fName = kData->engine->getUniquePluginName(name); else if (fRdfDescriptor != nullptr && fRdfDescriptor->Title != nullptr) - fName = kData->engine->getNewUniquePluginName(fRdfDescriptor->Title); + fName = kData->engine->getUniquePluginName(fRdfDescriptor->Title); else if (fDescriptor->Name != nullptr) - fName = kData->engine->getNewUniquePluginName(fDescriptor->Name); + fName = kData->engine->getUniquePluginName(fDescriptor->Name); else - fName = kData->engine->getNewUniquePluginName(fDescriptor->Label); + fName = kData->engine->getUniquePluginName(fDescriptor->Label); fFilename = filename; diff --git a/source/backend/plugin/LinuxSamplerPlugin.cpp b/source/backend/plugin/LinuxSamplerPlugin.cpp index 45e4fdcc7..5057d43ef 100644 --- a/source/backend/plugin/LinuxSamplerPlugin.cpp +++ b/source/backend/plugin/LinuxSamplerPlugin.cpp @@ -1011,9 +1011,9 @@ public: fFilename = filename; if (name != nullptr) - fName = kData->engine->getNewUniquePluginName(name); + fName = kData->engine->getUniquePluginName(name); else - fName = kData->engine->getNewUniquePluginName((const char*)fRealName); + fName = kData->engine->getUniquePluginName((const char*)fRealName); // --------------------------------------------------------------- // Register client diff --git a/source/backend/plugin/NativePlugin.cpp b/source/backend/plugin/NativePlugin.cpp index beaf5436d..8f4d7fa3e 100644 --- a/source/backend/plugin/NativePlugin.cpp +++ b/source/backend/plugin/NativePlugin.cpp @@ -2049,11 +2049,11 @@ public: // get info if (name != nullptr) - fName = kData->engine->getNewUniquePluginName(name); + fName = kData->engine->getUniquePluginName(name); else if (fDescriptor->name != nullptr) - fName = kData->engine->getNewUniquePluginName(fDescriptor->name); + fName = kData->engine->getUniquePluginName(fDescriptor->name); else - fName = kData->engine->getNewUniquePluginName(label); + fName = kData->engine->getUniquePluginName(label); // --------------------------------------------------------------- // register client diff --git a/source/backend/plugin/VstPlugin.cpp b/source/backend/plugin/VstPlugin.cpp index 30999ba06..472e33fba 100644 --- a/source/backend/plugin/VstPlugin.cpp +++ b/source/backend/plugin/VstPlugin.cpp @@ -2158,7 +2158,7 @@ public: if (name != nullptr) { - fName = kData->engine->getNewUniquePluginName(name); + fName = kData->engine->getUniquePluginName(name); } else { @@ -2167,12 +2167,12 @@ public: if (strBuf[0] != '\0') { - fName = kData->engine->getNewUniquePluginName(strBuf); + fName = kData->engine->getUniquePluginName(strBuf); } else { const char* const label = std::strrchr(filename, OS_SEP)+1; - fName = kData->engine->getNewUniquePluginName(label); + fName = kData->engine->getUniquePluginName(label); } } diff --git a/source/carla_backend.py b/source/carla_backend.py index 502a235cf..842e13296 100644 --- a/source/carla_backend.py +++ b/source/carla_backend.py @@ -708,7 +708,7 @@ class Host(object): self.lib.carla_remove_all_plugins() def rename_plugin(self, pluginId, newName): - return self.lib.carla_rename_plugin(pluginId, newName) + return self.lib.carla_rename_plugin(pluginId, newName.encode("utf-8")) def clone_plugin(self, pluginId): return self.lib.carla_clone_plugin(pluginId) diff --git a/source/carla_shared.py b/source/carla_shared.py index 020f06f10..b39a7bf07 100644 --- a/source/carla_shared.py +++ b/source/carla_shared.py @@ -26,7 +26,7 @@ from copy import deepcopy from subprocess import Popen, PIPE from PyQt4.QtCore import pyqtSlot, qWarning, Qt, QByteArray, QSettings, QThread, QTimer, SIGNAL, SLOT from PyQt4.QtGui import QColor, QCursor, QDialog, QIcon, QInputDialog, QFileDialog, QFontMetrics, QFrame, QMenu -from PyQt4.QtGui import QMessageBox, QPainter, QPainterPath, QTableWidgetItem, QVBoxLayout, QWidget +from PyQt4.QtGui import QLineEdit, QMessageBox, QPainter, QPainterPath, QTableWidgetItem, QVBoxLayout, QWidget # ------------------------------------------------------------------------------------------------------------ # Imports (Custom) @@ -2161,6 +2161,7 @@ class PluginWidget(QFrame): menu.addSeparator() actClone = menu.addAction(self.tr("Clone")) + actRename = menu.addAction(self.tr("Rename...")) actRemove = menu.addAction(self.tr("Remove")) actSel = menu.exec_(QCursor.pos()) @@ -2179,6 +2180,24 @@ class PluginWidget(QFrame): CustomMessageBox(self, QMessageBox.Warning, self.tr("Error"), self.tr("Operation failed"), cString(Carla.host.get_last_error()), QMessageBox.Ok, QMessageBox.Ok) + elif actSel == actRename: + oldName = self.fPluginInfo['name'] + newNameTry = QInputDialog.getText(self, self.tr("Rename Plugin"), self.tr("New plugin name:"), QLineEdit.Normal, oldName) + + if not (newNameTry[1] and newNameTry[0] and oldName != newNameTry[0]): + return + + newName = newNameTry[0] + + if Carla.host.rename_plugin(self.fPluginId, newName): + self.fPluginInfo['name'] = newName + self.ui.edit_dialog.fPluginInfo["name"] = newName + self.ui.edit_dialog.reloadInfo() + self.ui.label_name.setText(newName) + else: + CustomMessageBox(self, QMessageBox.Warning, self.tr("Error"), self.tr("Operation failed"), + cString(Carla.host.get_last_error()), QMessageBox.Ok, QMessageBox.Ok) + elif actSel == actRemove: if not Carla.host.remove_plugin(self.fPluginId): CustomMessageBox(self, QMessageBox.Warning, self.tr("Error"), self.tr("Operation failed"), diff --git a/source/libs/jackbridge/JackBridge.cpp b/source/libs/jackbridge/JackBridge.cpp index 7ec01f0e9..ec5e58127 100644 --- a/source/libs/jackbridge/JackBridge.cpp +++ b/source/libs/jackbridge/JackBridge.cpp @@ -35,6 +35,7 @@ typedef const char* (*jacksym_get_version_string)(); typedef jack_client_t* (*jacksym_client_open)(const char*, jack_options_t, jack_status_t*, ...); +typedef const char* (*jacksym_client_rename)(jack_client_t* client, const char* new_name); typedef int (*jacksym_client_close)(jack_client_t*); typedef int (*jacksym_client_name_size)(); @@ -98,6 +99,7 @@ struct JackBridge { jacksym_get_version_string get_version_string_ptr; jacksym_client_open client_open_ptr; + jacksym_client_rename client_rename_ptr; jacksym_client_close client_close_ptr; jacksym_client_name_size client_name_size_ptr; jacksym_get_client_name get_client_name_ptr; @@ -150,6 +152,7 @@ struct JackBridge { : lib(nullptr), get_version_string_ptr(nullptr), client_open_ptr(nullptr), + client_rename_ptr(nullptr), client_close_ptr(nullptr), client_name_size_ptr(nullptr), get_client_name_ptr(nullptr), @@ -197,19 +200,18 @@ struct JackBridge { transport_query_ptr(nullptr) { #if defined(CARLA_OS_MAC) - lib = lib_open("libjack.dylib"); - fprintf(stderr, "load JACK DLL FOR MAC\n"); + const char* const filename = "libjack.dylib"; #elif defined(CARLA_OS_WIN) && ! defined(__WINE__) - lib = lib_open("libjack.dll"); - fprintf(stderr, "load JACK DLL FOR WINDOWS\n"); + const char* const filename = "libjack.dll"; #else - lib = lib_open("libjack.so"); - fprintf(stderr, "load JACK DLL FOR LINUX\n"); + const char* const filename = "libjack.so.0"; #endif + lib = lib_open(filename); + if (lib == nullptr) { - fprintf(stderr, "Failed to load JACK DLL\n"); + fprintf(stderr, "Failed to load JACK DLL, reason:\n%s\n", lib_error(filename)); return; } @@ -218,6 +220,7 @@ struct JackBridge { LIB_SYMBOL(get_version_string) LIB_SYMBOL(client_open) + LIB_SYMBOL(client_rename) LIB_SYMBOL(client_close) LIB_SYMBOL(client_name_size) LIB_SYMBOL(get_client_name) @@ -295,6 +298,13 @@ jack_client_t* jackbridge_client_open(const char* client_name, jack_options_t op return nullptr; } +const char* jackbridge_client_rename(jack_client_t* client, const char* new_name) +{ + if (bridge.client_rename_ptr != nullptr) + return bridge.client_rename_ptr(client, new_name); + return nullptr; +} + // ----------------------------------------------------------------------------- bool jackbridge_client_close(jack_client_t* client) diff --git a/source/libs/jackbridge/JackBridge.hpp b/source/libs/jackbridge/JackBridge.hpp index c345bbc66..6a5701e80 100644 --- a/source/libs/jackbridge/JackBridge.hpp +++ b/source/libs/jackbridge/JackBridge.hpp @@ -164,6 +164,7 @@ typedef void (*JackShutdownCallback)(void *arg); CARLA_EXPORT const char* jackbridge_get_version_string(); CARLA_EXPORT jack_client_t* jackbridge_client_open(const char* client_name, jack_options_t options, jack_status_t* status, ...); +CARLA_EXPORT const char* jackbridge_client_rename(jack_client_t* client, const char* new_name); CARLA_EXPORT bool jackbridge_client_close(jack_client_t* client); CARLA_EXPORT int jackbridge_client_name_size();