| @@ -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 | |||
| @@ -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. | |||
| @@ -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) | |||
| @@ -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() | |||
| { | |||
| @@ -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 | |||
| @@ -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; | |||
| @@ -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) | |||
| @@ -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; | |||
| @@ -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; | |||
| @@ -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 | |||
| @@ -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; | |||
| @@ -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 | |||
| @@ -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 | |||
| @@ -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); | |||
| } | |||
| } | |||
| @@ -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) | |||
| @@ -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"), | |||
| @@ -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) | |||
| @@ -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(); | |||