Browse Source

Implement CV exposed ports in carla-patchbay

Signed-off-by: falkTX <falktx@falktx.com>
tags/v2.1-rc1
falkTX 5 years ago
parent
commit
a7e907d951
Signed by: falkTX <falktx@falktx.com> GPG Key ID: CDBAA37ABC74FBA0
33 changed files with 640 additions and 224 deletions
  1. +10
    -0
      source/backend/CarlaUtils.h
  2. +1
    -1
      source/backend/engine/CarlaEngineDummy.cpp
  3. +88
    -23
      source/backend/engine/CarlaEngineGraph.cpp
  4. +13
    -4
      source/backend/engine/CarlaEngineGraph.hpp
  5. +1
    -1
      source/backend/engine/CarlaEngineInternal.hpp
  6. +2
    -2
      source/backend/engine/CarlaEngineJack.cpp
  7. +3
    -1
      source/backend/engine/CarlaEngineJuce.cpp
  8. +82
    -10
      source/backend/engine/CarlaEngineNative.cpp
  9. +1
    -1
      source/backend/engine/CarlaEngineRtAudio.cpp
  10. +158
    -65
      source/backend/plugin/CarlaPluginNative.cpp
  11. +14
    -0
      source/backend/utils/CachedPlugins.cpp
  12. +2
    -0
      source/discovery/carla-discovery.cpp
  13. +10
    -1
      source/frontend/carla_database.py
  14. +8
    -0
      source/frontend/carla_utils.py
  15. +6
    -1
      source/includes/CarlaNative.h
  16. +2
    -1
      source/includes/CarlaNative.hpp
  17. +5
    -0
      source/includes/CarlaNativePlugin.h
  18. +0
    -13
      source/modules/water/processors/AudioProcessor.cpp
  19. +1
    -17
      source/modules/water/processors/AudioProcessor.h
  20. +140
    -47
      source/modules/water/processors/AudioProcessorGraph.cpp
  21. +17
    -9
      source/modules/water/processors/AudioProcessorGraph.h
  22. +54
    -27
      source/native-plugins/_data.cpp
  23. +2
    -0
      source/native-plugins/audio-gain.c
  24. +2
    -0
      source/native-plugins/bypass.c
  25. +2
    -0
      source/native-plugins/lfo.c
  26. +2
    -0
      source/native-plugins/midi-channel-ab.c
  27. +2
    -0
      source/native-plugins/midi-channel-filter.c
  28. +2
    -0
      source/native-plugins/midi-channelize.c
  29. +2
    -0
      source/native-plugins/midi-gain.c
  30. +2
    -0
      source/native-plugins/midi-join.c
  31. +2
    -0
      source/native-plugins/midi-split.c
  32. +2
    -0
      source/native-plugins/midi-through.c
  33. +2
    -0
      source/native-plugins/midi-transpose.c

+ 10
- 0
source/backend/CarlaUtils.h View File

@@ -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.
*/ */


+ 1
- 1
source/backend/engine/CarlaEngineDummy.cpp View File

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


+ 88
- 23
source/backend/engine/CarlaEngineGraph.cpp View File

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


+ 13
- 4
source/backend/engine/CarlaEngineGraph.hpp View File

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


+ 1
- 1
source/backend/engine/CarlaEngineInternal.hpp View File

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


+ 2
- 2
source/backend/engine/CarlaEngineJack.cpp View File

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


+ 3
- 1
source/backend/engine/CarlaEngineJuce.cpp View File

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




+ 82
- 10
source/backend/engine/CarlaEngineNative.cpp View File

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




+ 1
- 1
source/backend/engine/CarlaEngineRtAudio.cpp View File

@@ -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();


+ 158
- 65
source/backend/plugin/CarlaPluginNative.cpp View File

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


+ 14
- 0
source/backend/utils/CachedPlugins.cpp View File

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


+ 2
- 0
source/discovery/carla-discovery.cpp View File

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


+ 10
- 1
source/frontend/carla_database.py View File

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




+ 8
- 0
source/frontend/carla_utils.py View File

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


+ 6
- 1
source/includes/CarlaNative.h View File

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


/* ------------------------------------------------------------------------------------------------------------ /* ------------------------------------------------------------------------------------------------------------


+ 2
- 1
source/includes/CarlaNative.hpp View File

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


// ----------------------------------------------------------------------- // -----------------------------------------------------------------------




+ 5
- 0
source/includes/CarlaNativePlugin.h View File

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


+ 0
- 13
source/modules/water/processors/AudioProcessor.cpp View File

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


+ 1
- 17
source/modules/water/processors/AudioProcessor.h View File

@@ -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. */


+ 140
- 47
source/modules/water/processors/AudioProcessorGraph.cpp View File

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


+ 17
- 9
source/modules/water/processors/AudioProcessorGraph.h View File

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


+ 54
- 27
source/native-plugins/_data.cpp View File

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


// -------------------------------------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------------------------------------




+ 2
- 0
source/native-plugins/audio-gain.c View File

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


+ 2
- 0
source/native-plugins/bypass.c View File

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


+ 2
- 0
source/native-plugins/lfo.c View File

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


+ 2
- 0
source/native-plugins/midi-channel-ab.c View File

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


+ 2
- 0
source/native-plugins/midi-channel-filter.c View File

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


+ 2
- 0
source/native-plugins/midi-channelize.c View File

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


+ 2
- 0
source/native-plugins/midi-gain.c View File

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


+ 2
- 0
source/native-plugins/midi-join.c View File

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


+ 2
- 0
source/native-plugins/midi-split.c View File

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


+ 2
- 0
source/native-plugins/midi-through.c View File

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


+ 2
- 0
source/native-plugins/midi-transpose.c View File

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


Loading…
Cancel
Save