@@ -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 |