Signed-off-by: falkTX <falktx@falktx.com>tags/v2.1-rc1
@@ -78,6 +78,16 @@ typedef struct _CarlaCachedPluginInfo { | |||||
*/ | */ | ||||
uint32_t audioOuts; | uint32_t audioOuts; | ||||
/*! | |||||
* Number of CV inputs. | |||||
*/ | |||||
uint32_t cvIns; | |||||
/*! | |||||
* Number of CV outputs. | |||||
*/ | |||||
uint32_t cvOuts; | |||||
/*! | /*! | ||||
* Number of MIDI inputs. | * Number of MIDI inputs. | ||||
*/ | */ | ||||
@@ -72,7 +72,7 @@ public: | |||||
pData->sampleRate = pData->options.audioSampleRate; | pData->sampleRate = pData->options.audioSampleRate; | ||||
pData->initTime(pData->options.transportExtra); | pData->initTime(pData->options.transportExtra); | ||||
pData->graph.create(2, 2); | |||||
pData->graph.create(2, 2, 0, 0); | |||||
if (! startThread(true)) | if (! startThread(true)) | ||||
{ | { | ||||
@@ -1413,11 +1413,6 @@ public: | |||||
return fPlugin->getName(); | return fPlugin->getName(); | ||||
} | } | ||||
void processBlock(AudioSampleBuffer&, MidiBuffer&) override | |||||
{ | |||||
carla_stderr2("CarlaPluginInstance::processBlock called, this is wrong!"); | |||||
} | |||||
void processBlockWithCV(AudioSampleBuffer& audio, | void processBlockWithCV(AudioSampleBuffer& audio, | ||||
const AudioSampleBuffer& cvIn, | const AudioSampleBuffer& cvIn, | ||||
AudioSampleBuffer& cvOut, | AudioSampleBuffer& cvOut, | ||||
@@ -1605,14 +1600,20 @@ private: | |||||
StringArray outputNames; | StringArray outputNames; | ||||
}; | }; | ||||
PatchbayGraph::PatchbayGraph(CarlaEngine* const engine, const uint32_t ins, const uint32_t outs) | |||||
PatchbayGraph::PatchbayGraph(CarlaEngine* const engine, | |||||
const uint32_t audioIns, const uint32_t audioOuts, | |||||
const uint32_t cvIns, const uint32_t cvOuts) | |||||
: CarlaThread("PatchbayReorderThread"), | : CarlaThread("PatchbayReorderThread"), | ||||
connections(), | connections(), | ||||
graph(), | graph(), | ||||
audioBuffer(), | audioBuffer(), | ||||
cvInBuffer(), | |||||
cvOutBuffer(), | |||||
midiBuffer(), | midiBuffer(), | ||||
inputs(carla_fixedValue(0U, 64U, ins)), | |||||
outputs(carla_fixedValue(0U, 64U, outs)), | |||||
numAudioIns(carla_fixedValue(0U, 64U, audioIns)), | |||||
numAudioOuts(carla_fixedValue(0U, 64U, audioOuts)), | |||||
numCVIns(carla_fixedValue(0U, 8U, cvIns)), | |||||
numCVOuts(carla_fixedValue(0U, 8U, cvOuts)), | |||||
retCon(), | retCon(), | ||||
usingExternalHost(false), | usingExternalHost(false), | ||||
usingExternalOSC(false), | usingExternalOSC(false), | ||||
@@ -1622,17 +1623,22 @@ PatchbayGraph::PatchbayGraph(CarlaEngine* const engine, const uint32_t ins, cons | |||||
const uint32_t bufferSize(engine->getBufferSize()); | const uint32_t bufferSize(engine->getBufferSize()); | ||||
const double sampleRate(engine->getSampleRate()); | const double sampleRate(engine->getSampleRate()); | ||||
graph.setPlayConfigDetails(inputs, outputs, 0, 0, 1, 1, sampleRate, static_cast<int>(bufferSize)); | |||||
graph.setPlayConfigDetails(numAudioIns, numAudioOuts, | |||||
numCVIns, numCVOuts, | |||||
1, 1, | |||||
sampleRate, static_cast<int>(bufferSize)); | |||||
graph.prepareToPlay(sampleRate, static_cast<int>(bufferSize)); | graph.prepareToPlay(sampleRate, static_cast<int>(bufferSize)); | ||||
audioBuffer.setSize(jmax(inputs, outputs), bufferSize); | |||||
audioBuffer.setSize(jmax(numAudioIns, numAudioOuts), bufferSize); | |||||
cvInBuffer.setSize(numCVIns, bufferSize); | |||||
cvOutBuffer.setSize(numCVOuts, bufferSize); | |||||
midiBuffer.ensureSize(kMaxEngineEventInternalCount*2); | midiBuffer.ensureSize(kMaxEngineEventInternalCount*2); | ||||
midiBuffer.clear(); | midiBuffer.clear(); | ||||
StringArray channelNames; | StringArray channelNames; | ||||
switch (inputs) | |||||
switch (numAudioIns) | |||||
{ | { | ||||
case 2: | case 2: | ||||
channelNames.add("Left"); | channelNames.add("Left"); | ||||
@@ -1645,6 +1651,7 @@ PatchbayGraph::PatchbayGraph(CarlaEngine* const engine, const uint32_t ins, cons | |||||
break; | break; | ||||
} | } | ||||
if (numAudioIns != 0) | |||||
{ | { | ||||
NamedAudioGraphIOProcessor* const proc( | NamedAudioGraphIOProcessor* const proc( | ||||
new NamedAudioGraphIOProcessor(NamedAudioGraphIOProcessor::audioInputNode)); | new NamedAudioGraphIOProcessor(NamedAudioGraphIOProcessor::audioInputNode)); | ||||
@@ -1659,6 +1666,7 @@ PatchbayGraph::PatchbayGraph(CarlaEngine* const engine, const uint32_t ins, cons | |||||
node->properties.set("isOSC", false); | node->properties.set("isOSC", false); | ||||
} | } | ||||
if (numAudioOuts != 0) | |||||
{ | { | ||||
NamedAudioGraphIOProcessor* const proc( | NamedAudioGraphIOProcessor* const proc( | ||||
new NamedAudioGraphIOProcessor(NamedAudioGraphIOProcessor::audioOutputNode)); | new NamedAudioGraphIOProcessor(NamedAudioGraphIOProcessor::audioOutputNode)); | ||||
@@ -1673,6 +1681,36 @@ PatchbayGraph::PatchbayGraph(CarlaEngine* const engine, const uint32_t ins, cons | |||||
node->properties.set("isOSC", false); | node->properties.set("isOSC", false); | ||||
} | } | ||||
if (numCVIns != 0) | |||||
{ | |||||
NamedAudioGraphIOProcessor* const proc( | |||||
new NamedAudioGraphIOProcessor(NamedAudioGraphIOProcessor::cvInputNode)); | |||||
// proc->setNames(false, channelNames); | |||||
AudioProcessorGraph::Node* const node(graph.addNode(proc)); | |||||
node->properties.set("isPlugin", false); | |||||
node->properties.set("isOutput", false); | |||||
node->properties.set("isAudio", false); | |||||
node->properties.set("isCV", true); | |||||
node->properties.set("isMIDI", false); | |||||
node->properties.set("isOSC", false); | |||||
} | |||||
if (numCVOuts != 0) | |||||
{ | |||||
NamedAudioGraphIOProcessor* const proc( | |||||
new NamedAudioGraphIOProcessor(NamedAudioGraphIOProcessor::cvOutputNode)); | |||||
// proc->setNames(true, channelNames); | |||||
AudioProcessorGraph::Node* const node(graph.addNode(proc)); | |||||
node->properties.set("isPlugin", false); | |||||
node->properties.set("isOutput", false); | |||||
node->properties.set("isAudio", false); | |||||
node->properties.set("isCV", true); | |||||
node->properties.set("isMIDI", false); | |||||
node->properties.set("isOSC", false); | |||||
} | |||||
{ | { | ||||
NamedAudioGraphIOProcessor* const proc( | NamedAudioGraphIOProcessor* const proc( | ||||
new NamedAudioGraphIOProcessor(NamedAudioGraphIOProcessor::midiInputNode)); | new NamedAudioGraphIOProcessor(NamedAudioGraphIOProcessor::midiInputNode)); | ||||
@@ -1710,6 +1748,8 @@ PatchbayGraph::~PatchbayGraph() | |||||
graph.releaseResources(); | graph.releaseResources(); | ||||
graph.clear(); | graph.clear(); | ||||
audioBuffer.clear(); | audioBuffer.clear(); | ||||
cvInBuffer.clear(); | |||||
cvOutBuffer.clear(); | |||||
} | } | ||||
void PatchbayGraph::setBufferSize(const uint32_t bufferSize) | void PatchbayGraph::setBufferSize(const uint32_t bufferSize) | ||||
@@ -1719,6 +1759,8 @@ void PatchbayGraph::setBufferSize(const uint32_t bufferSize) | |||||
graph.releaseResources(); | graph.releaseResources(); | ||||
graph.prepareToPlay(kEngine->getSampleRate(), static_cast<int>(bufferSize)); | graph.prepareToPlay(kEngine->getSampleRate(), static_cast<int>(bufferSize)); | ||||
audioBuffer.setSize(audioBuffer.getNumChannels(), bufferSize); | audioBuffer.setSize(audioBuffer.getNumChannels(), bufferSize); | ||||
cvInBuffer.setSize(numCVIns, bufferSize); | |||||
cvOutBuffer.setSize(numCVOuts, bufferSize); | |||||
} | } | ||||
void PatchbayGraph::setSampleRate(const double sampleRate) | void PatchbayGraph::setSampleRate(const double sampleRate) | ||||
@@ -2175,7 +2217,10 @@ bool PatchbayGraph::getGroupAndPortIdFromFullName(const bool external, const cha | |||||
return false; | return false; | ||||
} | } | ||||
void PatchbayGraph::process(CarlaEngine::ProtectedData* const data, const float* const* const inBuf, float* const* const outBuf, const uint32_t frames) | |||||
void PatchbayGraph::process(CarlaEngine::ProtectedData* const data, | |||||
const float* const* const inBuf, | |||||
float* const* const outBuf, | |||||
const uint32_t frames) | |||||
{ | { | ||||
CARLA_SAFE_ASSERT_RETURN(data != nullptr,); | CARLA_SAFE_ASSERT_RETURN(data != nullptr,); | ||||
CARLA_SAFE_ASSERT_RETURN(data->events.in != nullptr,); | CARLA_SAFE_ASSERT_RETURN(data->events.in != nullptr,); | ||||
@@ -2188,29 +2233,48 @@ void PatchbayGraph::process(CarlaEngine::ProtectedData* const data, const float* | |||||
fillWaterMidiBufferFromEngineEvents(midiBuffer, data->events.in); | fillWaterMidiBufferFromEngineEvents(midiBuffer, data->events.in); | ||||
} | } | ||||
// set audio buffer size, needed for water internals | |||||
// set audio and cv buffer size, needed for water internals | |||||
if (! audioBuffer.setSizeRT(frames)) | if (! audioBuffer.setSizeRT(frames)) | ||||
return; | return; | ||||
if (! cvInBuffer.setSizeRT(frames)) | |||||
return; | |||||
if (! cvOutBuffer.setSizeRT(frames)) | |||||
return; | |||||
// put carla audio in water buffer | |||||
// put carla audio and cv in water buffer | |||||
{ | { | ||||
uint32_t i=0; | uint32_t i=0; | ||||
for (; i < inputs; ++i) | |||||
for (; i < numAudioIns; ++i) { | |||||
CARLA_SAFE_ASSERT_BREAK(inBuf[i]); | |||||
audioBuffer.copyFrom(i, 0, inBuf[i], frames); | audioBuffer.copyFrom(i, 0, inBuf[i], frames); | ||||
} | |||||
for (uint32_t j=0; j < numCVIns; ++j, ++i) { | |||||
CARLA_SAFE_ASSERT_BREAK(inBuf[i]); | |||||
cvInBuffer.copyFrom(j, 0, inBuf[i], frames); | |||||
} | |||||
// clear remaining channels | // clear remaining channels | ||||
for (const uint32_t count=audioBuffer.getNumChannels(); i<count; ++i) | |||||
audioBuffer.clear(i, 0, frames); | |||||
for (uint32_t j=numAudioIns, count=audioBuffer.getNumChannels(); j < count; ++j) | |||||
audioBuffer.clear(j, 0, frames); | |||||
for (uint32_t j=0; j < numCVOuts; ++j) | |||||
cvOutBuffer.clear(j, 0, frames); | |||||
} | } | ||||
// ready to go! | // ready to go! | ||||
graph.processBlock(audioBuffer, midiBuffer); | |||||
graph.processBlockWithCV(audioBuffer, cvInBuffer, cvOutBuffer, midiBuffer); | |||||
// put water audio in carla buffer | |||||
// put water audio and cv in carla buffer | |||||
{ | { | ||||
for (uint32_t i=0; i < outputs; ++i) | |||||
uint32_t i=0; | |||||
for (; i < numAudioOuts; ++i) | |||||
carla_copyFloats(outBuf[i], audioBuffer.getReadPointer(i), frames); | carla_copyFloats(outBuf[i], audioBuffer.getReadPointer(i), frames); | ||||
for (uint32_t j=0; j < numCVOuts; ++j, ++i) | |||||
carla_copyFloats(outBuf[i], cvOutBuffer.getReadPointer(j), frames); | |||||
} | } | ||||
// put water events in carla buffer | // put water events in carla buffer | ||||
@@ -2245,19 +2309,20 @@ EngineInternalGraph::~EngineInternalGraph() noexcept | |||||
CARLA_SAFE_ASSERT(fRack == nullptr); | CARLA_SAFE_ASSERT(fRack == nullptr); | ||||
} | } | ||||
void EngineInternalGraph::create(const uint32_t inputs, const uint32_t outputs) | |||||
void EngineInternalGraph::create(const uint32_t audioIns, const uint32_t audioOuts, | |||||
const uint32_t cvIns, const uint32_t cvOuts) | |||||
{ | { | ||||
fIsRack = (kEngine->getOptions().processMode == ENGINE_PROCESS_MODE_CONTINUOUS_RACK); | fIsRack = (kEngine->getOptions().processMode == ENGINE_PROCESS_MODE_CONTINUOUS_RACK); | ||||
if (fIsRack) | if (fIsRack) | ||||
{ | { | ||||
CARLA_SAFE_ASSERT_RETURN(fRack == nullptr,); | CARLA_SAFE_ASSERT_RETURN(fRack == nullptr,); | ||||
fRack = new RackGraph(kEngine, inputs, outputs); | |||||
fRack = new RackGraph(kEngine, audioIns, audioOuts); | |||||
} | } | ||||
else | else | ||||
{ | { | ||||
CARLA_SAFE_ASSERT_RETURN(fPatchbay == nullptr,); | CARLA_SAFE_ASSERT_RETURN(fPatchbay == nullptr,); | ||||
fPatchbay = new PatchbayGraph(kEngine, inputs, outputs); | |||||
fPatchbay = new PatchbayGraph(kEngine, audioIns, audioOuts, cvIns, cvOuts); | |||||
} | } | ||||
fIsReady = true; | fIsReady = true; | ||||
@@ -157,16 +157,22 @@ public: | |||||
PatchbayConnectionList connections; | PatchbayConnectionList connections; | ||||
AudioProcessorGraph graph; | AudioProcessorGraph graph; | ||||
AudioSampleBuffer audioBuffer; | AudioSampleBuffer audioBuffer; | ||||
AudioSampleBuffer cvInBuffer; | |||||
AudioSampleBuffer cvOutBuffer; | |||||
MidiBuffer midiBuffer; | MidiBuffer midiBuffer; | ||||
const uint32_t inputs; | |||||
const uint32_t outputs; | |||||
const uint32_t numAudioIns; | |||||
const uint32_t numAudioOuts; | |||||
const uint32_t numCVIns; | |||||
const uint32_t numCVOuts; | |||||
mutable CharStringListPtr retCon; | mutable CharStringListPtr retCon; | ||||
bool usingExternalHost; | bool usingExternalHost; | ||||
bool usingExternalOSC; | bool usingExternalOSC; | ||||
ExternalGraph extGraph; | ExternalGraph extGraph; | ||||
PatchbayGraph(CarlaEngine* const engine, const uint32_t inputs, const uint32_t outputs); | |||||
PatchbayGraph(CarlaEngine* const engine, | |||||
const uint32_t audioIns, const uint32_t audioOuts, | |||||
const uint32_t cvIns, const uint32_t cvOuts); | |||||
~PatchbayGraph(); | ~PatchbayGraph(); | ||||
void setBufferSize(const uint32_t bufferSize); | void setBufferSize(const uint32_t bufferSize); | ||||
@@ -187,7 +193,10 @@ public: | |||||
const char* const* getConnections(const bool external) const; | const char* const* getConnections(const bool external) const; | ||||
bool getGroupAndPortIdFromFullName(const bool external, const char* const fullPortName, uint& groupId, uint& portId) const; | bool getGroupAndPortIdFromFullName(const bool external, const char* const fullPortName, uint& groupId, uint& portId) const; | ||||
void process(CarlaEngine::ProtectedData* const data, const float* const* const inBuf, float* const* const outBuf, const uint32_t frames); | |||||
void process(CarlaEngine::ProtectedData* const data, | |||||
const float* const* const inBuf, | |||||
float* const* const outBuf, | |||||
const uint32_t frames); | |||||
private: | private: | ||||
void run() override; | void run() override; | ||||
@@ -74,7 +74,7 @@ public: | |||||
EngineInternalGraph(CarlaEngine* const engine) noexcept; | EngineInternalGraph(CarlaEngine* const engine) noexcept; | ||||
~EngineInternalGraph() noexcept; | ~EngineInternalGraph() noexcept; | ||||
void create(const uint32_t inputs, const uint32_t outputs); | |||||
void create(const uint32_t audioIns, const uint32_t audioOuts, const uint32_t cvIns, const uint32_t cvOuts); | |||||
void destroy() noexcept; | void destroy() noexcept; | ||||
void setBufferSize(const uint32_t bufferSize); | void setBufferSize(const uint32_t bufferSize); | ||||
@@ -1004,11 +1004,11 @@ public: | |||||
if (opts.processMode == ENGINE_PROCESS_MODE_CONTINUOUS_RACK) | if (opts.processMode == ENGINE_PROCESS_MODE_CONTINUOUS_RACK) | ||||
{ | { | ||||
// FIXME? | // FIXME? | ||||
pData->graph.create(0, 0); | |||||
pData->graph.create(0, 0, 0, 0); | |||||
} | } | ||||
else | else | ||||
{ | { | ||||
pData->graph.create(2, 2); | |||||
pData->graph.create(2, 2, 0, 0); | |||||
// pData->graph.setUsingExternalHost(true); | // pData->graph.setUsingExternalHost(true); | ||||
// pData->graph.setUsingExternalOSC(true); | // pData->graph.setUsingExternalOSC(true); | ||||
patchbayRefresh(true, false, false); | patchbayRefresh(true, false, false); | ||||
@@ -218,7 +218,9 @@ public: | |||||
pData->sampleRate = fDevice->getCurrentSampleRate(); | pData->sampleRate = fDevice->getCurrentSampleRate(); | ||||
pData->initTime(pData->options.transportExtra); | pData->initTime(pData->options.transportExtra); | ||||
pData->graph.create(static_cast<uint32_t>(inputNames.size()), static_cast<uint32_t>(outputNames.size())); | |||||
pData->graph.create(static_cast<uint32_t>(inputNames.size()), | |||||
static_cast<uint32_t>(outputNames.size()), | |||||
0, 0); | |||||
fDevice->start(this); | fDevice->start(this); | ||||
@@ -163,7 +163,8 @@ class CarlaEngineNative : public CarlaEngine | |||||
{ | { | ||||
public: | public: | ||||
CarlaEngineNative(const NativeHostDescriptor* const host, const bool isPatchbay, const bool withMidiOut, | CarlaEngineNative(const NativeHostDescriptor* const host, const bool isPatchbay, const bool withMidiOut, | ||||
const uint32_t inChan = 2, uint32_t outChan = 2) | |||||
const uint32_t inChan = 2, uint32_t outChan = 2, | |||||
const uint32_t cvIns = 0, const uint32_t cvOuts = 0) | |||||
: CarlaEngine(), | : CarlaEngine(), | ||||
pHost(host), | pHost(host), | ||||
#ifdef USE_JUCE_MESSAGE_THREAD | #ifdef USE_JUCE_MESSAGE_THREAD | ||||
@@ -211,7 +212,7 @@ public: | |||||
pData->options.preferPluginBridges = false; | pData->options.preferPluginBridges = false; | ||||
pData->options.preferUiBridges = false; | pData->options.preferUiBridges = false; | ||||
init("Carla-Patchbay"); | init("Carla-Patchbay"); | ||||
pData->graph.create(inChan, outChan); | |||||
pData->graph.create(inChan, outChan, cvIns, cvOuts); | |||||
} | } | ||||
else | else | ||||
{ | { | ||||
@@ -223,7 +224,7 @@ public: | |||||
pData->options.preferPluginBridges = false; | pData->options.preferPluginBridges = false; | ||||
pData->options.preferUiBridges = false; | pData->options.preferUiBridges = false; | ||||
init("Carla-Rack"); | init("Carla-Rack"); | ||||
pData->graph.create(0, 0); // FIXME? | |||||
pData->graph.create(0, 0, 0, 0); // FIXME? | |||||
} | } | ||||
if (pData->options.resourceDir != nullptr) | if (pData->options.resourceDir != nullptr) | ||||
@@ -1567,6 +1568,11 @@ public: | |||||
return new CarlaEngineNative(host, true, true, 64, 64); | return new CarlaEngineNative(host, true, true, 64, 64); | ||||
} | } | ||||
static NativePluginHandle _instantiatePatchbayCV(const NativeHostDescriptor* host) | |||||
{ | |||||
return new CarlaEngineNative(host, true, true, 2, 2, 5, 5); | |||||
} | |||||
static void _cleanup(NativePluginHandle handle) | static void _cleanup(NativePluginHandle handle) | ||||
{ | { | ||||
delete handlePtr; | delete handlePtr; | ||||
@@ -2345,7 +2351,9 @@ static const NativePluginDescriptor carlaRackDesc = { | |||||
CarlaEngineNative::_get_state, | CarlaEngineNative::_get_state, | ||||
CarlaEngineNative::_set_state, | CarlaEngineNative::_set_state, | ||||
CarlaEngineNative::_dispatcher, | CarlaEngineNative::_dispatcher, | ||||
/* _render_inline_dsplay */ nullptr | |||||
/* _render_inline_dsplay */ nullptr, | |||||
/* cvIns */ 0, | |||||
/* cvOuts */ 0 | |||||
}; | }; | ||||
static const NativePluginDescriptor carlaRackNoMidiOutDesc = { | static const NativePluginDescriptor carlaRackNoMidiOutDesc = { | ||||
@@ -2387,7 +2395,9 @@ static const NativePluginDescriptor carlaRackNoMidiOutDesc = { | |||||
CarlaEngineNative::_get_state, | CarlaEngineNative::_get_state, | ||||
CarlaEngineNative::_set_state, | CarlaEngineNative::_set_state, | ||||
CarlaEngineNative::_dispatcher, | CarlaEngineNative::_dispatcher, | ||||
/* _render_inline_dsplay */ nullptr | |||||
/* _render_inline_dsplay */ nullptr, | |||||
/* cvIns */ 0, | |||||
/* cvOuts */ 0 | |||||
}; | }; | ||||
static const NativePluginDescriptor carlaPatchbayDesc = { | static const NativePluginDescriptor carlaPatchbayDesc = { | ||||
@@ -2429,7 +2439,9 @@ static const NativePluginDescriptor carlaPatchbayDesc = { | |||||
CarlaEngineNative::_get_state, | CarlaEngineNative::_get_state, | ||||
CarlaEngineNative::_set_state, | CarlaEngineNative::_set_state, | ||||
CarlaEngineNative::_dispatcher, | CarlaEngineNative::_dispatcher, | ||||
/* _render_inline_dsplay */ nullptr | |||||
/* _render_inline_dsplay */ nullptr, | |||||
/* cvIns */ 0, | |||||
/* cvOuts */ 0 | |||||
}; | }; | ||||
static const NativePluginDescriptor carlaPatchbay3sDesc = { | static const NativePluginDescriptor carlaPatchbay3sDesc = { | ||||
@@ -2471,7 +2483,9 @@ static const NativePluginDescriptor carlaPatchbay3sDesc = { | |||||
CarlaEngineNative::_get_state, | CarlaEngineNative::_get_state, | ||||
CarlaEngineNative::_set_state, | CarlaEngineNative::_set_state, | ||||
CarlaEngineNative::_dispatcher, | CarlaEngineNative::_dispatcher, | ||||
/* _render_inline_dsplay */ nullptr | |||||
/* _render_inline_dsplay */ nullptr, | |||||
/* cvIns */ 0, | |||||
/* cvOuts */ 0 | |||||
}; | }; | ||||
static const NativePluginDescriptor carlaPatchbay16Desc = { | static const NativePluginDescriptor carlaPatchbay16Desc = { | ||||
@@ -2513,7 +2527,9 @@ static const NativePluginDescriptor carlaPatchbay16Desc = { | |||||
CarlaEngineNative::_get_state, | CarlaEngineNative::_get_state, | ||||
CarlaEngineNative::_set_state, | CarlaEngineNative::_set_state, | ||||
CarlaEngineNative::_dispatcher, | CarlaEngineNative::_dispatcher, | ||||
/* _render_inline_dsplay */ nullptr | |||||
/* _render_inline_dsplay */ nullptr, | |||||
/* cvIns */ 0, | |||||
/* cvOuts */ 0 | |||||
}; | }; | ||||
static const NativePluginDescriptor carlaPatchbay32Desc = { | static const NativePluginDescriptor carlaPatchbay32Desc = { | ||||
@@ -2555,7 +2571,9 @@ static const NativePluginDescriptor carlaPatchbay32Desc = { | |||||
CarlaEngineNative::_get_state, | CarlaEngineNative::_get_state, | ||||
CarlaEngineNative::_set_state, | CarlaEngineNative::_set_state, | ||||
CarlaEngineNative::_dispatcher, | CarlaEngineNative::_dispatcher, | ||||
/* _render_inline_dsplay */ nullptr | |||||
/* _render_inline_dsplay */ nullptr, | |||||
/* cvIns */ 0, | |||||
/* cvOuts */ 0 | |||||
}; | }; | ||||
static const NativePluginDescriptor carlaPatchbay64Desc = { | static const NativePluginDescriptor carlaPatchbay64Desc = { | ||||
@@ -2597,7 +2615,54 @@ static const NativePluginDescriptor carlaPatchbay64Desc = { | |||||
CarlaEngineNative::_get_state, | CarlaEngineNative::_get_state, | ||||
CarlaEngineNative::_set_state, | CarlaEngineNative::_set_state, | ||||
CarlaEngineNative::_dispatcher, | CarlaEngineNative::_dispatcher, | ||||
/* _render_inline_dsplay */ nullptr | |||||
/* _render_inline_dsplay */ nullptr, | |||||
/* cvIns */ 0, | |||||
/* cvOuts */ 0 | |||||
}; | |||||
static const NativePluginDescriptor carlaPatchbayCVDesc = { | |||||
/* category */ NATIVE_PLUGIN_CATEGORY_OTHER, | |||||
/* hints */ static_cast<NativePluginHints>(NATIVE_PLUGIN_IS_SYNTH | |||||
|NATIVE_PLUGIN_HAS_UI | |||||
|NATIVE_PLUGIN_NEEDS_UI_MAIN_THREAD | |||||
|NATIVE_PLUGIN_USES_CONTROL_VOLTAGE | |||||
|NATIVE_PLUGIN_USES_STATE | |||||
|NATIVE_PLUGIN_USES_TIME), | |||||
/* supports */ static_cast<NativePluginSupports>(NATIVE_PLUGIN_SUPPORTS_EVERYTHING), | |||||
/* audioIns */ 2, | |||||
/* audioOuts */ 2, | |||||
/* midiIns */ 1, | |||||
/* midiOuts */ 1, | |||||
/* paramIns */ kNumInParams, | |||||
/* paramOuts */ kNumOutParams, | |||||
/* name */ "Carla-Patchbay (CV)", | |||||
/* label */ "carlapatchbaycv", | |||||
/* maker */ "falkTX", | |||||
/* copyright */ "GNU GPL v2+", | |||||
CarlaEngineNative::_instantiatePatchbayCV, | |||||
CarlaEngineNative::_cleanup, | |||||
CarlaEngineNative::_get_parameter_count, | |||||
CarlaEngineNative::_get_parameter_info, | |||||
CarlaEngineNative::_get_parameter_value, | |||||
CarlaEngineNative::_get_midi_program_count, | |||||
CarlaEngineNative::_get_midi_program_info, | |||||
CarlaEngineNative::_set_parameter_value, | |||||
CarlaEngineNative::_set_midi_program, | |||||
/* _set_custom_data */ nullptr, | |||||
CarlaEngineNative::_ui_show, | |||||
CarlaEngineNative::_ui_idle, | |||||
/* _ui_set_parameter_value */ nullptr, | |||||
/* _ui_set_midi_program */ nullptr, | |||||
/* _ui_set_custom_data */ nullptr, | |||||
CarlaEngineNative::_activate, | |||||
CarlaEngineNative::_deactivate, | |||||
CarlaEngineNative::_process, | |||||
CarlaEngineNative::_get_state, | |||||
CarlaEngineNative::_set_state, | |||||
CarlaEngineNative::_dispatcher, | |||||
/* _render_inline_dsplay */ nullptr, | |||||
/* cvIns */ 5, | |||||
/* cvOuts */ 5 | |||||
}; | }; | ||||
CARLA_BACKEND_END_NAMESPACE | CARLA_BACKEND_END_NAMESPACE | ||||
@@ -2617,6 +2682,7 @@ void carla_register_native_plugin_carla() | |||||
carla_register_native_plugin(&carlaPatchbay16Desc); | carla_register_native_plugin(&carlaPatchbay16Desc); | ||||
carla_register_native_plugin(&carlaPatchbay32Desc); | carla_register_native_plugin(&carlaPatchbay32Desc); | ||||
carla_register_native_plugin(&carlaPatchbay64Desc); | carla_register_native_plugin(&carlaPatchbay64Desc); | ||||
carla_register_native_plugin(&carlaPatchbayCVDesc); | |||||
} | } | ||||
// ----------------------------------------------------------------------- | // ----------------------------------------------------------------------- | ||||
@@ -2651,6 +2717,12 @@ const NativePluginDescriptor* carla_get_native_patchbay64_plugin() | |||||
return &carlaPatchbay64Desc; | return &carlaPatchbay64Desc; | ||||
} | } | ||||
const NativePluginDescriptor* carla_get_native_patchbay_cv_plugin() | |||||
{ | |||||
CARLA_BACKEND_USE_NAMESPACE; | |||||
return &carlaPatchbayCVDesc; | |||||
} | |||||
// ----------------------------------------------------------------------- | // ----------------------------------------------------------------------- | ||||
// Extra stuff for linking purposes | // Extra stuff for linking purposes | ||||
@@ -332,7 +332,7 @@ public: | |||||
if (fAudioOutCount > 0) | if (fAudioOutCount > 0) | ||||
fAudioIntBufOut = new float[fAudioOutCount*bufferFrames]; | fAudioIntBufOut = new float[fAudioOutCount*bufferFrames]; | ||||
pData->graph.create(fAudioInCount, fAudioOutCount); | |||||
pData->graph.create(fAudioInCount, fAudioOutCount, 0, 0); | |||||
try { | try { | ||||
fAudio.startStream(); | fAudio.startStream(); | ||||
@@ -254,8 +254,8 @@ public: | |||||
fIsUiVisible(false), | fIsUiVisible(false), | ||||
fInlineDisplayNeedsRedraw(false), | fInlineDisplayNeedsRedraw(false), | ||||
fInlineDisplayLastRedrawTime(0), | fInlineDisplayLastRedrawTime(0), | ||||
fAudioInBuffers(nullptr), | |||||
fAudioOutBuffers(nullptr), | |||||
fAudioAndCvInBuffers(nullptr), | |||||
fAudioAndCvOutBuffers(nullptr), | |||||
fMidiEventInCount(0), | fMidiEventInCount(0), | ||||
fMidiEventOutCount(0), | fMidiEventOutCount(0), | ||||
fCurBufferSize(engine->getBufferSize()), | fCurBufferSize(engine->getBufferSize()), | ||||
@@ -421,8 +421,8 @@ public: | |||||
if ((fDescriptor->hints & NATIVE_PLUGIN_NEEDS_FIXED_BUFFERS) == 0x0) | if ((fDescriptor->hints & NATIVE_PLUGIN_NEEDS_FIXED_BUFFERS) == 0x0) | ||||
options |= PLUGIN_OPTION_FIXED_BUFFERS; | options |= PLUGIN_OPTION_FIXED_BUFFERS; | ||||
// can't disable forced stereo if enabled in the engine | |||||
if (pData->engine->getOptions().forceStereo) | |||||
// can't disable forced stereo if enabled in the engine, or using CV | |||||
if (pData->engine->getOptions().forceStereo || pData->cvIn.count != 0 || pData->cvOut.count != 0) | |||||
pass(); | pass(); | ||||
// if inputs or outputs are just 1, then yes we can force stereo | // if inputs or outputs are just 1, then yes we can force stereo | ||||
else if (pData->audioIn.count == 1 || pData->audioOut.count == 1 || fHandle2 != nullptr) | else if (pData->audioIn.count == 1 || pData->audioOut.count == 1 || fHandle2 != nullptr) | ||||
@@ -978,7 +978,7 @@ public: | |||||
const float sampleRate((float)pData->engine->getSampleRate()); | const float sampleRate((float)pData->engine->getSampleRate()); | ||||
uint32_t aIns, aOuts, mIns, mOuts, params, j; | |||||
uint32_t aIns, aOuts, cvIns, cvOuts, mIns, mOuts, params, j; | |||||
bool forcedStereoIn, forcedStereoOut; | bool forcedStereoIn, forcedStereoOut; | ||||
forcedStereoIn = forcedStereoOut = false; | forcedStereoIn = forcedStereoOut = false; | ||||
@@ -988,6 +988,8 @@ public: | |||||
aIns = fDescriptor->audioIns; | aIns = fDescriptor->audioIns; | ||||
aOuts = fDescriptor->audioOuts; | aOuts = fDescriptor->audioOuts; | ||||
cvIns = fDescriptor->cvIns; | |||||
cvOuts = fDescriptor->cvOuts; | |||||
mIns = fDescriptor->midiIns; | mIns = fDescriptor->midiIns; | ||||
mOuts = fDescriptor->midiOuts; | mOuts = fDescriptor->midiOuts; | ||||
params = (fDescriptor->get_parameter_count != nullptr && fDescriptor->get_parameter_info != nullptr) ? fDescriptor->get_parameter_count(fHandle) : 0; | params = (fDescriptor->get_parameter_count != nullptr && fDescriptor->get_parameter_info != nullptr) ? fDescriptor->get_parameter_count(fHandle) : 0; | ||||
@@ -1016,20 +1018,34 @@ public: | |||||
if (aIns > 0) | if (aIns > 0) | ||||
{ | { | ||||
pData->audioIn.createNew(aIns); | pData->audioIn.createNew(aIns); | ||||
fAudioInBuffers = new float*[aIns]; | |||||
for (uint32_t i=0; i < aIns; ++i) | |||||
fAudioInBuffers[i] = nullptr; | |||||
} | } | ||||
if (aOuts > 0) | if (aOuts > 0) | ||||
{ | { | ||||
pData->audioOut.createNew(aOuts); | pData->audioOut.createNew(aOuts); | ||||
fAudioOutBuffers = new float*[aOuts]; | |||||
needsCtrlIn = true; | needsCtrlIn = true; | ||||
} | |||||
for (uint32_t i=0; i < aOuts; ++i) | |||||
fAudioOutBuffers[i] = nullptr; | |||||
if (cvIns > 0) | |||||
{ | |||||
pData->cvIn.createNew(cvIns); | |||||
} | |||||
if (cvOuts > 0) | |||||
{ | |||||
pData->cvOut.createNew(cvOuts); | |||||
} | |||||
if (const uint32_t acIns = aIns + cvIns) | |||||
{ | |||||
fAudioAndCvInBuffers = new float*[acIns]; | |||||
carla_zeroPointers(fAudioAndCvInBuffers, acIns); | |||||
} | |||||
if (const uint32_t acOuts = aOuts + cvOuts) | |||||
{ | |||||
fAudioAndCvOutBuffers = new float*[acOuts]; | |||||
carla_zeroPointers(fAudioAndCvOutBuffers, acOuts); | |||||
} | } | ||||
if (mIns > 0) | if (mIns > 0) | ||||
@@ -1118,6 +1134,56 @@ public: | |||||
} | } | ||||
} | } | ||||
// CV Ins | |||||
for (j=0; j < cvIns; ++j) | |||||
{ | |||||
portName.clear(); | |||||
if (processMode == ENGINE_PROCESS_MODE_SINGLE_CLIENT) | |||||
{ | |||||
portName = pData->name; | |||||
portName += ":"; | |||||
} | |||||
if (cvIns > 1) | |||||
{ | |||||
portName += "cv_input_"; | |||||
portName += CarlaString(j+1); | |||||
} | |||||
else | |||||
portName += "cv_input"; | |||||
portName.truncate(portNameSize); | |||||
pData->cvIn.ports[j].port = (CarlaEngineCVPort*)pData->client->addPort(kEnginePortTypeCV, portName, true, j); | |||||
pData->cvIn.ports[j].rindex = j; | |||||
} | |||||
// CV Outs | |||||
for (j=0; j < cvOuts; ++j) | |||||
{ | |||||
portName.clear(); | |||||
if (processMode == ENGINE_PROCESS_MODE_SINGLE_CLIENT) | |||||
{ | |||||
portName = pData->name; | |||||
portName += ":"; | |||||
} | |||||
if (cvOuts > 1) | |||||
{ | |||||
portName += "cv_output_"; | |||||
portName += CarlaString(j+1); | |||||
} | |||||
else | |||||
portName += "cv_output"; | |||||
portName.truncate(portNameSize); | |||||
pData->cvOut.ports[j].port = (CarlaEngineCVPort*)pData->client->addPort(kEnginePortTypeCV, portName, false, j); | |||||
pData->cvOut.ports[j].rindex = j; | |||||
} | |||||
// MIDI Input (only if multiple) | // MIDI Input (only if multiple) | ||||
if (mIns > 1) | if (mIns > 1) | ||||
{ | { | ||||
@@ -1514,7 +1580,8 @@ public: | |||||
return kNullEngineEvent; | return kNullEngineEvent; | ||||
} | } | ||||
void process(const float** const audioIn, float** const audioOut, const float** const, float** const, const uint32_t frames) override | |||||
void process(const float** const audioIn, float** const audioOut, | |||||
const float** const cvIn, float** const cvOut, const uint32_t frames) override | |||||
{ | { | ||||
// -------------------------------------------------------------------------------------------------------- | // -------------------------------------------------------------------------------------------------------- | ||||
// Check if active | // Check if active | ||||
@@ -1524,6 +1591,8 @@ public: | |||||
// disable any output sound | // disable any output sound | ||||
for (uint32_t i=0; i < pData->audioOut.count; ++i) | for (uint32_t i=0; i < pData->audioOut.count; ++i) | ||||
carla_zeroFloats(audioOut[i], frames); | carla_zeroFloats(audioOut[i], frames); | ||||
for (uint32_t i=0; i < pData->cvOut.count; ++i) | |||||
carla_zeroFloats(cvOut[i], frames); | |||||
return; | return; | ||||
} | } | ||||
@@ -1697,7 +1766,7 @@ public: | |||||
if (sampleAccurate && eventTime > timeOffset) | if (sampleAccurate && eventTime > timeOffset) | ||||
{ | { | ||||
if (processSingle(audioIn, audioOut, eventTime - timeOffset, timeOffset)) | |||||
if (processSingle(audioIn, audioOut, cvIn, cvOut, eventTime - timeOffset, timeOffset)) | |||||
{ | { | ||||
startTime = 0; | startTime = 0; | ||||
timeOffset = eventTime; | timeOffset = eventTime; | ||||
@@ -2005,7 +2074,7 @@ public: | |||||
pData->postRtEvents.trySplice(); | pData->postRtEvents.trySplice(); | ||||
if (frames > timeOffset) | if (frames > timeOffset) | ||||
processSingle(audioIn, audioOut, frames - timeOffset, timeOffset); | |||||
processSingle(audioIn, audioOut, cvIn, cvOut, frames - timeOffset, timeOffset); | |||||
} // End of Event Input and Processing | } // End of Event Input and Processing | ||||
@@ -2014,7 +2083,7 @@ public: | |||||
else | else | ||||
{ | { | ||||
processSingle(audioIn, audioOut, frames, 0); | |||||
processSingle(audioIn, audioOut, cvIn, cvOut, frames, 0); | |||||
} // End of Plugin processing (no events) | } // End of Plugin processing (no events) | ||||
@@ -2044,18 +2113,24 @@ public: | |||||
#endif | #endif | ||||
} | } | ||||
bool processSingle(const float** const audioIn, float** const audioOut, const uint32_t frames, const uint32_t timeOffset) | |||||
bool processSingle(const float** const audioIn, float** const audioOut, | |||||
const float** const cvIn, float** const cvOut, | |||||
const uint32_t frames, const uint32_t timeOffset) | |||||
{ | { | ||||
CARLA_SAFE_ASSERT_RETURN(frames > 0, false); | CARLA_SAFE_ASSERT_RETURN(frames > 0, false); | ||||
if (pData->audioIn.count > 0) | |||||
{ | |||||
if (pData->audioIn.count > 0) { | |||||
CARLA_SAFE_ASSERT_RETURN(audioIn != nullptr, false); | CARLA_SAFE_ASSERT_RETURN(audioIn != nullptr, false); | ||||
} | } | ||||
if (pData->audioOut.count > 0) | |||||
{ | |||||
if (pData->audioOut.count > 0) { | |||||
CARLA_SAFE_ASSERT_RETURN(audioOut != nullptr, false); | CARLA_SAFE_ASSERT_RETURN(audioOut != nullptr, false); | ||||
} | } | ||||
if (pData->cvIn.count > 0) { | |||||
CARLA_SAFE_ASSERT_RETURN(cvIn != nullptr, false); | |||||
} | |||||
if (pData->cvOut.count > 0) { | |||||
CARLA_SAFE_ASSERT_RETURN(cvOut != nullptr, false); | |||||
} | |||||
// -------------------------------------------------------------------------------------------------------- | // -------------------------------------------------------------------------------------------------------- | ||||
// Try lock, silence otherwise | // Try lock, silence otherwise | ||||
@@ -2071,6 +2146,11 @@ public: | |||||
for (uint32_t k=0; k < frames; ++k) | for (uint32_t k=0; k < frames; ++k) | ||||
audioOut[i][k+timeOffset] = 0.0f; | audioOut[i][k+timeOffset] = 0.0f; | ||||
} | } | ||||
for (uint32_t i=0; i < pData->cvOut.count; ++i) | |||||
{ | |||||
for (uint32_t k=0; k < frames; ++k) | |||||
cvOut[i][k+timeOffset] = 0.0f; | |||||
} | |||||
return false; | return false; | ||||
} | } | ||||
@@ -2078,11 +2158,17 @@ public: | |||||
// -------------------------------------------------------------------------------------------------------- | // -------------------------------------------------------------------------------------------------------- | ||||
// Set audio buffers | // Set audio buffers | ||||
for (uint32_t i=0; i < pData->audioIn.count; ++i) | |||||
carla_copyFloats(fAudioInBuffers[i], audioIn[i]+timeOffset, frames); | |||||
{ | |||||
for (uint32_t i=0; i < pData->audioIn.count; ++i) | |||||
carla_copyFloats(fAudioAndCvInBuffers[i], audioIn[i]+timeOffset, frames); | |||||
for (uint32_t i=0; i < pData->cvIn.count; ++i) | |||||
carla_copyFloats(fAudioAndCvInBuffers[pData->audioIn.count+i], cvIn[i]+timeOffset, frames); | |||||
for (uint32_t i=0; i < pData->audioOut.count; ++i) | |||||
carla_zeroFloats(fAudioOutBuffers[i], frames); | |||||
for (uint32_t i=0; i < pData->audioOut.count; ++i) | |||||
carla_zeroFloats(fAudioAndCvOutBuffers[i], frames); | |||||
for (uint32_t i=0; i < pData->cvOut.count; ++i) | |||||
carla_zeroFloats(fAudioAndCvOutBuffers[pData->audioOut.count+i], frames); | |||||
} | |||||
// -------------------------------------------------------------------------------------------------------- | // -------------------------------------------------------------------------------------------------------- | ||||
// Run plugin | // Run plugin | ||||
@@ -2092,19 +2178,19 @@ public: | |||||
if (fHandle2 == nullptr) | if (fHandle2 == nullptr) | ||||
{ | { | ||||
fDescriptor->process(fHandle, | fDescriptor->process(fHandle, | ||||
const_cast<const float**>(fAudioInBuffers), fAudioOutBuffers, frames, | |||||
const_cast<const float**>(fAudioAndCvInBuffers), fAudioAndCvOutBuffers, frames, | |||||
fMidiInEvents, fMidiEventInCount); | fMidiInEvents, fMidiEventInCount); | ||||
} | } | ||||
else | else | ||||
{ | { | ||||
fDescriptor->process(fHandle, | fDescriptor->process(fHandle, | ||||
(pData->audioIn.count > 0) ? const_cast<const float**>(&fAudioInBuffers[0]) : nullptr, | |||||
(pData->audioOut.count > 0) ? &fAudioOutBuffers[0] : nullptr, | |||||
(fAudioAndCvInBuffers != nullptr) ? const_cast<const float**>(&fAudioAndCvInBuffers[0]) : nullptr, | |||||
(fAudioAndCvOutBuffers != nullptr) ? &fAudioAndCvOutBuffers[0] : nullptr, | |||||
frames, fMidiInEvents, fMidiEventInCount); | frames, fMidiInEvents, fMidiEventInCount); | ||||
fDescriptor->process(fHandle2, | fDescriptor->process(fHandle2, | ||||
(pData->audioIn.count > 0) ? const_cast<const float**>(&fAudioInBuffers[1]) : nullptr, | |||||
(pData->audioOut.count > 0) ? &fAudioOutBuffers[1] : nullptr, | |||||
(fAudioAndCvInBuffers != nullptr) ? const_cast<const float**>(&fAudioAndCvInBuffers[1]) : nullptr, | |||||
(fAudioAndCvOutBuffers != nullptr) ? &fAudioAndCvOutBuffers[1] : nullptr, | |||||
frames, fMidiInEvents, fMidiEventInCount); | frames, fMidiInEvents, fMidiEventInCount); | ||||
} | } | ||||
@@ -2113,6 +2199,7 @@ public: | |||||
if (fTimeInfo.playing) | if (fTimeInfo.playing) | ||||
fTimeInfo.frame += frames; | fTimeInfo.frame += frames; | ||||
uint32_t i=0; | |||||
#ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH | #ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH | ||||
// -------------------------------------------------------------------------------------------------------- | // -------------------------------------------------------------------------------------------------------- | ||||
// Post-processing (dry/wet, volume and balance) | // Post-processing (dry/wet, volume and balance) | ||||
@@ -2124,15 +2211,15 @@ public: | |||||
bool isPair; | bool isPair; | ||||
float bufValue, oldBufLeft[doBalance ? frames : 1]; | float bufValue, oldBufLeft[doBalance ? frames : 1]; | ||||
for (uint32_t i=0; i < pData->audioOut.count; ++i) | |||||
for (; i < pData->audioOut.count; ++i) | |||||
{ | { | ||||
// Dry/Wet | // Dry/Wet | ||||
if (doDryWet) | if (doDryWet) | ||||
{ | { | ||||
for (uint32_t k=0; k < frames; ++k) | for (uint32_t k=0; k < frames; ++k) | ||||
{ | { | ||||
bufValue = fAudioInBuffers[(pData->audioIn.count == 1) ? 0 : i][k]; | |||||
fAudioOutBuffers[i][k] = (fAudioOutBuffers[i][k] * pData->postProc.dryWet) + (bufValue * (1.0f - pData->postProc.dryWet)); | |||||
bufValue = fAudioAndCvInBuffers[(pData->audioIn.count == 1) ? 0 : i][k]; | |||||
fAudioAndCvOutBuffers[i][k] = (fAudioAndCvOutBuffers[i][k] * pData->postProc.dryWet) + (bufValue * (1.0f - pData->postProc.dryWet)); | |||||
} | } | ||||
} | } | ||||
@@ -2144,7 +2231,7 @@ public: | |||||
if (isPair) | if (isPair) | ||||
{ | { | ||||
CARLA_ASSERT(i+1 < pData->audioOut.count); | CARLA_ASSERT(i+1 < pData->audioOut.count); | ||||
carla_copyFloats(oldBufLeft, fAudioOutBuffers[i], frames); | |||||
carla_copyFloats(oldBufLeft, fAudioAndCvOutBuffers[i], frames); | |||||
} | } | ||||
float balRangeL = (pData->postProc.balanceLeft + 1.0f)/2.0f; | float balRangeL = (pData->postProc.balanceLeft + 1.0f)/2.0f; | ||||
@@ -2155,14 +2242,14 @@ public: | |||||
if (isPair) | if (isPair) | ||||
{ | { | ||||
// left | // left | ||||
fAudioOutBuffers[i][k] = oldBufLeft[k] * (1.0f - balRangeL); | |||||
fAudioOutBuffers[i][k] += fAudioOutBuffers[i+1][k] * (1.0f - balRangeR); | |||||
fAudioAndCvOutBuffers[i][k] = oldBufLeft[k] * (1.0f - balRangeL); | |||||
fAudioAndCvOutBuffers[i][k] += fAudioAndCvOutBuffers[i+1][k] * (1.0f - balRangeR); | |||||
} | } | ||||
else | else | ||||
{ | { | ||||
// right | // right | ||||
fAudioOutBuffers[i][k] = fAudioOutBuffers[i][k] * balRangeR; | |||||
fAudioOutBuffers[i][k] += oldBufLeft[k] * balRangeL; | |||||
fAudioAndCvOutBuffers[i][k] = fAudioAndCvOutBuffers[i][k] * balRangeR; | |||||
fAudioAndCvOutBuffers[i][k] += oldBufLeft[k] * balRangeL; | |||||
} | } | ||||
} | } | ||||
} | } | ||||
@@ -2170,18 +2257,24 @@ public: | |||||
// Volume (and buffer copy) | // Volume (and buffer copy) | ||||
{ | { | ||||
for (uint32_t k=0; k < frames; ++k) | for (uint32_t k=0; k < frames; ++k) | ||||
audioOut[i][k+timeOffset] = fAudioOutBuffers[i][k] * pData->postProc.volume; | |||||
audioOut[i][k+timeOffset] = fAudioAndCvOutBuffers[i][k] * pData->postProc.volume; | |||||
} | } | ||||
} | } | ||||
} // End of Post-processing | } // End of Post-processing | ||||
#else | #else | ||||
for (uint32_t i=0; i < pData->audioOut.count; ++i) | |||||
for (; i < pData->audioOut.count; ++i) | |||||
{ | { | ||||
for (uint32_t k=0; k < frames; ++k) | for (uint32_t k=0; k < frames; ++k) | ||||
audioOut[i][k+timeOffset] = fAudioOutBuffers[i][k]; | |||||
audioOut[i][k+timeOffset] = fAudioAndCvOutBuffers[i][k]; | |||||
} | } | ||||
#endif | #endif | ||||
// CV stuff too | |||||
for (; i < pData->cvOut.count; ++i) | |||||
{ | |||||
for (uint32_t k=0; k < frames; ++k) | |||||
cvOut[i][k+timeOffset] = fAudioAndCvOutBuffers[pData->audioOut.count+i][k]; | |||||
} | |||||
// -------------------------------------------------------------------------------------------------------- | // -------------------------------------------------------------------------------------------------------- | ||||
// MIDI Output | // MIDI Output | ||||
@@ -2211,18 +2304,18 @@ public: | |||||
CARLA_ASSERT_INT(newBufferSize > 0, newBufferSize); | CARLA_ASSERT_INT(newBufferSize > 0, newBufferSize); | ||||
carla_debug("CarlaPluginNative::bufferSizeChanged(%i)", newBufferSize); | carla_debug("CarlaPluginNative::bufferSizeChanged(%i)", newBufferSize); | ||||
for (uint32_t i=0; i < pData->audioIn.count; ++i) | |||||
for (uint32_t i=0; i < (pData->audioIn.count+pData->cvIn.count); ++i) | |||||
{ | { | ||||
if (fAudioInBuffers[i] != nullptr) | |||||
delete[] fAudioInBuffers[i]; | |||||
fAudioInBuffers[i] = new float[newBufferSize]; | |||||
if (fAudioAndCvInBuffers[i] != nullptr) | |||||
delete[] fAudioAndCvInBuffers[i]; | |||||
fAudioAndCvInBuffers[i] = new float[newBufferSize]; | |||||
} | } | ||||
for (uint32_t i=0; i < pData->audioOut.count; ++i) | |||||
for (uint32_t i=0; i < (pData->audioOut.count+pData->cvOut.count); ++i) | |||||
{ | { | ||||
if (fAudioOutBuffers[i] != nullptr) | |||||
delete[] fAudioOutBuffers[i]; | |||||
fAudioOutBuffers[i] = new float[newBufferSize]; | |||||
if (fAudioAndCvOutBuffers[i] != nullptr) | |||||
delete[] fAudioAndCvOutBuffers[i]; | |||||
fAudioAndCvOutBuffers[i] = new float[newBufferSize]; | |||||
} | } | ||||
if (fCurBufferSize == newBufferSize) | if (fCurBufferSize == newBufferSize) | ||||
@@ -2289,34 +2382,34 @@ public: | |||||
{ | { | ||||
carla_debug("CarlaPluginNative::clearBuffers() - start"); | carla_debug("CarlaPluginNative::clearBuffers() - start"); | ||||
if (fAudioInBuffers != nullptr) | |||||
if (fAudioAndCvInBuffers != nullptr) | |||||
{ | { | ||||
for (uint32_t i=0; i < pData->audioIn.count; ++i) | |||||
for (uint32_t i=0; i < (pData->audioIn.count+pData->cvIn.count); ++i) | |||||
{ | { | ||||
if (fAudioInBuffers[i] != nullptr) | |||||
if (fAudioAndCvInBuffers[i] != nullptr) | |||||
{ | { | ||||
delete[] fAudioInBuffers[i]; | |||||
fAudioInBuffers[i] = nullptr; | |||||
delete[] fAudioAndCvInBuffers[i]; | |||||
fAudioAndCvInBuffers[i] = nullptr; | |||||
} | } | ||||
} | } | ||||
delete[] fAudioInBuffers; | |||||
fAudioInBuffers = nullptr; | |||||
delete[] fAudioAndCvInBuffers; | |||||
fAudioAndCvInBuffers = nullptr; | |||||
} | } | ||||
if (fAudioOutBuffers != nullptr) | |||||
if (fAudioAndCvOutBuffers != nullptr) | |||||
{ | { | ||||
for (uint32_t i=0; i < pData->audioOut.count; ++i) | |||||
for (uint32_t i=0; i < (pData->audioOut.count+pData->cvOut.count); ++i) | |||||
{ | { | ||||
if (fAudioOutBuffers[i] != nullptr) | |||||
if (fAudioAndCvOutBuffers[i] != nullptr) | |||||
{ | { | ||||
delete[] fAudioOutBuffers[i]; | |||||
fAudioOutBuffers[i] = nullptr; | |||||
delete[] fAudioAndCvOutBuffers[i]; | |||||
fAudioAndCvOutBuffers[i] = nullptr; | |||||
} | } | ||||
} | } | ||||
delete[] fAudioOutBuffers; | |||||
fAudioOutBuffers = nullptr; | |||||
delete[] fAudioAndCvOutBuffers; | |||||
fAudioAndCvOutBuffers = nullptr; | |||||
} | } | ||||
if (fMidiIn.count > 1) | if (fMidiIn.count > 1) | ||||
@@ -2699,8 +2792,8 @@ private: | |||||
bool fInlineDisplayNeedsRedraw; | bool fInlineDisplayNeedsRedraw; | ||||
int64_t fInlineDisplayLastRedrawTime; | int64_t fInlineDisplayLastRedrawTime; | ||||
float** fAudioInBuffers; | |||||
float** fAudioOutBuffers; | |||||
float** fAudioAndCvInBuffers; | |||||
float** fAudioAndCvOutBuffers; | |||||
uint32_t fMidiEventInCount; | uint32_t fMidiEventInCount; | ||||
uint32_t fMidiEventOutCount; | uint32_t fMidiEventOutCount; | ||||
NativeMidiEvent fMidiInEvents[kPluginMaxMidiEvents]; | NativeMidiEvent fMidiInEvents[kPluginMaxMidiEvents]; | ||||
@@ -63,6 +63,8 @@ _CarlaCachedPluginInfo::_CarlaCachedPluginInfo() noexcept | |||||
hints(0x0), | hints(0x0), | ||||
audioIns(0), | audioIns(0), | ||||
audioOuts(0), | audioOuts(0), | ||||
cvIns(0), | |||||
cvOuts(0), | |||||
midiIns(0), | midiIns(0), | ||||
midiOuts(0), | midiOuts(0), | ||||
parameterIns(0), | parameterIns(0), | ||||
@@ -119,6 +121,8 @@ static const CarlaCachedPluginInfo* get_cached_plugin_internal(const NativePlugi | |||||
info.valid = true; | info.valid = true; | ||||
info.audioIns = desc.audioIns; | info.audioIns = desc.audioIns; | ||||
info.audioOuts = desc.audioOuts; | info.audioOuts = desc.audioOuts; | ||||
info.cvIns = desc.cvIns; | |||||
info.cvOuts = desc.cvOuts; | |||||
info.midiIns = desc.midiIns; | info.midiIns = desc.midiIns; | ||||
info.midiOuts = desc.midiOuts; | info.midiOuts = desc.midiOuts; | ||||
info.parameterIns = desc.paramIns; | info.parameterIns = desc.paramIns; | ||||
@@ -336,6 +340,8 @@ static const CarlaCachedPluginInfo* get_cached_plugin_lv2(Lv2WorldClass& lv2Worl | |||||
info.audioIns = 0; | info.audioIns = 0; | ||||
info.audioOuts = 0; | info.audioOuts = 0; | ||||
info.cvIns = 0; | |||||
info.cvOuts = 0; | |||||
info.midiIns = 0; | info.midiIns = 0; | ||||
info.midiOuts = 0; | info.midiOuts = 0; | ||||
info.parameterIns = 0; | info.parameterIns = 0; | ||||
@@ -429,6 +435,10 @@ static const CarlaCachedPluginInfo* get_cached_plugin_lv2(Lv2WorldClass& lv2Worl | |||||
} | } | ||||
else if (lilvPort.is_a(lv2World.port_cv)) | else if (lilvPort.is_a(lv2World.port_cv)) | ||||
{ | { | ||||
if (isInput) | |||||
++(info.cvIns); | |||||
else | |||||
++(info.cvOuts); | |||||
} | } | ||||
else if (lilvPort.is_a(lv2World.port_atom)) | else if (lilvPort.is_a(lv2World.port_atom)) | ||||
{ | { | ||||
@@ -527,6 +537,8 @@ static const CarlaCachedPluginInfo* get_cached_plugin_au(const juce::String plug | |||||
info.audioIns = static_cast<uint32_t>(desc->numInputChannels); | info.audioIns = static_cast<uint32_t>(desc->numInputChannels); | ||||
info.audioOuts = static_cast<uint32_t>(desc->numOutputChannels); | info.audioOuts = static_cast<uint32_t>(desc->numOutputChannels); | ||||
info.cvIns = 0; | |||||
info.cvOuts = 0; | |||||
info.midiIns = desc->isInstrument ? 1 : 0; | info.midiIns = desc->isInstrument ? 1 : 0; | ||||
info.midiOuts = 0; | info.midiOuts = 0; | ||||
info.parameterIns = 0; | info.parameterIns = 0; | ||||
@@ -565,6 +577,8 @@ static const CarlaCachedPluginInfo* get_cached_plugin_sfz(const File file) | |||||
info.valid = true; | info.valid = true; | ||||
info.audioIns = 0; | info.audioIns = 0; | ||||
info.audioOuts = 2; | info.audioOuts = 2; | ||||
info.cvIns = 0; | |||||
info.cvOuts = 0; | |||||
info.midiIns = 1; | info.midiIns = 1; | ||||
info.midiOuts = 0; | info.midiOuts = 0; | ||||
info.parameterIns = 0; | info.parameterIns = 0; | ||||
@@ -108,6 +108,8 @@ static void print_cached_plugin(const CarlaCachedPluginInfo* const pinfo) | |||||
DISCOVERY_OUT("label", pinfo->label); | DISCOVERY_OUT("label", pinfo->label); | ||||
DISCOVERY_OUT("audio.ins", pinfo->audioIns); | DISCOVERY_OUT("audio.ins", pinfo->audioIns); | ||||
DISCOVERY_OUT("audio.outs", pinfo->audioOuts); | DISCOVERY_OUT("audio.outs", pinfo->audioOuts); | ||||
DISCOVERY_OUT("cv.ins", pinfo->cvIns); | |||||
DISCOVERY_OUT("cv.outs", pinfo->cvOuts); | |||||
DISCOVERY_OUT("midi.ins", pinfo->midiIns); | DISCOVERY_OUT("midi.ins", pinfo->midiIns); | ||||
DISCOVERY_OUT("midi.outs", pinfo->midiOuts); | DISCOVERY_OUT("midi.outs", pinfo->midiOuts); | ||||
DISCOVERY_OUT("parameters.ins", pinfo->parameterIns); | DISCOVERY_OUT("parameters.ins", pinfo->parameterIns); | ||||
@@ -133,7 +133,7 @@ def findFilenames(filePath, stype): | |||||
# --------------------------------------------------------------------------------------------------------------------- | # --------------------------------------------------------------------------------------------------------------------- | ||||
# Plugin Query | # Plugin Query | ||||
PLUGIN_QUERY_API_VERSION = 8 | |||||
PLUGIN_QUERY_API_VERSION = 9 | |||||
PyPluginInfo = { | PyPluginInfo = { | ||||
'API': PLUGIN_QUERY_API_VERSION, | 'API': PLUGIN_QUERY_API_VERSION, | ||||
@@ -148,6 +148,8 @@ PyPluginInfo = { | |||||
'uniqueId': 0, | 'uniqueId': 0, | ||||
'audio.ins': 0, | 'audio.ins': 0, | ||||
'audio.outs': 0, | 'audio.outs': 0, | ||||
'cv.ins': 0, | |||||
'cv.outs': 0, | |||||
'midi.ins': 0, | 'midi.ins': 0, | ||||
'midi.outs': 0, | 'midi.outs': 0, | ||||
'parameters.ins': 0, | 'parameters.ins': 0, | ||||
@@ -285,6 +287,10 @@ def runCarlaDiscovery(itype, stype, filename, tool, wineSettings=None): | |||||
if value.isdigit(): pinfo['audio.ins'] = int(value) | if value.isdigit(): pinfo['audio.ins'] = int(value) | ||||
elif prop == "audio.outs": | elif prop == "audio.outs": | ||||
if value.isdigit(): pinfo['audio.outs'] = int(value) | if value.isdigit(): pinfo['audio.outs'] = int(value) | ||||
elif prop == "cv.ins": | |||||
if value.isdigit(): pinfo['cv.ins'] = int(value) | |||||
elif prop == "cv.outs": | |||||
if value.isdigit(): pinfo['cv.outs'] = int(value) | |||||
elif prop == "midi.ins": | elif prop == "midi.ins": | ||||
if value.isdigit(): pinfo['midi.ins'] = int(value) | if value.isdigit(): pinfo['midi.ins'] = int(value) | ||||
elif prop == "midi.outs": | elif prop == "midi.outs": | ||||
@@ -329,6 +335,9 @@ def checkPluginCached(desc, ptype): | |||||
pinfo['audio.ins'] = desc['audioIns'] | pinfo['audio.ins'] = desc['audioIns'] | ||||
pinfo['audio.outs'] = desc['audioOuts'] | pinfo['audio.outs'] = desc['audioOuts'] | ||||
pinfo['cv.ins'] = desc['cvIns'] | |||||
pinfo['cv.outs'] = desc['cvOuts'] | |||||
pinfo['midi.ins'] = desc['midiIns'] | pinfo['midi.ins'] = desc['midiIns'] | ||||
pinfo['midi.outs'] = desc['midiOuts'] | pinfo['midi.outs'] = desc['midiOuts'] | ||||
@@ -117,6 +117,12 @@ class CarlaCachedPluginInfo(Structure): | |||||
# Number of audio outputs. | # Number of audio outputs. | ||||
("audioOuts", c_uint32), | ("audioOuts", c_uint32), | ||||
# Number of CV inputs. | |||||
("cvIns", c_uint32), | |||||
# Number of CV outputs. | |||||
("cvOuts", c_uint32), | |||||
# Number of MIDI inputs. | # Number of MIDI inputs. | ||||
("midiIns", c_uint32), | ("midiIns", c_uint32), | ||||
@@ -152,6 +158,8 @@ PyCarlaCachedPluginInfo = { | |||||
'hints': 0x0, | 'hints': 0x0, | ||||
'audioIns': 0, | 'audioIns': 0, | ||||
'audioOuts': 0, | 'audioOuts': 0, | ||||
'cvIns': 0, | |||||
'cvOuts': 0, | |||||
'midiIns': 0, | 'midiIns': 0, | ||||
'midiOuts': 0, | 'midiOuts': 0, | ||||
'parameterIns': 0, | 'parameterIns': 0, | ||||
@@ -64,7 +64,8 @@ typedef enum { | |||||
NATIVE_PLUGIN_USES_STATE = 1 << 9, | NATIVE_PLUGIN_USES_STATE = 1 << 9, | ||||
NATIVE_PLUGIN_USES_TIME = 1 << 10, | NATIVE_PLUGIN_USES_TIME = 1 << 10, | ||||
NATIVE_PLUGIN_USES_PARENT_ID = 1 << 11, /** can set transient hint to parent */ | NATIVE_PLUGIN_USES_PARENT_ID = 1 << 11, /** can set transient hint to parent */ | ||||
NATIVE_PLUGIN_HAS_INLINE_DISPLAY = 1 << 12 | |||||
NATIVE_PLUGIN_HAS_INLINE_DISPLAY = 1 << 12, | |||||
NATIVE_PLUGIN_USES_CONTROL_VOLTAGE = 1 << 13 | |||||
} NativePluginHints; | } NativePluginHints; | ||||
typedef enum { | typedef enum { | ||||
@@ -268,6 +269,10 @@ typedef struct _NativePluginDescriptor { | |||||
const NativeInlineDisplayImageSurface* (*render_inline_display)(NativePluginHandle handle, | const NativeInlineDisplayImageSurface* (*render_inline_display)(NativePluginHandle handle, | ||||
uint32_t width, uint32_t height); | uint32_t width, uint32_t height); | ||||
// placed at the end for backwards compatibility. only valid if NATIVE_PLUGIN_USES_CONTROL_VOLTAGE is set | |||||
const uint32_t cvIns; | |||||
const uint32_t cvOuts; | |||||
} NativePluginDescriptor; | } NativePluginDescriptor; | ||||
/* ------------------------------------------------------------------------------------------------------------ | /* ------------------------------------------------------------------------------------------------------------ | ||||
@@ -577,7 +577,8 @@ public: \ | |||||
ClassName::_get_state, \ | ClassName::_get_state, \ | ||||
ClassName::_set_state, \ | ClassName::_set_state, \ | ||||
ClassName::_dispatcher, \ | ClassName::_dispatcher, \ | ||||
ClassName::_render_inline_display | |||||
ClassName::_render_inline_display, \ | |||||
0, 0 | |||||
// ----------------------------------------------------------------------- | // ----------------------------------------------------------------------- | ||||
@@ -58,6 +58,11 @@ CARLA_EXPORT const NativePluginDescriptor* carla_get_native_patchbay32_plugin(); | |||||
*/ | */ | ||||
CARLA_EXPORT const NativePluginDescriptor* carla_get_native_patchbay64_plugin(); | CARLA_EXPORT const NativePluginDescriptor* carla_get_native_patchbay64_plugin(); | ||||
/*! | |||||
* Get the native plugin descriptor for the carla-patchbay-cv plugin. | |||||
*/ | |||||
CARLA_EXPORT const NativePluginDescriptor* carla_get_native_patchbay_cv_plugin(); | |||||
#ifdef __cplusplus | #ifdef __cplusplus | ||||
/*! | /*! | ||||
* Get the internal CarlaEngine instance. | * Get the internal CarlaEngine instance. | ||||
@@ -88,19 +88,6 @@ void AudioProcessor::suspendProcessing (const bool shouldBeSuspended) | |||||
void AudioProcessor::reset() {} | void AudioProcessor::reset() {} | ||||
void AudioProcessor::processBlockBypassed (AudioSampleBuffer& buffer, MidiBuffer&) | |||||
{ | |||||
for (uint ch = getTotalNumInputChannels(ChannelTypeAudio); ch < getTotalNumOutputChannels(ChannelTypeAudio); ++ch) | |||||
buffer.clear (ch, 0, buffer.getNumSamples()); | |||||
} | |||||
void AudioProcessor::processBlockWithCV (AudioSampleBuffer& audioBuffer, | |||||
const AudioSampleBuffer&, AudioSampleBuffer&, | |||||
MidiBuffer& midiMessages) | |||||
{ | |||||
processBlock (audioBuffer, midiMessages); | |||||
} | |||||
uint AudioProcessor::getTotalNumInputChannels(ChannelType t) const noexcept | uint AudioProcessor::getTotalNumInputChannels(ChannelType t) const noexcept | ||||
{ | { | ||||
switch (t) | switch (t) | ||||
@@ -154,26 +154,10 @@ public: | |||||
@see AudiobusLayout::getBusBuffer | @see AudiobusLayout::getBusBuffer | ||||
*/ | */ | ||||
virtual void processBlock (AudioSampleBuffer& buffer, | |||||
MidiBuffer& midiMessages) = 0; | |||||
virtual void processBlockWithCV (AudioSampleBuffer& audioBuffer, | virtual void processBlockWithCV (AudioSampleBuffer& audioBuffer, | ||||
const AudioSampleBuffer& cvInBuffer, | const AudioSampleBuffer& cvInBuffer, | ||||
AudioSampleBuffer& cvOutBuffer, | AudioSampleBuffer& cvOutBuffer, | ||||
MidiBuffer& midiMessages); | |||||
/** Renders the next block when the processor is being bypassed. | |||||
The default implementation of this method will pass-through any incoming audio, but | |||||
you may override this method e.g. to add latency compensation to the data to match | |||||
the processor's latency characteristics. This will avoid situations where bypassing | |||||
will shift the signal forward in time, possibly creating pre-echo effects and odd timings. | |||||
Another use for this method would be to cross-fade or morph between the wet (not bypassed) | |||||
and dry (bypassed) signals. | |||||
*/ | |||||
virtual void processBlockBypassed (AudioSampleBuffer& buffer, | |||||
MidiBuffer& midiMessages); | |||||
MidiBuffer& midiMessages) = 0; | |||||
//============================================================================== | //============================================================================== | ||||
/** Returns the total number of input channels. */ | /** Returns the total number of input channels. */ | ||||
@@ -1158,7 +1158,8 @@ void AudioProcessorGraph::Node::setParentGraph (AudioProcessorGraph* const graph | |||||
struct AudioProcessorGraph::AudioProcessorGraphBufferHelpers | struct AudioProcessorGraph::AudioProcessorGraphBufferHelpers | ||||
{ | { | ||||
AudioProcessorGraphBufferHelpers() noexcept | AudioProcessorGraphBufferHelpers() noexcept | ||||
: currentAudioInputBuffer (nullptr) {} | |||||
: currentAudioInputBuffer (nullptr), | |||||
currentCVInputBuffer (nullptr) {} | |||||
void setRenderingBufferSize (int newNumAudioChannels, int newNumCVChannels, int newNumSamples) noexcept | void setRenderingBufferSize (int newNumAudioChannels, int newNumCVChannels, int newNumSamples) noexcept | ||||
{ | { | ||||
@@ -1173,26 +1174,32 @@ struct AudioProcessorGraph::AudioProcessorGraphBufferHelpers | |||||
{ | { | ||||
renderingAudioBuffers.setSize (1, 1); | renderingAudioBuffers.setSize (1, 1); | ||||
currentAudioInputBuffer = nullptr; | currentAudioInputBuffer = nullptr; | ||||
currentCVInputBuffer = nullptr; | |||||
currentAudioOutputBuffer.setSize (1, 1); | currentAudioOutputBuffer.setSize (1, 1); | ||||
currentCVOutputBuffer.setSize (1, 1); | |||||
renderingCVBuffers.setSize (1, 1); | renderingCVBuffers.setSize (1, 1); | ||||
} | } | ||||
void prepareInOutBuffers(int newNumChannels, int newNumSamples) noexcept | |||||
void prepareInOutBuffers (int newNumAudioChannels, int newNumCVChannels, int newNumSamples) noexcept | |||||
{ | { | ||||
currentAudioInputBuffer = nullptr; | currentAudioInputBuffer = nullptr; | ||||
currentAudioOutputBuffer.setSize (newNumChannels, newNumSamples); | |||||
currentCVInputBuffer = nullptr; | |||||
currentAudioOutputBuffer.setSize (newNumAudioChannels, newNumSamples); | |||||
currentCVOutputBuffer.setSize (newNumCVChannels, newNumSamples); | |||||
} | } | ||||
AudioSampleBuffer renderingAudioBuffers; | |||||
AudioSampleBuffer renderingCVBuffers; | |||||
AudioSampleBuffer* currentAudioInputBuffer; | |||||
AudioSampleBuffer currentAudioOutputBuffer; | |||||
AudioSampleBuffer renderingAudioBuffers; | |||||
AudioSampleBuffer renderingCVBuffers; | |||||
AudioSampleBuffer* currentAudioInputBuffer; | |||||
const AudioSampleBuffer* currentCVInputBuffer; | |||||
AudioSampleBuffer currentAudioOutputBuffer; | |||||
AudioSampleBuffer currentCVOutputBuffer; | |||||
}; | }; | ||||
//============================================================================== | //============================================================================== | ||||
AudioProcessorGraph::AudioProcessorGraph() | AudioProcessorGraph::AudioProcessorGraph() | ||||
: lastNodeId (0), audioBuffers (new AudioProcessorGraphBufferHelpers), | |||||
: lastNodeId (0), audioAndCVBuffers (new AudioProcessorGraphBufferHelpers), | |||||
currentMidiInputBuffer (nullptr), isPrepared (false), needsReorder (false) | currentMidiInputBuffer (nullptr), isPrepared (false), needsReorder (false) | ||||
{ | { | ||||
} | } | ||||
@@ -1525,9 +1532,9 @@ void AudioProcessorGraph::buildRenderingSequence() | |||||
// swap over to the new rendering sequence.. | // swap over to the new rendering sequence.. | ||||
const CarlaRecursiveMutexLocker cml (getCallbackLock()); | const CarlaRecursiveMutexLocker cml (getCallbackLock()); | ||||
audioBuffers->setRenderingBufferSize (numAudioRenderingBuffersNeeded, | |||||
numCVRenderingBuffersNeeded, | |||||
getBlockSize()); | |||||
audioAndCVBuffers->setRenderingBufferSize (numAudioRenderingBuffersNeeded, | |||||
numCVRenderingBuffersNeeded, | |||||
getBlockSize()); | |||||
for (int i = static_cast<int>(midiBuffers.size()); --i >= 0;) | for (int i = static_cast<int>(midiBuffers.size()); --i >= 0;) | ||||
midiBuffers.getUnchecked(i)->clear(); | midiBuffers.getUnchecked(i)->clear(); | ||||
@@ -1547,7 +1554,9 @@ void AudioProcessorGraph::prepareToPlay (double sampleRate, int estimatedSamples | |||||
{ | { | ||||
setRateAndBufferSizeDetails(sampleRate, estimatedSamplesPerBlock); | setRateAndBufferSizeDetails(sampleRate, estimatedSamplesPerBlock); | ||||
audioBuffers->prepareInOutBuffers(jmax(1U, getTotalNumOutputChannels(AudioProcessor::ChannelTypeAudio)), estimatedSamplesPerBlock); | |||||
audioAndCVBuffers->prepareInOutBuffers(jmax(1U, getTotalNumOutputChannels(AudioProcessor::ChannelTypeAudio)), | |||||
jmax(1U, getTotalNumOutputChannels(AudioProcessor::ChannelTypeCV)), | |||||
estimatedSamplesPerBlock); | |||||
currentMidiInputBuffer = nullptr; | currentMidiInputBuffer = nullptr; | ||||
currentMidiOutputBuffer.clear(); | currentMidiOutputBuffer.clear(); | ||||
@@ -1565,7 +1574,7 @@ void AudioProcessorGraph::releaseResources() | |||||
for (int i = 0; i < nodes.size(); ++i) | for (int i = 0; i < nodes.size(); ++i) | ||||
nodes.getUnchecked(i)->unprepare(); | nodes.getUnchecked(i)->unprepare(); | ||||
audioBuffers->release(); | |||||
audioAndCVBuffers->release(); | |||||
midiBuffers.clear(); | midiBuffers.clear(); | ||||
currentMidiInputBuffer = nullptr; | currentMidiInputBuffer = nullptr; | ||||
@@ -1590,23 +1599,24 @@ void AudioProcessorGraph::setNonRealtime (bool isProcessingNonRealtime) noexcept | |||||
nodes.getUnchecked(i)->getProcessor()->setNonRealtime (isProcessingNonRealtime); | nodes.getUnchecked(i)->getProcessor()->setNonRealtime (isProcessingNonRealtime); | ||||
} | } | ||||
void AudioProcessorGraph::processAudio (AudioSampleBuffer& buffer, MidiBuffer& midiMessages) | |||||
/* | |||||
void AudioProcessorGraph::processAudio (AudioSampleBuffer& audioBuffer, MidiBuffer& midiMessages) | |||||
{ | { | ||||
AudioSampleBuffer*& currentAudioInputBuffer = audioBuffers->currentAudioInputBuffer; | |||||
AudioSampleBuffer& currentAudioOutputBuffer = audioBuffers->currentAudioOutputBuffer; | |||||
AudioSampleBuffer& renderingAudioBuffers = audioBuffers->renderingAudioBuffers; | |||||
AudioSampleBuffer& renderingCVBuffers = audioBuffers->renderingCVBuffers; | |||||
AudioSampleBuffer*& currentAudioInputBuffer = audioAndCVBuffers->currentAudioInputBuffer; | |||||
AudioSampleBuffer& currentAudioOutputBuffer = audioAndCVBuffers->currentAudioOutputBuffer; | |||||
AudioSampleBuffer& renderingAudioBuffers = audioAndCVBuffers->renderingAudioBuffers; | |||||
AudioSampleBuffer& renderingCVBuffers = audioAndCVBuffers->renderingCVBuffers; | |||||
const int numSamples = buffer.getNumSamples(); | |||||
const int numSamples = audioBuffer.getNumSamples(); | |||||
if (! audioBuffers->currentAudioOutputBuffer.setSizeRT(numSamples)) | |||||
if (! audioAndCVBuffers->currentAudioOutputBuffer.setSizeRT(numSamples)) | |||||
return; | return; | ||||
if (! audioBuffers->renderingAudioBuffers.setSizeRT(numSamples)) | |||||
if (! audioAndCVBuffers->renderingAudioBuffers.setSizeRT(numSamples)) | |||||
return; | return; | ||||
if (! audioBuffers->renderingCVBuffers.setSizeRT(numSamples)) | |||||
if (! audioAndCVBuffers->renderingCVBuffers.setSizeRT(numSamples)) | |||||
return; | return; | ||||
currentAudioInputBuffer = &buffer; | |||||
currentAudioInputBuffer = &audioBuffer; | |||||
currentAudioOutputBuffer.clear(); | currentAudioOutputBuffer.clear(); | ||||
currentMidiInputBuffer = &midiMessages; | currentMidiInputBuffer = &midiMessages; | ||||
currentMidiOutputBuffer.clear(); | currentMidiOutputBuffer.clear(); | ||||
@@ -1619,27 +1629,78 @@ void AudioProcessorGraph::processAudio (AudioSampleBuffer& buffer, MidiBuffer& m | |||||
op->perform (renderingAudioBuffers, renderingCVBuffers, midiBuffers, numSamples); | op->perform (renderingAudioBuffers, renderingCVBuffers, midiBuffers, numSamples); | ||||
} | } | ||||
for (uint32_t i = 0; i < buffer.getNumChannels(); ++i) | |||||
buffer.copyFrom (i, 0, currentAudioOutputBuffer, i, 0, numSamples); | |||||
for (uint32_t i = 0; i < audioBuffer.getNumChannels(); ++i) | |||||
audioBuffer.copyFrom (i, 0, currentAudioOutputBuffer, i, 0, numSamples); | |||||
midiMessages.clear(); | midiMessages.clear(); | ||||
midiMessages.addEvents (currentMidiOutputBuffer, 0, buffer.getNumSamples(), 0); | |||||
midiMessages.addEvents (currentMidiOutputBuffer, 0, audioBuffer.getNumSamples(), 0); | |||||
} | |||||
*/ | |||||
void AudioProcessorGraph::processAudioAndCV (AudioSampleBuffer& audioBuffer, | |||||
const AudioSampleBuffer& cvInBuffer, | |||||
AudioSampleBuffer& cvOutBuffer, | |||||
MidiBuffer& midiMessages) | |||||
{ | |||||
AudioSampleBuffer*& currentAudioInputBuffer = audioAndCVBuffers->currentAudioInputBuffer; | |||||
const AudioSampleBuffer*& currentCVInputBuffer = audioAndCVBuffers->currentCVInputBuffer; | |||||
AudioSampleBuffer& currentAudioOutputBuffer = audioAndCVBuffers->currentAudioOutputBuffer; | |||||
AudioSampleBuffer& currentCVOutputBuffer = audioAndCVBuffers->currentCVOutputBuffer; | |||||
AudioSampleBuffer& renderingAudioBuffers = audioAndCVBuffers->renderingAudioBuffers; | |||||
AudioSampleBuffer& renderingCVBuffers = audioAndCVBuffers->renderingCVBuffers; | |||||
const int numSamples = audioBuffer.getNumSamples(); | |||||
if (! audioAndCVBuffers->currentAudioOutputBuffer.setSizeRT(numSamples)) | |||||
return; | |||||
if (! audioAndCVBuffers->currentCVOutputBuffer.setSizeRT(numSamples)) | |||||
return; | |||||
if (! audioAndCVBuffers->renderingAudioBuffers.setSizeRT(numSamples)) | |||||
return; | |||||
if (! audioAndCVBuffers->renderingCVBuffers.setSizeRT(numSamples)) | |||||
return; | |||||
currentAudioInputBuffer = &audioBuffer; | |||||
currentCVInputBuffer = &cvInBuffer; | |||||
currentAudioOutputBuffer.clear(); | |||||
currentCVOutputBuffer.clear(); | |||||
currentMidiInputBuffer = &midiMessages; | |||||
currentMidiOutputBuffer.clear(); | |||||
for (int i = 0; i < renderingOps.size(); ++i) | |||||
{ | |||||
GraphRenderingOps::AudioGraphRenderingOpBase* const op | |||||
= (GraphRenderingOps::AudioGraphRenderingOpBase*) renderingOps.getUnchecked(i); | |||||
op->perform (renderingAudioBuffers, renderingCVBuffers, midiBuffers, numSamples); | |||||
} | |||||
for (uint32_t i = 0; i < audioBuffer.getNumChannels(); ++i) | |||||
audioBuffer.copyFrom (i, 0, currentAudioOutputBuffer, i, 0, numSamples); | |||||
for (uint32_t i = 0; i < cvOutBuffer.getNumChannels(); ++i) | |||||
cvOutBuffer.copyFrom (i, 0, currentCVOutputBuffer, i, 0, numSamples); | |||||
midiMessages.clear(); | |||||
midiMessages.addEvents (currentMidiOutputBuffer, 0, audioBuffer.getNumSamples(), 0); | |||||
} | } | ||||
bool AudioProcessorGraph::acceptsMidi() const { return true; } | bool AudioProcessorGraph::acceptsMidi() const { return true; } | ||||
bool AudioProcessorGraph::producesMidi() const { return true; } | bool AudioProcessorGraph::producesMidi() const { return true; } | ||||
/* | |||||
void AudioProcessorGraph::processBlock (AudioSampleBuffer& buffer, MidiBuffer& midiMessages) | void AudioProcessorGraph::processBlock (AudioSampleBuffer& buffer, MidiBuffer& midiMessages) | ||||
{ | { | ||||
processAudio (buffer, midiMessages); | processAudio (buffer, midiMessages); | ||||
} | } | ||||
*/ | |||||
void AudioProcessorGraph::processBlockWithCV (AudioSampleBuffer& buffer, | |||||
const AudioSampleBuffer&, | |||||
AudioSampleBuffer&, | |||||
void AudioProcessorGraph::processBlockWithCV (AudioSampleBuffer& audioBuffer, | |||||
const AudioSampleBuffer& cvInBuffer, | |||||
AudioSampleBuffer& cvOutBuffer, | |||||
MidiBuffer& midiMessages) | MidiBuffer& midiMessages) | ||||
{ | { | ||||
processAudio (buffer, midiMessages); | |||||
processAudioAndCV (audioBuffer, cvInBuffer, cvOutBuffer, midiMessages); | |||||
} | } | ||||
void AudioProcessorGraph::reorderNowIfNeeded() | void AudioProcessorGraph::reorderNowIfNeeded() | ||||
@@ -1691,25 +1752,24 @@ void AudioProcessorGraph::AudioGraphIOProcessor::releaseResources() | |||||
{ | { | ||||
} | } | ||||
void AudioProcessorGraph::AudioGraphIOProcessor::processAudio (AudioSampleBuffer& buffer, | |||||
MidiBuffer& midiMessages) | |||||
void AudioProcessorGraph::AudioGraphIOProcessor::processAudioAndCV (AudioSampleBuffer& audioBuffer, | |||||
const AudioSampleBuffer& cvInBuffer, | |||||
AudioSampleBuffer& cvOutBuffer, | |||||
MidiBuffer& midiMessages) | |||||
{ | { | ||||
CARLA_SAFE_ASSERT_RETURN(graph != nullptr,); | CARLA_SAFE_ASSERT_RETURN(graph != nullptr,); | ||||
AudioSampleBuffer*& currentAudioInputBuffer = | |||||
graph->audioBuffers->currentAudioInputBuffer; | |||||
AudioSampleBuffer& currentAudioOutputBuffer = | |||||
graph->audioBuffers->currentAudioOutputBuffer; | |||||
switch (type) | switch (type) | ||||
{ | { | ||||
case audioOutputNode: | case audioOutputNode: | ||||
{ | { | ||||
AudioSampleBuffer& currentAudioOutputBuffer = | |||||
graph->audioAndCVBuffers->currentAudioOutputBuffer; | |||||
for (int i = jmin (currentAudioOutputBuffer.getNumChannels(), | for (int i = jmin (currentAudioOutputBuffer.getNumChannels(), | ||||
buffer.getNumChannels()); --i >= 0;) | |||||
audioBuffer.getNumChannels()); --i >= 0;) | |||||
{ | { | ||||
currentAudioOutputBuffer.addFrom (i, 0, buffer, i, 0, buffer.getNumSamples()); | |||||
currentAudioOutputBuffer.addFrom (i, 0, audioBuffer, i, 0, audioBuffer.getNumSamples()); | |||||
} | } | ||||
break; | break; | ||||
@@ -1717,21 +1777,52 @@ void AudioProcessorGraph::AudioGraphIOProcessor::processAudio (AudioSampleBuffer | |||||
case audioInputNode: | case audioInputNode: | ||||
{ | { | ||||
AudioSampleBuffer*& currentAudioInputBuffer = | |||||
graph->audioAndCVBuffers->currentAudioInputBuffer; | |||||
for (int i = jmin (currentAudioInputBuffer->getNumChannels(), | for (int i = jmin (currentAudioInputBuffer->getNumChannels(), | ||||
buffer.getNumChannels()); --i >= 0;) | |||||
audioBuffer.getNumChannels()); --i >= 0;) | |||||
{ | { | ||||
buffer.copyFrom (i, 0, *currentAudioInputBuffer, i, 0, buffer.getNumSamples()); | |||||
audioBuffer.copyFrom (i, 0, *currentAudioInputBuffer, i, 0, audioBuffer.getNumSamples()); | |||||
} | |||||
break; | |||||
} | |||||
case cvOutputNode: | |||||
{ | |||||
AudioSampleBuffer& currentCVOutputBuffer = | |||||
graph->audioAndCVBuffers->currentCVOutputBuffer; | |||||
for (int i = jmin (currentCVOutputBuffer.getNumChannels(), | |||||
cvInBuffer.getNumChannels()); --i >= 0;) | |||||
{ | |||||
currentCVOutputBuffer.addFrom (i, 0, cvInBuffer, i, 0, cvInBuffer.getNumSamples()); | |||||
} | |||||
break; | |||||
} | |||||
case cvInputNode: | |||||
{ | |||||
const AudioSampleBuffer*& currentCVInputBuffer = | |||||
graph->audioAndCVBuffers->currentCVInputBuffer; | |||||
for (int i = jmin (currentCVInputBuffer->getNumChannels(), | |||||
cvOutBuffer.getNumChannels()); --i >= 0;) | |||||
{ | |||||
cvOutBuffer.copyFrom (i, 0, *currentCVInputBuffer, i, 0, cvOutBuffer.getNumSamples()); | |||||
} | } | ||||
break; | break; | ||||
} | } | ||||
case midiOutputNode: | case midiOutputNode: | ||||
graph->currentMidiOutputBuffer.addEvents (midiMessages, 0, buffer.getNumSamples(), 0); | |||||
graph->currentMidiOutputBuffer.addEvents (midiMessages, 0, audioBuffer.getNumSamples(), 0); | |||||
break; | break; | ||||
case midiInputNode: | case midiInputNode: | ||||
midiMessages.addEvents (*graph->currentMidiInputBuffer, 0, buffer.getNumSamples(), 0); | |||||
midiMessages.addEvents (*graph->currentMidiInputBuffer, 0, audioBuffer.getNumSamples(), 0); | |||||
break; | break; | ||||
default: | default: | ||||
@@ -1739,10 +1830,12 @@ void AudioProcessorGraph::AudioGraphIOProcessor::processAudio (AudioSampleBuffer | |||||
} | } | ||||
} | } | ||||
void AudioProcessorGraph::AudioGraphIOProcessor::processBlock (AudioSampleBuffer& buffer, | |||||
MidiBuffer& midiMessages) | |||||
void AudioProcessorGraph::AudioGraphIOProcessor::processBlockWithCV (AudioSampleBuffer& audioBuffer, | |||||
const AudioSampleBuffer& cvInBuffer, | |||||
AudioSampleBuffer& cvOutBuffer, | |||||
MidiBuffer& midiMessages) | |||||
{ | { | ||||
processAudio (buffer, midiMessages); | |||||
processAudioAndCV (audioBuffer, cvInBuffer, cvOutBuffer, midiMessages); | |||||
} | } | ||||
bool AudioProcessorGraph::AudioGraphIOProcessor::acceptsMidi() const | bool AudioProcessorGraph::AudioGraphIOProcessor::acceptsMidi() const | ||||
@@ -318,12 +318,12 @@ public: | |||||
~AudioGraphIOProcessor(); | ~AudioGraphIOProcessor(); | ||||
const String getName() const override; | const String getName() const override; | ||||
#if 0 | |||||
void fillInPluginDescription (PluginDescription&) const override; | |||||
#endif | |||||
void prepareToPlay (double newSampleRate, int estimatedSamplesPerBlock) override; | void prepareToPlay (double newSampleRate, int estimatedSamplesPerBlock) override; | ||||
void releaseResources() override; | void releaseResources() override; | ||||
void processBlock (AudioSampleBuffer&, MidiBuffer&) override; | |||||
void processBlockWithCV (AudioSampleBuffer& audioBuffer, | |||||
const AudioSampleBuffer& cvInBuffer, | |||||
AudioSampleBuffer& cvOutBuffer, | |||||
MidiBuffer& midiMessages) override; | |||||
bool acceptsMidi() const override; | bool acceptsMidi() const override; | ||||
bool producesMidi() const override; | bool producesMidi() const override; | ||||
@@ -336,7 +336,11 @@ public: | |||||
AudioProcessorGraph* graph; | AudioProcessorGraph* graph; | ||||
//============================================================================== | //============================================================================== | ||||
void processAudio (AudioSampleBuffer& buffer, MidiBuffer& midiMessages); | |||||
//void processAudio (AudioSampleBuffer& buffer, MidiBuffer& midiMessages); | |||||
void processAudioAndCV (AudioSampleBuffer& audioBuffer, | |||||
const AudioSampleBuffer& cvInBuffer, | |||||
AudioSampleBuffer& cvOutBuffer, | |||||
MidiBuffer& midiMessages); | |||||
CARLA_DECLARE_NON_COPY_CLASS (AudioGraphIOProcessor) | CARLA_DECLARE_NON_COPY_CLASS (AudioGraphIOProcessor) | ||||
}; | }; | ||||
@@ -345,8 +349,8 @@ public: | |||||
const String getName() const override; | const String getName() const override; | ||||
void prepareToPlay (double, int) override; | void prepareToPlay (double, int) override; | ||||
void releaseResources() override; | void releaseResources() override; | ||||
void processBlock (AudioSampleBuffer&, MidiBuffer&) override; | |||||
void processBlockWithCV (AudioSampleBuffer& buffer, | |||||
//void processBlock (AudioSampleBuffer&, MidiBuffer&) override; | |||||
void processBlockWithCV (AudioSampleBuffer& audioBuffer, | |||||
const AudioSampleBuffer& cvInBuffer, | const AudioSampleBuffer& cvInBuffer, | ||||
AudioSampleBuffer& cvOutBuffer, | AudioSampleBuffer& cvOutBuffer, | ||||
MidiBuffer& midiMessages) override; | MidiBuffer& midiMessages) override; | ||||
@@ -362,7 +366,11 @@ public: | |||||
private: | private: | ||||
//============================================================================== | //============================================================================== | ||||
void processAudio (AudioSampleBuffer& buffer, MidiBuffer& midiMessages); | |||||
// void processAudio (AudioSampleBuffer& audioBuffer, MidiBuffer& midiMessages); | |||||
void processAudioAndCV (AudioSampleBuffer& audioBuffer, | |||||
const AudioSampleBuffer& cvInBuffer, | |||||
AudioSampleBuffer& cvOutBuffer, | |||||
MidiBuffer& midiMessages); | |||||
//============================================================================== | //============================================================================== | ||||
ReferenceCountedArray<Node> nodes; | ReferenceCountedArray<Node> nodes; | ||||
@@ -373,7 +381,7 @@ private: | |||||
friend class AudioGraphIOProcessor; | friend class AudioGraphIOProcessor; | ||||
struct AudioProcessorGraphBufferHelpers; | struct AudioProcessorGraphBufferHelpers; | ||||
ScopedPointer<AudioProcessorGraphBufferHelpers> audioBuffers; | |||||
ScopedPointer<AudioProcessorGraphBufferHelpers> audioAndCVBuffers; | |||||
MidiBuffer* currentMidiInputBuffer; | MidiBuffer* currentMidiInputBuffer; | ||||
MidiBuffer currentMidiOutputBuffer; | MidiBuffer currentMidiOutputBuffer; | ||||
@@ -19,13 +19,16 @@ | |||||
#include "CarlaMIDI.h" | #include "CarlaMIDI.h" | ||||
#include "CarlaUtils.hpp" | #include "CarlaUtils.hpp" | ||||
#undef DESCFUNCS | |||||
#define DESCFUNCS \ | |||||
#undef DESCFUNCS_WITHCV | |||||
#undef DESCFUNCS_WITHOUTCV | |||||
#define DESCFUNCS_WITHCV \ | |||||
nullptr, nullptr, nullptr, nullptr, nullptr, \ | nullptr, nullptr, nullptr, nullptr, nullptr, \ | ||||
nullptr, nullptr, nullptr, nullptr, nullptr, \ | nullptr, nullptr, nullptr, nullptr, nullptr, \ | ||||
nullptr, nullptr, nullptr, nullptr, nullptr, \ | nullptr, nullptr, nullptr, nullptr, nullptr, \ | ||||
nullptr, nullptr, nullptr, nullptr, nullptr, \ | nullptr, nullptr, nullptr, nullptr, nullptr, \ | ||||
nullptr, nullptr | nullptr, nullptr | ||||
#define DESCFUNCS_WITHOUTCV \ | |||||
DESCFUNCS_WITHCV, 0, 0 | |||||
static const NativePluginDescriptor sNativePluginDescriptors[] = { | static const NativePluginDescriptor sNativePluginDescriptors[] = { | ||||
@@ -46,7 +49,7 @@ static const NativePluginDescriptor sNativePluginDescriptors[] = { | |||||
/* label */ "audiogain", | /* label */ "audiogain", | ||||
/* maker */ "falkTX", | /* maker */ "falkTX", | ||||
/* copyright */ "GNU GPL v2+", | /* copyright */ "GNU GPL v2+", | ||||
DESCFUNCS | |||||
DESCFUNCS_WITHOUTCV | |||||
}, | }, | ||||
{ | { | ||||
/* category */ NATIVE_PLUGIN_CATEGORY_UTILITY, | /* category */ NATIVE_PLUGIN_CATEGORY_UTILITY, | ||||
@@ -62,7 +65,7 @@ static const NativePluginDescriptor sNativePluginDescriptors[] = { | |||||
/* label */ "audiogain_s", | /* label */ "audiogain_s", | ||||
/* maker */ "falkTX", | /* maker */ "falkTX", | ||||
/* copyright */ "GNU GPL v2+", | /* copyright */ "GNU GPL v2+", | ||||
DESCFUNCS | |||||
DESCFUNCS_WITHOUTCV | |||||
}, | }, | ||||
{ | { | ||||
/* category */ NATIVE_PLUGIN_CATEGORY_NONE, | /* category */ NATIVE_PLUGIN_CATEGORY_NONE, | ||||
@@ -78,7 +81,7 @@ static const NativePluginDescriptor sNativePluginDescriptors[] = { | |||||
/* label */ "bypass", | /* label */ "bypass", | ||||
/* maker */ "falkTX", | /* maker */ "falkTX", | ||||
/* copyright */ "GNU GPL v2+", | /* copyright */ "GNU GPL v2+", | ||||
DESCFUNCS | |||||
DESCFUNCS_WITHOUTCV | |||||
}, | }, | ||||
{ | { | ||||
/* category */ NATIVE_PLUGIN_CATEGORY_UTILITY, | /* category */ NATIVE_PLUGIN_CATEGORY_UTILITY, | ||||
@@ -94,7 +97,7 @@ static const NativePluginDescriptor sNativePluginDescriptors[] = { | |||||
/* label */ "lfo", | /* label */ "lfo", | ||||
/* maker */ "falkTX", | /* maker */ "falkTX", | ||||
/* copyright */ "GNU GPL v2+", | /* copyright */ "GNU GPL v2+", | ||||
DESCFUNCS | |||||
DESCFUNCS_WITHOUTCV | |||||
}, | }, | ||||
{ | { | ||||
/* category */ NATIVE_PLUGIN_CATEGORY_UTILITY, | /* category */ NATIVE_PLUGIN_CATEGORY_UTILITY, | ||||
@@ -110,7 +113,7 @@ static const NativePluginDescriptor sNativePluginDescriptors[] = { | |||||
/* label */ "midichanfilter", | /* label */ "midichanfilter", | ||||
/* maker */ "falkTX", | /* maker */ "falkTX", | ||||
/* copyright */ "GNU GPL v2+", | /* copyright */ "GNU GPL v2+", | ||||
DESCFUNCS | |||||
DESCFUNCS_WITHOUTCV | |||||
}, | }, | ||||
{ | { | ||||
/* category */ NATIVE_PLUGIN_CATEGORY_UTILITY, | /* category */ NATIVE_PLUGIN_CATEGORY_UTILITY, | ||||
@@ -126,7 +129,7 @@ static const NativePluginDescriptor sNativePluginDescriptors[] = { | |||||
/* label */ "midichanab", | /* label */ "midichanab", | ||||
/* maker */ "Milk Brewster", | /* maker */ "Milk Brewster", | ||||
/* copyright */ "GNU GPL v2+", | /* copyright */ "GNU GPL v2+", | ||||
DESCFUNCS | |||||
DESCFUNCS_WITHOUTCV | |||||
}, | }, | ||||
{ | { | ||||
/* category */ NATIVE_PLUGIN_CATEGORY_UTILITY, | /* category */ NATIVE_PLUGIN_CATEGORY_UTILITY, | ||||
@@ -142,7 +145,7 @@ static const NativePluginDescriptor sNativePluginDescriptors[] = { | |||||
/* label */ "midigain", | /* label */ "midigain", | ||||
/* maker */ "falkTX", | /* maker */ "falkTX", | ||||
/* copyright */ "GNU GPL v2+", | /* copyright */ "GNU GPL v2+", | ||||
DESCFUNCS | |||||
DESCFUNCS_WITHOUTCV | |||||
}, | }, | ||||
{ | { | ||||
/* category */ NATIVE_PLUGIN_CATEGORY_UTILITY, | /* category */ NATIVE_PLUGIN_CATEGORY_UTILITY, | ||||
@@ -158,7 +161,7 @@ static const NativePluginDescriptor sNativePluginDescriptors[] = { | |||||
/* label */ "midijoin", | /* label */ "midijoin", | ||||
/* maker */ "falkTX", | /* maker */ "falkTX", | ||||
/* copyright */ "GNU GPL v2+", | /* copyright */ "GNU GPL v2+", | ||||
DESCFUNCS | |||||
DESCFUNCS_WITHOUTCV | |||||
}, | }, | ||||
{ | { | ||||
/* category */ NATIVE_PLUGIN_CATEGORY_UTILITY, | /* category */ NATIVE_PLUGIN_CATEGORY_UTILITY, | ||||
@@ -174,7 +177,7 @@ static const NativePluginDescriptor sNativePluginDescriptors[] = { | |||||
/* label */ "midisplit", | /* label */ "midisplit", | ||||
/* maker */ "falkTX", | /* maker */ "falkTX", | ||||
/* copyright */ "GNU GPL v2+", | /* copyright */ "GNU GPL v2+", | ||||
DESCFUNCS | |||||
DESCFUNCS_WITHOUTCV | |||||
}, | }, | ||||
{ | { | ||||
/* category */ NATIVE_PLUGIN_CATEGORY_UTILITY, | /* category */ NATIVE_PLUGIN_CATEGORY_UTILITY, | ||||
@@ -190,7 +193,7 @@ static const NativePluginDescriptor sNativePluginDescriptors[] = { | |||||
/* label */ "midithrough", | /* label */ "midithrough", | ||||
/* maker */ "falkTX", | /* maker */ "falkTX", | ||||
/* copyright */ "GNU GPL v2+", | /* copyright */ "GNU GPL v2+", | ||||
DESCFUNCS | |||||
DESCFUNCS_WITHOUTCV | |||||
}, | }, | ||||
{ | { | ||||
/* category */ NATIVE_PLUGIN_CATEGORY_UTILITY, | /* category */ NATIVE_PLUGIN_CATEGORY_UTILITY, | ||||
@@ -206,7 +209,7 @@ static const NativePluginDescriptor sNativePluginDescriptors[] = { | |||||
/* label */ "miditranspose", | /* label */ "miditranspose", | ||||
/* maker */ "falkTX", | /* maker */ "falkTX", | ||||
/* copyright */ "GNU GPL v2+", | /* copyright */ "GNU GPL v2+", | ||||
DESCFUNCS | |||||
DESCFUNCS_WITHOUTCV | |||||
}, | }, | ||||
{ | { | ||||
/* category */ NATIVE_PLUGIN_CATEGORY_UTILITY, | /* category */ NATIVE_PLUGIN_CATEGORY_UTILITY, | ||||
@@ -222,7 +225,7 @@ static const NativePluginDescriptor sNativePluginDescriptors[] = { | |||||
/* label */ "midichannelize", | /* label */ "midichannelize", | ||||
/* maker */ "falkTX", | /* maker */ "falkTX", | ||||
/* copyright */ "GNU GPL v2+", | /* copyright */ "GNU GPL v2+", | ||||
DESCFUNCS | |||||
DESCFUNCS_WITHOUTCV | |||||
}, | }, | ||||
// -------------------------------------------------------------------------------------------------------------------- | // -------------------------------------------------------------------------------------------------------------------- | ||||
@@ -245,7 +248,7 @@ static const NativePluginDescriptor sNativePluginDescriptors[] = { | |||||
/* label */ "audiofile", | /* label */ "audiofile", | ||||
/* maker */ "falkTX", | /* maker */ "falkTX", | ||||
/* copyright */ "GNU GPL v2+", | /* copyright */ "GNU GPL v2+", | ||||
DESCFUNCS | |||||
DESCFUNCS_WITHOUTCV | |||||
}, | }, | ||||
// -------------------------------------------------------------------------------------------------------------------- | // -------------------------------------------------------------------------------------------------------------------- | ||||
@@ -269,7 +272,7 @@ static const NativePluginDescriptor sNativePluginDescriptors[] = { | |||||
/* label */ "midifile", | /* label */ "midifile", | ||||
/* maker */ "falkTX", | /* maker */ "falkTX", | ||||
/* copyright */ "GNU GPL v2+", | /* copyright */ "GNU GPL v2+", | ||||
DESCFUNCS | |||||
DESCFUNCS_WITHOUTCV | |||||
}, | }, | ||||
#ifdef HAVE_PYQT | #ifdef HAVE_PYQT | ||||
{ | { | ||||
@@ -289,7 +292,7 @@ static const NativePluginDescriptor sNativePluginDescriptors[] = { | |||||
/* label */ "midipattern", | /* label */ "midipattern", | ||||
/* maker */ "falkTX, tatch", | /* maker */ "falkTX, tatch", | ||||
/* copyright */ "GNU GPL v2+", | /* copyright */ "GNU GPL v2+", | ||||
DESCFUNCS | |||||
DESCFUNCS_WITHOUTCV | |||||
}, | }, | ||||
#endif | #endif | ||||
@@ -315,7 +318,7 @@ static const NativePluginDescriptor sNativePluginDescriptors[] = { | |||||
/* label */ "carlarack", | /* label */ "carlarack", | ||||
/* maker */ "falkTX", | /* maker */ "falkTX", | ||||
/* copyright */ "GNU GPL v2+", | /* copyright */ "GNU GPL v2+", | ||||
DESCFUNCS | |||||
DESCFUNCS_WITHOUTCV | |||||
}, | }, | ||||
{ | { | ||||
/* category */ NATIVE_PLUGIN_CATEGORY_OTHER, | /* category */ NATIVE_PLUGIN_CATEGORY_OTHER, | ||||
@@ -335,7 +338,7 @@ static const NativePluginDescriptor sNativePluginDescriptors[] = { | |||||
/* label */ "carlarack-nomidiout", | /* label */ "carlarack-nomidiout", | ||||
/* maker */ "falkTX", | /* maker */ "falkTX", | ||||
/* copyright */ "GNU GPL v2+", | /* copyright */ "GNU GPL v2+", | ||||
DESCFUNCS | |||||
DESCFUNCS_WITHOUTCV | |||||
}, | }, | ||||
{ | { | ||||
/* category */ NATIVE_PLUGIN_CATEGORY_OTHER, | /* category */ NATIVE_PLUGIN_CATEGORY_OTHER, | ||||
@@ -355,7 +358,7 @@ static const NativePluginDescriptor sNativePluginDescriptors[] = { | |||||
/* label */ "carlapatchbay", | /* label */ "carlapatchbay", | ||||
/* maker */ "falkTX", | /* maker */ "falkTX", | ||||
/* copyright */ "GNU GPL v2+", | /* copyright */ "GNU GPL v2+", | ||||
DESCFUNCS | |||||
DESCFUNCS_WITHOUTCV | |||||
}, | }, | ||||
{ | { | ||||
/* category */ NATIVE_PLUGIN_CATEGORY_OTHER, | /* category */ NATIVE_PLUGIN_CATEGORY_OTHER, | ||||
@@ -375,7 +378,7 @@ static const NativePluginDescriptor sNativePluginDescriptors[] = { | |||||
/* label */ "carlapatchbay3s", | /* label */ "carlapatchbay3s", | ||||
/* maker */ "falkTX", | /* maker */ "falkTX", | ||||
/* copyright */ "GNU GPL v2+", | /* copyright */ "GNU GPL v2+", | ||||
DESCFUNCS | |||||
DESCFUNCS_WITHOUTCV | |||||
}, | }, | ||||
{ | { | ||||
/* category */ NATIVE_PLUGIN_CATEGORY_OTHER, | /* category */ NATIVE_PLUGIN_CATEGORY_OTHER, | ||||
@@ -395,7 +398,7 @@ static const NativePluginDescriptor sNativePluginDescriptors[] = { | |||||
/* label */ "carlapatchbay16", | /* label */ "carlapatchbay16", | ||||
/* maker */ "falkTX", | /* maker */ "falkTX", | ||||
/* copyright */ "GNU GPL v2+", | /* copyright */ "GNU GPL v2+", | ||||
DESCFUNCS | |||||
DESCFUNCS_WITHOUTCV | |||||
}, | }, | ||||
{ | { | ||||
/* category */ NATIVE_PLUGIN_CATEGORY_OTHER, | /* category */ NATIVE_PLUGIN_CATEGORY_OTHER, | ||||
@@ -415,7 +418,7 @@ static const NativePluginDescriptor sNativePluginDescriptors[] = { | |||||
/* label */ "carlapatchbay32", | /* label */ "carlapatchbay32", | ||||
/* maker */ "falkTX", | /* maker */ "falkTX", | ||||
/* copyright */ "GNU GPL v2+", | /* copyright */ "GNU GPL v2+", | ||||
DESCFUNCS | |||||
DESCFUNCS_WITHOUTCV | |||||
}, | }, | ||||
{ | { | ||||
/* category */ NATIVE_PLUGIN_CATEGORY_OTHER, | /* category */ NATIVE_PLUGIN_CATEGORY_OTHER, | ||||
@@ -435,7 +438,30 @@ static const NativePluginDescriptor sNativePluginDescriptors[] = { | |||||
/* label */ "carlapatchbay64", | /* label */ "carlapatchbay64", | ||||
/* maker */ "falkTX", | /* maker */ "falkTX", | ||||
/* copyright */ "GNU GPL v2+", | /* copyright */ "GNU GPL v2+", | ||||
DESCFUNCS | |||||
DESCFUNCS_WITHOUTCV | |||||
}, | |||||
{ | |||||
/* category */ NATIVE_PLUGIN_CATEGORY_OTHER, | |||||
/* hints */ static_cast<NativePluginHints>(NATIVE_PLUGIN_IS_SYNTH | |||||
|NATIVE_PLUGIN_HAS_UI | |||||
|NATIVE_PLUGIN_NEEDS_UI_MAIN_THREAD | |||||
|NATIVE_PLUGIN_USES_CONTROL_VOLTAGE | |||||
|NATIVE_PLUGIN_USES_STATE | |||||
|NATIVE_PLUGIN_USES_TIME), | |||||
/* supports */ static_cast<NativePluginSupports>(NATIVE_PLUGIN_SUPPORTS_EVERYTHING), | |||||
/* audioIns */ 2, | |||||
/* audioOuts */ 2, | |||||
/* midiIns */ 1, | |||||
/* midiOuts */ 1, | |||||
/* paramIns */ 100, | |||||
/* paramOuts */ 10, | |||||
/* name */ "Carla-Patchbay (CV)", | |||||
/* label */ "carlapatchbaycv", | |||||
/* maker */ "falkTX", | |||||
/* copyright */ "GNU GPL v2+", | |||||
DESCFUNCS_WITHCV, | |||||
/* cvIns */ 5, | |||||
/* cvOuts */ 5, | |||||
}, | }, | ||||
#endif | #endif | ||||
@@ -459,7 +485,7 @@ static const NativePluginDescriptor sNativePluginDescriptors[] = { | |||||
/* label */ "bigmeter", | /* label */ "bigmeter", | ||||
/* maker */ "falkTX", | /* maker */ "falkTX", | ||||
/* copyright */ "GNU GPL v2+", | /* copyright */ "GNU GPL v2+", | ||||
DESCFUNCS | |||||
DESCFUNCS_WITHOUTCV | |||||
}, | }, | ||||
{ | { | ||||
/* category */ NATIVE_PLUGIN_CATEGORY_UTILITY, | /* category */ NATIVE_PLUGIN_CATEGORY_UTILITY, | ||||
@@ -476,7 +502,7 @@ static const NativePluginDescriptor sNativePluginDescriptors[] = { | |||||
/* label */ "notes", | /* label */ "notes", | ||||
/* maker */ "falkTX", | /* maker */ "falkTX", | ||||
/* copyright */ "GNU GPL v2+", | /* copyright */ "GNU GPL v2+", | ||||
DESCFUNCS | |||||
DESCFUNCS_WITHOUTCV | |||||
}, | }, | ||||
#endif | #endif | ||||
@@ -487,7 +513,8 @@ static const NativePluginDescriptor sNativePluginDescriptors[] = { | |||||
}; | }; | ||||
#undef DESCFUNCS | |||||
#undef DESCFUNCS_WITHCV | |||||
#undef DESCFUNCS_WITHOUTCV | |||||
// -------------------------------------------------------------------------------------------------------------------- | // -------------------------------------------------------------------------------------------------------------------- | ||||
@@ -258,6 +258,8 @@ static const NativePluginDescriptor audiogainStereoDesc = { | |||||
.supports = NATIVE_PLUGIN_SUPPORTS_NOTHING, | .supports = NATIVE_PLUGIN_SUPPORTS_NOTHING, | ||||
.audioIns = 2, | .audioIns = 2, | ||||
.audioOuts = 2, | .audioOuts = 2, | ||||
.cvIns = 0, | |||||
.cvOuts = 0, | |||||
.midiIns = 0, | .midiIns = 0, | ||||
.midiOuts = 0, | .midiOuts = 0, | ||||
.paramIns = PARAM_COUNT_STEREO, | .paramIns = PARAM_COUNT_STEREO, | ||||
@@ -52,6 +52,8 @@ static const NativePluginDescriptor bypassDesc = { | |||||
.supports = NATIVE_PLUGIN_SUPPORTS_NOTHING, | .supports = NATIVE_PLUGIN_SUPPORTS_NOTHING, | ||||
.audioIns = 1, | .audioIns = 1, | ||||
.audioOuts = 1, | .audioOuts = 1, | ||||
.cvIns = 0, | |||||
.cvOuts = 0, | |||||
.midiIns = 0, | .midiIns = 0, | ||||
.midiOuts = 0, | .midiOuts = 0, | ||||
.paramIns = 0, | .paramIns = 0, | ||||
@@ -272,6 +272,8 @@ static const NativePluginDescriptor lfoDesc = { | |||||
.supports = NATIVE_PLUGIN_SUPPORTS_NOTHING, | .supports = NATIVE_PLUGIN_SUPPORTS_NOTHING, | ||||
.audioIns = 0, | .audioIns = 0, | ||||
.audioOuts = 0, | .audioOuts = 0, | ||||
.cvIns = 0, | |||||
.cvOuts = 0, | |||||
.midiIns = 0, | .midiIns = 0, | ||||
.midiOuts = 0, | .midiOuts = 0, | ||||
.paramIns = PARAM_COUNT-1, | .paramIns = PARAM_COUNT-1, | ||||
@@ -161,6 +161,8 @@ static const NativePluginDescriptor midichanabDesc = { | |||||
.supports = NATIVE_PLUGIN_SUPPORTS_EVERYTHING, | .supports = NATIVE_PLUGIN_SUPPORTS_EVERYTHING, | ||||
.audioIns = 0, | .audioIns = 0, | ||||
.audioOuts = 0, | .audioOuts = 0, | ||||
.cvIns = 0, | |||||
.cvOuts = 0, | |||||
.midiIns = 1, | .midiIns = 1, | ||||
.midiOuts = 2, | .midiOuts = 2, | ||||
.paramIns = 0, | .paramIns = 0, | ||||
@@ -152,6 +152,8 @@ static const NativePluginDescriptor midichanfilterDesc = { | |||||
.supports = NATIVE_PLUGIN_SUPPORTS_EVERYTHING, | .supports = NATIVE_PLUGIN_SUPPORTS_EVERYTHING, | ||||
.audioIns = 0, | .audioIns = 0, | ||||
.audioOuts = 0, | .audioOuts = 0, | ||||
.cvIns = 0, | |||||
.cvOuts = 0, | |||||
.midiIns = 1, | .midiIns = 1, | ||||
.midiOuts = 1, | .midiOuts = 1, | ||||
.paramIns = 0, | .paramIns = 0, | ||||
@@ -160,6 +160,8 @@ static const NativePluginDescriptor midichannelizeDesc = { | |||||
.supports = NATIVE_PLUGIN_SUPPORTS_EVERYTHING, | .supports = NATIVE_PLUGIN_SUPPORTS_EVERYTHING, | ||||
.audioIns = 0, | .audioIns = 0, | ||||
.audioOuts = 0, | .audioOuts = 0, | ||||
.cvIns = 0, | |||||
.cvOuts = 0, | |||||
.midiIns = 1, | .midiIns = 1, | ||||
.midiOuts = 1, | .midiOuts = 1, | ||||
.paramIns = 1, | .paramIns = 1, | ||||
@@ -222,6 +222,8 @@ static const NativePluginDescriptor midigainDesc = { | |||||
.supports = NATIVE_PLUGIN_SUPPORTS_EVERYTHING, | .supports = NATIVE_PLUGIN_SUPPORTS_EVERYTHING, | ||||
.audioIns = 0, | .audioIns = 0, | ||||
.audioOuts = 0, | .audioOuts = 0, | ||||
.cvIns = 0, | |||||
.cvOuts = 0, | |||||
.midiIns = 1, | .midiIns = 1, | ||||
.midiOuts = 1, | .midiOuts = 1, | ||||
.paramIns = 0, | .paramIns = 0, | ||||
@@ -99,6 +99,8 @@ static const NativePluginDescriptor midijoinDesc = { | |||||
.supports = NATIVE_PLUGIN_SUPPORTS_EVERYTHING, | .supports = NATIVE_PLUGIN_SUPPORTS_EVERYTHING, | ||||
.audioIns = 0, | .audioIns = 0, | ||||
.audioOuts = 0, | .audioOuts = 0, | ||||
.cvIns = 0, | |||||
.cvOuts = 0, | |||||
.midiIns = MAX_MIDI_CHANNELS, | .midiIns = MAX_MIDI_CHANNELS, | ||||
.midiOuts = 1, | .midiOuts = 1, | ||||
.paramIns = 0, | .paramIns = 0, | ||||
@@ -92,6 +92,8 @@ static const NativePluginDescriptor midisplitDesc = { | |||||
.supports = NATIVE_PLUGIN_SUPPORTS_EVERYTHING, | .supports = NATIVE_PLUGIN_SUPPORTS_EVERYTHING, | ||||
.audioIns = 0, | .audioIns = 0, | ||||
.audioOuts = 0, | .audioOuts = 0, | ||||
.cvIns = 0, | |||||
.cvOuts = 0, | |||||
.midiIns = 1, | .midiIns = 1, | ||||
.midiOuts = MAX_MIDI_CHANNELS, | .midiOuts = MAX_MIDI_CHANNELS, | ||||
.paramIns = 0, | .paramIns = 0, | ||||
@@ -73,6 +73,8 @@ static const NativePluginDescriptor midithroughDesc = { | |||||
.supports = NATIVE_PLUGIN_SUPPORTS_EVERYTHING, | .supports = NATIVE_PLUGIN_SUPPORTS_EVERYTHING, | ||||
.audioIns = 0, | .audioIns = 0, | ||||
.audioOuts = 0, | .audioOuts = 0, | ||||
.cvIns = 0, | |||||
.cvOuts = 0, | |||||
.midiIns = 1, | .midiIns = 1, | ||||
.midiOuts = 1, | .midiOuts = 1, | ||||
.paramIns = 0, | .paramIns = 0, | ||||
@@ -185,6 +185,8 @@ static const NativePluginDescriptor miditransposeDesc = { | |||||
.supports = NATIVE_PLUGIN_SUPPORTS_EVERYTHING, | .supports = NATIVE_PLUGIN_SUPPORTS_EVERYTHING, | ||||
.audioIns = 0, | .audioIns = 0, | ||||
.audioOuts = 0, | .audioOuts = 0, | ||||
.cvIns = 0, | |||||
.cvOuts = 0, | |||||
.midiIns = 1, | .midiIns = 1, | ||||
.midiOuts = 1, | .midiOuts = 1, | ||||
.paramIns = 2, | .paramIns = 2, | ||||