| @@ -759,6 +759,7 @@ public: | |||||
| */ | */ | ||||
| bool removeAllPlugins(); | bool removeAllPlugins(); | ||||
| #ifndef BUILD_BRIDGE | |||||
| /*! | /*! | ||||
| * Rename plugin with id @a id to @a newName. | * Rename plugin with id @a id to @a newName. | ||||
| * Returns the new name, or null if the operation failed. | * Returns the new name, or null if the operation failed. | ||||
| @@ -783,6 +784,7 @@ public: | |||||
| * Switch plugins with id @a idA and @a idB. | * Switch plugins with id @a idA and @a idB. | ||||
| */ | */ | ||||
| bool switchPlugins(const uint idA, const uint idB); | bool switchPlugins(const uint idA, const uint idB); | ||||
| #endif | |||||
| /*! | /*! | ||||
| * Get plugin with id @a id. | * Get plugin with id @a id. | ||||
| @@ -564,6 +564,7 @@ CARLA_EXPORT bool carla_remove_plugin(uint pluginId); | |||||
| */ | */ | ||||
| CARLA_EXPORT bool carla_remove_all_plugins(); | CARLA_EXPORT bool carla_remove_all_plugins(); | ||||
| #ifndef BUILD_BRIDGE | |||||
| /*! | /*! | ||||
| * Rename a plugin.\n | * Rename a plugin.\n | ||||
| * Returns the new name, or NULL if the operation failed. | * Returns the new name, or NULL if the operation failed. | ||||
| @@ -592,6 +593,7 @@ CARLA_EXPORT bool carla_replace_plugin(uint pluginId); | |||||
| * @param pluginIdB Plugin B | * @param pluginIdB Plugin B | ||||
| */ | */ | ||||
| CARLA_EXPORT bool carla_switch_plugins(uint pluginIdA, uint pluginIdB); | CARLA_EXPORT bool carla_switch_plugins(uint pluginIdA, uint pluginIdB); | ||||
| #endif | |||||
| /*! | /*! | ||||
| * Load a plugin state. | * Load a plugin state. | ||||
| @@ -1203,6 +1203,7 @@ bool carla_remove_all_plugins() | |||||
| return false; | return false; | ||||
| } | } | ||||
| #ifndef BUILD_BRIDGE | |||||
| const char* carla_rename_plugin(uint pluginId, const char* newName) | const char* carla_rename_plugin(uint pluginId, const char* newName) | ||||
| { | { | ||||
| CARLA_SAFE_ASSERT_RETURN(newName != nullptr && newName[0] != '\0', nullptr); | CARLA_SAFE_ASSERT_RETURN(newName != nullptr && newName[0] != '\0', nullptr); | ||||
| @@ -1252,6 +1253,7 @@ bool carla_switch_plugins(uint pluginIdA, uint pluginIdB) | |||||
| gStandalone.lastError = "Engine is not running"; | gStandalone.lastError = "Engine is not running"; | ||||
| return false; | return false; | ||||
| } | } | ||||
| #endif | |||||
| // ------------------------------------------------------------------------------------------------------------------- | // ------------------------------------------------------------------------------------------------------------------- | ||||
| @@ -292,7 +292,7 @@ bool CarlaEngine::close() | |||||
| void CarlaEngine::idle() noexcept | void CarlaEngine::idle() noexcept | ||||
| { | { | ||||
| CARLA_SAFE_ASSERT_RETURN(pData->nextAction.opcode == kEnginePostActionNull,); | |||||
| CARLA_SAFE_ASSERT_RETURN(pData->nextAction.opcode.get() == kEnginePostActionNull,); // FIXME REMOVE | |||||
| CARLA_SAFE_ASSERT_RETURN(pData->nextPluginId == pData->maxPluginNumber,); | CARLA_SAFE_ASSERT_RETURN(pData->nextPluginId == pData->maxPluginNumber,); | ||||
| for (uint i=0; i < pData->curPluginCount; ++i) | for (uint i=0; i < pData->curPluginCount; ++i) | ||||
| @@ -323,7 +323,6 @@ bool CarlaEngine::addPlugin(const BinaryType btype, const PluginType ptype, cons | |||||
| CARLA_SAFE_ASSERT_RETURN_ERR(! pData->isIdling, "An operation is still being processed, please wait for it to finish"); | CARLA_SAFE_ASSERT_RETURN_ERR(! pData->isIdling, "An operation is still being processed, please wait for it to finish"); | ||||
| CARLA_SAFE_ASSERT_RETURN_ERR(pData->plugins != nullptr, "Invalid engine internal data"); | CARLA_SAFE_ASSERT_RETURN_ERR(pData->plugins != nullptr, "Invalid engine internal data"); | ||||
| CARLA_SAFE_ASSERT_RETURN_ERR(pData->nextPluginId <= pData->maxPluginNumber, "Invalid engine internal data"); | CARLA_SAFE_ASSERT_RETURN_ERR(pData->nextPluginId <= pData->maxPluginNumber, "Invalid engine internal data"); | ||||
| CARLA_SAFE_ASSERT_RETURN_ERR(pData->nextAction.opcode == kEnginePostActionNull, "Invalid engine internal data"); | |||||
| CARLA_SAFE_ASSERT_RETURN_ERR(btype != BINARY_NONE, "Invalid plugin binary mode"); | CARLA_SAFE_ASSERT_RETURN_ERR(btype != BINARY_NONE, "Invalid plugin binary mode"); | ||||
| CARLA_SAFE_ASSERT_RETURN_ERR(ptype != PLUGIN_NONE, "Invalid plugin type"); | CARLA_SAFE_ASSERT_RETURN_ERR(ptype != PLUGIN_NONE, "Invalid plugin type"); | ||||
| CARLA_SAFE_ASSERT_RETURN_ERR((filename != nullptr && filename[0] != '\0') || (label != nullptr && label[0] != '\0'), "Invalid plugin filename and label"); | CARLA_SAFE_ASSERT_RETURN_ERR((filename != nullptr && filename[0] != '\0') || (label != nullptr && label[0] != '\0'), "Invalid plugin filename and label"); | ||||
| @@ -575,7 +574,6 @@ bool CarlaEngine::removePlugin(const uint id) | |||||
| CARLA_SAFE_ASSERT_RETURN_ERR(! pData->isIdling, "An operation is still being processed, please wait for it to finish"); | CARLA_SAFE_ASSERT_RETURN_ERR(! pData->isIdling, "An operation is still being processed, please wait for it to finish"); | ||||
| CARLA_SAFE_ASSERT_RETURN_ERR(pData->plugins != nullptr, "Invalid engine internal data"); | CARLA_SAFE_ASSERT_RETURN_ERR(pData->plugins != nullptr, "Invalid engine internal data"); | ||||
| CARLA_SAFE_ASSERT_RETURN_ERR(pData->curPluginCount != 0, "Invalid engine internal data"); | CARLA_SAFE_ASSERT_RETURN_ERR(pData->curPluginCount != 0, "Invalid engine internal data"); | ||||
| CARLA_SAFE_ASSERT_RETURN_ERR(pData->nextAction.opcode == kEnginePostActionNull, "Invalid engine internal data"); | |||||
| CARLA_SAFE_ASSERT_RETURN_ERR(id < pData->curPluginCount, "Invalid plugin Id"); | CARLA_SAFE_ASSERT_RETURN_ERR(id < pData->curPluginCount, "Invalid plugin Id"); | ||||
| carla_debug("CarlaEngine::removePlugin(%i)", id); | carla_debug("CarlaEngine::removePlugin(%i)", id); | ||||
| @@ -587,13 +585,13 @@ 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 ScopedActionLock sal(pData, kEnginePostActionRemovePlugin, id, 0, lockWait); | |||||
| const ScopedActionLock sal(pData, kEnginePostActionRemovePlugin, id, 0, isRunning()); | |||||
| if (isOscControlRegistered()) | if (isOscControlRegistered()) | ||||
| oscSend_control_remove_plugin(id); | oscSend_control_remove_plugin(id); | ||||
| #else | #else | ||||
| pData->plugins[0].plugin = nullptr; | |||||
| pData->curPluginCount = 0; | |||||
| carla_zeroStruct(pData->plugins, 1); | |||||
| #endif | #endif | ||||
| delete plugin; | delete plugin; | ||||
| @@ -610,7 +608,6 @@ bool CarlaEngine::removeAllPlugins() | |||||
| CARLA_SAFE_ASSERT_RETURN_ERR(! pData->isIdling, "An operation is still being processed, please wait for it to finish"); | CARLA_SAFE_ASSERT_RETURN_ERR(! pData->isIdling, "An operation is still being processed, please wait for it to finish"); | ||||
| CARLA_SAFE_ASSERT_RETURN_ERR(pData->plugins != nullptr, "Invalid engine internal data"); | CARLA_SAFE_ASSERT_RETURN_ERR(pData->plugins != nullptr, "Invalid engine internal data"); | ||||
| CARLA_SAFE_ASSERT_RETURN_ERR(pData->nextPluginId == pData->maxPluginNumber, "Invalid engine internal data"); | CARLA_SAFE_ASSERT_RETURN_ERR(pData->nextPluginId == pData->maxPluginNumber, "Invalid engine internal data"); | ||||
| CARLA_SAFE_ASSERT_RETURN_ERR(pData->nextAction.opcode == kEnginePostActionNull, "Invalid engine internal data"); | |||||
| carla_debug("CarlaEngine::removeAllPlugins()"); | carla_debug("CarlaEngine::removeAllPlugins()"); | ||||
| if (pData->curPluginCount == 0) | if (pData->curPluginCount == 0) | ||||
| @@ -618,8 +615,7 @@ bool CarlaEngine::removeAllPlugins() | |||||
| pData->thread.stopThread(500); | pData->thread.stopThread(500); | ||||
| const bool lockWait(isRunning()); | |||||
| const ScopedActionLock sal(pData, kEnginePostActionZeroCount, 0, 0, lockWait); | |||||
| const ScopedActionLock sal(pData, kEnginePostActionZeroCount, 0, 0, isRunning()); | |||||
| callback(ENGINE_CALLBACK_IDLE, 0, 0, 0, 0.0f, nullptr); | callback(ENGINE_CALLBACK_IDLE, 0, 0, 0, 0.0f, nullptr); | ||||
| @@ -647,12 +643,12 @@ bool CarlaEngine::removeAllPlugins() | |||||
| return true; | return true; | ||||
| } | } | ||||
| #ifndef BUILD_BRIDGE | |||||
| const char* CarlaEngine::renamePlugin(const uint id, const char* const newName) | const char* CarlaEngine::renamePlugin(const uint id, const char* const newName) | ||||
| { | { | ||||
| CARLA_SAFE_ASSERT_RETURN_ERRN(! pData->isIdling, "An operation is still being processed, please wait for it to finish"); | CARLA_SAFE_ASSERT_RETURN_ERRN(! pData->isIdling, "An operation is still being processed, please wait for it to finish"); | ||||
| CARLA_SAFE_ASSERT_RETURN_ERRN(pData->plugins != nullptr, "Invalid engine internal data"); | CARLA_SAFE_ASSERT_RETURN_ERRN(pData->plugins != nullptr, "Invalid engine internal data"); | ||||
| CARLA_SAFE_ASSERT_RETURN_ERRN(pData->curPluginCount != 0, "Invalid engine internal data"); | CARLA_SAFE_ASSERT_RETURN_ERRN(pData->curPluginCount != 0, "Invalid engine internal data"); | ||||
| CARLA_SAFE_ASSERT_RETURN_ERRN(pData->nextAction.opcode == kEnginePostActionNull, "Invalid engine internal data"); | |||||
| CARLA_SAFE_ASSERT_RETURN_ERRN(id < pData->curPluginCount, "Invalid plugin Id"); | CARLA_SAFE_ASSERT_RETURN_ERRN(id < pData->curPluginCount, "Invalid plugin Id"); | ||||
| CARLA_SAFE_ASSERT_RETURN_ERRN(newName != nullptr && newName[0] != '\0', "Invalid plugin name"); | CARLA_SAFE_ASSERT_RETURN_ERRN(newName != nullptr && newName[0] != '\0', "Invalid plugin name"); | ||||
| carla_debug("CarlaEngine::renamePlugin(%i, \"%s\")", id, newName); | carla_debug("CarlaEngine::renamePlugin(%i, \"%s\")", id, newName); | ||||
| @@ -677,7 +673,6 @@ bool CarlaEngine::clonePlugin(const uint id) | |||||
| CARLA_SAFE_ASSERT_RETURN_ERR(! pData->isIdling, "An operation is still being processed, please wait for it to finish"); | CARLA_SAFE_ASSERT_RETURN_ERR(! pData->isIdling, "An operation is still being processed, please wait for it to finish"); | ||||
| CARLA_SAFE_ASSERT_RETURN_ERR(pData->plugins != nullptr, "Invalid engine internal data"); | CARLA_SAFE_ASSERT_RETURN_ERR(pData->plugins != nullptr, "Invalid engine internal data"); | ||||
| CARLA_SAFE_ASSERT_RETURN_ERR(pData->curPluginCount != 0, "Invalid engine internal data"); | CARLA_SAFE_ASSERT_RETURN_ERR(pData->curPluginCount != 0, "Invalid engine internal data"); | ||||
| CARLA_SAFE_ASSERT_RETURN_ERR(pData->nextAction.opcode == kEnginePostActionNull, "Invalid engine internal data"); | |||||
| CARLA_SAFE_ASSERT_RETURN_ERR(id < pData->curPluginCount, "Invalid plugin Id"); | CARLA_SAFE_ASSERT_RETURN_ERR(id < pData->curPluginCount, "Invalid plugin Id"); | ||||
| carla_debug("CarlaEngine::clonePlugin(%i)", id); | carla_debug("CarlaEngine::clonePlugin(%i)", id); | ||||
| @@ -708,7 +703,6 @@ bool CarlaEngine::replacePlugin(const uint id) | |||||
| CARLA_SAFE_ASSERT_RETURN_ERR(! pData->isIdling, "An operation is still being processed, please wait for it to finish"); | CARLA_SAFE_ASSERT_RETURN_ERR(! pData->isIdling, "An operation is still being processed, please wait for it to finish"); | ||||
| CARLA_SAFE_ASSERT_RETURN_ERR(pData->plugins != nullptr, "Invalid engine internal data"); | CARLA_SAFE_ASSERT_RETURN_ERR(pData->plugins != nullptr, "Invalid engine internal data"); | ||||
| CARLA_SAFE_ASSERT_RETURN_ERR(pData->curPluginCount != 0, "Invalid engine internal data"); | CARLA_SAFE_ASSERT_RETURN_ERR(pData->curPluginCount != 0, "Invalid engine internal data"); | ||||
| CARLA_SAFE_ASSERT_RETURN_ERR(pData->nextAction.opcode == kEnginePostActionNull, "Invalid engine internal data"); | |||||
| carla_debug("CarlaEngine::replacePlugin(%i)", id); | carla_debug("CarlaEngine::replacePlugin(%i)", id); | ||||
| // might use this to reset | // might use this to reset | ||||
| @@ -735,7 +729,6 @@ bool CarlaEngine::switchPlugins(const uint idA, const uint idB) | |||||
| CARLA_SAFE_ASSERT_RETURN_ERR(! pData->isIdling, "An operation is still being processed, please wait for it to finish"); | CARLA_SAFE_ASSERT_RETURN_ERR(! pData->isIdling, "An operation is still being processed, please wait for it to finish"); | ||||
| CARLA_SAFE_ASSERT_RETURN_ERR(pData->plugins != nullptr, "Invalid engine internal data"); | CARLA_SAFE_ASSERT_RETURN_ERR(pData->plugins != nullptr, "Invalid engine internal data"); | ||||
| CARLA_SAFE_ASSERT_RETURN_ERR(pData->curPluginCount >= 2, "Invalid engine internal data"); | CARLA_SAFE_ASSERT_RETURN_ERR(pData->curPluginCount >= 2, "Invalid engine internal data"); | ||||
| CARLA_SAFE_ASSERT_RETURN_ERR(pData->nextAction.opcode == kEnginePostActionNull, "Invalid engine internal data"); | |||||
| CARLA_SAFE_ASSERT_RETURN_ERR(idA != idB, "Invalid operation, cannot switch plugin with itself"); | CARLA_SAFE_ASSERT_RETURN_ERR(idA != idB, "Invalid operation, cannot switch plugin with itself"); | ||||
| CARLA_SAFE_ASSERT_RETURN_ERR(idA < pData->curPluginCount, "Invalid plugin Id"); | CARLA_SAFE_ASSERT_RETURN_ERR(idA < pData->curPluginCount, "Invalid plugin Id"); | ||||
| CARLA_SAFE_ASSERT_RETURN_ERR(idB < pData->curPluginCount, "Invalid plugin Id"); | CARLA_SAFE_ASSERT_RETURN_ERR(idB < pData->curPluginCount, "Invalid plugin Id"); | ||||
| @@ -751,28 +744,23 @@ bool CarlaEngine::switchPlugins(const uint idA, const uint idB) | |||||
| pData->thread.stopThread(500); | pData->thread.stopThread(500); | ||||
| #ifndef BUILD_BRIDGE | |||||
| 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, isRunning()); | |||||
| // TODO | // TODO | ||||
| //if (isOscControlRegistered()) | //if (isOscControlRegistered()) | ||||
| // oscSend_control_switch_plugins(idA, idB); | // oscSend_control_switch_plugins(idA, idB); | ||||
| #else | |||||
| pData->plugins[0].plugin = nullptr; | |||||
| #endif | |||||
| if (isRunning() && ! pData->aboutToClose) | if (isRunning() && ! pData->aboutToClose) | ||||
| pData->thread.startThread(); | pData->thread.startThread(); | ||||
| return true; | return true; | ||||
| } | } | ||||
| #endif | |||||
| CarlaPlugin* CarlaEngine::getPlugin(const uint id) const | CarlaPlugin* CarlaEngine::getPlugin(const uint id) const | ||||
| { | { | ||||
| CARLA_SAFE_ASSERT_RETURN_ERRN(pData->plugins != nullptr, "Invalid engine internal data"); | CARLA_SAFE_ASSERT_RETURN_ERRN(pData->plugins != nullptr, "Invalid engine internal data"); | ||||
| CARLA_SAFE_ASSERT_RETURN_ERRN(pData->curPluginCount != 0, "Invalid engine internal data"); | CARLA_SAFE_ASSERT_RETURN_ERRN(pData->curPluginCount != 0, "Invalid engine internal data"); | ||||
| CARLA_SAFE_ASSERT_RETURN_ERRN(pData->nextAction.opcode == kEnginePostActionNull, "Invalid engine internal data"); | |||||
| CARLA_SAFE_ASSERT_RETURN_ERRN(id < pData->curPluginCount, "Invalid plugin Id"); | CARLA_SAFE_ASSERT_RETURN_ERRN(id < pData->curPluginCount, "Invalid plugin Id"); | ||||
| return pData->plugins[id].plugin; | return pData->plugins[id].plugin; | ||||
| @@ -785,7 +773,6 @@ CarlaPlugin* CarlaEngine::getPluginUnchecked(const uint id) const noexcept | |||||
| const char* CarlaEngine::getUniquePluginName(const char* const name) const | const char* CarlaEngine::getUniquePluginName(const char* const name) const | ||||
| { | { | ||||
| CARLA_SAFE_ASSERT_RETURN(pData->nextAction.opcode == kEnginePostActionNull, nullptr); | |||||
| CARLA_SAFE_ASSERT_RETURN(name != nullptr && name[0] != '\0', nullptr); | CARLA_SAFE_ASSERT_RETURN(name != nullptr && name[0] != '\0', nullptr); | ||||
| carla_debug("CarlaEngine::getUniquePluginName(\"%s\")", name); | carla_debug("CarlaEngine::getUniquePluginName(\"%s\")", name); | ||||
| @@ -71,13 +71,12 @@ EngineNextAction::EngineNextAction() noexcept | |||||
| EngineNextAction::~EngineNextAction() noexcept | EngineNextAction::~EngineNextAction() noexcept | ||||
| { | { | ||||
| CARLA_SAFE_ASSERT(opcode == kEnginePostActionNull); | |||||
| CARLA_SAFE_ASSERT(opcode.get() == kEnginePostActionNull); | |||||
| } | } | ||||
| void EngineNextAction::ready() const noexcept | void EngineNextAction::ready() const noexcept | ||||
| { | { | ||||
| mutex.lock(); | |||||
| mutex.unlock(); | |||||
| waitEvent.reset(); | |||||
| } | } | ||||
| // ----------------------------------------------------------------------- | // ----------------------------------------------------------------------- | ||||
| @@ -131,39 +130,38 @@ bool CarlaEngine::ProtectedData::init(const char* const clientName) | |||||
| CARLA_SAFE_ASSERT_RETURN_INTERNAL_ERR(plugins == nullptr, "Invalid engine internal data (err #3)"); | CARLA_SAFE_ASSERT_RETURN_INTERNAL_ERR(plugins == nullptr, "Invalid engine internal data (err #3)"); | ||||
| #endif | #endif | ||||
| aboutToClose = false; | |||||
| curPluginCount = 0; | |||||
| maxPluginNumber = 0; | |||||
| nextPluginId = 0; | |||||
| aboutToClose = false; | |||||
| curPluginCount = 0; | |||||
| nextPluginId = 0; | |||||
| switch (options.processMode) | switch (options.processMode) | ||||
| { | { | ||||
| case ENGINE_PROCESS_MODE_SINGLE_CLIENT: | |||||
| case ENGINE_PROCESS_MODE_MULTIPLE_CLIENTS: | |||||
| maxPluginNumber = MAX_DEFAULT_PLUGINS; | |||||
| break; | |||||
| case ENGINE_PROCESS_MODE_CONTINUOUS_RACK: | case ENGINE_PROCESS_MODE_CONTINUOUS_RACK: | ||||
| maxPluginNumber = MAX_RACK_PLUGINS; | maxPluginNumber = MAX_RACK_PLUGINS; | ||||
| events.in = new EngineEvent[kMaxEngineEventInternalCount]; | |||||
| events.out = new EngineEvent[kMaxEngineEventInternalCount]; | |||||
| break; | break; | ||||
| case ENGINE_PROCESS_MODE_PATCHBAY: | case ENGINE_PROCESS_MODE_PATCHBAY: | ||||
| maxPluginNumber = MAX_PATCHBAY_PLUGINS; | maxPluginNumber = MAX_PATCHBAY_PLUGINS; | ||||
| events.in = new EngineEvent[kMaxEngineEventInternalCount]; | |||||
| events.out = new EngineEvent[kMaxEngineEventInternalCount]; | |||||
| break; | break; | ||||
| case ENGINE_PROCESS_MODE_BRIDGE: | case ENGINE_PROCESS_MODE_BRIDGE: | ||||
| maxPluginNumber = 1; | maxPluginNumber = 1; | ||||
| break; | |||||
| default: | |||||
| maxPluginNumber = MAX_DEFAULT_PLUGINS; | |||||
| break; | |||||
| } | |||||
| switch (options.processMode) | |||||
| { | |||||
| case ENGINE_PROCESS_MODE_CONTINUOUS_RACK: | |||||
| case ENGINE_PROCESS_MODE_PATCHBAY: | |||||
| case ENGINE_PROCESS_MODE_BRIDGE: | |||||
| events.in = new EngineEvent[kMaxEngineEventInternalCount]; | events.in = new EngineEvent[kMaxEngineEventInternalCount]; | ||||
| events.out = new EngineEvent[kMaxEngineEventInternalCount]; | events.out = new EngineEvent[kMaxEngineEventInternalCount]; | ||||
| break; | break; | ||||
| default: | |||||
| break; | |||||
| } | } | ||||
| CARLA_SAFE_ASSERT_RETURN_INTERNAL_ERR(maxPluginNumber != 0, "Invalid engine process mode"); | |||||
| nextPluginId = maxPluginNumber; | nextPluginId = maxPluginNumber; | ||||
| name = clientName; | name = clientName; | ||||
| @@ -171,15 +169,12 @@ bool CarlaEngine::ProtectedData::init(const char* const clientName) | |||||
| timeInfo.clear(); | timeInfo.clear(); | ||||
| #ifndef BUILD_BRIDGE | |||||
| plugins = new EnginePluginData[maxPluginNumber]; | |||||
| carla_zeroStruct(plugins, maxPluginNumber); | |||||
| #endif | |||||
| osc.init(clientName); | osc.init(clientName); | ||||
| #ifndef BUILD_BRIDGE | #ifndef BUILD_BRIDGE | ||||
| oscData = osc.getControlData(); | oscData = osc.getControlData(); | ||||
| plugins = new EnginePluginData[maxPluginNumber]; | |||||
| carla_zeroStruct(plugins, maxPluginNumber); | |||||
| #endif | #endif | ||||
| nextAction.ready(); | nextAction.ready(); | ||||
| @@ -193,7 +188,7 @@ void CarlaEngine::ProtectedData::close() | |||||
| CARLA_SAFE_ASSERT(name.isNotEmpty()); | CARLA_SAFE_ASSERT(name.isNotEmpty()); | ||||
| CARLA_SAFE_ASSERT(plugins != nullptr); | CARLA_SAFE_ASSERT(plugins != nullptr); | ||||
| CARLA_SAFE_ASSERT(nextPluginId == maxPluginNumber); | CARLA_SAFE_ASSERT(nextPluginId == maxPluginNumber); | ||||
| CARLA_SAFE_ASSERT(nextAction.opcode == kEnginePostActionNull); | |||||
| CARLA_SAFE_ASSERT(nextAction.opcode.get() == kEnginePostActionNull); | |||||
| aboutToClose = true; | aboutToClose = true; | ||||
| @@ -280,7 +275,9 @@ void CarlaEngine::ProtectedData::doPluginsSwitch() noexcept | |||||
| void CarlaEngine::ProtectedData::doNextPluginAction(const bool unlock) noexcept | void CarlaEngine::ProtectedData::doNextPluginAction(const bool unlock) noexcept | ||||
| { | { | ||||
| switch (nextAction.opcode) | |||||
| const EnginePostAction action(nextAction.opcode.exchange(kEnginePostActionNull)); | |||||
| switch (action) | |||||
| { | { | ||||
| case kEnginePostActionNull: | case kEnginePostActionNull: | ||||
| break; | break; | ||||
| @@ -301,11 +298,8 @@ void CarlaEngine::ProtectedData::doNextPluginAction(const bool unlock) noexcept | |||||
| nextAction.pluginId = 0; | nextAction.pluginId = 0; | ||||
| nextAction.value = 0; | nextAction.value = 0; | ||||
| if (unlock) | |||||
| { | |||||
| nextAction.mutex.tryLock(); | |||||
| nextAction.mutex.unlock(); | |||||
| } | |||||
| if (unlock && action != kEnginePostActionNull) | |||||
| nextAction.waitEvent.signal(); | |||||
| } | } | ||||
| // ----------------------------------------------------------------------- | // ----------------------------------------------------------------------- | ||||
| @@ -314,19 +308,18 @@ 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) | ||||
| { | { | ||||
| fData->nextAction.mutex.lock(); | |||||
| CARLA_SAFE_ASSERT_RETURN(fData->nextAction.opcode == kEnginePostActionNull,); | |||||
| CARLA_SAFE_ASSERT_RETURN(action != kEnginePostActionNull,); | |||||
| CARLA_SAFE_ASSERT_RETURN(fData->nextAction.opcode.get() == kEnginePostActionNull,); | |||||
| fData->nextAction.opcode = action; | |||||
| fData->nextAction.pluginId = pluginId; | fData->nextAction.pluginId = pluginId; | ||||
| fData->nextAction.value = value; | fData->nextAction.value = value; | ||||
| fData->nextAction.opcode = action; | |||||
| if (lockWait) | if (lockWait) | ||||
| { | { | ||||
| // block wait for unlock on processing side | // block wait for unlock on processing side | ||||
| carla_stdout("ScopedPluginAction(%i) - blocking START", pluginId); | carla_stdout("ScopedPluginAction(%i) - blocking START", pluginId); | ||||
| fData->nextAction.mutex.lock(); | |||||
| fData->nextAction.waitEvent.wait(2000); | |||||
| carla_stdout("ScopedPluginAction(%i) - blocking DONE", pluginId); | carla_stdout("ScopedPluginAction(%i) - blocking DONE", pluginId); | ||||
| } | } | ||||
| else | else | ||||
| @@ -337,7 +330,7 @@ ScopedActionLock::ScopedActionLock(CarlaEngine::ProtectedData* const data, const | |||||
| ScopedActionLock::~ScopedActionLock() noexcept | ScopedActionLock::~ScopedActionLock() noexcept | ||||
| { | { | ||||
| fData->nextAction.mutex.unlock(); | |||||
| //fData->nextAction.mutex.unlock(); | |||||
| } | } | ||||
| // ----------------------------------------------------------------------- | // ----------------------------------------------------------------------- | ||||
| @@ -22,6 +22,10 @@ | |||||
| #include "CarlaEngineThread.hpp" | #include "CarlaEngineThread.hpp" | ||||
| #include "CarlaEngineUtils.hpp" | #include "CarlaEngineUtils.hpp" | ||||
| #include "juce_core.h" | |||||
| using juce::Atomic; | |||||
| using juce::WaitableEvent; | |||||
| CARLA_BACKEND_START_NAMESPACE | CARLA_BACKEND_START_NAMESPACE | ||||
| // ----------------------------------------------------------------------- | // ----------------------------------------------------------------------- | ||||
| @@ -112,10 +116,10 @@ enum EnginePostAction { | |||||
| }; | }; | ||||
| struct EngineNextAction { | struct EngineNextAction { | ||||
| EnginePostAction opcode; | |||||
| Atomic<EnginePostAction> opcode; | |||||
| uint pluginId; | uint pluginId; | ||||
| uint value; | uint value; | ||||
| CarlaMutex mutex; | |||||
| WaitableEvent waitEvent; | |||||
| EngineNextAction() noexcept; | EngineNextAction() noexcept; | ||||
| ~EngineNextAction() noexcept; | ~EngineNextAction() noexcept; | ||||
| @@ -162,7 +162,7 @@ void CarlaEngineOsc::close() noexcept | |||||
| fServerPathUDP.clear(); | fServerPathUDP.clear(); | ||||
| #ifndef BUILD_BRIDGE | #ifndef BUILD_BRIDGE | ||||
| fControlData.free(); | |||||
| fControlData.clear(); | |||||
| #endif | #endif | ||||
| } | } | ||||
| @@ -448,7 +448,7 @@ int CarlaEngineOsc::handleMsgUnregister() | |||||
| return 1; | return 1; | ||||
| } | } | ||||
| fControlData.free(); | |||||
| fControlData.clear(); | |||||
| return 0; | return 0; | ||||
| } | } | ||||
| #endif | #endif | ||||
| @@ -135,7 +135,7 @@ const EngineEvent& CarlaEngineEventPort::getEvent(const uint32_t index) const no | |||||
| { | { | ||||
| CARLA_SAFE_ASSERT_RETURN(kIsInput, kFallbackEngineEvent); | CARLA_SAFE_ASSERT_RETURN(kIsInput, kFallbackEngineEvent); | ||||
| CARLA_SAFE_ASSERT_RETURN(fBuffer != nullptr, kFallbackEngineEvent); | CARLA_SAFE_ASSERT_RETURN(fBuffer != nullptr, kFallbackEngineEvent); | ||||
| CARLA_SAFE_ASSERT_RETURN(kProcessMode != ENGINE_PROCESS_MODE_SINGLE_CLIENT && kProcessMode != ENGINE_PROCESS_MODE_MULTIPLE_CLIENTS, kFallbackEngineEvent); | |||||
| CARLA_SAFE_ASSERT_RETURN(kProcessMode == ENGINE_PROCESS_MODE_CONTINUOUS_RACK || kProcessMode == ENGINE_PROCESS_MODE_PATCHBAY, kFallbackEngineEvent); | |||||
| CARLA_SAFE_ASSERT_RETURN(index < kMaxEngineEventInternalCount, kFallbackEngineEvent); | CARLA_SAFE_ASSERT_RETURN(index < kMaxEngineEventInternalCount, kFallbackEngineEvent); | ||||
| return fBuffer[index]; | return fBuffer[index]; | ||||
| @@ -155,7 +155,7 @@ bool CarlaEngineEventPort::writeControlEvent(const uint32_t time, const uint8_t | |||||
| { | { | ||||
| CARLA_SAFE_ASSERT_RETURN(! kIsInput, false); | CARLA_SAFE_ASSERT_RETURN(! kIsInput, false); | ||||
| CARLA_SAFE_ASSERT_RETURN(fBuffer != nullptr, false); | CARLA_SAFE_ASSERT_RETURN(fBuffer != nullptr, false); | ||||
| CARLA_SAFE_ASSERT_RETURN(kProcessMode != ENGINE_PROCESS_MODE_SINGLE_CLIENT && kProcessMode != ENGINE_PROCESS_MODE_MULTIPLE_CLIENTS, false); | |||||
| CARLA_SAFE_ASSERT_RETURN(kProcessMode == ENGINE_PROCESS_MODE_CONTINUOUS_RACK || kProcessMode == ENGINE_PROCESS_MODE_PATCHBAY, false); | |||||
| CARLA_SAFE_ASSERT_RETURN(type != kEngineControlEventTypeNull, false); | CARLA_SAFE_ASSERT_RETURN(type != kEngineControlEventTypeNull, false); | ||||
| CARLA_SAFE_ASSERT_RETURN(channel < MAX_MIDI_CHANNELS, false); | CARLA_SAFE_ASSERT_RETURN(channel < MAX_MIDI_CHANNELS, false); | ||||
| CARLA_SAFE_ASSERT(value >= 0.0f && value <= 1.0f); | CARLA_SAFE_ASSERT(value >= 0.0f && value <= 1.0f); | ||||
| @@ -200,7 +200,7 @@ bool CarlaEngineEventPort::writeMidiEvent(const uint32_t time, const uint8_t cha | |||||
| { | { | ||||
| CARLA_SAFE_ASSERT_RETURN(! kIsInput, false); | CARLA_SAFE_ASSERT_RETURN(! kIsInput, false); | ||||
| CARLA_SAFE_ASSERT_RETURN(fBuffer != nullptr, false); | CARLA_SAFE_ASSERT_RETURN(fBuffer != nullptr, false); | ||||
| CARLA_SAFE_ASSERT_RETURN(kProcessMode != ENGINE_PROCESS_MODE_SINGLE_CLIENT && kProcessMode != ENGINE_PROCESS_MODE_MULTIPLE_CLIENTS, false); | |||||
| CARLA_SAFE_ASSERT_RETURN(kProcessMode == ENGINE_PROCESS_MODE_CONTINUOUS_RACK || kProcessMode == ENGINE_PROCESS_MODE_PATCHBAY, false); | |||||
| CARLA_SAFE_ASSERT_RETURN(channel < MAX_MIDI_CHANNELS, false); | CARLA_SAFE_ASSERT_RETURN(channel < MAX_MIDI_CHANNELS, false); | ||||
| CARLA_SAFE_ASSERT_RETURN(size > 0 && size <= EngineMidiEvent::kDataSize, false); | CARLA_SAFE_ASSERT_RETURN(size > 0 && size <= EngineMidiEvent::kDataSize, false); | ||||
| CARLA_SAFE_ASSERT_RETURN(data != nullptr, false); | CARLA_SAFE_ASSERT_RETURN(data != nullptr, false); | ||||
| @@ -44,7 +44,7 @@ void CarlaEngineThread::run() noexcept | |||||
| CARLA_SAFE_ASSERT(kEngine->isRunning()); | CARLA_SAFE_ASSERT(kEngine->isRunning()); | ||||
| carla_debug("CarlaEngineThread::run()"); | carla_debug("CarlaEngineThread::run()"); | ||||
| bool hasUi, oscRegisted, needsSingleThread; | |||||
| bool hasUI, oscRegisted, needsSingleThread; | |||||
| float value; | float value; | ||||
| for (; kEngine->isRunning() && ! shouldThreadExit();) | for (; kEngine->isRunning() && ! shouldThreadExit();) | ||||
| @@ -62,7 +62,7 @@ void CarlaEngineThread::run() noexcept | |||||
| CARLA_SAFE_ASSERT_CONTINUE(plugin != nullptr && plugin->isEnabled()); | CARLA_SAFE_ASSERT_CONTINUE(plugin != nullptr && plugin->isEnabled()); | ||||
| CARLA_SAFE_ASSERT_UINT2(i == plugin->getId(), i, plugin->getId()); | CARLA_SAFE_ASSERT_UINT2(i == plugin->getId(), i, plugin->getId()); | ||||
| hasUi = (plugin->getHints() & PLUGIN_HAS_CUSTOM_UI); | |||||
| hasUI = (plugin->getHints() & PLUGIN_HAS_CUSTOM_UI); | |||||
| needsSingleThread = (plugin->getHints() & PLUGIN_NEEDS_SINGLE_THREAD); | needsSingleThread = (plugin->getHints() & PLUGIN_NEEDS_SINGLE_THREAD); | ||||
| // ----------------------------------------------------------- | // ----------------------------------------------------------- | ||||
| @@ -77,7 +77,7 @@ void CarlaEngineThread::run() noexcept | |||||
| } CARLA_SAFE_EXCEPTION("postRtEventsRun()") | } CARLA_SAFE_EXCEPTION("postRtEventsRun()") | ||||
| } | } | ||||
| if (oscRegisted || (hasUi && ! needsSingleThread)) | |||||
| if (oscRegisted || (hasUI && ! needsSingleThread)) | |||||
| { | { | ||||
| // --------------------------------------------------- | // --------------------------------------------------- | ||||
| // Update parameter outputs | // Update parameter outputs | ||||
| @@ -100,7 +100,7 @@ void CarlaEngineThread::run() noexcept | |||||
| } | } | ||||
| // Update UI | // Update UI | ||||
| if (hasUi && ! needsSingleThread) | |||||
| if (hasUI && ! needsSingleThread) | |||||
| plugin->uiParameterChange(j, value); | plugin->uiParameterChange(j, value); | ||||
| } | } | ||||
| } | } | ||||
| @@ -353,7 +353,7 @@ public: | |||||
| osc_send_quit(pData->osc.data); | osc_send_quit(pData->osc.data); | ||||
| } | } | ||||
| pData->osc.data.free(); | |||||
| pData->osc.data.clear(); | |||||
| pData->osc.thread.stopThread(3000); | pData->osc.thread.stopThread(3000); | ||||
| if (fNeedsSemDestroy) | if (fNeedsSemDestroy) | ||||
| @@ -1658,7 +1658,7 @@ void CarlaPlugin::updateOscData(const lo_address& source, const char* const url) | |||||
| // FIXME - remove debug prints later | // FIXME - remove debug prints later | ||||
| carla_stdout("CarlaPlugin::updateOscData(%p, \"%s\")", source, url); | carla_stdout("CarlaPlugin::updateOscData(%p, \"%s\")", source, url); | ||||
| pData->osc.data.free(); | |||||
| pData->osc.data.clear(); | |||||
| const int proto = lo_address_get_protocol(source); | const int proto = lo_address_get_protocol(source); | ||||
| @@ -408,7 +408,7 @@ public: | |||||
| { | { | ||||
| if (yesNo) | if (yesNo) | ||||
| { | { | ||||
| pData->osc.data.free(); | |||||
| pData->osc.data.clear(); | |||||
| pData->osc.thread.startThread(); | pData->osc.thread.startThread(); | ||||
| } | } | ||||
| else | else | ||||
| @@ -419,7 +419,7 @@ public: | |||||
| { | { | ||||
| osc_send_hide(pData->osc.data); | osc_send_hide(pData->osc.data); | ||||
| osc_send_quit(pData->osc.data); | osc_send_quit(pData->osc.data); | ||||
| pData->osc.data.free(); | |||||
| pData->osc.data.clear(); | |||||
| } | } | ||||
| pData->osc.thread.stopThread(static_cast<int>(pData->engine->getOptions().uiBridgesTimeout * 2)); | pData->osc.thread.stopThread(static_cast<int>(pData->engine->getOptions().uiBridgesTimeout * 2)); | ||||
| @@ -1126,7 +1126,7 @@ public: | |||||
| { | { | ||||
| if (yesNo) | if (yesNo) | ||||
| { | { | ||||
| pData->osc.data.free(); | |||||
| pData->osc.data.clear(); | |||||
| pData->osc.thread.startThread(); | pData->osc.thread.startThread(); | ||||
| } | } | ||||
| else | else | ||||
| @@ -1135,7 +1135,7 @@ public: | |||||
| { | { | ||||
| osc_send_hide(pData->osc.data); | osc_send_hide(pData->osc.data); | ||||
| osc_send_quit(pData->osc.data); | osc_send_quit(pData->osc.data); | ||||
| pData->osc.data.free(); | |||||
| pData->osc.data.clear(); | |||||
| } | } | ||||
| pData->osc.thread.stopThread(static_cast<int>(pData->engine->getOptions().uiBridgesTimeout * 2)); | pData->osc.thread.stopThread(static_cast<int>(pData->engine->getOptions().uiBridgesTimeout * 2)); | ||||
| @@ -401,7 +401,7 @@ public: | |||||
| { | { | ||||
| if (yesNo) | if (yesNo) | ||||
| { | { | ||||
| pData->osc.data.free(); | |||||
| pData->osc.data.clear(); | |||||
| pData->osc.thread.startThread(); | pData->osc.thread.startThread(); | ||||
| } | } | ||||
| else | else | ||||
| @@ -412,7 +412,7 @@ public: | |||||
| { | { | ||||
| osc_send_hide(pData->osc.data); | osc_send_hide(pData->osc.data); | ||||
| osc_send_quit(pData->osc.data); | osc_send_quit(pData->osc.data); | ||||
| pData->osc.data.free(); | |||||
| pData->osc.data.clear(); | |||||
| } | } | ||||
| pData->osc.thread.stopThread(static_cast<int>(pData->engine->getOptions().uiBridgesTimeout * 2)); | pData->osc.thread.stopThread(static_cast<int>(pData->engine->getOptions().uiBridgesTimeout * 2)); | ||||
| @@ -41,10 +41,10 @@ struct CarlaOscData { | |||||
| ~CarlaOscData() noexcept | ~CarlaOscData() noexcept | ||||
| { | { | ||||
| free(); | |||||
| clear(); | |||||
| } | } | ||||
| void free() noexcept | |||||
| void clear() noexcept | |||||
| { | { | ||||
| if (path != nullptr) | if (path != nullptr) | ||||
| { | { | ||||
| @@ -56,7 +56,7 @@ struct CarlaOscData { | |||||
| { | { | ||||
| try { | try { | ||||
| lo_address_free(source); | lo_address_free(source); | ||||
| } catch(...) {} | |||||
| } CARLA_SAFE_EXCEPTION("lo_address_free source"); | |||||
| source = nullptr; | source = nullptr; | ||||
| } | } | ||||
| @@ -64,7 +64,7 @@ struct CarlaOscData { | |||||
| { | { | ||||
| try { | try { | ||||
| lo_address_free(target); | lo_address_free(target); | ||||
| } catch(...) {} | |||||
| } CARLA_SAFE_EXCEPTION("lo_address_free target"); | |||||
| target = nullptr; | target = nullptr; | ||||
| } | } | ||||
| } | } | ||||