@@ -1833,6 +1833,7 @@ typedef struct { | |||||
/* Forward declarations of commonly used Carla classes */ | /* Forward declarations of commonly used Carla classes */ | ||||
class CarlaEngine; | class CarlaEngine; | ||||
class CarlaEngineClient; | class CarlaEngineClient; | ||||
class CarlaEngineCVSourcePorts; | |||||
class CarlaPlugin; | class CarlaPlugin; | ||||
/* End namespace */ | /* End namespace */ | ||||
CARLA_BACKEND_END_NAMESPACE | CARLA_BACKEND_END_NAMESPACE | ||||
@@ -361,7 +361,7 @@ class CARLA_API CarlaEnginePort | |||||
{ | { | ||||
protected: | protected: | ||||
/*! | /*! | ||||
* The constructor. | |||||
* The constructor, protected. | |||||
* All constructor parameters are constant and will never change in the lifetime of the port. | * All constructor parameters are constant and will never change in the lifetime of the port. | ||||
*/ | */ | ||||
CarlaEnginePort(const CarlaEngineClient& client, bool isInputPort, uint32_t indexOffset) noexcept; | CarlaEnginePort(const CarlaEngineClient& client, bool isInputPort, uint32_t indexOffset) noexcept; | ||||
@@ -626,17 +626,17 @@ protected: | |||||
*/ | */ | ||||
class CARLA_API CarlaEngineCVSourcePorts | class CARLA_API CarlaEngineCVSourcePorts | ||||
{ | { | ||||
public: | |||||
protected: | |||||
/*! | /*! | ||||
* The constructor. | |||||
* All constructor parameters are constant and will never change in the lifetime of the port. | |||||
* The constructor, protected. | |||||
*/ | */ | ||||
CarlaEngineCVSourcePorts(/*const CarlaEngineClient& client*/); | |||||
CarlaEngineCVSourcePorts(); | |||||
public: | |||||
/*! | /*! | ||||
* The destructor. | * The destructor. | ||||
*/ | */ | ||||
~CarlaEngineCVSourcePorts(); | |||||
virtual ~CarlaEngineCVSourcePorts(); | |||||
/*! | /*! | ||||
* Add a CV port as a source of events. | * Add a CV port as a source of events. | ||||
@@ -664,7 +664,6 @@ public: | |||||
protected: | protected: | ||||
struct ProtectedData; | struct ProtectedData; | ||||
ProtectedData* const pData; | ProtectedData* const pData; | ||||
friend class CarlaPluginInstance; | |||||
CARLA_DECLARE_NON_COPY_CLASS(CarlaEngineCVSourcePorts) | CARLA_DECLARE_NON_COPY_CLASS(CarlaEngineCVSourcePorts) | ||||
#endif | #endif | ||||
@@ -680,13 +679,6 @@ protected: | |||||
class CARLA_API CarlaEngineClient | class CARLA_API CarlaEngineClient | ||||
{ | { | ||||
public: | public: | ||||
/*! | |||||
* The constructor, protected. | |||||
* All constructor parameters are constant and will never change in the lifetime of the client. | |||||
* Client starts in deactivated state. | |||||
*/ | |||||
CarlaEngineClient(const CarlaEngine& engine); | |||||
/*! | /*! | ||||
* The destructor. | * The destructor. | ||||
*/ | */ | ||||
@@ -778,6 +770,12 @@ protected: | |||||
struct ProtectedData; | struct ProtectedData; | ||||
ProtectedData* const pData; | ProtectedData* const pData; | ||||
/*! | |||||
* The constructor, protected. | |||||
*/ | |||||
CarlaEngineClient(ProtectedData* pData); | |||||
/** internal */ | |||||
void _addAudioPortName(bool, const char*); | void _addAudioPortName(bool, const char*); | ||||
void _addCVPortName(bool, const char*); | void _addCVPortName(bool, const char*); | ||||
void _addEventPortName(bool, const char*); | void _addEventPortName(bool, const char*); | ||||
@@ -2011,7 +2011,7 @@ void carla_set_parameter_mapped_control_index(uint pluginId, uint32_t parameterI | |||||
CarlaPlugin* const plugin(gStandalone.engine->getPlugin(pluginId)); | CarlaPlugin* const plugin(gStandalone.engine->getPlugin(pluginId)); | ||||
CARLA_SAFE_ASSERT_RETURN(plugin != nullptr,); | CARLA_SAFE_ASSERT_RETURN(plugin != nullptr,); | ||||
carla_debug("carla_set_parameter_mapped_control_index(%i, %i, %i)", pluginId, parameterId, cc); | |||||
carla_debug("carla_set_parameter_mapped_control_index(%i, %i, %i)", pluginId, parameterId, index); | |||||
CARLA_SAFE_ASSERT_RETURN(parameterId < plugin->getParameterCount(),); | CARLA_SAFE_ASSERT_RETURN(parameterId < plugin->getParameterCount(),); | ||||
return plugin->setParameterMappedControlIndex(parameterId, index, true, false); | return plugin->setParameterMappedControlIndex(parameterId, index, true, false); | ||||
@@ -376,9 +376,9 @@ void CarlaEngine::idle() noexcept | |||||
#endif | #endif | ||||
} | } | ||||
CarlaEngineClient* CarlaEngine::addClient(CarlaPlugin* const) | |||||
CarlaEngineClient* CarlaEngine::addClient(CarlaPlugin* const plugin) | |||||
{ | { | ||||
return new CarlaEngineClient(*this); | |||||
return new CarlaEngineClient2(*this, pData->graph, plugin); | |||||
} | } | ||||
float CarlaEngine::getDSPLoad() const noexcept | float CarlaEngine::getDSPLoad() const noexcept | ||||
@@ -703,7 +703,7 @@ bool CarlaEngine::addPlugin(const BinaryType btype, | |||||
#ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH | #ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH | ||||
if (pData->options.processMode == ENGINE_PROCESS_MODE_PATCHBAY) | if (pData->options.processMode == ENGINE_PROCESS_MODE_PATCHBAY) | ||||
pData->graph.addPlugin(plugin); | |||||
pData->graph.addPlugin(plugin, 1); | |||||
#endif | #endif | ||||
} | } | ||||
@@ -2571,7 +2571,7 @@ bool CarlaEngine::loadProjectInternal(water::XmlDocument& xmlDoc) | |||||
callback(true, true, ENGINE_CALLBACK_PLUGIN_ADDED, pluginId, 0, 0, 0, 0.0f, plugin->getName()); | callback(true, true, ENGINE_CALLBACK_PLUGIN_ADDED, pluginId, 0, 0, 0, 0.0f, plugin->getName()); | ||||
if (pData->options.processMode == ENGINE_PROCESS_MODE_PATCHBAY) | if (pData->options.processMode == ENGINE_PROCESS_MODE_PATCHBAY) | ||||
pData->graph.addPlugin(plugin); | |||||
pData->graph.addPlugin(plugin, 1); | |||||
} | } | ||||
else | else | ||||
{ | { | ||||
@@ -2714,7 +2714,7 @@ bool CarlaEngine::loadProjectInternal(water::XmlDocument& xmlDoc) | |||||
#ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH | #ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH | ||||
if (pData->options.processMode == ENGINE_PROCESS_MODE_PATCHBAY) | if (pData->options.processMode == ENGINE_PROCESS_MODE_PATCHBAY) | ||||
pData->graph.addPlugin(plugin); | |||||
pData->graph.addPlugin(plugin, 1); | |||||
#endif | #endif | ||||
} | } | ||||
else | else | ||||
@@ -16,12 +16,34 @@ | |||||
*/ | */ | ||||
#include "CarlaEngineUtils.hpp" | #include "CarlaEngineUtils.hpp" | ||||
#include "CarlaEngineInternal.hpp" | |||||
#include "CarlaString.hpp" | #include "CarlaString.hpp" | ||||
#include "CarlaStringList.hpp" | #include "CarlaStringList.hpp" | ||||
CARLA_BACKEND_START_NAMESPACE | CARLA_BACKEND_START_NAMESPACE | ||||
#ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH | |||||
// ----------------------------------------------------------------------- | |||||
// Carla Engine Meta CV port | |||||
class CarlaEngineCVSourcePorts2 : public CarlaEngineCVSourcePorts | |||||
{ | |||||
public: | |||||
CarlaEngineCVSourcePorts2() | |||||
: CarlaEngineCVSourcePorts() | |||||
{} | |||||
~CarlaEngineCVSourcePorts2() override {} | |||||
void setGraphAndPlugin(PatchbayGraph* const graph, CarlaPlugin* const plugin) noexcept | |||||
{ | |||||
pData->graph = graph; | |||||
pData->plugin = plugin; | |||||
} | |||||
}; | |||||
#endif | |||||
// ----------------------------------------------------------------------- | // ----------------------------------------------------------------------- | ||||
// Carla Engine client (Abstract) | // Carla Engine client (Abstract) | ||||
@@ -31,6 +53,12 @@ struct CarlaEngineClient::ProtectedData { | |||||
bool active; | bool active; | ||||
uint32_t latency; | uint32_t latency; | ||||
#ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH | |||||
CarlaEngineCVSourcePorts2 cvSourcePorts; | |||||
EngineInternalGraph& egraph; | |||||
CarlaPlugin* const plugin; | |||||
#endif | |||||
CarlaStringList audioInList; | CarlaStringList audioInList; | ||||
CarlaStringList audioOutList; | CarlaStringList audioOutList; | ||||
CarlaStringList cvInList; | CarlaStringList cvInList; | ||||
@@ -38,10 +66,15 @@ struct CarlaEngineClient::ProtectedData { | |||||
CarlaStringList eventInList; | CarlaStringList eventInList; | ||||
CarlaStringList eventOutList; | CarlaStringList eventOutList; | ||||
ProtectedData(const CarlaEngine& eng) noexcept | |||||
ProtectedData(const CarlaEngine& eng, EngineInternalGraph& eg, CarlaPlugin* const p) noexcept | |||||
: engine(eng), | : engine(eng), | ||||
active(false), | active(false), | ||||
latency(0), | latency(0), | ||||
#ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH | |||||
cvSourcePorts(), | |||||
egraph(eg), | |||||
plugin(p), | |||||
#endif | |||||
audioInList(), | audioInList(), | ||||
audioOutList(), | audioOutList(), | ||||
cvInList(), | cvInList(), | ||||
@@ -55,8 +88,27 @@ struct CarlaEngineClient::ProtectedData { | |||||
#endif | #endif | ||||
}; | }; | ||||
CarlaEngineClient::CarlaEngineClient(const CarlaEngine& engine) | |||||
: pData(new ProtectedData(engine)) | |||||
CarlaEngineClient2::CarlaEngineClient2(const CarlaEngine& engine, EngineInternalGraph& egraph, CarlaPlugin* const plugin) | |||||
: CarlaEngineClient(new ProtectedData(engine, egraph, plugin)) | |||||
{ | |||||
} | |||||
CarlaEngineClient2::~CarlaEngineClient2() | |||||
{ | |||||
} | |||||
PatchbayGraph* CarlaEngineClient2::getPatchbayGraph() const noexcept | |||||
{ | |||||
return pData->egraph.getPatchbayGraph(); | |||||
} | |||||
CarlaPlugin* CarlaEngineClient2::getPlugin() const noexcept | |||||
{ | |||||
return pData->plugin; | |||||
} | |||||
CarlaEngineClient::CarlaEngineClient(ProtectedData* const p) | |||||
: pData(p) | |||||
{ | { | ||||
carla_debug("CarlaEngineClient::CarlaEngineClient()"); | carla_debug("CarlaEngineClient::CarlaEngineClient()"); | ||||
} | } | ||||
@@ -132,11 +184,8 @@ CarlaEnginePort* CarlaEngineClient::addPort(const EnginePortType portType, const | |||||
#ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH | #ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH | ||||
CarlaEngineCVSourcePorts* CarlaEngineClient::createCVSourcePorts() | CarlaEngineCVSourcePorts* CarlaEngineClient::createCVSourcePorts() | ||||
{ | { | ||||
// AudioProcessorGraph::Node* const oldNode(graph.getNodeForId(oldPlugin->getPatchbayNodeId())); | |||||
// CARLA_SAFE_ASSERT_RETURN(oldNode != nullptr,); | |||||
// pData->engine.pData->graph; | |||||
return new CarlaEngineCVSourcePorts(); | |||||
pData->cvSourcePorts.setGraphAndPlugin(pData->egraph.getPatchbayGraph(), pData->plugin); | |||||
return &pData->cvSourcePorts; | |||||
} | } | ||||
#endif | #endif | ||||
@@ -306,6 +355,11 @@ void CarlaEngineClient::_clearPorts() | |||||
pData->eventOutList.clear(); | pData->eventOutList.clear(); | ||||
} | } | ||||
// void* CarlaEngineClient::_getNode() const noexcept | |||||
// { | |||||
// return pData->node; | |||||
// } | |||||
// ----------------------------------------------------------------------- | // ----------------------------------------------------------------------- | ||||
CARLA_BACKEND_END_NAMESPACE | CARLA_BACKEND_END_NAMESPACE |
@@ -1388,7 +1388,7 @@ public: | |||||
: kEngine(engine), | : kEngine(engine), | ||||
fPlugin(plugin) | fPlugin(plugin) | ||||
{ | { | ||||
CarlaEngineClient* const client = fPlugin->getEngineClient(); | |||||
CarlaEngineClient* const client = plugin->getEngineClient(); | |||||
setPlayConfigDetails(client->getPortCount(kEnginePortTypeAudio, true), | setPlayConfigDetails(client->getPortCount(kEnginePortTypeAudio, true), | ||||
client->getPortCount(kEnginePortTypeAudio, false), | client->getPortCount(kEnginePortTypeAudio, false), | ||||
@@ -1403,6 +1403,24 @@ public: | |||||
{ | { | ||||
} | } | ||||
void reconfigure() override | |||||
{ | |||||
CARLA_SAFE_ASSERT_RETURN(fPlugin != nullptr,); | |||||
CarlaEngineClient* const client = fPlugin->getEngineClient(); | |||||
CARLA_SAFE_ASSERT_RETURN(client != nullptr,); | |||||
carla_stdout("reconfigure called"); | |||||
setPlayConfigDetails(client->getPortCount(kEnginePortTypeAudio, true), | |||||
client->getPortCount(kEnginePortTypeAudio, false), | |||||
client->getPortCount(kEnginePortTypeCV, true), | |||||
client->getPortCount(kEnginePortTypeCV, false), | |||||
client->getPortCount(kEnginePortTypeEvent, true), | |||||
client->getPortCount(kEnginePortTypeEvent, false), | |||||
getSampleRate(), getBlockSize()); | |||||
} | |||||
void invalidatePlugin() noexcept | void invalidatePlugin() noexcept | ||||
{ | { | ||||
fPlugin = nullptr; | fPlugin = nullptr; | ||||
@@ -1778,14 +1796,14 @@ void PatchbayGraph::setOffline(const bool offline) | |||||
graph.setNonRealtime(offline); | graph.setNonRealtime(offline); | ||||
} | } | ||||
void PatchbayGraph::addPlugin(CarlaPlugin* const plugin) | |||||
AudioProcessorGraph::Node* PatchbayGraph::addPlugin(CarlaPlugin* const plugin, bool) | |||||
{ | { | ||||
CARLA_SAFE_ASSERT_RETURN(plugin != nullptr,); | |||||
CARLA_SAFE_ASSERT_RETURN(plugin != nullptr, nullptr); | |||||
carla_debug("PatchbayGraph::addPlugin(%p)", plugin); | carla_debug("PatchbayGraph::addPlugin(%p)", plugin); | ||||
CarlaPluginInstance* const instance(new CarlaPluginInstance(kEngine, plugin)); | CarlaPluginInstance* const instance(new CarlaPluginInstance(kEngine, plugin)); | ||||
AudioProcessorGraph::Node* const node(graph.addNode(instance)); | AudioProcessorGraph::Node* const node(graph.addNode(instance)); | ||||
CARLA_SAFE_ASSERT_RETURN(node != nullptr,); | |||||
CARLA_SAFE_ASSERT_RETURN(node != nullptr, nullptr); | |||||
const bool sendHost = !usingExternalHost; | const bool sendHost = !usingExternalHost; | ||||
const bool sendOSC = !usingExternalOSC; | const bool sendOSC = !usingExternalOSC; | ||||
@@ -1796,6 +1814,8 @@ void PatchbayGraph::addPlugin(CarlaPlugin* const plugin) | |||||
node->properties.set("pluginId", static_cast<int>(plugin->getId())); | node->properties.set("pluginId", static_cast<int>(plugin->getId())); | ||||
addNodeToPatchbay(sendHost, sendOSC, kEngine, node->nodeId, static_cast<int>(plugin->getId()), instance); | addNodeToPatchbay(sendHost, sendOSC, kEngine, node->nodeId, static_cast<int>(plugin->getId()), instance); | ||||
return node; | |||||
} | } | ||||
void PatchbayGraph::replacePlugin(CarlaPlugin* const oldPlugin, CarlaPlugin* const newPlugin) | void PatchbayGraph::replacePlugin(CarlaPlugin* const oldPlugin, CarlaPlugin* const newPlugin) | ||||
@@ -1848,6 +1868,60 @@ void PatchbayGraph::renamePlugin(CarlaPlugin* const plugin, const char* const ne | |||||
newName); | newName); | ||||
} | } | ||||
void PatchbayGraph::reconfigureForCV(CarlaPlugin* const plugin, const uint portIndex, bool added) | |||||
{ | |||||
CARLA_SAFE_ASSERT_RETURN(plugin != nullptr,); | |||||
carla_debug("PatchbayGraph::reconfigureForCV(%p, %u, %s)", plugin, portIndex, bool2str(added)); | |||||
AudioProcessorGraph::Node* const node = graph.getNodeForId(plugin->getPatchbayNodeId()); | |||||
CARLA_SAFE_ASSERT_RETURN(node != nullptr,); | |||||
CarlaPluginInstance* const proc = dynamic_cast<CarlaPluginInstance*>(node->getProcessor()); | |||||
CARLA_SAFE_ASSERT_RETURN(proc != nullptr,); | |||||
const bool sendHost = !usingExternalHost; | |||||
const bool sendOSC = !usingExternalOSC; | |||||
const uint oldCvIn = proc->getTotalNumInputChannels(AudioProcessor::ChannelTypeCV); | |||||
const uint oldCvOut = proc->getTotalNumOutputChannels(AudioProcessor::ChannelTypeCV); | |||||
{ | |||||
const CarlaRecursiveMutexLocker crml(graph.getCallbackLock()); | |||||
proc->reconfigure(); | |||||
graph.buildRenderingSequence(); | |||||
} | |||||
const uint newCvIn = proc->getTotalNumInputChannels(AudioProcessor::ChannelTypeCV); | |||||
const uint newCvOut = proc->getTotalNumOutputChannels(AudioProcessor::ChannelTypeCV); | |||||
if (added) | |||||
{ | |||||
CARLA_SAFE_ASSERT_UINT2_RETURN(newCvIn >= oldCvIn, newCvIn, oldCvIn,); | |||||
CARLA_SAFE_ASSERT_UINT2_RETURN(newCvOut >= oldCvOut, newCvOut, oldCvOut,); | |||||
kEngine->callback(sendHost, sendOSC, | |||||
ENGINE_CALLBACK_PATCHBAY_PORT_ADDED, | |||||
node->nodeId, | |||||
static_cast<int>(kCVInputPortOffset + plugin->getCVInCount() + portIndex), | |||||
PATCHBAY_PORT_TYPE_CV|PATCHBAY_PORT_IS_INPUT, | |||||
0, 0.0f, | |||||
proc->getInputChannelName(AudioProcessor::ChannelTypeCV, portIndex).toRawUTF8()); | |||||
} | |||||
else | |||||
{ | |||||
CARLA_SAFE_ASSERT_UINT2_RETURN(newCvIn <= oldCvIn, newCvIn, oldCvIn,); | |||||
CARLA_SAFE_ASSERT_UINT2_RETURN(newCvOut <= oldCvOut, newCvOut, oldCvOut,); | |||||
kEngine->callback(sendHost, sendOSC, | |||||
ENGINE_CALLBACK_PATCHBAY_PORT_REMOVED, | |||||
node->nodeId, | |||||
static_cast<int>(kCVInputPortOffset + plugin->getCVInCount() + portIndex), | |||||
0, 0, 0.0f, nullptr); | |||||
} | |||||
} | |||||
void PatchbayGraph::removePlugin(CarlaPlugin* const plugin) | void PatchbayGraph::removePlugin(CarlaPlugin* const plugin) | ||||
{ | { | ||||
CARLA_SAFE_ASSERT_RETURN(plugin != nullptr,); | CARLA_SAFE_ASSERT_RETURN(plugin != nullptr,); | ||||
@@ -2443,10 +2517,10 @@ void EngineInternalGraph::processRack(CarlaEngine::ProtectedData* const data, co | |||||
// ----------------------------------------------------------------------- | // ----------------------------------------------------------------------- | ||||
// used for internal patchbay mode | // used for internal patchbay mode | ||||
void EngineInternalGraph::addPlugin(CarlaPlugin* const plugin) | |||||
water::AudioProcessorGraph::Node* EngineInternalGraph::addPlugin(CarlaPlugin* const plugin, bool x) | |||||
{ | { | ||||
CARLA_SAFE_ASSERT_RETURN(fPatchbay != nullptr,); | |||||
fPatchbay->addPlugin(plugin); | |||||
CARLA_SAFE_ASSERT_RETURN(fPatchbay != nullptr, nullptr); | |||||
return fPatchbay->addPlugin(plugin, x); | |||||
} | } | ||||
void EngineInternalGraph::replacePlugin(CarlaPlugin* const oldPlugin, CarlaPlugin* const newPlugin) | void EngineInternalGraph::replacePlugin(CarlaPlugin* const oldPlugin, CarlaPlugin* const newPlugin) | ||||
@@ -179,9 +179,11 @@ public: | |||||
void setSampleRate(double sampleRate); | void setSampleRate(double sampleRate); | ||||
void setOffline(bool offline); | void setOffline(bool offline); | ||||
void addPlugin(CarlaPlugin* plugin); | |||||
AudioProcessorGraph::Node* addPlugin(CarlaPlugin* plugin, bool); | |||||
void replacePlugin(CarlaPlugin* oldPlugin, CarlaPlugin* newPlugin); | void replacePlugin(CarlaPlugin* oldPlugin, CarlaPlugin* newPlugin); | ||||
void renamePlugin(CarlaPlugin* plugin, const char* newName); | void renamePlugin(CarlaPlugin* plugin, const char* newName); | ||||
void reconfigureForCV(CarlaPlugin* const plugin, const uint portIndex, bool added); | |||||
void reconfigurePlugin(CarlaPlugin* plugin, bool portsAdded); | |||||
void removePlugin(CarlaPlugin* plugin); | void removePlugin(CarlaPlugin* plugin); | ||||
void removeAllPlugins(); | void removeAllPlugins(); | ||||
@@ -28,6 +28,7 @@ | |||||
#endif | #endif | ||||
#ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH | #ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH | ||||
# include "water/processors/AudioProcessorGraph.h" | |||||
# include "water/containers/Array.h" | # include "water/containers/Array.h" | ||||
# include "water/memory/Atomic.h" | # include "water/memory/Atomic.h" | ||||
#endif | #endif | ||||
@@ -94,7 +95,7 @@ public: | |||||
void processRack(CarlaEngine::ProtectedData* data, const float* inBuf[2], float* outBuf[2], uint32_t frames); | void processRack(CarlaEngine::ProtectedData* data, const float* inBuf[2], float* outBuf[2], uint32_t frames); | ||||
// used for internal patchbay mode | // used for internal patchbay mode | ||||
void addPlugin(CarlaPlugin* plugin); | |||||
water::AudioProcessorGraph::Node* addPlugin(CarlaPlugin* plugin, bool); | |||||
void replacePlugin(CarlaPlugin* oldPlugin, CarlaPlugin* newPlugin); | void replacePlugin(CarlaPlugin* oldPlugin, CarlaPlugin* newPlugin); | ||||
void renamePlugin(CarlaPlugin* plugin, const char* newName); | void renamePlugin(CarlaPlugin* plugin, const char* newName); | ||||
void removePlugin(CarlaPlugin* plugin); | void removePlugin(CarlaPlugin* plugin); | ||||
@@ -225,6 +226,9 @@ struct CarlaEngineCVSourcePorts::ProtectedData { | |||||
EngineEvent* buffer; | EngineEvent* buffer; | ||||
water::Array<CarlaEngineEventCV> cvs; | water::Array<CarlaEngineEventCV> cvs; | ||||
PatchbayGraph* graph; | |||||
CarlaPlugin* plugin; | |||||
ProtectedData(); | ProtectedData(); | ||||
~ProtectedData(); | ~ProtectedData(); | ||||
@@ -232,6 +236,19 @@ struct CarlaEngineCVSourcePorts::ProtectedData { | |||||
}; | }; | ||||
#endif | #endif | ||||
// ----------------------------------------------------------------------- | |||||
class CarlaEngineClient2 : public CarlaEngineClient | |||||
{ | |||||
public: | |||||
CarlaEngineClient2(const CarlaEngine& engine, EngineInternalGraph& egraph, CarlaPlugin* const plugin); | |||||
virtual ~CarlaEngineClient2() override; | |||||
protected: | |||||
PatchbayGraph* getPatchbayGraph() const noexcept; | |||||
CarlaPlugin* getPlugin() const noexcept; | |||||
}; | |||||
// ----------------------------------------------------------------------- | // ----------------------------------------------------------------------- | ||||
// CarlaEngineProtectedData | // CarlaEngineProtectedData | ||||
@@ -510,18 +510,24 @@ public: | |||||
const int ioffset = static_cast<int>(portIndexOffset); | const int ioffset = static_cast<int>(portIndexOffset); | ||||
return pData->cvs[ioffset].cvPort; | return pData->cvs[ioffset].cvPort; | ||||
} | } | ||||
void setGraphAndPlugin(PatchbayGraph* const graph, CarlaPlugin* const plugin) noexcept | |||||
{ | |||||
pData->graph = graph; | |||||
pData->plugin = plugin; | |||||
} | |||||
}; | }; | ||||
#endif | #endif | ||||
// ----------------------------------------------------------------------- | // ----------------------------------------------------------------------- | ||||
// Jack Engine client | // Jack Engine client | ||||
class CarlaEngineJackClient : public CarlaEngineClient, | |||||
class CarlaEngineJackClient : public CarlaEngineClient2, | |||||
private JackPortDeletionCallback | private JackPortDeletionCallback | ||||
{ | { | ||||
public: | public: | ||||
CarlaEngineJackClient(const CarlaEngine& engine, jack_client_t* const jackClient) | |||||
: CarlaEngineClient(engine), | |||||
CarlaEngineJackClient(const CarlaEngine& engine, EngineInternalGraph& egraph, CarlaPlugin* const plugin, jack_client_t* const jackClient) | |||||
: CarlaEngineClient2(engine, egraph, plugin), | |||||
fJackClient(jackClient), | fJackClient(jackClient), | ||||
fUseClient(engine.getProccessMode() == ENGINE_PROCESS_MODE_SINGLE_CLIENT || engine.getProccessMode() == ENGINE_PROCESS_MODE_MULTIPLE_CLIENTS), | fUseClient(engine.getProccessMode() == ENGINE_PROCESS_MODE_SINGLE_CLIENT || engine.getProccessMode() == ENGINE_PROCESS_MODE_MULTIPLE_CLIENTS), | ||||
fAudioPorts(), | fAudioPorts(), | ||||
@@ -696,6 +702,7 @@ public: | |||||
#ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH | #ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH | ||||
CarlaEngineCVSourcePorts* createCVSourcePorts() override | CarlaEngineCVSourcePorts* createCVSourcePorts() override | ||||
{ | { | ||||
fCVSourcePorts.setGraphAndPlugin(getPatchbayGraph(), getPlugin()); | |||||
return &fCVSourcePorts; | return &fCVSourcePorts; | ||||
} | } | ||||
@@ -1437,7 +1444,7 @@ public: | |||||
#endif | #endif | ||||
} | } | ||||
return new CarlaEngineJackClient(*this, client); | |||||
return new CarlaEngineJackClient(*this, pData->graph, plugin, client); | |||||
} | } | ||||
#ifndef BUILD_BRIDGE | #ifndef BUILD_BRIDGE | ||||
@@ -16,6 +16,7 @@ | |||||
*/ | */ | ||||
#include "CarlaEngineInternal.hpp" | #include "CarlaEngineInternal.hpp" | ||||
#include "CarlaEngineGraph.hpp" | |||||
#include "CarlaEngineUtils.hpp" | #include "CarlaEngineUtils.hpp" | ||||
#include "CarlaMathUtils.hpp" | #include "CarlaMathUtils.hpp" | ||||
#include "CarlaMIDI.h" | #include "CarlaMIDI.h" | ||||
@@ -329,7 +330,9 @@ bool CarlaEngineEventPort::writeMidiEvent(const uint32_t time, const uint8_t cha | |||||
CarlaEngineCVSourcePorts::ProtectedData::ProtectedData() | CarlaEngineCVSourcePorts::ProtectedData::ProtectedData() | ||||
: rmutex(), | : rmutex(), | ||||
buffer(nullptr), | buffer(nullptr), | ||||
cvs() | |||||
cvs(), | |||||
graph(nullptr), | |||||
plugin(nullptr) | |||||
{ | { | ||||
} | } | ||||
@@ -337,8 +340,12 @@ CarlaEngineCVSourcePorts::ProtectedData::~ProtectedData() | |||||
{ | { | ||||
const CarlaRecursiveMutexLocker crml(rmutex); | const CarlaRecursiveMutexLocker crml(rmutex); | ||||
carla_stdout("CarlaEngineCVSourcePorts::ProtectedData::~ProtectedData size %i", cvs.size()); | |||||
/* | |||||
for (int i = cvs.size(); --i >= 0;) | for (int i = cvs.size(); --i >= 0;) | ||||
delete cvs[i].cvPort; | delete cvs[i].cvPort; | ||||
*/ | |||||
cvs.clear(); | cvs.clear(); | ||||
@@ -349,7 +356,7 @@ CarlaEngineCVSourcePorts::ProtectedData::~ProtectedData() | |||||
} | } | ||||
} | } | ||||
CarlaEngineCVSourcePorts::CarlaEngineCVSourcePorts(/*const CarlaEngineClient& client*/) | |||||
CarlaEngineCVSourcePorts::CarlaEngineCVSourcePorts() | |||||
: pData(new ProtectedData()) | : pData(new ProtectedData()) | ||||
{ | { | ||||
carla_debug("CarlaEngineCVSourcePorts::CarlaEngineCVSourcePorts()"); | carla_debug("CarlaEngineCVSourcePorts::CarlaEngineCVSourcePorts()"); | ||||
@@ -358,6 +365,7 @@ CarlaEngineCVSourcePorts::CarlaEngineCVSourcePorts(/*const CarlaEngineClient& cl | |||||
CarlaEngineCVSourcePorts::~CarlaEngineCVSourcePorts() | CarlaEngineCVSourcePorts::~CarlaEngineCVSourcePorts() | ||||
{ | { | ||||
carla_debug("CarlaEngineCVSourcePorts::~CarlaEngineCVSourcePorts()"); | carla_debug("CarlaEngineCVSourcePorts::~CarlaEngineCVSourcePorts()"); | ||||
delete pData; | |||||
} | } | ||||
bool CarlaEngineCVSourcePorts::addCVSource(CarlaEngineCVPort* const port, const uint32_t portIndexOffset) | bool CarlaEngineCVSourcePorts::addCVSource(CarlaEngineCVPort* const port, const uint32_t portIndexOffset) | ||||
@@ -366,16 +374,21 @@ bool CarlaEngineCVSourcePorts::addCVSource(CarlaEngineCVPort* const port, const | |||||
CARLA_SAFE_ASSERT_RETURN(port->isInput(), false); | CARLA_SAFE_ASSERT_RETURN(port->isInput(), false); | ||||
carla_debug("CarlaEngineCVSourcePorts::addCVSource(%p)", port); | carla_debug("CarlaEngineCVSourcePorts::addCVSource(%p)", port); | ||||
const CarlaRecursiveMutexLocker crml(pData->rmutex); | |||||
{ | |||||
const CarlaRecursiveMutexLocker crml(pData->rmutex); | |||||
const CarlaEngineEventCV ecv = { port, portIndexOffset, 0.0f }; | |||||
if (! pData->cvs.add(ecv)) | |||||
return false; | |||||
const CarlaEngineEventCV ecv = { port, portIndexOffset, 0.0f }; | |||||
if (! pData->cvs.add(ecv)) | |||||
return false; | |||||
/* | |||||
if (pData->buffer == nullptr) | |||||
pData->buffer = new EngineEvent[kMaxEngineEventInternalCount]; | |||||
*/ | |||||
if (pData->graph != nullptr && pData->plugin != nullptr) | |||||
pData->graph->reconfigureForCV(pData->plugin, pData->cvs.size()-1, true); | |||||
/* | |||||
if (pData->buffer == nullptr) | |||||
pData->buffer = new EngineEvent[kMaxEngineEventInternalCount]; | |||||
*/ | |||||
} | |||||
return true; | return true; | ||||
} | } | ||||
@@ -384,16 +397,24 @@ bool CarlaEngineCVSourcePorts::removeCVSource(const uint32_t portIndexOffset) | |||||
{ | { | ||||
carla_debug("CarlaEngineCVSourcePorts::removeCVSource(%u)", portIndexOffset); | carla_debug("CarlaEngineCVSourcePorts::removeCVSource(%u)", portIndexOffset); | ||||
const CarlaRecursiveMutexLocker crml(pData->rmutex); | |||||
for (int i = pData->cvs.size(); --i >= 0;) | |||||
{ | { | ||||
const CarlaEngineEventCV& ecv(pData->cvs[i]); | |||||
const CarlaRecursiveMutexLocker crml(pData->rmutex); | |||||
if (ecv.indexOffset == portIndexOffset) | |||||
for (int i = pData->cvs.size(); --i >= 0;) | |||||
{ | { | ||||
pData->cvs.remove(i); | |||||
break; | |||||
const CarlaEngineEventCV& ecv(pData->cvs[i]); | |||||
if (ecv.indexOffset == portIndexOffset) | |||||
{ | |||||
if (pData->graph != nullptr && pData->plugin != nullptr) | |||||
pData->graph->reconfigureForCV(pData->plugin, i, false); | |||||
carla_stdout("found cv source to remove %u", portIndexOffset); | |||||
delete ecv.cvPort; | |||||
pData->cvs.remove(i); | |||||
return true; | |||||
} | |||||
} | } | ||||
} | } | ||||
@@ -403,7 +424,8 @@ bool CarlaEngineCVSourcePorts::removeCVSource(const uint32_t portIndexOffset) | |||||
pData->buffer = nullptr; | pData->buffer = nullptr; | ||||
} | } | ||||
return true; | |||||
carla_stdout("did NOT found cv source to remove %u", portIndexOffset); | |||||
return false; | |||||
} | } | ||||
bool CarlaEngineCVSourcePorts::setCVSourceRange(const uint32_t portIndexOffset, const float minimum, const float maximum) | bool CarlaEngineCVSourcePorts::setCVSourceRange(const uint32_t portIndexOffset, const float minimum, const float maximum) | ||||
@@ -438,6 +460,19 @@ void CarlaEngineCVSourcePorts::initPortBuffers(const float* const* const buffers | |||||
if (! crmtl.wasLocked()) | if (! crmtl.wasLocked()) | ||||
return; | return; | ||||
const int numCVs = pData->cvs.size(); | |||||
static int oldNumCVs = 0; | |||||
if (oldNumCVs != numCVs) | |||||
{ | |||||
carla_stdout("initPortBuffers %i %i", numCVs, oldNumCVs); | |||||
oldNumCVs = numCVs; | |||||
} | |||||
if (numCVs == 0) | |||||
return; | |||||
EngineEvent* const buffer = eventPort->fBuffer; | EngineEvent* const buffer = eventPort->fBuffer; | ||||
CARLA_SAFE_ASSERT_RETURN(buffer != nullptr,); | CARLA_SAFE_ASSERT_RETURN(buffer != nullptr,); | ||||
/* | /* | ||||
@@ -459,7 +494,7 @@ void CarlaEngineCVSourcePorts::initPortBuffers(const float* const* const buffers | |||||
if (sampleAccurate || true) | if (sampleAccurate || true) | ||||
{ | { | ||||
for (int i = 0; i < pData->cvs.size() && eventCount < kMaxEngineEventInternalCount; ++i) | |||||
for (int i = 0; i < numCVs && eventCount < kMaxEngineEventInternalCount; ++i) | |||||
{ | { | ||||
CarlaEngineEventCV& ecv(pData->cvs.getReference(i)); | CarlaEngineEventCV& ecv(pData->cvs.getReference(i)); | ||||
CARLA_SAFE_ASSERT_CONTINUE(ecv.cvPort != nullptr); | CARLA_SAFE_ASSERT_CONTINUE(ecv.cvPort != nullptr); | ||||
@@ -173,11 +173,7 @@ void PluginEventData::clear() noexcept | |||||
} | } | ||||
#ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH | #ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH | ||||
if (cvSourcePorts != nullptr) | |||||
{ | |||||
delete cvSourcePorts; | |||||
cvSourcePorts = nullptr; | |||||
} | |||||
cvSourcePorts = nullptr; | |||||
#endif | #endif | ||||
} | } | ||||
@@ -1310,6 +1310,9 @@ public: | |||||
portName.truncate(portNameSize); | portName.truncate(portNameSize); | ||||
pData->event.portIn = (CarlaEngineEventPort*)pData->client->addPort(kEnginePortTypeEvent, portName, true, 0); | pData->event.portIn = (CarlaEngineEventPort*)pData->client->addPort(kEnginePortTypeEvent, portName, true, 0); | ||||
#ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH | |||||
pData->event.cvSourcePorts = pData->client->createCVSourcePorts(); | |||||
#endif | |||||
} | } | ||||
if (needsCtrlOut || mOuts == 1) | if (needsCtrlOut || mOuts == 1) | ||||
@@ -1469,10 +1472,15 @@ public: | |||||
// extra parameter hints | // extra parameter hints | ||||
if (paramInfo->hints & NATIVE_PARAMETER_IS_ENABLED) | if (paramInfo->hints & NATIVE_PARAMETER_IS_ENABLED) | ||||
{ | |||||
pData->param.data[j].hints |= PARAMETER_IS_ENABLED; | pData->param.data[j].hints |= PARAMETER_IS_ENABLED; | ||||
if (paramInfo->hints & NATIVE_PARAMETER_IS_AUTOMABLE) | |||||
pData->param.data[j].hints |= PARAMETER_IS_AUTOMABLE; | |||||
if (paramInfo->hints & NATIVE_PARAMETER_IS_AUTOMABLE) | |||||
{ | |||||
pData->param.data[j].hints |= PARAMETER_IS_AUTOMABLE; | |||||
pData->param.data[j].hints |= PARAMETER_CAN_BE_CV_CONTROLLED; | |||||
} | |||||
} | |||||
if (paramInfo->hints & NATIVE_PARAMETER_IS_LOGARITHMIC) | if (paramInfo->hints & NATIVE_PARAMETER_IS_LOGARITHMIC) | ||||
pData->param.data[j].hints |= PARAMETER_IS_LOGARITHMIC; | pData->param.data[j].hints |= PARAMETER_IS_LOGARITHMIC; | ||||
@@ -1821,7 +1829,7 @@ public: | |||||
#ifndef BUILD_BRIDGE | #ifndef BUILD_BRIDGE | ||||
bool allNotesOffSent = false; | bool allNotesOffSent = false; | ||||
#endif | #endif | ||||
bool sampleAccurate = (pData->options & PLUGIN_OPTION_FIXED_BUFFERS) == 0; | |||||
bool isSampleAccurate = (pData->options & PLUGIN_OPTION_FIXED_BUFFERS) == 0; | |||||
uint32_t startTime = 0; | uint32_t startTime = 0; | ||||
uint32_t timeOffset = 0; | uint32_t timeOffset = 0; | ||||
@@ -1832,6 +1840,11 @@ public: | |||||
else | else | ||||
nextBankId = 0; | nextBankId = 0; | ||||
#ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH | |||||
if (cvIn != nullptr && pData->event.cvSourcePorts != nullptr) | |||||
pData->event.cvSourcePorts->initPortBuffers(cvIn + pData->cvIn.count, frames, isSampleAccurate, pData->event.portIn); | |||||
#endif | |||||
for (;;) | for (;;) | ||||
{ | { | ||||
const EngineEvent& event(findNextEvent()); | const EngineEvent& event(findNextEvent()); | ||||
@@ -1849,7 +1862,7 @@ public: | |||||
eventTime = timeOffset; | eventTime = timeOffset; | ||||
} | } | ||||
if (sampleAccurate && eventTime > timeOffset) | |||||
if (isSampleAccurate && eventTime > timeOffset) | |||||
{ | { | ||||
if (processSingle(audioIn, audioOut, cvIn, cvOut, eventTime - timeOffset, timeOffset)) | if (processSingle(audioIn, audioOut, cvIn, cvOut, eventTime - timeOffset, timeOffset)) | ||||
{ | { | ||||
@@ -1976,7 +1989,7 @@ public: | |||||
NativeMidiEvent& nativeEvent(fMidiInEvents[fMidiEventInCount++]); | NativeMidiEvent& nativeEvent(fMidiInEvents[fMidiEventInCount++]); | ||||
carla_zeroStruct(nativeEvent); | carla_zeroStruct(nativeEvent); | ||||
nativeEvent.time = sampleAccurate ? startTime : eventTime; | |||||
nativeEvent.time = isSampleAccurate ? startTime : eventTime; | |||||
nativeEvent.data[0] = uint8_t(MIDI_STATUS_CONTROL_CHANGE | (event.channel & MIDI_CHANNEL_BIT)); | nativeEvent.data[0] = uint8_t(MIDI_STATUS_CONTROL_CHANGE | (event.channel & MIDI_CHANNEL_BIT)); | ||||
nativeEvent.data[1] = uint8_t(ctrlEvent.param); | nativeEvent.data[1] = uint8_t(ctrlEvent.param); | ||||
nativeEvent.data[2] = uint8_t(ctrlEvent.value*127.0f); | nativeEvent.data[2] = uint8_t(ctrlEvent.value*127.0f); | ||||
@@ -2000,7 +2013,7 @@ public: | |||||
NativeMidiEvent& nativeEvent(fMidiInEvents[fMidiEventInCount++]); | NativeMidiEvent& nativeEvent(fMidiInEvents[fMidiEventInCount++]); | ||||
carla_zeroStruct(nativeEvent); | carla_zeroStruct(nativeEvent); | ||||
nativeEvent.time = sampleAccurate ? startTime : eventTime; | |||||
nativeEvent.time = isSampleAccurate ? startTime : eventTime; | |||||
nativeEvent.data[0] = uint8_t(MIDI_STATUS_CONTROL_CHANGE | (event.channel & MIDI_CHANNEL_BIT)); | nativeEvent.data[0] = uint8_t(MIDI_STATUS_CONTROL_CHANGE | (event.channel & MIDI_CHANNEL_BIT)); | ||||
nativeEvent.data[1] = MIDI_CONTROL_BANK_SELECT; | nativeEvent.data[1] = MIDI_CONTROL_BANK_SELECT; | ||||
nativeEvent.data[2] = uint8_t(ctrlEvent.param); | nativeEvent.data[2] = uint8_t(ctrlEvent.param); | ||||
@@ -2047,7 +2060,7 @@ public: | |||||
NativeMidiEvent& nativeEvent(fMidiInEvents[fMidiEventInCount++]); | NativeMidiEvent& nativeEvent(fMidiInEvents[fMidiEventInCount++]); | ||||
carla_zeroStruct(nativeEvent); | carla_zeroStruct(nativeEvent); | ||||
nativeEvent.time = sampleAccurate ? startTime : eventTime; | |||||
nativeEvent.time = isSampleAccurate ? startTime : eventTime; | |||||
nativeEvent.data[0] = uint8_t(MIDI_STATUS_PROGRAM_CHANGE | (event.channel & MIDI_CHANNEL_BIT)); | nativeEvent.data[0] = uint8_t(MIDI_STATUS_PROGRAM_CHANGE | (event.channel & MIDI_CHANNEL_BIT)); | ||||
nativeEvent.data[1] = uint8_t(ctrlEvent.param); | nativeEvent.data[1] = uint8_t(ctrlEvent.param); | ||||
nativeEvent.size = 2; | nativeEvent.size = 2; | ||||
@@ -2063,7 +2076,7 @@ public: | |||||
NativeMidiEvent& nativeEvent(fMidiInEvents[fMidiEventInCount++]); | NativeMidiEvent& nativeEvent(fMidiInEvents[fMidiEventInCount++]); | ||||
carla_zeroStruct(nativeEvent); | carla_zeroStruct(nativeEvent); | ||||
nativeEvent.time = sampleAccurate ? startTime : eventTime; | |||||
nativeEvent.time = isSampleAccurate ? startTime : eventTime; | |||||
nativeEvent.data[0] = uint8_t(MIDI_STATUS_CONTROL_CHANGE | (event.channel & MIDI_CHANNEL_BIT)); | nativeEvent.data[0] = uint8_t(MIDI_STATUS_CONTROL_CHANGE | (event.channel & MIDI_CHANNEL_BIT)); | ||||
nativeEvent.data[1] = MIDI_CONTROL_ALL_SOUND_OFF; | nativeEvent.data[1] = MIDI_CONTROL_ALL_SOUND_OFF; | ||||
nativeEvent.data[2] = 0; | nativeEvent.data[2] = 0; | ||||
@@ -2088,7 +2101,7 @@ public: | |||||
NativeMidiEvent& nativeEvent(fMidiInEvents[fMidiEventInCount++]); | NativeMidiEvent& nativeEvent(fMidiInEvents[fMidiEventInCount++]); | ||||
carla_zeroStruct(nativeEvent); | carla_zeroStruct(nativeEvent); | ||||
nativeEvent.time = sampleAccurate ? startTime : eventTime; | |||||
nativeEvent.time = isSampleAccurate ? startTime : eventTime; | |||||
nativeEvent.data[0] = uint8_t(MIDI_STATUS_CONTROL_CHANGE | (event.channel & MIDI_CHANNEL_BIT)); | nativeEvent.data[0] = uint8_t(MIDI_STATUS_CONTROL_CHANGE | (event.channel & MIDI_CHANNEL_BIT)); | ||||
nativeEvent.data[1] = MIDI_CONTROL_ALL_NOTES_OFF; | nativeEvent.data[1] = MIDI_CONTROL_ALL_NOTES_OFF; | ||||
nativeEvent.data[2] = 0; | nativeEvent.data[2] = 0; | ||||
@@ -2130,7 +2143,7 @@ public: | |||||
carla_zeroStruct(nativeEvent); | carla_zeroStruct(nativeEvent); | ||||
nativeEvent.port = midiEvent.port; | nativeEvent.port = midiEvent.port; | ||||
nativeEvent.time = sampleAccurate ? startTime : eventTime; | |||||
nativeEvent.time = isSampleAccurate ? startTime : eventTime; | |||||
nativeEvent.size = midiEvent.size; | nativeEvent.size = midiEvent.size; | ||||
nativeEvent.data[0] = uint8_t(status | (event.channel & MIDI_CHANNEL_BIT)); | nativeEvent.data[0] = uint8_t(status | (event.channel & MIDI_CHANNEL_BIT)); | ||||
@@ -87,6 +87,7 @@ void AudioProcessor::suspendProcessing (const bool shouldBeSuspended) | |||||
} | } | ||||
void AudioProcessor::reset() {} | void AudioProcessor::reset() {} | ||||
void AudioProcessor::reconfigure() {} | |||||
uint AudioProcessor::getTotalNumInputChannels(ChannelType t) const noexcept | uint AudioProcessor::getTotalNumInputChannels(ChannelType t) const noexcept | ||||
{ | { | ||||
@@ -270,6 +270,13 @@ public: | |||||
*/ | */ | ||||
virtual void reset(); | virtual void reset(); | ||||
/** A plugin can override this to be told when it should reconfigure itself. | |||||
The default implementation does nothing, but a host may call this to tell the | |||||
plugin that it should call setPlayConfigDetails again. | |||||
*/ | |||||
virtual void reconfigure(); | |||||
//============================================================================== | //============================================================================== | ||||
/** Returns true if the processor is being run in an offline mode for rendering. | /** Returns true if the processor is being run in an offline mode for rendering. | ||||
@@ -389,6 +389,7 @@ private: | |||||
bool isPrepared, needsReorder; | bool isPrepared, needsReorder; | ||||
CarlaRecursiveMutex reorderMutex; | CarlaRecursiveMutex reorderMutex; | ||||
public: | |||||
void clearRenderingSequence(); | void clearRenderingSequence(); | ||||
void buildRenderingSequence(); | void buildRenderingSequence(); | ||||
bool isAnInputTo (uint32 possibleInputId, uint32 possibleDestinationId, int recursionCheck) const; | bool isAnInputTo (uint32 possibleInputId, uint32 possibleDestinationId, int recursionCheck) const; | ||||