| @@ -741,6 +741,11 @@ | |||||
| <string>Continuous Rack</string> | <string>Continuous Rack</string> | ||||
| </property> | </property> | ||||
| </item> | </item> | ||||
| <item> | |||||
| <property name="text"> | |||||
| <string>Patchbay (EXPERIMENTAL)</string> | |||||
| </property> | |||||
| </item> | |||||
| </widget> | </widget> | ||||
| </item> | </item> | ||||
| </layout> | </layout> | ||||
| @@ -757,7 +762,12 @@ | |||||
| <widget class="QComboBox" name="cb_engine_process_mode_other"> | <widget class="QComboBox" name="cb_engine_process_mode_other"> | ||||
| <item> | <item> | ||||
| <property name="text"> | <property name="text"> | ||||
| <string>Continuous Rack (EXPERIMENTAL)</string> | |||||
| <string>Continuous Rack</string> | |||||
| </property> | |||||
| </item> | |||||
| <item> | |||||
| <property name="text"> | |||||
| <string>Patchbay (EXPERIMENTAL)</string> | |||||
| </property> | </property> | ||||
| </item> | </item> | ||||
| </widget> | </widget> | ||||
| @@ -594,7 +594,7 @@ bool CarlaEngine::removePlugin(const uint id) | |||||
| pData->thread.stopThread(500); | pData->thread.stopThread(500); | ||||
| #ifndef BUILD_BRIDGE | #ifndef BUILD_BRIDGE | ||||
| const bool lockWait(isRunning() && pData->options.processMode != ENGINE_PROCESS_MODE_MULTIPLE_CLIENTS); | |||||
| const bool lockWait(isRunning() /*&& pData->options.processMode != ENGINE_PROCESS_MODE_MULTIPLE_CLIENTS*/); | |||||
| const ScopedActionLock sal(pData, kEnginePostActionRemovePlugin, id, 0, lockWait); | const ScopedActionLock sal(pData, kEnginePostActionRemovePlugin, id, 0, lockWait); | ||||
| for (uint i=id; i < pData->curPluginCount; ++i) | for (uint i=id; i < pData->curPluginCount; ++i) | ||||
| @@ -604,6 +604,9 @@ bool CarlaEngine::removePlugin(const uint id) | |||||
| plugin2->updateOscURL(); | plugin2->updateOscURL(); | ||||
| } | } | ||||
| if (pData->options.processMode == ENGINE_PROCESS_MODE_PATCHBAY) | |||||
| pData->graph.removePlugin(plugin); | |||||
| if (isOscControlRegistered()) | if (isOscControlRegistered()) | ||||
| oscSend_control_remove_plugin(id); | oscSend_control_remove_plugin(id); | ||||
| #else | #else | ||||
| @@ -611,9 +614,6 @@ bool CarlaEngine::removePlugin(const uint id) | |||||
| carla_zeroStruct(pData->plugins, 1); | carla_zeroStruct(pData->plugins, 1); | ||||
| #endif | #endif | ||||
| if (pData->options.processMode == ENGINE_PROCESS_MODE_PATCHBAY) | |||||
| pData->graph.removePlugin(plugin); | |||||
| delete plugin; | delete plugin; | ||||
| if (isRunning() && ! pData->aboutToClose) | if (isRunning() && ! pData->aboutToClose) | ||||
| @@ -777,7 +777,7 @@ bool CarlaEngine::switchPlugins(const uint idA, const uint idB) noexcept | |||||
| pData->thread.stopThread(500); | pData->thread.stopThread(500); | ||||
| const bool lockWait(isRunning() && pData->options.processMode != ENGINE_PROCESS_MODE_MULTIPLE_CLIENTS); | |||||
| const bool lockWait(isRunning() /*&& pData->options.processMode != ENGINE_PROCESS_MODE_MULTIPLE_CLIENTS*/); | |||||
| const ScopedActionLock sal(pData, kEnginePostActionSwitchPlugins, idA, idB, lockWait); | const ScopedActionLock sal(pData, kEnginePostActionSwitchPlugins, idA, idB, lockWait); | ||||
| CarlaPlugin* const pluginA(pData->plugins[idA].plugin); | CarlaPlugin* const pluginA(pData->plugins[idA].plugin); | ||||
| @@ -940,6 +940,9 @@ public: | |||||
| if (const int numChan = audio.getNumChannels()) | if (const int numChan = audio.getNumChannels()) | ||||
| { | { | ||||
| if (fPlugin->getAudioInCount() == 0) | |||||
| audio.clear(); | |||||
| float* audioBuffers[numChan]; | float* audioBuffers[numChan]; | ||||
| for (int i=0; i<numChan; ++i) | for (int i=0; i<numChan; ++i) | ||||
| @@ -983,10 +986,11 @@ public: | |||||
| if (CarlaEngineEventPort* const port = fPlugin->getDefaultEventOutPort()) | if (CarlaEngineEventPort* const port = fPlugin->getDefaultEventOutPort()) | ||||
| { | { | ||||
| const EngineEvent* const engineEvents(port->fBuffer); | |||||
| /*const*/ EngineEvent* const engineEvents(port->fBuffer); | |||||
| CARLA_SAFE_ASSERT_RETURN(engineEvents != nullptr,); | CARLA_SAFE_ASSERT_RETURN(engineEvents != nullptr,); | ||||
| fillJuceMidiBufferFromEngineEvents(midi, engineEvents); | fillJuceMidiBufferFromEngineEvents(midi, engineEvents); | ||||
| carla_zeroStruct<EngineEvent>(engineEvents, kMaxEngineEventInternalCount); | |||||
| } | } | ||||
| } | } | ||||
| @@ -1175,10 +1179,8 @@ void PatchbayGraph::removePlugin(CarlaPlugin* const plugin) | |||||
| // TODO | // TODO | ||||
| //removePluginFromPatchbay(plugin); | //removePluginFromPatchbay(plugin); | ||||
| graph.removeNode(plugin->getPatchbayNodeId()); | |||||
| // Fix plugin Ids properties | // Fix plugin Ids properties | ||||
| for (uint i=plugin->getId(), count=engine->getCurrentPluginCount(); i<count; ++i) | |||||
| for (uint i=0, count=engine->getCurrentPluginCount(); i<count; ++i) | |||||
| { | { | ||||
| CarlaPlugin* const plugin2(engine->getPlugin(i)); | CarlaPlugin* const plugin2(engine->getPlugin(i)); | ||||
| CARLA_SAFE_ASSERT_BREAK(plugin2 != nullptr); | CARLA_SAFE_ASSERT_BREAK(plugin2 != nullptr); | ||||
| @@ -1189,6 +1191,8 @@ void PatchbayGraph::removePlugin(CarlaPlugin* const plugin) | |||||
| node->properties.set("pluginId", static_cast<int>(plugin2->getId())); | node->properties.set("pluginId", static_cast<int>(plugin2->getId())); | ||||
| } | } | ||||
| } | } | ||||
| CARLA_SAFE_ASSERT_RETURN(graph.removeNode(plugin->getPatchbayNodeId()),); | |||||
| } | } | ||||
| void PatchbayGraph::removeAllPlugins() | void PatchbayGraph::removeAllPlugins() | ||||
| @@ -331,9 +331,12 @@ void CarlaEngine::ProtectedData::doNextPluginAction(const bool unlock) noexcept | |||||
| ScopedActionLock::ScopedActionLock(CarlaEngine::ProtectedData* const data, const EnginePostAction action, const uint pluginId, const uint value, const bool lockWait) noexcept | ScopedActionLock::ScopedActionLock(CarlaEngine::ProtectedData* const data, const EnginePostAction action, const uint pluginId, const uint value, const bool lockWait) noexcept | ||||
| : fData(data) | : fData(data) | ||||
| { | { | ||||
| CARLA_SAFE_ASSERT_RETURN(fData->nextAction.opcode == kEnginePostActionNull,); | |||||
| CARLA_SAFE_ASSERT_RETURN(action != kEnginePostActionNull,); | CARLA_SAFE_ASSERT_RETURN(action != kEnginePostActionNull,); | ||||
| fData->nextAction.mutex.lock(); | |||||
| CARLA_SAFE_ASSERT_RETURN(fData->nextAction.opcode == kEnginePostActionNull,); | |||||
| fData->nextAction.opcode = action; | fData->nextAction.opcode = action; | ||||
| fData->nextAction.pluginId = pluginId; | fData->nextAction.pluginId = pluginId; | ||||
| fData->nextAction.value = value; | fData->nextAction.value = value; | ||||
| @@ -353,6 +356,7 @@ ScopedActionLock::ScopedActionLock(CarlaEngine::ProtectedData* const data, const | |||||
| ScopedActionLock::~ScopedActionLock() noexcept | ScopedActionLock::~ScopedActionLock() noexcept | ||||
| { | { | ||||
| CARLA_SAFE_ASSERT(fData->nextAction.opcode == kEnginePostActionNull); | |||||
| fData->nextAction.mutex.unlock(); | fData->nextAction.mutex.unlock(); | ||||
| } | } | ||||