| @@ -49,11 +49,11 @@ ALL_LIBS += source/modules/jackbridge.a | |||
| ALL_LIBS += source/modules/juce_audio_basics.a | |||
| ALL_LIBS += source/modules/juce_audio_devices.a | |||
| ALL_LIBS += source/modules/juce_audio_formats.a | |||
| ALL_LIBS += source/modules/juce_audio_processors.a | |||
| ALL_LIBS += source/modules/juce_core.a | |||
| ALL_LIBS += source/modules/juce_events.a | |||
| ifeq ($(HAVE_JUCE_UI),true) | |||
| ALL_LIBS += source/modules/juce_audio_processors.a | |||
| ALL_LIBS += source/modules/juce_data_structures.a | |||
| ALL_LIBS += source/modules/juce_graphics.a | |||
| ALL_LIBS += source/modules/juce_gui_basics.a | |||
| @@ -24,14 +24,8 @@ | |||
| struct CarlaOscData; | |||
| #endif | |||
| // ----------------------------------------------------------------------- | |||
| CARLA_BACKEND_START_NAMESPACE | |||
| #if 0 | |||
| } /* Fix editor indentation */ | |||
| #endif | |||
| // ----------------------------------------------------------------------- | |||
| /*! | |||
| @@ -1044,6 +1038,13 @@ protected: | |||
| */ | |||
| struct ProtectedData; | |||
| ProtectedData* const pData; | |||
| /*! | |||
| * Some internal classes read directly from pData. | |||
| */ | |||
| friend class EngineInternalGraph; | |||
| friend class PatchbayGraph; | |||
| friend class RackGraph; | |||
| friend class ScopedActionLock; | |||
| // ------------------------------------------------------------------- | |||
| @@ -16,6 +16,7 @@ STANDALONE_LIBS += ../modules/jackbridge.a | |||
| STANDALONE_LIBS += ../modules/juce_audio_basics.a | |||
| STANDALONE_LIBS += ../modules/juce_audio_devices.a | |||
| STANDALONE_LIBS += ../modules/juce_audio_formats.a | |||
| STANDALONE_LIBS += ../modules/juce_audio_processors.a | |||
| STANDALONE_LIBS += ../modules/juce_core.a | |||
| STANDALONE_LIBS += ../modules/juce_events.a | |||
| STANDALONE_LIBS += ../modules/native-plugins.a | |||
| @@ -36,7 +37,6 @@ STANDALONE_LIBS += ../modules/dgl.a | |||
| endif | |||
| ifeq ($(HAVE_JUCE_UI),true) | |||
| STANDALONE_LIBS += ../modules/juce_audio_processors.a | |||
| STANDALONE_LIBS += ../modules/juce_data_structures.a | |||
| STANDALONE_LIBS += ../modules/juce_graphics.a | |||
| STANDALONE_LIBS += ../modules/juce_gui_basics.a | |||
| @@ -1500,8 +1500,7 @@ void CarlaEngine::bufferSizeChanged(const uint32_t newBufferSize) | |||
| carla_debug("CarlaEngine::bufferSizeChanged(%i)", newBufferSize); | |||
| #ifndef BUILD_BRIDGE | |||
| if (pData->graph.graph != nullptr) | |||
| pData->graph.setBufferSize(newBufferSize); | |||
| pData->graph.setBufferSize(newBufferSize); | |||
| #endif | |||
| for (uint i=0; i < pData->curPluginCount; ++i) | |||
| @@ -1520,8 +1519,7 @@ void CarlaEngine::sampleRateChanged(const double newSampleRate) | |||
| carla_debug("CarlaEngine::sampleRateChanged(%g)", newSampleRate); | |||
| #ifndef BUILD_BRIDGE | |||
| if (pData->graph.graph != nullptr) | |||
| pData->graph.setSampleRate(newSampleRate); | |||
| pData->graph.setSampleRate(newSampleRate); | |||
| #endif | |||
| for (uint i=0; i < pData->curPluginCount; ++i) | |||
| @@ -1539,6 +1537,10 @@ void CarlaEngine::offlineModeChanged(const bool isOfflineNow) | |||
| { | |||
| carla_debug("CarlaEngine::offlineModeChanged(%s)", bool2str(isOfflineNow)); | |||
| #ifndef BUILD_BRIDGE | |||
| pData->graph.setOffline(isOfflineNow); | |||
| #endif | |||
| for (uint i=0; i < pData->curPluginCount; ++i) | |||
| { | |||
| CarlaPlugin* const plugin(pData->plugins[i].plugin); | |||
| @@ -21,6 +21,12 @@ | |||
| #include "CarlaEngine.hpp" | |||
| #include "CarlaMutex.hpp" | |||
| #include "CarlaPatchbayUtils.hpp" | |||
| #include "CarlaStringList.hpp" | |||
| #include "juce_audio_processors.h" | |||
| using juce::AudioProcessorGraph; | |||
| using juce::AudioSampleBuffer; | |||
| CARLA_BACKEND_START_NAMESPACE | |||
| @@ -47,25 +53,15 @@ enum RackGraphCarlaPortIds { | |||
| RACK_GRAPH_CARLA_PORT_MAX = 7 | |||
| }; | |||
| // ----------------------------------------------------------------------- | |||
| // InternalGraph | |||
| struct InternalGraph { | |||
| virtual ~InternalGraph() noexcept {} | |||
| virtual void clear() noexcept = 0; | |||
| virtual void setBufferSize(const uint32_t bufferSize) = 0; | |||
| virtual void setSampleRate(const double sampleRate) = 0; | |||
| virtual bool connect(CarlaEngine* const engine, const uint groupA, const uint portA, const uint groupB, const uint portB) noexcept = 0; | |||
| virtual bool disconnect(CarlaEngine* const engine, const uint connectionId) noexcept = 0; | |||
| virtual const char* const* getConnections() const = 0; | |||
| virtual bool getPortIdFromFullName(const char* const fullPortName, uint& groupId, uint& portId) const = 0; | |||
| }; | |||
| // ----------------------------------------------------------------------- | |||
| // RackGraph | |||
| struct RackGraph : InternalGraph { | |||
| struct RackGraph { | |||
| PatchbayConnectionList connections; | |||
| const uint32_t inputs; | |||
| const uint32_t outputs; | |||
| bool isOffline; | |||
| CharStringListPtr retCon; | |||
| struct Audio { | |||
| CarlaRecursiveMutex mutex; | |||
| @@ -74,6 +70,7 @@ struct RackGraph : InternalGraph { | |||
| LinkedList<uint> connectedOut1; | |||
| LinkedList<uint> connectedOut2; | |||
| float* inBuf[2]; | |||
| float* inBufTmp[2]; | |||
| float* outBuf[2]; | |||
| } audio; | |||
| @@ -81,35 +78,51 @@ struct RackGraph : InternalGraph { | |||
| LinkedList<PortNameToId> ins; | |||
| LinkedList<PortNameToId> outs; | |||
| const char* getName(const bool isInput, const uint portId) const noexcept; | |||
| uint getPortId(const bool isInput, const char portName[]) const noexcept; | |||
| uint getPortId(const bool isInput, const char portName[], bool* const ok = nullptr) const noexcept; | |||
| } midi; | |||
| RackGraph(const uint32_t bufferSize) noexcept; | |||
| ~RackGraph() noexcept override; | |||
| void clear() noexcept override; | |||
| void setBufferSize(const uint32_t bufferSize) noexcept override; | |||
| void setSampleRate(const double sampleRate) noexcept override; | |||
| bool connect(CarlaEngine* const engine, const uint groupA, const uint portA, const uint groupB, const uint portB) noexcept override; | |||
| bool disconnect(CarlaEngine* const engine, const uint connectionId) noexcept override; | |||
| const char* const* getConnections() const override; | |||
| bool getPortIdFromFullName(const char* const fullPortName, uint& groupId, uint& portId) const override; | |||
| RackGraph(const uint32_t bufferSize, const uint32_t inputs, const uint32_t outputs) noexcept; | |||
| ~RackGraph() noexcept; | |||
| void setBufferSize(const uint32_t bufferSize) noexcept; | |||
| void setOffline(const bool offline) noexcept; | |||
| bool connect(CarlaEngine* const engine, const uint groupA, const uint portA, const uint groupB, const uint portB) noexcept; | |||
| bool disconnect(CarlaEngine* const engine, const uint connectionId) noexcept; | |||
| void clearConnections() noexcept; | |||
| const char* const* getConnections() noexcept; | |||
| bool getGroupAndPortIdFromFullName(const char* const fullPortName, uint& groupId, uint& portId) const noexcept; | |||
| // the base, where plugins run | |||
| void process(CarlaEngine::ProtectedData* const data, const float* inBufReal[2], float* outBuf[2], const uint32_t frames); | |||
| // extended, will call process() in the middle | |||
| void processHelper(CarlaEngine::ProtectedData* const data, const float* const* const inBuf, float* const* const outBuf, const uint32_t frames); | |||
| }; | |||
| // ----------------------------------------------------------------------- | |||
| // PatchbayGraph | |||
| struct PatchbayGraph : InternalGraph { | |||
| // TODO | |||
| PatchbayGraph() noexcept; | |||
| ~PatchbayGraph() noexcept override; | |||
| void clear() noexcept override; | |||
| void setBufferSize(const uint32_t bufferSize) noexcept override; | |||
| void setSampleRate(const double sampleRate) noexcept override; | |||
| bool connect(CarlaEngine* const engine, const uint groupA, const uint portA, const uint groupB, const uint portB) noexcept override; | |||
| bool disconnect(CarlaEngine* const engine, const uint connectionId) noexcept override; | |||
| const char* const* getConnections() const noexcept override; | |||
| bool getPortIdFromFullName(const char* const fullPortName, uint& groupId, uint& portId) const noexcept override; | |||
| struct PatchbayGraph { | |||
| AudioProcessorGraph graph; | |||
| AudioSampleBuffer audioBuffer; | |||
| //CharStringListPtr retCon; | |||
| PatchbayGraph(const uint32_t bufferSize, const double sampleRate, const uint32_t inputs, const uint32_t outputs); | |||
| ~PatchbayGraph(); | |||
| void setBufferSize(const uint32_t bufferSize); | |||
| void setSampleRate(const double sampleRate); | |||
| void setOffline(const bool offline); | |||
| //bool connect(CarlaEngine* const engine, const uint groupA, const uint portA, const uint groupB, const uint portB) noexcept; | |||
| //bool disconnect(CarlaEngine* const engine, const uint connectionId) noexcept; | |||
| //const char* const* getConnections() const noexcept; | |||
| //bool getPortIdFromFullName(const char* const fullPortName, uint& groupId, uint& portId) const noexcept; | |||
| //void process(const float* const* const inBuf, float* const* const outBuf, const uint32_t nframes); | |||
| }; | |||
| // ----------------------------------------------------------------------- | |||
| @@ -19,11 +19,6 @@ | |||
| #include "CarlaPlugin.hpp" | |||
| #include "CarlaMIDI.h" | |||
| #include "CarlaMathUtils.hpp" | |||
| #include "juce_audio_basics.h" | |||
| using juce::FloatVectorOperations; | |||
| CARLA_BACKEND_START_NAMESPACE | |||
| // ----------------------------------------------------------------------- | |||
| @@ -32,114 +27,6 @@ CARLA_BACKEND_START_NAMESPACE | |||
| #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; } | |||
| #if 0 | |||
| // ----------------------------------------------------------------------- | |||
| // InternalAudio | |||
| EngineInternalAudio::EngineInternalAudio() noexcept | |||
| : isReady(false), | |||
| inCount(0), | |||
| outCount(0), | |||
| inBuf(nullptr), | |||
| outBuf(nullptr) {} | |||
| EngineInternalAudio::~EngineInternalAudio() noexcept | |||
| { | |||
| CARLA_SAFE_ASSERT(! isReady); | |||
| CARLA_SAFE_ASSERT(inCount == 0); | |||
| CARLA_SAFE_ASSERT(outCount == 0); | |||
| CARLA_SAFE_ASSERT(inBuf == nullptr); | |||
| CARLA_SAFE_ASSERT(outBuf == nullptr); | |||
| } | |||
| void EngineInternalAudio::clearBuffers() noexcept | |||
| { | |||
| for (uint32_t i=0; i < inCount; ++i) | |||
| { | |||
| if (inBuf[i] != nullptr) | |||
| { | |||
| delete[] inBuf[i]; | |||
| inBuf[i] = nullptr; | |||
| } | |||
| } | |||
| for (uint32_t i=0; i < outCount; ++i) | |||
| { | |||
| if (outBuf[i] != nullptr) | |||
| { | |||
| delete[] outBuf[i]; | |||
| outBuf[i] = nullptr; | |||
| } | |||
| } | |||
| } | |||
| void EngineInternalAudio::clear() noexcept | |||
| { | |||
| isReady = false; | |||
| clearBuffers(); | |||
| inCount = 0; | |||
| outCount = 0; | |||
| if (inBuf != nullptr) | |||
| { | |||
| delete[] inBuf; | |||
| inBuf = nullptr; | |||
| } | |||
| if (outBuf != nullptr) | |||
| { | |||
| delete[] outBuf; | |||
| outBuf = nullptr; | |||
| } | |||
| } | |||
| void EngineInternalAudio::create(const uint32_t bufferSize) | |||
| { | |||
| CARLA_SAFE_ASSERT(! isReady); | |||
| CARLA_SAFE_ASSERT(inBuf == nullptr); | |||
| CARLA_SAFE_ASSERT(outBuf == nullptr); | |||
| if (inCount > 0) | |||
| { | |||
| inBuf = new float*[inCount]; | |||
| for (uint32_t i=0; i < inCount; ++i) | |||
| inBuf[i] = nullptr; | |||
| } | |||
| if (outCount > 0) | |||
| { | |||
| outBuf = new float*[outCount]; | |||
| for (uint32_t i=0; i < outCount; ++i) | |||
| outBuf[i] = nullptr; | |||
| } | |||
| resize(bufferSize, false); | |||
| } | |||
| void EngineInternalAudio::resize(const uint32_t bufferSize, const bool doClear = true) | |||
| { | |||
| if (doClear) | |||
| clearBuffers(); | |||
| CARLA_SAFE_ASSERT_RETURN(bufferSize != 0,); | |||
| for (uint32_t i=0; i < inCount; ++i) | |||
| { | |||
| inBuf[i] = new float[bufferSize]; | |||
| FloatVectorOperations::clear(inBuf[i], bufferSize); | |||
| } | |||
| for (uint32_t i=0; i < outCount; ++i) | |||
| { | |||
| outBuf[i] = new float[bufferSize]; | |||
| FloatVectorOperations::clear(outBuf[i], bufferSize); | |||
| } | |||
| } | |||
| #endif | |||
| // ----------------------------------------------------------------------- | |||
| // InternalEvents | |||
| @@ -327,7 +214,7 @@ void CarlaEngine::ProtectedData::close() | |||
| plugins = nullptr; | |||
| } | |||
| graph.clear(); | |||
| graph.destroy(); | |||
| #endif | |||
| events.clear(); | |||
| @@ -49,21 +49,40 @@ struct EngineInternalEvents { | |||
| // ----------------------------------------------------------------------- | |||
| // InternalGraph | |||
| struct InternalGraph; | |||
| struct EngineInternalGraph { | |||
| bool isRack; | |||
| bool isReady; | |||
| InternalGraph* graph; | |||
| struct RackGraph; | |||
| struct PatchbayGraph; | |||
| class EngineInternalGraph | |||
| { | |||
| public: | |||
| EngineInternalGraph() noexcept; | |||
| ~EngineInternalGraph() noexcept; | |||
| void create(const double sampleRate, const uint32_t bufferSize); | |||
| void clear() noexcept; | |||
| void create(const bool isRack, const double sampleRate, const uint32_t bufferSize, const uint32_t inputs, const uint32_t outputs); | |||
| void destroy() noexcept; | |||
| void setBufferSize(const uint32_t bufferSize); | |||
| void setSampleRate(const double sampleRate); | |||
| void setOffline(const bool offline); | |||
| bool isReady() const noexcept; | |||
| RackGraph* getRackGraph() const noexcept; | |||
| PatchbayGraph* getPatchbayGraph() const noexcept; | |||
| void process(CarlaEngine::ProtectedData* const data, const float* const* const inBuf, float* const* const outBuf, const uint32_t frames); | |||
| // special direct process with connections already handled, used in JACK and Plugin | |||
| void processRack(CarlaEngine::ProtectedData* const data, const float* inBuf[2], float* outBuf[2], const uint32_t frames); | |||
| private: | |||
| bool fIsRack; | |||
| bool fIsReady; | |||
| union { | |||
| RackGraph* fRack; | |||
| PatchbayGraph* fPatchbay; | |||
| }; | |||
| CARLA_DECLARE_NON_COPY_STRUCT(EngineInternalGraph) | |||
| }; | |||
| @@ -174,16 +193,6 @@ struct CarlaEngine::ProtectedData { | |||
| void doPluginsSwitch() noexcept; | |||
| void doNextPluginAction(const bool unlock) noexcept; | |||
| #ifndef BUILD_BRIDGE | |||
| // ------------------------------------------------------------------- | |||
| // the base, where plugins run | |||
| void processRack(const float* inBufReal[2], float* outBuf[2], const uint32_t nframes, const bool isOffline); | |||
| // extended, will call processRack() in the middle | |||
| void processRackFull(const float* const* const inBuf, const uint32_t inCount, float* const* const outBuf, const uint32_t outCount, const uint32_t nframes, const bool isOffline); | |||
| #endif | |||
| // ------------------------------------------------------------------- | |||
| //friend class ScopedActionLock; | |||
| @@ -915,6 +915,8 @@ public: | |||
| fRackPorts[kRackPortAudioOut2] = jackbridge_port_register(fClient, "audio-out2", JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0); | |||
| fRackPorts[kRackPortEventIn] = jackbridge_port_register(fClient, "events-in", JACK_DEFAULT_MIDI_TYPE, JackPortIsInput, 0); | |||
| fRackPorts[kRackPortEventOut] = jackbridge_port_register(fClient, "events-out", JACK_DEFAULT_MIDI_TYPE, JackPortIsOutput, 0); | |||
| pData->graph.create(true, pData->sampleRate, pData->bufferSize, 0, 0); | |||
| } | |||
| if (jackbridge_activate(fClient)) | |||
| @@ -1516,7 +1518,7 @@ protected: | |||
| } | |||
| // process rack | |||
| pData->processRack(inBuf, outBuf, nframes, fFreewheel); | |||
| pData->graph.processRack(pData, inBuf, outBuf, nframes); | |||
| // output control | |||
| { | |||
| @@ -160,13 +160,11 @@ public: | |||
| pData->bufferSize = static_cast<uint32_t>(fDevice->getCurrentBufferSizeSamples()); | |||
| pData->sampleRate = fDevice->getCurrentSampleRate(); | |||
| pData->graph.isRack = (pData->options.processMode == ENGINE_PROCESS_MODE_CONTINUOUS_RACK); | |||
| pData->graph.create(pData->sampleRate, pData->bufferSize); | |||
| pData->graph.create(pData->options.processMode == ENGINE_PROCESS_MODE_CONTINUOUS_RACK, pData->sampleRate, pData->bufferSize, inputNames.size(), outputNames.size()); | |||
| fDevice->start(this); | |||
| CarlaEngine::init(clientName); | |||
| pData->graph.isReady = true; | |||
| patchbayRefresh(); | |||
| @@ -177,8 +175,6 @@ public: | |||
| { | |||
| carla_debug("CarlaEngineJuce::close()"); | |||
| pData->graph.isReady = false; | |||
| bool hasError = !CarlaEngine::close(); | |||
| if (fDevice != nullptr) | |||
| @@ -246,11 +242,11 @@ public: | |||
| bool patchbayRefresh() override | |||
| { | |||
| CARLA_SAFE_ASSERT_RETURN(pData->graph.isReady, false); | |||
| CARLA_SAFE_ASSERT_RETURN(pData->graph.isReady(), false); | |||
| //fUsedMidiPorts.clear(); | |||
| if (pData->graph.isRack) | |||
| if (pData->options.processMode == ENGINE_PROCESS_MODE_CONTINUOUS_RACK) | |||
| patchbayRefreshRack(); | |||
| else | |||
| patchbayRefreshPatchbay(); | |||
| @@ -260,9 +256,10 @@ public: | |||
| void patchbayRefreshRack() | |||
| { | |||
| RackGraph* const rack((RackGraph*)pData->graph.graph); | |||
| RackGraph* const graph(pData->graph.getRackGraph()); | |||
| CARLA_SAFE_ASSERT_RETURN(graph != nullptr,); | |||
| rack->connections.clear(); | |||
| graph->connections.clear(); | |||
| char strBuf[STR_MAX+1]; | |||
| strBuf[STR_MAX] = '\0'; | |||
| @@ -331,7 +328,7 @@ public: | |||
| callback(ENGINE_CALLBACK_PATCHBAY_PORT_ADDED, portNameToId.group, static_cast<int>(portNameToId.port), PATCHBAY_PORT_TYPE_MIDI, 0.0f, portNameToId.name); | |||
| rack->midi.ins.append(portNameToId); | |||
| graph->midi.ins.append(portNameToId); | |||
| } | |||
| } | |||
| @@ -352,90 +349,90 @@ public: | |||
| callback(ENGINE_CALLBACK_PATCHBAY_PORT_ADDED, portNameToId.group, static_cast<int>(portNameToId.port), PATCHBAY_PORT_TYPE_MIDI|PATCHBAY_PORT_IS_INPUT, 0.0f, portNameToId.name); | |||
| rack->midi.outs.append(portNameToId); | |||
| graph->midi.outs.append(portNameToId); | |||
| } | |||
| } | |||
| // Connections | |||
| rack->audio.mutex.lock(); | |||
| graph->audio.mutex.lock(); | |||
| for (LinkedList<uint>::Itenerator it = rack->audio.connectedIn1.begin(); it.valid(); it.next()) | |||
| for (LinkedList<uint>::Itenerator it = graph->audio.connectedIn1.begin(); it.valid(); it.next()) | |||
| { | |||
| const uint& portId(it.getValue()); | |||
| //CARLA_SAFE_ASSERT_CONTINUE(portId < fAudioInCount); | |||
| ConnectionToId connectionToId; | |||
| connectionToId.setData(++(rack->connections.lastId), RACK_GRAPH_GROUP_AUDIO_IN, portId, RACK_GRAPH_GROUP_CARLA, RACK_GRAPH_CARLA_PORT_AUDIO_IN1); | |||
| connectionToId.setData(++(graph->connections.lastId), RACK_GRAPH_GROUP_AUDIO_IN, portId, RACK_GRAPH_GROUP_CARLA, RACK_GRAPH_CARLA_PORT_AUDIO_IN1); | |||
| std::snprintf(strBuf, STR_MAX, "%i:%i:%i:%i", connectionToId.groupA, connectionToId.portA, connectionToId.groupB, connectionToId.portB); | |||
| callback(ENGINE_CALLBACK_PATCHBAY_CONNECTION_ADDED, connectionToId.id, 0, 0, 0.0f, strBuf); | |||
| rack->connections.list.append(connectionToId); | |||
| graph->connections.list.append(connectionToId); | |||
| } | |||
| for (LinkedList<uint>::Itenerator it = rack->audio.connectedIn2.begin(); it.valid(); it.next()) | |||
| for (LinkedList<uint>::Itenerator it = graph->audio.connectedIn2.begin(); it.valid(); it.next()) | |||
| { | |||
| const uint& portId(it.getValue()); | |||
| //CARLA_SAFE_ASSERT_CONTINUE(portId < fAudioInCount); | |||
| ConnectionToId connectionToId; | |||
| connectionToId.setData(++(rack->connections.lastId), RACK_GRAPH_GROUP_AUDIO_IN, portId, RACK_GRAPH_GROUP_CARLA, RACK_GRAPH_CARLA_PORT_AUDIO_IN2); | |||
| connectionToId.setData(++(graph->connections.lastId), RACK_GRAPH_GROUP_AUDIO_IN, portId, RACK_GRAPH_GROUP_CARLA, RACK_GRAPH_CARLA_PORT_AUDIO_IN2); | |||
| std::snprintf(strBuf, STR_MAX, "%i:%i:%i:%i", connectionToId.groupA, connectionToId.portA, connectionToId.groupB, connectionToId.portB); | |||
| callback(ENGINE_CALLBACK_PATCHBAY_CONNECTION_ADDED, connectionToId.id, 0, 0, 0.0f, strBuf); | |||
| rack->connections.list.append(connectionToId); | |||
| graph->connections.list.append(connectionToId); | |||
| } | |||
| for (LinkedList<uint>::Itenerator it = rack->audio.connectedOut1.begin(); it.valid(); it.next()) | |||
| for (LinkedList<uint>::Itenerator it = graph->audio.connectedOut1.begin(); it.valid(); it.next()) | |||
| { | |||
| const uint& portId(it.getValue()); | |||
| //CARLA_SAFE_ASSERT_CONTINUE(portId < fAudioOutCount); | |||
| ConnectionToId connectionToId; | |||
| connectionToId.setData(++(rack->connections.lastId), RACK_GRAPH_GROUP_CARLA, RACK_GRAPH_CARLA_PORT_AUDIO_OUT1, RACK_GRAPH_GROUP_AUDIO_OUT, portId); | |||
| connectionToId.setData(++(graph->connections.lastId), RACK_GRAPH_GROUP_CARLA, RACK_GRAPH_CARLA_PORT_AUDIO_OUT1, RACK_GRAPH_GROUP_AUDIO_OUT, portId); | |||
| std::snprintf(strBuf, STR_MAX, "%i:%i:%i:%i", connectionToId.groupA, connectionToId.portA, connectionToId.groupB, connectionToId.portB); | |||
| callback(ENGINE_CALLBACK_PATCHBAY_CONNECTION_ADDED, connectionToId.id, 0, 0, 0.0f, strBuf); | |||
| rack->connections.list.append(connectionToId); | |||
| graph->connections.list.append(connectionToId); | |||
| } | |||
| for (LinkedList<uint>::Itenerator it = rack->audio.connectedOut2.begin(); it.valid(); it.next()) | |||
| for (LinkedList<uint>::Itenerator it = graph->audio.connectedOut2.begin(); it.valid(); it.next()) | |||
| { | |||
| const uint& portId(it.getValue()); | |||
| //CARLA_SAFE_ASSERT_CONTINUE(portId < fAudioOutCount); | |||
| ConnectionToId connectionToId; | |||
| connectionToId.setData(++(rack->connections.lastId), RACK_GRAPH_GROUP_CARLA, RACK_GRAPH_CARLA_PORT_AUDIO_OUT2, RACK_GRAPH_GROUP_AUDIO_OUT, portId); | |||
| connectionToId.setData(++(graph->connections.lastId), RACK_GRAPH_GROUP_CARLA, RACK_GRAPH_CARLA_PORT_AUDIO_OUT2, RACK_GRAPH_GROUP_AUDIO_OUT, portId); | |||
| std::snprintf(strBuf, STR_MAX, "%i:%i:%i:%i", connectionToId.groupA, connectionToId.portA, connectionToId.groupB, connectionToId.portB); | |||
| callback(ENGINE_CALLBACK_PATCHBAY_CONNECTION_ADDED, connectionToId.id, 0, 0, 0.0f, strBuf); | |||
| rack->connections.list.append(connectionToId); | |||
| graph->connections.list.append(connectionToId); | |||
| } | |||
| rack->audio.mutex.unlock(); | |||
| graph->audio.mutex.unlock(); | |||
| for (LinkedList<MidiInPort>::Itenerator it=fMidiIns.begin(); it.valid(); it.next()) | |||
| { | |||
| const MidiInPort& inPort(it.getValue()); | |||
| const uint portId(rack->midi.getPortId(true, inPort.name)); | |||
| CARLA_SAFE_ASSERT_CONTINUE(portId < rack->midi.ins.count()); | |||
| const uint portId(graph->midi.getPortId(true, inPort.name)); | |||
| CARLA_SAFE_ASSERT_CONTINUE(portId < graph->midi.ins.count()); | |||
| ConnectionToId connectionToId; | |||
| connectionToId.setData(++(rack->connections.lastId), RACK_GRAPH_GROUP_MIDI_IN, portId, RACK_GRAPH_GROUP_CARLA, RACK_GRAPH_CARLA_PORT_MIDI_IN); | |||
| connectionToId.setData(++(graph->connections.lastId), RACK_GRAPH_GROUP_MIDI_IN, portId, RACK_GRAPH_GROUP_CARLA, RACK_GRAPH_CARLA_PORT_MIDI_IN); | |||
| std::snprintf(strBuf, STR_MAX, "%i:%i:%i:%i", connectionToId.groupA, connectionToId.portA, connectionToId.groupB, connectionToId.portB); | |||
| callback(ENGINE_CALLBACK_PATCHBAY_CONNECTION_ADDED, connectionToId.id, 0, 0, 0.0f, strBuf); | |||
| rack->connections.list.append(connectionToId); | |||
| graph->connections.list.append(connectionToId); | |||
| } | |||
| fMidiOutMutex.lock(); | |||
| @@ -444,17 +441,17 @@ public: | |||
| { | |||
| const MidiOutPort& outPort(it.getValue()); | |||
| const uint portId(rack->midi.getPortId(false, outPort.name)); | |||
| CARLA_SAFE_ASSERT_CONTINUE(portId < rack->midi.outs.count()); | |||
| const uint portId(graph->midi.getPortId(false, outPort.name)); | |||
| CARLA_SAFE_ASSERT_CONTINUE(portId < graph->midi.outs.count()); | |||
| ConnectionToId connectionToId; | |||
| connectionToId.setData(++(rack->connections.lastId), RACK_GRAPH_GROUP_CARLA, RACK_GRAPH_CARLA_PORT_MIDI_OUT, RACK_GRAPH_GROUP_MIDI_OUT, portId); | |||
| connectionToId.setData(++(graph->connections.lastId), RACK_GRAPH_GROUP_CARLA, RACK_GRAPH_CARLA_PORT_MIDI_OUT, RACK_GRAPH_GROUP_MIDI_OUT, portId); | |||
| std::snprintf(strBuf, STR_MAX, "%i:%i:%i:%i", connectionToId.groupA, connectionToId.portA, connectionToId.groupB, connectionToId.portB); | |||
| callback(ENGINE_CALLBACK_PATCHBAY_CONNECTION_ADDED, connectionToId.id, 0, 0, 0.0f, strBuf); | |||
| rack->connections.list.append(connectionToId); | |||
| graph->connections.list.append(connectionToId); | |||
| } | |||
| fMidiOutMutex.unlock(); | |||
| @@ -462,6 +459,8 @@ public: | |||
| void patchbayRefreshPatchbay() noexcept | |||
| { | |||
| PatchbayGraph* const graph(pData->graph.getPatchbayGraph()); | |||
| CARLA_SAFE_ASSERT_RETURN(graph != nullptr,); | |||
| } | |||
| // ------------------------------------------------------------------- | |||
| @@ -475,9 +474,6 @@ protected: | |||
| CARLA_SAFE_ASSERT_RETURN(outputChannelData != nullptr, runPendingRtEvents()); | |||
| CARLA_SAFE_ASSERT_RETURN(numSamples == static_cast<int>(pData->bufferSize), runPendingRtEvents()); | |||
| if (! pData->graph.isReady) | |||
| return runPendingRtEvents(); | |||
| const uint32_t nframes(static_cast<uint32_t>(numSamples)); | |||
| // initialize juce output | |||
| @@ -520,15 +516,7 @@ protected: | |||
| fMidiInEvents.mutex.unlock(); | |||
| } | |||
| if (pData->graph.isRack) | |||
| { | |||
| pData->processRackFull(inputChannelData, static_cast<uint32_t>(numInputChannels), | |||
| outputChannelData, static_cast<uint32_t>(numOutputChannels), | |||
| static_cast<uint32_t>(numSamples), false); | |||
| } | |||
| else | |||
| { | |||
| } | |||
| pData->graph.process(pData, inputChannelData, outputChannelData, static_cast<uint32_t>(numSamples)); | |||
| fMidiOutMutex.lock(); | |||
| @@ -605,9 +593,6 @@ protected: | |||
| void handleIncomingMidiMessage(MidiInput* /*source*/, const MidiMessage& message) override | |||
| { | |||
| if (! pData->graph.isReady) | |||
| return; | |||
| const int messageSize(message.getRawDataSize()); | |||
| if (messageSize <= 0 || messageSize > EngineMidiEvent::kDataSize) | |||
| @@ -636,8 +621,9 @@ protected: | |||
| CARLA_SAFE_ASSERT_RETURN(portName != nullptr && portName[0] != '\0', false); | |||
| carla_debug("CarlaEngineJuce::connectRackMidiInPort(\"%s\")", portName); | |||
| RackGraph* const rack((RackGraph*)pData->graph.graph); | |||
| CARLA_SAFE_ASSERT_RETURN(rack->midi.ins.count() > 0, false); | |||
| RackGraph* const graph(pData->graph.getRackGraph()); | |||
| CARLA_SAFE_ASSERT_RETURN(graph != nullptr, false); | |||
| CARLA_SAFE_ASSERT_RETURN(graph->midi.ins.count() > 0, false); | |||
| StringArray midiIns(MidiInput::getDevices()); | |||
| @@ -662,8 +648,9 @@ protected: | |||
| CARLA_SAFE_ASSERT_RETURN(portName != nullptr && portName[0] != '\0', false); | |||
| carla_debug("CarlaEngineJuce::connectRackMidiOutPort(\"%s\")", portName); | |||
| RackGraph* const rack((RackGraph*)pData->graph.graph); | |||
| CARLA_SAFE_ASSERT_RETURN(rack->midi.ins.count() > 0, false); | |||
| RackGraph* const graph(pData->graph.getRackGraph()); | |||
| CARLA_SAFE_ASSERT_RETURN(graph != nullptr, false); | |||
| CARLA_SAFE_ASSERT_RETURN(graph->midi.ins.count() > 0, false); | |||
| StringArray midiOuts(MidiOutput::getDevices()); | |||
| @@ -690,8 +677,9 @@ protected: | |||
| CARLA_SAFE_ASSERT_RETURN(portName != nullptr && portName[0] != '\0', false); | |||
| carla_debug("CarlaEngineRtAudio::disconnectRackMidiInPort(\"%s\")", portName); | |||
| RackGraph* const rack((RackGraph*)pData->graph.graph); | |||
| CARLA_SAFE_ASSERT_RETURN(rack->midi.ins.count() > 0, false); | |||
| RackGraph* const graph(pData->graph.getRackGraph()); | |||
| CARLA_SAFE_ASSERT_RETURN(graph != nullptr, false); | |||
| CARLA_SAFE_ASSERT_RETURN(graph->midi.ins.count() > 0, false); | |||
| for (LinkedList<MidiInPort>::Itenerator it=fMidiIns.begin(); it.valid(); it.next()) | |||
| { | |||
| @@ -716,8 +704,9 @@ protected: | |||
| CARLA_SAFE_ASSERT_RETURN(portName != nullptr && portName[0] != '\0', false); | |||
| carla_debug("CarlaEngineRtAudio::disconnectRackMidiOutPort(\"%s\")", portName); | |||
| RackGraph* const rack((RackGraph*)pData->graph.graph); | |||
| CARLA_SAFE_ASSERT_RETURN(rack->midi.outs.count() > 0, false); | |||
| RackGraph* const graph(pData->graph.getRackGraph()); | |||
| CARLA_SAFE_ASSERT_RETURN(graph != nullptr, false); | |||
| CARLA_SAFE_ASSERT_RETURN(graph->midi.outs.count() > 0, false); | |||
| const CarlaMutexLocker cml(fMidiOutMutex); | |||
| @@ -579,6 +579,8 @@ public: | |||
| init("Carla-Rack"); | |||
| } | |||
| pData->graph.create(!fIsPatchbay, pData->sampleRate, pData->bufferSize, 0, 0); | |||
| if (pData->options.resourceDir != nullptr) | |||
| delete[] pData->options.resourceDir; | |||
| if (pData->options.binaryDir != nullptr) | |||
| @@ -1152,7 +1154,7 @@ protected: | |||
| // ----------------------------------------------------------- | |||
| // process | |||
| pData->processRack(inBuf, outBuf, frames, isOffline()); | |||
| pData->graph.processRack(pData, inBuf, outBuf, frames); | |||
| } | |||
| // --------------------------------------------------------------- | |||
| @@ -262,8 +262,7 @@ public: | |||
| fAudioOutCount = oParams.nChannels; | |||
| fLastEventTime = 0; | |||
| pData->graph.isRack = (pData->options.processMode == ENGINE_PROCESS_MODE_CONTINUOUS_RACK); | |||
| pData->graph.create(pData->sampleRate, pData->bufferSize); | |||
| pData->graph.create(pData->options.processMode == ENGINE_PROCESS_MODE_CONTINUOUS_RACK, pData->sampleRate, pData->bufferSize, fAudioInCount, fAudioOutCount); | |||
| try { | |||
| fAudio.startStream(); | |||
| @@ -276,7 +275,6 @@ public: | |||
| } | |||
| CarlaEngine::init(clientName); | |||
| pData->graph.isReady = true; | |||
| patchbayRefresh(); | |||
| @@ -288,8 +286,6 @@ public: | |||
| CARLA_SAFE_ASSERT(fAudioOutCount != 0); | |||
| carla_debug("CarlaEngineRtAudio::close()"); | |||
| pData->graph.isReady = false; | |||
| bool hasError = !CarlaEngine::close(); | |||
| if (fAudio.isStreamOpen()) | |||
| @@ -372,9 +368,9 @@ public: | |||
| bool patchbayRefresh() override | |||
| { | |||
| CARLA_SAFE_ASSERT_RETURN(pData->graph.isReady, false); | |||
| CARLA_SAFE_ASSERT_RETURN(pData->graph.isReady(), false); | |||
| if (pData->graph.isRack) | |||
| if (pData->options.processMode == ENGINE_PROCESS_MODE_CONTINUOUS_RACK) | |||
| patchbayRefreshRack(); | |||
| else | |||
| patchbayRefreshPatchbay(); | |||
| @@ -384,9 +380,10 @@ public: | |||
| void patchbayRefreshRack() | |||
| { | |||
| RackGraph* const rack((RackGraph*)pData->graph.graph); | |||
| RackGraph* const graph(pData->graph.getRackGraph()); | |||
| CARLA_SAFE_ASSERT_RETURN(graph != nullptr,); | |||
| rack->connections.clear(); | |||
| graph->connections.clear(); | |||
| char strBuf[STR_MAX+1]; | |||
| strBuf[STR_MAX] = '\0'; | |||
| @@ -452,7 +449,7 @@ public: | |||
| callback(ENGINE_CALLBACK_PATCHBAY_PORT_ADDED, portNameToId.group, static_cast<int>(portNameToId.port), PATCHBAY_PORT_TYPE_MIDI, 0.0f, portNameToId.name); | |||
| rack->midi.ins.append(portNameToId); | |||
| graph->midi.ins.append(portNameToId); | |||
| } | |||
| } | |||
| @@ -473,90 +470,90 @@ public: | |||
| callback(ENGINE_CALLBACK_PATCHBAY_PORT_ADDED, portNameToId.group, static_cast<int>(portNameToId.port), PATCHBAY_PORT_TYPE_MIDI|PATCHBAY_PORT_IS_INPUT, 0.0f, portNameToId.name); | |||
| rack->midi.outs.append(portNameToId); | |||
| graph->midi.outs.append(portNameToId); | |||
| } | |||
| } | |||
| // Connections | |||
| rack->audio.mutex.lock(); | |||
| graph->audio.mutex.lock(); | |||
| for (LinkedList<uint>::Itenerator it = rack->audio.connectedIn1.begin(); it.valid(); it.next()) | |||
| for (LinkedList<uint>::Itenerator it = graph->audio.connectedIn1.begin(); it.valid(); it.next()) | |||
| { | |||
| const uint& portId(it.getValue()); | |||
| CARLA_SAFE_ASSERT_CONTINUE(portId < fAudioInCount); | |||
| ConnectionToId connectionToId; | |||
| connectionToId.setData(++(rack->connections.lastId), RACK_GRAPH_GROUP_AUDIO_IN, portId, RACK_GRAPH_GROUP_CARLA, RACK_GRAPH_CARLA_PORT_AUDIO_IN1); | |||
| connectionToId.setData(++(graph->connections.lastId), RACK_GRAPH_GROUP_AUDIO_IN, portId, RACK_GRAPH_GROUP_CARLA, RACK_GRAPH_CARLA_PORT_AUDIO_IN1); | |||
| std::snprintf(strBuf, STR_MAX, "%i:%i:%i:%i", connectionToId.groupA, connectionToId.portA, connectionToId.groupB, connectionToId.portB); | |||
| callback(ENGINE_CALLBACK_PATCHBAY_CONNECTION_ADDED, connectionToId.id, 0, 0, 0.0f, strBuf); | |||
| rack->connections.list.append(connectionToId); | |||
| graph->connections.list.append(connectionToId); | |||
| } | |||
| for (LinkedList<uint>::Itenerator it = rack->audio.connectedIn2.begin(); it.valid(); it.next()) | |||
| for (LinkedList<uint>::Itenerator it = graph->audio.connectedIn2.begin(); it.valid(); it.next()) | |||
| { | |||
| const uint& portId(it.getValue()); | |||
| CARLA_SAFE_ASSERT_CONTINUE(portId < fAudioInCount); | |||
| ConnectionToId connectionToId; | |||
| connectionToId.setData(++(rack->connections.lastId), RACK_GRAPH_GROUP_AUDIO_IN, portId, RACK_GRAPH_GROUP_CARLA, RACK_GRAPH_CARLA_PORT_AUDIO_IN2); | |||
| connectionToId.setData(++(graph->connections.lastId), RACK_GRAPH_GROUP_AUDIO_IN, portId, RACK_GRAPH_GROUP_CARLA, RACK_GRAPH_CARLA_PORT_AUDIO_IN2); | |||
| std::snprintf(strBuf, STR_MAX, "%i:%i:%i:%i", connectionToId.groupA, connectionToId.portA, connectionToId.groupB, connectionToId.portB); | |||
| callback(ENGINE_CALLBACK_PATCHBAY_CONNECTION_ADDED, connectionToId.id, 0, 0, 0.0f, strBuf); | |||
| rack->connections.list.append(connectionToId); | |||
| graph->connections.list.append(connectionToId); | |||
| } | |||
| for (LinkedList<uint>::Itenerator it = rack->audio.connectedOut1.begin(); it.valid(); it.next()) | |||
| for (LinkedList<uint>::Itenerator it = graph->audio.connectedOut1.begin(); it.valid(); it.next()) | |||
| { | |||
| const uint& portId(it.getValue()); | |||
| CARLA_SAFE_ASSERT_CONTINUE(portId < fAudioOutCount); | |||
| ConnectionToId connectionToId; | |||
| connectionToId.setData(++(rack->connections.lastId), RACK_GRAPH_GROUP_CARLA, RACK_GRAPH_CARLA_PORT_AUDIO_OUT1, RACK_GRAPH_GROUP_AUDIO_OUT, portId); | |||
| connectionToId.setData(++(graph->connections.lastId), RACK_GRAPH_GROUP_CARLA, RACK_GRAPH_CARLA_PORT_AUDIO_OUT1, RACK_GRAPH_GROUP_AUDIO_OUT, portId); | |||
| std::snprintf(strBuf, STR_MAX, "%i:%i:%i:%i", connectionToId.groupA, connectionToId.portA, connectionToId.groupB, connectionToId.portB); | |||
| callback(ENGINE_CALLBACK_PATCHBAY_CONNECTION_ADDED, connectionToId.id, 0, 0, 0.0f, strBuf); | |||
| rack->connections.list.append(connectionToId); | |||
| graph->connections.list.append(connectionToId); | |||
| } | |||
| for (LinkedList<uint>::Itenerator it = rack->audio.connectedOut2.begin(); it.valid(); it.next()) | |||
| for (LinkedList<uint>::Itenerator it = graph->audio.connectedOut2.begin(); it.valid(); it.next()) | |||
| { | |||
| const uint& portId(it.getValue()); | |||
| CARLA_SAFE_ASSERT_CONTINUE(portId < fAudioOutCount); | |||
| ConnectionToId connectionToId; | |||
| connectionToId.setData(++(rack->connections.lastId), RACK_GRAPH_GROUP_CARLA, RACK_GRAPH_CARLA_PORT_AUDIO_OUT2, RACK_GRAPH_GROUP_AUDIO_OUT, portId); | |||
| connectionToId.setData(++(graph->connections.lastId), RACK_GRAPH_GROUP_CARLA, RACK_GRAPH_CARLA_PORT_AUDIO_OUT2, RACK_GRAPH_GROUP_AUDIO_OUT, portId); | |||
| std::snprintf(strBuf, STR_MAX, "%i:%i:%i:%i", connectionToId.groupA, connectionToId.portA, connectionToId.groupB, connectionToId.portB); | |||
| callback(ENGINE_CALLBACK_PATCHBAY_CONNECTION_ADDED, connectionToId.id, 0, 0, 0.0f, strBuf); | |||
| rack->connections.list.append(connectionToId); | |||
| graph->connections.list.append(connectionToId); | |||
| } | |||
| rack->audio.mutex.unlock(); | |||
| graph->audio.mutex.unlock(); | |||
| for (LinkedList<MidiInPort>::Itenerator it=fMidiIns.begin(); it.valid(); it.next()) | |||
| { | |||
| const MidiInPort& inPort(it.getValue()); | |||
| const uint portId(rack->midi.getPortId(true, inPort.name)); | |||
| CARLA_SAFE_ASSERT_CONTINUE(portId < rack->midi.ins.count()); | |||
| const uint portId(graph->midi.getPortId(true, inPort.name)); | |||
| CARLA_SAFE_ASSERT_CONTINUE(portId < graph->midi.ins.count()); | |||
| ConnectionToId connectionToId; | |||
| connectionToId.setData(++(rack->connections.lastId), RACK_GRAPH_GROUP_MIDI_IN, portId, RACK_GRAPH_GROUP_CARLA, RACK_GRAPH_CARLA_PORT_MIDI_IN); | |||
| connectionToId.setData(++(graph->connections.lastId), RACK_GRAPH_GROUP_MIDI_IN, portId, RACK_GRAPH_GROUP_CARLA, RACK_GRAPH_CARLA_PORT_MIDI_IN); | |||
| std::snprintf(strBuf, STR_MAX, "%i:%i:%i:%i", connectionToId.groupA, connectionToId.portA, connectionToId.groupB, connectionToId.portB); | |||
| callback(ENGINE_CALLBACK_PATCHBAY_CONNECTION_ADDED, connectionToId.id, 0, 0, 0.0f, strBuf); | |||
| rack->connections.list.append(connectionToId); | |||
| graph->connections.list.append(connectionToId); | |||
| } | |||
| fMidiOutMutex.lock(); | |||
| @@ -565,17 +562,17 @@ public: | |||
| { | |||
| const MidiOutPort& outPort(it.getValue()); | |||
| const uint portId(rack->midi.getPortId(false, outPort.name)); | |||
| CARLA_SAFE_ASSERT_CONTINUE(portId < rack->midi.outs.count()); | |||
| const uint portId(graph->midi.getPortId(false, outPort.name)); | |||
| CARLA_SAFE_ASSERT_CONTINUE(portId < graph->midi.outs.count()); | |||
| ConnectionToId connectionToId; | |||
| connectionToId.setData(++(rack->connections.lastId), RACK_GRAPH_GROUP_CARLA, RACK_GRAPH_CARLA_PORT_MIDI_OUT, RACK_GRAPH_GROUP_MIDI_OUT, portId); | |||
| connectionToId.setData(++(graph->connections.lastId), RACK_GRAPH_GROUP_CARLA, RACK_GRAPH_CARLA_PORT_MIDI_OUT, RACK_GRAPH_GROUP_MIDI_OUT, portId); | |||
| std::snprintf(strBuf, STR_MAX, "%i:%i:%i:%i", connectionToId.groupA, connectionToId.portA, connectionToId.groupB, connectionToId.portB); | |||
| callback(ENGINE_CALLBACK_PATCHBAY_CONNECTION_ADDED, connectionToId.id, 0, 0, 0.0f, strBuf); | |||
| rack->connections.list.append(connectionToId); | |||
| graph->connections.list.append(connectionToId); | |||
| } | |||
| fMidiOutMutex.unlock(); | |||
| @@ -598,9 +595,6 @@ protected: | |||
| CARLA_SAFE_ASSERT_RETURN(outputBuffer != nullptr, runPendingRtEvents()); | |||
| CARLA_SAFE_ASSERT_RETURN(pData->bufferSize == nframes, runPendingRtEvents()); | |||
| if (! pData->graph.isReady) | |||
| return runPendingRtEvents(); | |||
| // initialize rtaudio input | |||
| const float* inBuf[fAudioInCount]; | |||
| @@ -651,13 +645,7 @@ protected: | |||
| fMidiInEvents.mutex.unlock(); | |||
| } | |||
| if (pData->graph.isRack) | |||
| { | |||
| pData->processRackFull(inBuf, fAudioInCount, outBuf, fAudioOutCount, nframes, false); | |||
| } | |||
| else | |||
| { | |||
| } | |||
| pData->graph.process(pData, inBuf, outBuf, nframes); | |||
| fMidiOutMutex.lock(); | |||
| @@ -723,9 +711,6 @@ protected: | |||
| void handleMidiCallback(double timeStamp, std::vector<uchar>* const message) | |||
| { | |||
| if (! pData->graph.isReady) | |||
| return; | |||
| const size_t messageSize(message->size()); | |||
| if (messageSize == 0 || messageSize > EngineMidiEvent::kDataSize) | |||
| @@ -764,8 +749,9 @@ protected: | |||
| CARLA_SAFE_ASSERT_RETURN(portName != nullptr && portName[0] != '\0', false); | |||
| carla_debug("CarlaEngineRtAudio::connectRackMidiInPort(\"%s\")", portName); | |||
| RackGraph* const rack((RackGraph*)pData->graph.graph); | |||
| CARLA_SAFE_ASSERT_RETURN(rack->midi.ins.count() > 0, false); | |||
| RackGraph* const graph(pData->graph.getRackGraph()); | |||
| CARLA_SAFE_ASSERT_RETURN(graph != nullptr, false); | |||
| CARLA_SAFE_ASSERT_RETURN(graph->midi.ins.count() > 0, false); | |||
| CarlaString newRtMidiPortName; | |||
| newRtMidiPortName += getName(); | |||
| @@ -818,8 +804,9 @@ protected: | |||
| CARLA_SAFE_ASSERT_RETURN(portName != nullptr && portName[0] != '\0', false); | |||
| carla_debug("CarlaEngineRtAudio::connectRackMidiOutPort(\"%s\")", portName); | |||
| RackGraph* const rack((RackGraph*)pData->graph.graph); | |||
| CARLA_SAFE_ASSERT_RETURN(rack->midi.ins.count() > 0, false); | |||
| RackGraph* const graph(pData->graph.getRackGraph()); | |||
| CARLA_SAFE_ASSERT_RETURN(graph != nullptr, false); | |||
| CARLA_SAFE_ASSERT_RETURN(graph->midi.ins.count() > 0, false); | |||
| CarlaString newRtMidiPortName; | |||
| newRtMidiPortName += getName(); | |||
| @@ -872,8 +859,9 @@ protected: | |||
| CARLA_SAFE_ASSERT_RETURN(portName != nullptr && portName[0] != '\0', false); | |||
| carla_debug("CarlaEngineRtAudio::disconnectRackMidiInPort(\"%s\")", portName); | |||
| RackGraph* const rack((RackGraph*)pData->graph.graph); | |||
| CARLA_SAFE_ASSERT_RETURN(rack->midi.ins.count() > 0, false); | |||
| RackGraph* const graph(pData->graph.getRackGraph()); | |||
| CARLA_SAFE_ASSERT_RETURN(graph != nullptr, false); | |||
| CARLA_SAFE_ASSERT_RETURN(graph->midi.ins.count() > 0, false); | |||
| for (LinkedList<MidiInPort>::Itenerator it=fMidiIns.begin(); it.valid(); it.next()) | |||
| { | |||
| @@ -899,8 +887,9 @@ protected: | |||
| CARLA_SAFE_ASSERT_RETURN(portName != nullptr && portName[0] != '\0', false); | |||
| carla_debug("CarlaEngineRtAudio::disconnectRackMidiOutPort(\"%s\")", portName); | |||
| RackGraph* const rack((RackGraph*)pData->graph.graph); | |||
| CARLA_SAFE_ASSERT_RETURN(rack->midi.outs.count() > 0, false); | |||
| RackGraph* const graph(pData->graph.getRackGraph()); | |||
| CARLA_SAFE_ASSERT_RETURN(graph != nullptr, false); | |||
| CARLA_SAFE_ASSERT_RETURN(graph->midi.outs.count() > 0, false); | |||
| const CarlaMutexLocker cml(fMidiOutMutex); | |||
| @@ -396,6 +396,7 @@ private: | |||
| Array<void*> renderingOps; | |||
| friend class AudioGraphIOProcessor; | |||
| friend class CarlaPluginInstance; | |||
| AudioSampleBuffer* currentAudioInputBuffer; | |||
| AudioSampleBuffer currentAudioOutputBuffer; | |||
| MidiBuffer* currentMidiInputBuffer; | |||
| @@ -17,7 +17,7 @@ | |||
| #include "CarlaNative.hpp" | |||
| #include "juce_audio_processors.h" | |||
| #include "JuceInternalFilters.hpp" | |||
| #include "juce_gui_extra.h" | |||
| #ifdef HAVE_X11 | |||
| @@ -32,12 +32,10 @@ namespace juce { | |||
| #include "jucepluginhost/juce_MidiKeyboardComponent.cpp" | |||
| #include "jucepluginhost/FilterGraph.h" | |||
| #include "jucepluginhost/InternalFilters.h" | |||
| #include "jucepluginhost/GraphEditorPanel.h" | |||
| #include "jucepluginhost/MainHostWindow.h" | |||
| #include "jucepluginhost/FilterGraph.cpp" | |||
| #include "jucepluginhost/InternalFilters.cpp" | |||
| #include "jucepluginhost/GraphEditorPanel.cpp" | |||
| #include "jucepluginhost/MainHostWindow.cpp" | |||
| @@ -57,7 +55,6 @@ public: | |||
| : NativePluginClass(host), | |||
| fFormatManager(), | |||
| fGraph(fFormatManager), | |||
| fAudioBuffer(1, 0), | |||
| fMidiKeyState(nullptr) | |||
| { | |||
| PropertiesFile::Options options; | |||
| @@ -1,89 +0,0 @@ | |||
| /* | |||
| ============================================================================== | |||
| This file is part of the JUCE library. | |||
| Copyright (c) 2013 - Raw Material Software Ltd. | |||
| Permission is granted to use this software under the terms of either: | |||
| a) the GPL v2 (or any later version) | |||
| b) the Affero GPL v3 | |||
| Details of these licenses can be found at: www.gnu.org/licenses | |||
| JUCE is distributed in the hope that it will be useful, but WITHOUT ANY | |||
| WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR | |||
| A PARTICULAR PURPOSE. See the GNU General Public License for more details. | |||
| ------------------------------------------------------------------------------ | |||
| To release a closed-source product which uses JUCE, commercial licenses are | |||
| available: visit www.juce.com for more information. | |||
| ============================================================================== | |||
| */ | |||
| #include "InternalFilters.h" | |||
| #include "FilterGraph.h" | |||
| //============================================================================== | |||
| InternalPluginFormat::InternalPluginFormat() | |||
| { | |||
| { | |||
| AudioProcessorGraph::AudioGraphIOProcessor p (AudioProcessorGraph::AudioGraphIOProcessor::audioOutputNode); | |||
| p.fillInPluginDescription (audioOutDesc); | |||
| } | |||
| { | |||
| AudioProcessorGraph::AudioGraphIOProcessor p (AudioProcessorGraph::AudioGraphIOProcessor::audioInputNode); | |||
| p.fillInPluginDescription (audioInDesc); | |||
| } | |||
| { | |||
| AudioProcessorGraph::AudioGraphIOProcessor p (AudioProcessorGraph::AudioGraphIOProcessor::midiInputNode); | |||
| p.fillInPluginDescription (midiInDesc); | |||
| } | |||
| { | |||
| AudioProcessorGraph::AudioGraphIOProcessor p (AudioProcessorGraph::AudioGraphIOProcessor::midiOutputNode); | |||
| p.fillInPluginDescription (midiOutDesc); | |||
| } | |||
| } | |||
| AudioPluginInstance* InternalPluginFormat::createInstanceFromDescription (const PluginDescription& desc, | |||
| double /*sampleRate*/, int /*blockSize*/) | |||
| { | |||
| if (desc.name == audioOutDesc.name) | |||
| return new AudioProcessorGraph::AudioGraphIOProcessor (AudioProcessorGraph::AudioGraphIOProcessor::audioOutputNode); | |||
| if (desc.name == audioInDesc.name) | |||
| return new AudioProcessorGraph::AudioGraphIOProcessor (AudioProcessorGraph::AudioGraphIOProcessor::audioInputNode); | |||
| if (desc.name == midiInDesc.name) | |||
| return new AudioProcessorGraph::AudioGraphIOProcessor (AudioProcessorGraph::AudioGraphIOProcessor::midiInputNode); | |||
| if (desc.name == midiOutDesc.name) | |||
| return new AudioProcessorGraph::AudioGraphIOProcessor (AudioProcessorGraph::AudioGraphIOProcessor::midiOutputNode); | |||
| return 0; | |||
| } | |||
| const PluginDescription* InternalPluginFormat::getDescriptionFor (const InternalFilterType type) | |||
| { | |||
| switch (type) | |||
| { | |||
| case audioInputFilter: return &audioInDesc; | |||
| case audioOutputFilter: return &audioOutDesc; | |||
| case midiInputFilter: return &midiInDesc; | |||
| case midiOutputFilter: return &midiOutDesc; | |||
| default: break; | |||
| } | |||
| return 0; | |||
| } | |||
| void InternalPluginFormat::getAllTypes (OwnedArray <PluginDescription>& results) | |||
| { | |||
| for (int i = 0; i < (int) endOfFilterTypes; ++i) | |||
| results.add (new PluginDescription (*getDescriptionFor ((InternalFilterType) i))); | |||
| } | |||
| @@ -1,78 +0,0 @@ | |||
| /* | |||
| ============================================================================== | |||
| This file is part of the JUCE library. | |||
| Copyright (c) 2013 - Raw Material Software Ltd. | |||
| Permission is granted to use this software under the terms of either: | |||
| a) the GPL v2 (or any later version) | |||
| b) the Affero GPL v3 | |||
| Details of these licenses can be found at: www.gnu.org/licenses | |||
| JUCE is distributed in the hope that it will be useful, but WITHOUT ANY | |||
| WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR | |||
| A PARTICULAR PURPOSE. See the GNU General Public License for more details. | |||
| ------------------------------------------------------------------------------ | |||
| To release a closed-source product which uses JUCE, commercial licenses are | |||
| available: visit www.juce.com for more information. | |||
| ============================================================================== | |||
| */ | |||
| #ifndef __INTERNALFILTERS_JUCEHEADER__ | |||
| #define __INTERNALFILTERS_JUCEHEADER__ | |||
| #include "FilterGraph.h" | |||
| //============================================================================== | |||
| /** | |||
| Manages the internal plugin types. | |||
| */ | |||
| class InternalPluginFormat : public AudioPluginFormat | |||
| { | |||
| public: | |||
| //============================================================================== | |||
| InternalPluginFormat(); | |||
| ~InternalPluginFormat() {} | |||
| //============================================================================== | |||
| enum InternalFilterType | |||
| { | |||
| audioInputFilter = 0, | |||
| audioOutputFilter, | |||
| midiInputFilter, | |||
| midiOutputFilter, | |||
| endOfFilterTypes | |||
| }; | |||
| const PluginDescription* getDescriptionFor (const InternalFilterType type); | |||
| void getAllTypes (OwnedArray <PluginDescription>& results); | |||
| //============================================================================== | |||
| String getName() const override { return "Internal"; } | |||
| bool fileMightContainThisPluginType (const String&) override { return false; } | |||
| FileSearchPath getDefaultLocationsToSearch() override { return FileSearchPath(); } | |||
| bool canScanForPlugins() const override { return false; } | |||
| void findAllTypesForFile (OwnedArray <PluginDescription>&, const String&) override {} | |||
| bool doesPluginStillExist (const PluginDescription&) override { return true; } | |||
| String getNameOfPluginFromIdentifier (const String& fileOrIdentifier) override { return fileOrIdentifier; } | |||
| bool pluginNeedsRescanning (const PluginDescription&) override { return false; } | |||
| StringArray searchPathsForPlugins (const FileSearchPath&, bool) override { return StringArray(); } | |||
| AudioPluginInstance* createInstanceFromDescription (const PluginDescription&, double, int) override; | |||
| private: | |||
| //============================================================================== | |||
| PluginDescription audioInDesc; | |||
| PluginDescription audioOutDesc; | |||
| PluginDescription midiInDesc; | |||
| PluginDescription midiOutDesc; | |||
| }; | |||
| #endif // __INTERNALFILTERS_JUCEHEADER__ | |||
| @@ -106,11 +106,7 @@ MainHostWindow::MainHostWindow (AudioPluginFormatManager& fm, FilterGraph& graph | |||
| //Process::setPriority (Process::HighPriority); | |||
| #if JUCE_MAC | |||
| setMacMainMenu (this); | |||
| #else | |||
| setMenuBar (this); | |||
| #endif | |||
| commandManager.setFirstCommandTarget (this); | |||
| commandManager.registerAllCommandsForTarget (this); | |||
| @@ -122,11 +118,7 @@ MainHostWindow::~MainHostWindow() | |||
| { | |||
| pluginListWindow = nullptr; | |||
| #if JUCE_MAC | |||
| setMacMainMenu (nullptr); | |||
| #else | |||
| setMenuBar (nullptr); | |||
| #endif | |||
| knownPluginList.removeChangeListener (this); | |||
| @@ -71,6 +71,7 @@ LIBS += ../backend/carla_plugin.a | |||
| LIBS += ../modules/native-plugins.a | |||
| LIBS += ../modules/jackbridge.a | |||
| LIBS += ../modules/juce_audio_basics.a | |||
| LIBS += ../modules/juce_audio_processors.a | |||
| LIBS += ../modules/juce_core.a | |||
| LIBS += ../modules/juce_events.a | |||
| LIBS += ../modules/rtmempool.a | |||
| @@ -84,7 +85,6 @@ LIBS += ../modules/dgl.a | |||
| endif | |||
| ifeq ($(HAVE_JUCE_UI),true) | |||
| LIBS += ../modules/juce_audio_processors.a | |||
| LIBS += ../modules/juce_data_structures.a | |||
| LIBS += ../modules/juce_graphics.a | |||
| LIBS += ../modules/juce_gui_basics.a | |||
| @@ -0,0 +1,132 @@ | |||
| /* | |||
| * Juce Internal Filters | |||
| * Copyright (c) 2013 Raw Material Software Ltd. | |||
| * Copyright (C) 2014 Filipe Coelho <falktx@falktx.com> | |||
| * | |||
| * This program is free software; you can redistribute it and/or | |||
| * modify it under the terms of the GNU General Public License as | |||
| * published by the Free Software Foundation; either version 2 of | |||
| * the License, or any later version. | |||
| * | |||
| * This program is distributed in the hope that it will be useful, | |||
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
| * GNU General Public License for more details. | |||
| * | |||
| * For a full copy of the GNU General Public License see the doc/GPL.txt file. | |||
| */ | |||
| #ifndef JUCE_INTERNAL_FILTERS_HPP_INCLUDED | |||
| #define JUCE_INTERNAL_FILTERS_HPP_INCLUDED | |||
| #include "juce_audio_processors.h" | |||
| // ----------------------------------------------------------------------- | |||
| namespace juce { | |||
| class InternalPluginFormat : public AudioPluginFormat | |||
| { | |||
| public: | |||
| enum InternalFilterType | |||
| { | |||
| audioInputFilter = 0, | |||
| audioOutputFilter, | |||
| midiInputFilter, | |||
| midiOutputFilter, | |||
| endOfFilterTypes | |||
| }; | |||
| InternalPluginFormat() | |||
| { | |||
| { | |||
| AudioProcessorGraph::AudioGraphIOProcessor p(AudioProcessorGraph::AudioGraphIOProcessor::audioOutputNode); | |||
| p.fillInPluginDescription(audioOutDesc); | |||
| } | |||
| { | |||
| AudioProcessorGraph::AudioGraphIOProcessor p(AudioProcessorGraph::AudioGraphIOProcessor::audioInputNode); | |||
| p.fillInPluginDescription(audioInDesc); | |||
| } | |||
| { | |||
| AudioProcessorGraph::AudioGraphIOProcessor p(AudioProcessorGraph::AudioGraphIOProcessor::midiInputNode); | |||
| p.fillInPluginDescription(midiInDesc); | |||
| } | |||
| { | |||
| AudioProcessorGraph::AudioGraphIOProcessor p(AudioProcessorGraph::AudioGraphIOProcessor::midiOutputNode); | |||
| p.fillInPluginDescription(midiOutDesc); | |||
| } | |||
| } | |||
| // ------------------------------------------------------------------- | |||
| const PluginDescription* getDescriptionFor(const InternalFilterType type) | |||
| { | |||
| switch (type) | |||
| { | |||
| case audioInputFilter: | |||
| return &audioInDesc; | |||
| case audioOutputFilter: | |||
| return &audioOutDesc; | |||
| case midiInputFilter: | |||
| return &midiInDesc; | |||
| case midiOutputFilter: | |||
| return &midiOutDesc; | |||
| default: | |||
| return nullptr; | |||
| } | |||
| } | |||
| void getAllTypes(OwnedArray <PluginDescription>& results) override | |||
| { | |||
| for (int i = 0; i < (int) endOfFilterTypes; ++i) | |||
| results.add(new PluginDescription(*getDescriptionFor((InternalFilterType)i))); | |||
| } | |||
| AudioPluginInstance* createInstanceFromDescription(const PluginDescription& desc, double, int) override | |||
| { | |||
| if (desc.name == audioOutDesc.name) | |||
| return new AudioProcessorGraph::AudioGraphIOProcessor(AudioProcessorGraph::AudioGraphIOProcessor::audioOutputNode); | |||
| if (desc.name == audioInDesc.name) | |||
| return new AudioProcessorGraph::AudioGraphIOProcessor(AudioProcessorGraph::AudioGraphIOProcessor::audioInputNode); | |||
| if (desc.name == midiInDesc.name) | |||
| return new AudioProcessorGraph::AudioGraphIOProcessor(AudioProcessorGraph::AudioGraphIOProcessor::midiInputNode); | |||
| if (desc.name == midiOutDesc.name) | |||
| return new AudioProcessorGraph::AudioGraphIOProcessor(AudioProcessorGraph::AudioGraphIOProcessor::midiOutputNode); | |||
| return nullptr; | |||
| } | |||
| // ------------------------------------------------------------------- | |||
| String getName() const override { return "Internal"; } | |||
| bool fileMightContainThisPluginType(const String&) override { return false; } | |||
| FileSearchPath getDefaultLocationsToSearch() override { return FileSearchPath(); } | |||
| bool canScanForPlugins() const override { return false; } | |||
| bool doesPluginStillExist(const PluginDescription&) override { return true; } | |||
| String getNameOfPluginFromIdentifier(const String& fileOrIdentifier) override { return fileOrIdentifier; } | |||
| bool pluginNeedsRescanning(const PluginDescription&) override { return false; } | |||
| StringArray searchPathsForPlugins(const FileSearchPath&, bool) override { return StringArray(); } | |||
| void findAllTypesForFile(OwnedArray <PluginDescription>&, const String&) override {} | |||
| // ------------------------------------------------------------------- | |||
| private: | |||
| PluginDescription audioInDesc; | |||
| PluginDescription audioOutDesc; | |||
| PluginDescription midiInDesc; | |||
| PluginDescription midiOutDesc; | |||
| }; | |||
| } // namespace juce | |||
| typedef juce::InternalPluginFormat JuceInternalPluginFormat; | |||
| // ----------------------------------------------------------------------- | |||
| #endif // JUCE_INTERNAL_FILTERS_HPP_INCLUDED | |||