|
|
@@ -248,6 +248,8 @@ private: |
|
|
|
|
|
|
|
JackPortDeletionCallback* const kDeletionCallback; |
|
|
|
|
|
|
|
friend class CarlaEngineJackClient; |
|
|
|
|
|
|
|
CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(CarlaEngineJackCVPort) |
|
|
|
}; |
|
|
|
|
|
|
@@ -439,6 +441,8 @@ private: |
|
|
|
|
|
|
|
JackPortDeletionCallback* const kDeletionCallback; |
|
|
|
|
|
|
|
friend class CarlaEngineJackClient; |
|
|
|
|
|
|
|
CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(CarlaEngineJackEventPort) |
|
|
|
}; |
|
|
|
|
|
|
@@ -496,6 +500,37 @@ public: |
|
|
|
} |
|
|
|
|
|
|
|
CarlaEngineClient::activate(); |
|
|
|
|
|
|
|
const CarlaMutexLocker cml(fPreRenameMutex); |
|
|
|
|
|
|
|
if (fJackClient != nullptr) |
|
|
|
{ |
|
|
|
// restore pre-rename connections |
|
|
|
const char* portNameA = nullptr; |
|
|
|
const char* portNameB = nullptr; |
|
|
|
bool doConnection = false; |
|
|
|
|
|
|
|
for (CarlaStringList::Itenerator it = fPreRenameConnections.begin2(); it.valid(); it.next()) |
|
|
|
{ |
|
|
|
const bool connectNow = doConnection; |
|
|
|
doConnection = !doConnection; |
|
|
|
|
|
|
|
if (connectNow) |
|
|
|
portNameB = it.getValue(nullptr); |
|
|
|
else |
|
|
|
portNameA = it.getValue(nullptr); |
|
|
|
|
|
|
|
if (! connectNow) |
|
|
|
continue; |
|
|
|
|
|
|
|
CARLA_SAFE_ASSERT_CONTINUE(portNameA != nullptr && portNameA[0] != '\0'); |
|
|
|
CARLA_SAFE_ASSERT_CONTINUE(portNameB != nullptr && portNameB[0] != '\0'); |
|
|
|
|
|
|
|
jackbridge_connect(fJackClient, portNameA, portNameB); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
fPreRenameConnections.clear(); |
|
|
|
} |
|
|
|
|
|
|
|
void deactivate() noexcept override |
|
|
@@ -640,14 +675,25 @@ public: |
|
|
|
fEventPorts.removeAll(port); |
|
|
|
} |
|
|
|
|
|
|
|
void closeForRename(jack_client_t* const client) noexcept |
|
|
|
void closeForRename(jack_client_t* const client, const char* const clientName) noexcept |
|
|
|
{ |
|
|
|
if (fJackClient != nullptr) |
|
|
|
{ |
|
|
|
if (isActive()) |
|
|
|
{ |
|
|
|
{ |
|
|
|
// store current client connections |
|
|
|
const CarlaMutexLocker cml(fPreRenameMutex); |
|
|
|
|
|
|
|
fPreRenameConnections.clear(); |
|
|
|
|
|
|
|
_savePortsConnections(fAudioPorts, clientName); |
|
|
|
_savePortsConnections(fCVPorts, clientName); |
|
|
|
_savePortsConnections(fEventPorts, clientName); |
|
|
|
} |
|
|
|
|
|
|
|
try { |
|
|
|
jackbridge_activate(fJackClient); |
|
|
|
jackbridge_deactivate(fJackClient); |
|
|
|
} catch(...) {} |
|
|
|
} |
|
|
|
|
|
|
@@ -674,6 +720,44 @@ private: |
|
|
|
LinkedList<CarlaEngineJackCVPort*> fCVPorts; |
|
|
|
LinkedList<CarlaEngineJackEventPort*> fEventPorts; |
|
|
|
|
|
|
|
CarlaMutex fPreRenameMutex; |
|
|
|
CarlaStringList fPreRenameConnections; |
|
|
|
|
|
|
|
template<typename T> |
|
|
|
void _savePortsConnections(const LinkedList<T*>& t, const char* const clientName) |
|
|
|
{ |
|
|
|
CarlaString clientNamePrefix(clientName); |
|
|
|
clientNamePrefix += ":"; |
|
|
|
|
|
|
|
for (typename LinkedList<T*>::Itenerator it = t.begin2(); it.valid(); it.next()) |
|
|
|
{ |
|
|
|
T* const port(it.getValue(nullptr)); |
|
|
|
CARLA_SAFE_ASSERT_CONTINUE(port != nullptr); |
|
|
|
CARLA_SAFE_ASSERT_CONTINUE(port->fJackPort != nullptr); |
|
|
|
|
|
|
|
const char* const shortPortName(jackbridge_port_short_name(port->fJackPort)); |
|
|
|
CARLA_SAFE_ASSERT_CONTINUE(shortPortName != nullptr && shortPortName[0] != '\0'); |
|
|
|
|
|
|
|
const CarlaString portName(clientNamePrefix + shortPortName); |
|
|
|
|
|
|
|
if (const char** const connections = jackbridge_port_get_all_connections(fJackClient, port->fJackPort)) |
|
|
|
{ |
|
|
|
for (int i=0; connections[i] != nullptr; ++i) |
|
|
|
{ |
|
|
|
if (! port->kIsInput) |
|
|
|
fPreRenameConnections.append(portName); |
|
|
|
|
|
|
|
fPreRenameConnections.append(connections[i]); |
|
|
|
|
|
|
|
if (port->kIsInput) |
|
|
|
fPreRenameConnections.append(portName); |
|
|
|
} |
|
|
|
|
|
|
|
jackbridge_free(connections); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(CarlaEngineJackClient) |
|
|
|
}; |
|
|
|
|
|
|
@@ -1080,15 +1164,16 @@ public: |
|
|
|
// we should not be able to do this, jack really needs to allow client rename |
|
|
|
if (jack_client_t* const jackClient = jackbridge_client_open(uniqueName, JackNullOption, nullptr)) |
|
|
|
{ |
|
|
|
// disable plugin |
|
|
|
plugin->setEnabled(false); |
|
|
|
// get new client name |
|
|
|
uniqueName = jackbridge_get_client_name(jackClient); |
|
|
|
|
|
|
|
// close client |
|
|
|
client->closeForRename(jackClient); |
|
|
|
client->closeForRename(jackClient, uniqueName); |
|
|
|
|
|
|
|
// set new client data |
|
|
|
uniqueName = jackbridge_get_client_name(jackClient); |
|
|
|
// disable plugin |
|
|
|
plugin->setEnabled(false); |
|
|
|
|
|
|
|
// set new client data |
|
|
|
jackbridge_set_thread_init_callback(jackClient, carla_jack_thread_init_callback, nullptr); |
|
|
|
jackbridge_set_latency_callback(jackClient, carla_jack_latency_callback_plugin, plugin); |
|
|
|
jackbridge_set_process_callback(jackClient, carla_jack_process_callback_plugin, plugin); |
|
|
|