| @@ -647,7 +647,7 @@ const char* CarlaEngine::getDriverName(const uint index2) | |||
| # endif | |||
| #endif | |||
| carla_stderr("CarlaEngine::getDriverName(%i) - invalid index", index); | |||
| carla_stderr("CarlaEngine::getDriverName(%i) - invalid index", index2); | |||
| return nullptr; | |||
| } | |||
| @@ -675,7 +675,7 @@ const char* const* CarlaEngine::getDriverDeviceNames(const uint index2) | |||
| # endif | |||
| #endif | |||
| carla_stderr("CarlaEngine::getDriverDeviceNames(%i) - invalid index", index); | |||
| carla_stderr("CarlaEngine::getDriverDeviceNames(%i) - invalid index", index2); | |||
| return nullptr; | |||
| } | |||
| @@ -707,7 +707,7 @@ const EngineDriverDeviceInfo* CarlaEngine::getDriverDeviceInfo(const uint index2 | |||
| # endif | |||
| #endif | |||
| carla_stderr("CarlaEngine::getDriverDeviceNames(%i, \"%s\") - invalid index", index, deviceName); | |||
| carla_stderr("CarlaEngine::getDriverDeviceNames(%i, \"%s\") - invalid index", index2, deviceName); | |||
| return nullptr; | |||
| } | |||
| @@ -809,125 +809,33 @@ uint CarlaEngine::getMaxPluginNumber() const noexcept | |||
| bool CarlaEngine::init(const char* const clientName) | |||
| { | |||
| CARLA_SAFE_ASSERT_RETURN_ERR(pData->name.isEmpty(), "Invalid engine internal data (err #1)"); | |||
| CARLA_SAFE_ASSERT_RETURN_ERR(pData->oscData == nullptr, "Invalid engine internal data (err #2)"); | |||
| CARLA_SAFE_ASSERT_RETURN_ERR(pData->plugins == nullptr, "Invalid engine internal data (err #3)"); | |||
| CARLA_SAFE_ASSERT_RETURN_ERR(pData->events.in == nullptr, "Invalid engine internal data (err #4)"); | |||
| CARLA_SAFE_ASSERT_RETURN_ERR(pData->events.out == nullptr, "Invalid engine internal data (err #5)"); | |||
| CARLA_SAFE_ASSERT_RETURN_ERR(clientName != nullptr && clientName[0] != '\0', "Invalid client name"); | |||
| carla_debug("CarlaEngine::init(\"%s\")", clientName); | |||
| pData->aboutToClose = false; | |||
| pData->curPluginCount = 0; | |||
| pData->maxPluginNumber = 0; | |||
| pData->nextPluginId = 0; | |||
| switch (pData->options.processMode) | |||
| { | |||
| case ENGINE_PROCESS_MODE_SINGLE_CLIENT: | |||
| case ENGINE_PROCESS_MODE_MULTIPLE_CLIENTS: | |||
| pData->maxPluginNumber = MAX_DEFAULT_PLUGINS; | |||
| break; | |||
| case ENGINE_PROCESS_MODE_CONTINUOUS_RACK: | |||
| pData->maxPluginNumber = MAX_RACK_PLUGINS; | |||
| pData->events.in = new EngineEvent[kMaxEngineEventInternalCount]; | |||
| pData->events.out = new EngineEvent[kMaxEngineEventInternalCount]; | |||
| break; | |||
| case ENGINE_PROCESS_MODE_PATCHBAY: | |||
| pData->maxPluginNumber = MAX_PATCHBAY_PLUGINS; | |||
| break; | |||
| case ENGINE_PROCESS_MODE_BRIDGE: | |||
| pData->maxPluginNumber = 1; | |||
| pData->events.in = new EngineEvent[kMaxEngineEventInternalCount]; | |||
| pData->events.out = new EngineEvent[kMaxEngineEventInternalCount]; | |||
| break; | |||
| } | |||
| CARLA_SAFE_ASSERT_RETURN_ERR(pData->maxPluginNumber != 0, "Invalid engine process mode"); | |||
| pData->nextPluginId = pData->maxPluginNumber; | |||
| pData->name = clientName; | |||
| pData->name.toBasic(); | |||
| pData->timeInfo.clear(); | |||
| pData->plugins = new EnginePluginData[pData->maxPluginNumber]; | |||
| for (uint i=0; i < pData->maxPluginNumber; ++i) | |||
| pData->plugins[i].clear(); | |||
| pData->osc.init(clientName); | |||
| #ifndef BUILD_BRIDGE | |||
| pData->oscData = pData->osc.getControlData(); | |||
| if (pData->options.processMode == ENGINE_PROCESS_MODE_CONTINUOUS_RACK || pData->options.processMode == ENGINE_PROCESS_MODE_PATCHBAY) | |||
| { | |||
| pData->graph.isRack = (pData->options.processMode == ENGINE_PROCESS_MODE_CONTINUOUS_RACK); | |||
| pData->graph.create(); | |||
| } | |||
| #endif | |||
| pData->nextAction.ready(); | |||
| pData->thread.startThread(); | |||
| callback(ENGINE_CALLBACK_ENGINE_STARTED, 0, 0, 0, 0.0f, getCurrentDriverName()); | |||
| if (! pData->init(clientName)) | |||
| return false; | |||
| callback(ENGINE_CALLBACK_ENGINE_STARTED, 0, pData->options.processMode, pData->options.transportMode, 0.0f, getCurrentDriverName()); | |||
| return true; | |||
| } | |||
| bool CarlaEngine::close() | |||
| { | |||
| CARLA_SAFE_ASSERT_RETURN_ERR(pData->name.isNotEmpty(), "Invalid engine internal data (err #6)"); | |||
| CARLA_SAFE_ASSERT_RETURN_ERR(pData->plugins != nullptr, "Invalid engine internal data (err #7)"); | |||
| CARLA_SAFE_ASSERT_RETURN_ERR(pData->nextPluginId == pData->maxPluginNumber, "Invalid engine internal data (err #8)"); | |||
| CARLA_SAFE_ASSERT_RETURN_ERR(pData->nextAction.opcode == kEnginePostActionNull, "Invalid engine internal data (err #9)"); | |||
| carla_debug("CarlaEngine::close()"); | |||
| pData->aboutToClose = true; | |||
| if (pData->curPluginCount != 0) | |||
| removeAllPlugins(); | |||
| pData->thread.stopThread(500); | |||
| pData->nextAction.ready(); | |||
| #ifndef BUILD_BRIDGE | |||
| if (pData->options.processMode == ENGINE_PROCESS_MODE_CONTINUOUS_RACK || pData->options.processMode == ENGINE_PROCESS_MODE_PATCHBAY) | |||
| { | |||
| pData->graph.clear(); | |||
| pData->aboutToClose = true; | |||
| removeAllPlugins(); | |||
| } | |||
| #ifndef BUILD_BRIDGE | |||
| if (pData->osc.isControlRegistered()) | |||
| oscSend_control_exit(); | |||
| #endif | |||
| pData->osc.close(); | |||
| pData->oscData = nullptr; | |||
| pData->curPluginCount = 0; | |||
| pData->maxPluginNumber = 0; | |||
| pData->nextPluginId = 0; | |||
| if (pData->plugins != nullptr) | |||
| { | |||
| delete[] pData->plugins; | |||
| pData->plugins = nullptr; | |||
| } | |||
| pData->events.clear(); | |||
| #ifndef BUILD_BRIDGE | |||
| pData->audio.clear(); | |||
| #endif | |||
| pData->name.clear(); | |||
| pData->close(); | |||
| callback(ENGINE_CALLBACK_ENGINE_STOPPED, 0, 0, 0, 0.0f, nullptr); | |||
| return true; | |||
| } | |||
| @@ -21,6 +21,12 @@ | |||
| #include "CarlaMathUtils.hpp" | |||
| // ----------------------------------------------------------------------- | |||
| // Engine Internal helper macro, sets lastError and returns false/NULL | |||
| #define CARLA_SAFE_ASSERT_RETURN_INTERNAL_ERR(cond, err) if (! (cond)) { carla_safe_assert(#cond, __FILE__, __LINE__); lastError = err; return false; } | |||
| #define CARLA_SAFE_ASSERT_RETURN_INTERNAL_ERRN(cond, err) if (! (cond)) { carla_safe_assert(#cond, __FILE__, __LINE__); lastError = err; return nullptr; } | |||
| // ----------------------------------------------------------------------- | |||
| CARLA_BACKEND_START_NAMESPACE | |||
| @@ -440,8 +446,15 @@ CarlaEngine::ProtectedData::ProtectedData(CarlaEngine* const engine) noexcept | |||
| aboutToClose(false), | |||
| curPluginCount(0), | |||
| maxPluginNumber(0), | |||
| nextPluginId(0), | |||
| plugins(nullptr) {} | |||
| nextPluginId(0) | |||
| #ifndef BUILD_BRIDGE | |||
| , plugins(nullptr) | |||
| #endif | |||
| { | |||
| #ifdef BUILD_BRIDGE | |||
| carla_zeroStruct(plugins, 1); | |||
| #endif | |||
| } | |||
| CarlaEngine::ProtectedData::~ProtectedData() noexcept | |||
| { | |||
| @@ -453,6 +466,118 @@ CarlaEngine::ProtectedData::~ProtectedData() noexcept | |||
| // ----------------------------------------------------------------------- | |||
| bool CarlaEngine::ProtectedData::init(const char* const clientName) | |||
| { | |||
| CARLA_SAFE_ASSERT_RETURN_INTERNAL_ERR(name.isEmpty(), "Invalid engine internal data (err #1)"); | |||
| CARLA_SAFE_ASSERT_RETURN_INTERNAL_ERR(oscData == nullptr, "Invalid engine internal data (err #2)"); | |||
| CARLA_SAFE_ASSERT_RETURN_INTERNAL_ERR(plugins == nullptr, "Invalid engine internal data (err #3)"); | |||
| CARLA_SAFE_ASSERT_RETURN_INTERNAL_ERR(events.in == nullptr, "Invalid engine internal data (err #4)"); | |||
| CARLA_SAFE_ASSERT_RETURN_INTERNAL_ERR(events.out == nullptr, "Invalid engine internal data (err #5)"); | |||
| CARLA_SAFE_ASSERT_RETURN_INTERNAL_ERR(clientName != nullptr && clientName[0] != '\0', "Invalid client name"); | |||
| aboutToClose = false; | |||
| curPluginCount = 0; | |||
| maxPluginNumber = 0; | |||
| nextPluginId = 0; | |||
| 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: | |||
| maxPluginNumber = MAX_RACK_PLUGINS; | |||
| events.in = new EngineEvent[kMaxEngineEventInternalCount]; | |||
| events.out = new EngineEvent[kMaxEngineEventInternalCount]; | |||
| break; | |||
| case ENGINE_PROCESS_MODE_PATCHBAY: | |||
| maxPluginNumber = MAX_PATCHBAY_PLUGINS; | |||
| break; | |||
| case ENGINE_PROCESS_MODE_BRIDGE: | |||
| maxPluginNumber = 1; | |||
| events.in = new EngineEvent[kMaxEngineEventInternalCount]; | |||
| events.out = new EngineEvent[kMaxEngineEventInternalCount]; | |||
| break; | |||
| } | |||
| CARLA_SAFE_ASSERT_RETURN_INTERNAL_ERR(maxPluginNumber != 0, "Invalid engine process mode"); | |||
| nextPluginId = maxPluginNumber; | |||
| name = clientName; | |||
| name.toBasic(); | |||
| timeInfo.clear(); | |||
| #ifndef BUILD_BRIDGE | |||
| plugins = new EnginePluginData[maxPluginNumber]; | |||
| carla_zeroStruct(plugins, maxPluginNumber); | |||
| #endif | |||
| osc.init(clientName); | |||
| #ifndef BUILD_BRIDGE | |||
| oscData = osc.getControlData(); | |||
| if (options.processMode == ENGINE_PROCESS_MODE_CONTINUOUS_RACK || options.processMode == ENGINE_PROCESS_MODE_PATCHBAY) | |||
| { | |||
| graph.isRack = (options.processMode == ENGINE_PROCESS_MODE_CONTINUOUS_RACK); | |||
| graph.create(); | |||
| } | |||
| #endif | |||
| nextAction.ready(); | |||
| thread.startThread(); | |||
| return true; | |||
| } | |||
| void CarlaEngine::ProtectedData::close() | |||
| { | |||
| CARLA_SAFE_ASSERT(name.isNotEmpty()); | |||
| CARLA_SAFE_ASSERT(plugins != nullptr); | |||
| CARLA_SAFE_ASSERT(nextPluginId == maxPluginNumber); | |||
| CARLA_SAFE_ASSERT(nextAction.opcode == kEnginePostActionNull); | |||
| aboutToClose = true; | |||
| thread.stopThread(500); | |||
| nextAction.ready(); | |||
| #ifndef BUILD_BRIDGE | |||
| if (options.processMode == ENGINE_PROCESS_MODE_CONTINUOUS_RACK || options.processMode == ENGINE_PROCESS_MODE_PATCHBAY) | |||
| graph.clear(); | |||
| #endif | |||
| osc.close(); | |||
| oscData = nullptr; | |||
| aboutToClose = false; | |||
| curPluginCount = 0; | |||
| maxPluginNumber = 0; | |||
| nextPluginId = 0; | |||
| #ifndef BUILD_BRIDGE | |||
| if (plugins != nullptr) | |||
| { | |||
| delete[] plugins; | |||
| plugins = nullptr; | |||
| } | |||
| #endif | |||
| events.clear(); | |||
| #ifndef BUILD_BRIDGE | |||
| audio.clear(); | |||
| #endif | |||
| name.clear(); | |||
| } | |||
| // ----------------------------------------------------------------------- | |||
| void CarlaEngine::ProtectedData::doPluginRemove() noexcept | |||
| { | |||
| CARLA_SAFE_ASSERT_RETURN(curPluginCount > 0,); | |||
| @@ -418,13 +418,6 @@ struct EnginePluginData { | |||
| CarlaPlugin* plugin; | |||
| float insPeak[2]; | |||
| float outsPeak[2]; | |||
| void clear() noexcept | |||
| { | |||
| plugin = nullptr; | |||
| insPeak[0] = insPeak[1] = 0.0f; | |||
| outsPeak[0] = outsPeak[1] = 0.0f; | |||
| } | |||
| }; | |||
| // ----------------------------------------------------------------------- | |||
| @@ -456,7 +449,11 @@ struct CarlaEngine::ProtectedData { | |||
| EngineOptions options; | |||
| EngineTimeInfo timeInfo; | |||
| #ifdef BUILD_BRIDGE | |||
| EnginePluginData plugins[1]; | |||
| #else | |||
| EnginePluginData* plugins; | |||
| #endif | |||
| #ifndef BUILD_BRIDGE | |||
| EngineInternalAudio audio; | |||
| @@ -475,6 +472,11 @@ struct CarlaEngine::ProtectedData { | |||
| // ------------------------------------------------------------------- | |||
| bool init(const char* const clientName); | |||
| void close(); | |||
| // ------------------------------------------------------------------- | |||
| void doPluginRemove() noexcept; | |||
| void doPluginsSwitch() noexcept; | |||
| void doNextPluginAction(const bool unlock) noexcept; | |||