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;

/*!
* Number of CV inputs.
*/
uint32_t cvIns;

/*!
* Number of CV outputs.
*/
uint32_t cvOuts;

/*!
* Number of MIDI inputs.
*/


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

@@ -72,7 +72,7 @@ public:
pData->sampleRate = pData->options.audioSampleRate;
pData->initTime(pData->options.transportExtra);

pData->graph.create(2, 2);
pData->graph.create(2, 2, 0, 0);

if (! startThread(true))
{


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

@@ -1413,11 +1413,6 @@ public:
return fPlugin->getName();
}

void processBlock(AudioSampleBuffer&, MidiBuffer&) override
{
carla_stderr2("CarlaPluginInstance::processBlock called, this is wrong!");
}

void processBlockWithCV(AudioSampleBuffer& audio,
const AudioSampleBuffer& cvIn,
AudioSampleBuffer& cvOut,
@@ -1605,14 +1600,20 @@ private:
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"),
connections(),
graph(),
audioBuffer(),
cvInBuffer(),
cvOutBuffer(),
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(),
usingExternalHost(false),
usingExternalOSC(false),
@@ -1622,17 +1623,22 @@ PatchbayGraph::PatchbayGraph(CarlaEngine* const engine, const uint32_t ins, cons
const uint32_t bufferSize(engine->getBufferSize());
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));

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.clear();

StringArray channelNames;

switch (inputs)
switch (numAudioIns)
{
case 2:
channelNames.add("Left");
@@ -1645,6 +1651,7 @@ PatchbayGraph::PatchbayGraph(CarlaEngine* const engine, const uint32_t ins, cons
break;
}

if (numAudioIns != 0)
{
NamedAudioGraphIOProcessor* const proc(
new NamedAudioGraphIOProcessor(NamedAudioGraphIOProcessor::audioInputNode));
@@ -1659,6 +1666,7 @@ PatchbayGraph::PatchbayGraph(CarlaEngine* const engine, const uint32_t ins, cons
node->properties.set("isOSC", false);
}

if (numAudioOuts != 0)
{
NamedAudioGraphIOProcessor* const proc(
new NamedAudioGraphIOProcessor(NamedAudioGraphIOProcessor::audioOutputNode));
@@ -1673,6 +1681,36 @@ PatchbayGraph::PatchbayGraph(CarlaEngine* const engine, const uint32_t ins, cons
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(
new NamedAudioGraphIOProcessor(NamedAudioGraphIOProcessor::midiInputNode));
@@ -1710,6 +1748,8 @@ PatchbayGraph::~PatchbayGraph()
graph.releaseResources();
graph.clear();
audioBuffer.clear();
cvInBuffer.clear();
cvOutBuffer.clear();
}

void PatchbayGraph::setBufferSize(const uint32_t bufferSize)
@@ -1719,6 +1759,8 @@ void PatchbayGraph::setBufferSize(const uint32_t bufferSize)
graph.releaseResources();
graph.prepareToPlay(kEngine->getSampleRate(), static_cast<int>(bufferSize));
audioBuffer.setSize(audioBuffer.getNumChannels(), bufferSize);
cvInBuffer.setSize(numCVIns, bufferSize);
cvOutBuffer.setSize(numCVOuts, bufferSize);
}

void PatchbayGraph::setSampleRate(const double sampleRate)
@@ -2175,7 +2217,10 @@ bool PatchbayGraph::getGroupAndPortIdFromFullName(const bool external, const cha
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->events.in != nullptr,);
@@ -2188,29 +2233,48 @@ void PatchbayGraph::process(CarlaEngine::ProtectedData* const data, const float*
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))
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;

for (; i < inputs; ++i)
for (; i < numAudioIns; ++i) {
CARLA_SAFE_ASSERT_BREAK(inBuf[i]);
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
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!
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);

for (uint32_t j=0; j < numCVOuts; ++j, ++i)
carla_copyFloats(outBuf[i], cvOutBuffer.getReadPointer(j), frames);
}

// put water events in carla buffer
@@ -2245,19 +2309,20 @@ EngineInternalGraph::~EngineInternalGraph() noexcept
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);

if (fIsRack)
{
CARLA_SAFE_ASSERT_RETURN(fRack == nullptr,);
fRack = new RackGraph(kEngine, inputs, outputs);
fRack = new RackGraph(kEngine, audioIns, audioOuts);
}
else
{
CARLA_SAFE_ASSERT_RETURN(fPatchbay == nullptr,);
fPatchbay = new PatchbayGraph(kEngine, inputs, outputs);
fPatchbay = new PatchbayGraph(kEngine, audioIns, audioOuts, cvIns, cvOuts);
}

fIsReady = true;


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

@@ -157,16 +157,22 @@ public:
PatchbayConnectionList connections;
AudioProcessorGraph graph;
AudioSampleBuffer audioBuffer;
AudioSampleBuffer cvInBuffer;
AudioSampleBuffer cvOutBuffer;
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;
bool usingExternalHost;
bool usingExternalOSC;

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

void setBufferSize(const uint32_t bufferSize);
@@ -187,7 +193,10 @@ public:
const char* const* getConnections(const bool external) 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:
void run() override;


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

@@ -74,7 +74,7 @@ public:
EngineInternalGraph(CarlaEngine* const engine) 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 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)
{
// FIXME?
pData->graph.create(0, 0);
pData->graph.create(0, 0, 0, 0);
}
else
{
pData->graph.create(2, 2);
pData->graph.create(2, 2, 0, 0);
// pData->graph.setUsingExternalHost(true);
// pData->graph.setUsingExternalOSC(true);
patchbayRefresh(true, false, false);


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

@@ -218,7 +218,9 @@ public:
pData->sampleRate = fDevice->getCurrentSampleRate();
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);



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

@@ -163,7 +163,8 @@ class CarlaEngineNative : public CarlaEngine
{
public:
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(),
pHost(host),
#ifdef USE_JUCE_MESSAGE_THREAD
@@ -211,7 +212,7 @@ public:
pData->options.preferPluginBridges = false;
pData->options.preferUiBridges = false;
init("Carla-Patchbay");
pData->graph.create(inChan, outChan);
pData->graph.create(inChan, outChan, cvIns, cvOuts);
}
else
{
@@ -223,7 +224,7 @@ public:
pData->options.preferPluginBridges = false;
pData->options.preferUiBridges = false;
init("Carla-Rack");
pData->graph.create(0, 0); // FIXME?
pData->graph.create(0, 0, 0, 0); // FIXME?
}

if (pData->options.resourceDir != nullptr)
@@ -1567,6 +1568,11 @@ public:
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)
{
delete handlePtr;
@@ -2345,7 +2351,9 @@ static const NativePluginDescriptor carlaRackDesc = {
CarlaEngineNative::_get_state,
CarlaEngineNative::_set_state,
CarlaEngineNative::_dispatcher,
/* _render_inline_dsplay */ nullptr
/* _render_inline_dsplay */ nullptr,
/* cvIns */ 0,
/* cvOuts */ 0
};

static const NativePluginDescriptor carlaRackNoMidiOutDesc = {
@@ -2387,7 +2395,9 @@ static const NativePluginDescriptor carlaRackNoMidiOutDesc = {
CarlaEngineNative::_get_state,
CarlaEngineNative::_set_state,
CarlaEngineNative::_dispatcher,
/* _render_inline_dsplay */ nullptr
/* _render_inline_dsplay */ nullptr,
/* cvIns */ 0,
/* cvOuts */ 0
};

static const NativePluginDescriptor carlaPatchbayDesc = {
@@ -2429,7 +2439,9 @@ static const NativePluginDescriptor carlaPatchbayDesc = {
CarlaEngineNative::_get_state,
CarlaEngineNative::_set_state,
CarlaEngineNative::_dispatcher,
/* _render_inline_dsplay */ nullptr
/* _render_inline_dsplay */ nullptr,
/* cvIns */ 0,
/* cvOuts */ 0
};

static const NativePluginDescriptor carlaPatchbay3sDesc = {
@@ -2471,7 +2483,9 @@ static const NativePluginDescriptor carlaPatchbay3sDesc = {
CarlaEngineNative::_get_state,
CarlaEngineNative::_set_state,
CarlaEngineNative::_dispatcher,
/* _render_inline_dsplay */ nullptr
/* _render_inline_dsplay */ nullptr,
/* cvIns */ 0,
/* cvOuts */ 0
};

static const NativePluginDescriptor carlaPatchbay16Desc = {
@@ -2513,7 +2527,9 @@ static const NativePluginDescriptor carlaPatchbay16Desc = {
CarlaEngineNative::_get_state,
CarlaEngineNative::_set_state,
CarlaEngineNative::_dispatcher,
/* _render_inline_dsplay */ nullptr
/* _render_inline_dsplay */ nullptr,
/* cvIns */ 0,
/* cvOuts */ 0
};

static const NativePluginDescriptor carlaPatchbay32Desc = {
@@ -2555,7 +2571,9 @@ static const NativePluginDescriptor carlaPatchbay32Desc = {
CarlaEngineNative::_get_state,
CarlaEngineNative::_set_state,
CarlaEngineNative::_dispatcher,
/* _render_inline_dsplay */ nullptr
/* _render_inline_dsplay */ nullptr,
/* cvIns */ 0,
/* cvOuts */ 0
};

static const NativePluginDescriptor carlaPatchbay64Desc = {
@@ -2597,7 +2615,54 @@ static const NativePluginDescriptor carlaPatchbay64Desc = {
CarlaEngineNative::_get_state,
CarlaEngineNative::_set_state,
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
@@ -2617,6 +2682,7 @@ void carla_register_native_plugin_carla()
carla_register_native_plugin(&carlaPatchbay16Desc);
carla_register_native_plugin(&carlaPatchbay32Desc);
carla_register_native_plugin(&carlaPatchbay64Desc);
carla_register_native_plugin(&carlaPatchbayCVDesc);
}

// -----------------------------------------------------------------------
@@ -2651,6 +2717,12 @@ const NativePluginDescriptor* carla_get_native_patchbay64_plugin()
return &carlaPatchbay64Desc;
}

const NativePluginDescriptor* carla_get_native_patchbay_cv_plugin()
{
CARLA_BACKEND_USE_NAMESPACE;
return &carlaPatchbayCVDesc;
}

// -----------------------------------------------------------------------
// Extra stuff for linking purposes



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

@@ -332,7 +332,7 @@ public:
if (fAudioOutCount > 0)
fAudioIntBufOut = new float[fAudioOutCount*bufferFrames];

pData->graph.create(fAudioInCount, fAudioOutCount);
pData->graph.create(fAudioInCount, fAudioOutCount, 0, 0);

try {
fAudio.startStream();


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

@@ -254,8 +254,8 @@ public:
fIsUiVisible(false),
fInlineDisplayNeedsRedraw(false),
fInlineDisplayLastRedrawTime(0),
fAudioInBuffers(nullptr),
fAudioOutBuffers(nullptr),
fAudioAndCvInBuffers(nullptr),
fAudioAndCvOutBuffers(nullptr),
fMidiEventInCount(0),
fMidiEventOutCount(0),
fCurBufferSize(engine->getBufferSize()),
@@ -421,8 +421,8 @@ public:
if ((fDescriptor->hints & NATIVE_PLUGIN_NEEDS_FIXED_BUFFERS) == 0x0)
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();
// 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)
@@ -978,7 +978,7 @@ public:

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;
forcedStereoIn = forcedStereoOut = false;
@@ -988,6 +988,8 @@ public:

aIns = fDescriptor->audioIns;
aOuts = fDescriptor->audioOuts;
cvIns = fDescriptor->cvIns;
cvOuts = fDescriptor->cvOuts;
mIns = fDescriptor->midiIns;
mOuts = fDescriptor->midiOuts;
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)
{
pData->audioIn.createNew(aIns);
fAudioInBuffers = new float*[aIns];

for (uint32_t i=0; i < aIns; ++i)
fAudioInBuffers[i] = nullptr;
}

if (aOuts > 0)
{
pData->audioOut.createNew(aOuts);
fAudioOutBuffers = new float*[aOuts];
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)
@@ -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)
if (mIns > 1)
{
@@ -1514,7 +1580,8 @@ public:
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
@@ -1524,6 +1591,8 @@ public:
// disable any output sound
for (uint32_t i=0; i < pData->audioOut.count; ++i)
carla_zeroFloats(audioOut[i], frames);
for (uint32_t i=0; i < pData->cvOut.count; ++i)
carla_zeroFloats(cvOut[i], frames);
return;
}

@@ -1697,7 +1766,7 @@ public:

if (sampleAccurate && eventTime > timeOffset)
{
if (processSingle(audioIn, audioOut, eventTime - timeOffset, timeOffset))
if (processSingle(audioIn, audioOut, cvIn, cvOut, eventTime - timeOffset, timeOffset))
{
startTime = 0;
timeOffset = eventTime;
@@ -2005,7 +2074,7 @@ public:
pData->postRtEvents.trySplice();

if (frames > timeOffset)
processSingle(audioIn, audioOut, frames - timeOffset, timeOffset);
processSingle(audioIn, audioOut, cvIn, cvOut, frames - timeOffset, timeOffset);

} // End of Event Input and Processing

@@ -2014,7 +2083,7 @@ public:

else
{
processSingle(audioIn, audioOut, frames, 0);
processSingle(audioIn, audioOut, cvIn, cvOut, frames, 0);

} // End of Plugin processing (no events)

@@ -2044,18 +2113,24 @@ public:
#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);

if (pData->audioIn.count > 0)
{
if (pData->audioIn.count > 0) {
CARLA_SAFE_ASSERT_RETURN(audioIn != nullptr, false);
}
if (pData->audioOut.count > 0)
{
if (pData->audioOut.count > 0) {
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
@@ -2071,6 +2146,11 @@ public:
for (uint32_t k=0; k < frames; ++k)
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;
}
@@ -2078,11 +2158,17 @@ public:
// --------------------------------------------------------------------------------------------------------
// 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
@@ -2092,19 +2178,19 @@ public:
if (fHandle2 == nullptr)
{
fDescriptor->process(fHandle,
const_cast<const float**>(fAudioInBuffers), fAudioOutBuffers, frames,
const_cast<const float**>(fAudioAndCvInBuffers), fAudioAndCvOutBuffers, frames,
fMidiInEvents, fMidiEventInCount);
}
else
{
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);

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

@@ -2113,6 +2199,7 @@ public:
if (fTimeInfo.playing)
fTimeInfo.frame += frames;

uint32_t i=0;
#ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH
// --------------------------------------------------------------------------------------------------------
// Post-processing (dry/wet, volume and balance)
@@ -2124,15 +2211,15 @@ public:
bool isPair;
float bufValue, oldBufLeft[doBalance ? frames : 1];

for (uint32_t i=0; i < pData->audioOut.count; ++i)
for (; i < pData->audioOut.count; ++i)
{
// Dry/Wet
if (doDryWet)
{
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)
{
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;
@@ -2155,14 +2242,14 @@ public:
if (isPair)
{
// 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
{
// 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)
{
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
#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)
audioOut[i][k+timeOffset] = fAudioOutBuffers[i][k];
audioOut[i][k+timeOffset] = fAudioAndCvOutBuffers[i][k];
}
#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
@@ -2211,18 +2304,18 @@ public:
CARLA_ASSERT_INT(newBufferSize > 0, 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)
@@ -2289,34 +2382,34 @@ public:
{
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)
@@ -2699,8 +2792,8 @@ private:
bool fInlineDisplayNeedsRedraw;
int64_t fInlineDisplayLastRedrawTime;

float** fAudioInBuffers;
float** fAudioOutBuffers;
float** fAudioAndCvInBuffers;
float** fAudioAndCvOutBuffers;
uint32_t fMidiEventInCount;
uint32_t fMidiEventOutCount;
NativeMidiEvent fMidiInEvents[kPluginMaxMidiEvents];


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

@@ -63,6 +63,8 @@ _CarlaCachedPluginInfo::_CarlaCachedPluginInfo() noexcept
hints(0x0),
audioIns(0),
audioOuts(0),
cvIns(0),
cvOuts(0),
midiIns(0),
midiOuts(0),
parameterIns(0),
@@ -119,6 +121,8 @@ static const CarlaCachedPluginInfo* get_cached_plugin_internal(const NativePlugi
info.valid = true;
info.audioIns = desc.audioIns;
info.audioOuts = desc.audioOuts;
info.cvIns = desc.cvIns;
info.cvOuts = desc.cvOuts;
info.midiIns = desc.midiIns;
info.midiOuts = desc.midiOuts;
info.parameterIns = desc.paramIns;
@@ -336,6 +340,8 @@ static const CarlaCachedPluginInfo* get_cached_plugin_lv2(Lv2WorldClass& lv2Worl

info.audioIns = 0;
info.audioOuts = 0;
info.cvIns = 0;
info.cvOuts = 0;
info.midiIns = 0;
info.midiOuts = 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))
{
if (isInput)
++(info.cvIns);
else
++(info.cvOuts);
}
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.audioOuts = static_cast<uint32_t>(desc->numOutputChannels);
info.cvIns = 0;
info.cvOuts = 0;
info.midiIns = desc->isInstrument ? 1 : 0;
info.midiOuts = 0;
info.parameterIns = 0;
@@ -565,6 +577,8 @@ static const CarlaCachedPluginInfo* get_cached_plugin_sfz(const File file)
info.valid = true;
info.audioIns = 0;
info.audioOuts = 2;
info.cvIns = 0;
info.cvOuts = 0;
info.midiIns = 1;
info.midiOuts = 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("audio.ins", pinfo->audioIns);
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.outs", pinfo->midiOuts);
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_API_VERSION = 8
PLUGIN_QUERY_API_VERSION = 9

PyPluginInfo = {
'API': PLUGIN_QUERY_API_VERSION,
@@ -148,6 +148,8 @@ PyPluginInfo = {
'uniqueId': 0,
'audio.ins': 0,
'audio.outs': 0,
'cv.ins': 0,
'cv.outs': 0,
'midi.ins': 0,
'midi.outs': 0,
'parameters.ins': 0,
@@ -285,6 +287,10 @@ def runCarlaDiscovery(itype, stype, filename, tool, wineSettings=None):
if value.isdigit(): pinfo['audio.ins'] = int(value)
elif prop == "audio.outs":
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":
if value.isdigit(): pinfo['midi.ins'] = int(value)
elif prop == "midi.outs":
@@ -329,6 +335,9 @@ def checkPluginCached(desc, ptype):
pinfo['audio.ins'] = desc['audioIns']
pinfo['audio.outs'] = desc['audioOuts']

pinfo['cv.ins'] = desc['cvIns']
pinfo['cv.outs'] = desc['cvOuts']

pinfo['midi.ins'] = desc['midiIns']
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.
("audioOuts", c_uint32),

# Number of CV inputs.
("cvIns", c_uint32),

# Number of CV outputs.
("cvOuts", c_uint32),

# Number of MIDI inputs.
("midiIns", c_uint32),

@@ -152,6 +158,8 @@ PyCarlaCachedPluginInfo = {
'hints': 0x0,
'audioIns': 0,
'audioOuts': 0,
'cvIns': 0,
'cvOuts': 0,
'midiIns': 0,
'midiOuts': 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_TIME = 1 << 10,
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;

typedef enum {
@@ -268,6 +269,10 @@ typedef struct _NativePluginDescriptor {
const NativeInlineDisplayImageSurface* (*render_inline_display)(NativePluginHandle handle,
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;

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


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

@@ -577,7 +577,8 @@ public: \
ClassName::_get_state, \
ClassName::_set_state, \
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();

/*!
* Get the native plugin descriptor for the carla-patchbay-cv plugin.
*/
CARLA_EXPORT const NativePluginDescriptor* carla_get_native_patchbay_cv_plugin();

#ifdef __cplusplus
/*!
* 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::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
{
switch (t)


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

@@ -154,26 +154,10 @@ public:
@see AudiobusLayout::getBusBuffer
*/
virtual void processBlock (AudioSampleBuffer& buffer,
MidiBuffer& midiMessages) = 0;
virtual void processBlockWithCV (AudioSampleBuffer& audioBuffer,
const AudioSampleBuffer& cvInBuffer,
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. */


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

@@ -1158,7 +1158,8 @@ void AudioProcessorGraph::Node::setParentGraph (AudioProcessorGraph* const graph
struct AudioProcessorGraph::AudioProcessorGraphBufferHelpers
{
AudioProcessorGraphBufferHelpers() noexcept
: currentAudioInputBuffer (nullptr) {}
: currentAudioInputBuffer (nullptr),
currentCVInputBuffer (nullptr) {}
void setRenderingBufferSize (int newNumAudioChannels, int newNumCVChannels, int newNumSamples) noexcept
{
@@ -1173,26 +1174,32 @@ struct AudioProcessorGraph::AudioProcessorGraphBufferHelpers
{
renderingAudioBuffers.setSize (1, 1);
currentAudioInputBuffer = nullptr;
currentCVInputBuffer = nullptr;
currentAudioOutputBuffer.setSize (1, 1);
currentCVOutputBuffer.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;
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()
: lastNodeId (0), audioBuffers (new AudioProcessorGraphBufferHelpers),
: lastNodeId (0), audioAndCVBuffers (new AudioProcessorGraphBufferHelpers),
currentMidiInputBuffer (nullptr), isPrepared (false), needsReorder (false)
{
}
@@ -1525,9 +1532,9 @@ void AudioProcessorGraph::buildRenderingSequence()
// swap over to the new rendering sequence..
const CarlaRecursiveMutexLocker cml (getCallbackLock());
audioBuffers->setRenderingBufferSize (numAudioRenderingBuffersNeeded,
numCVRenderingBuffersNeeded,
getBlockSize());
audioAndCVBuffers->setRenderingBufferSize (numAudioRenderingBuffersNeeded,
numCVRenderingBuffersNeeded,
getBlockSize());
for (int i = static_cast<int>(midiBuffers.size()); --i >= 0;)
midiBuffers.getUnchecked(i)->clear();
@@ -1547,7 +1554,9 @@ void AudioProcessorGraph::prepareToPlay (double sampleRate, int estimatedSamples
{
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;
currentMidiOutputBuffer.clear();
@@ -1565,7 +1574,7 @@ void AudioProcessorGraph::releaseResources()
for (int i = 0; i < nodes.size(); ++i)
nodes.getUnchecked(i)->unprepare();
audioBuffers->release();
audioAndCVBuffers->release();
midiBuffers.clear();
currentMidiInputBuffer = nullptr;
@@ -1590,23 +1599,24 @@ void AudioProcessorGraph::setNonRealtime (bool isProcessingNonRealtime) noexcept
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;
if (! audioBuffers->renderingAudioBuffers.setSizeRT(numSamples))
if (! audioAndCVBuffers->renderingAudioBuffers.setSizeRT(numSamples))
return;
if (! audioBuffers->renderingCVBuffers.setSizeRT(numSamples))
if (! audioAndCVBuffers->renderingCVBuffers.setSizeRT(numSamples))
return;
currentAudioInputBuffer = &buffer;
currentAudioInputBuffer = &audioBuffer;
currentAudioOutputBuffer.clear();
currentMidiInputBuffer = &midiMessages;
currentMidiOutputBuffer.clear();
@@ -1619,27 +1629,78 @@ void AudioProcessorGraph::processAudio (AudioSampleBuffer& buffer, MidiBuffer& m
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.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::producesMidi() const { return true; }
/*
void AudioProcessorGraph::processBlock (AudioSampleBuffer& buffer, MidiBuffer& midiMessages)
{
processAudio (buffer, midiMessages);
}
*/
void AudioProcessorGraph::processBlockWithCV (AudioSampleBuffer& buffer,
const AudioSampleBuffer&,
AudioSampleBuffer&,
void AudioProcessorGraph::processBlockWithCV (AudioSampleBuffer& audioBuffer,
const AudioSampleBuffer& cvInBuffer,
AudioSampleBuffer& cvOutBuffer,
MidiBuffer& midiMessages)
{
processAudio (buffer, midiMessages);
processAudioAndCV (audioBuffer, cvInBuffer, cvOutBuffer, midiMessages);
}
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,);
AudioSampleBuffer*& currentAudioInputBuffer =
graph->audioBuffers->currentAudioInputBuffer;
AudioSampleBuffer& currentAudioOutputBuffer =
graph->audioBuffers->currentAudioOutputBuffer;
switch (type)
{
case audioOutputNode:
{
AudioSampleBuffer& currentAudioOutputBuffer =
graph->audioAndCVBuffers->currentAudioOutputBuffer;
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;
@@ -1717,21 +1777,52 @@ void AudioProcessorGraph::AudioGraphIOProcessor::processAudio (AudioSampleBuffer
case audioInputNode:
{
AudioSampleBuffer*& currentAudioInputBuffer =
graph->audioAndCVBuffers->currentAudioInputBuffer;
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;
}
case midiOutputNode:
graph->currentMidiOutputBuffer.addEvents (midiMessages, 0, buffer.getNumSamples(), 0);
graph->currentMidiOutputBuffer.addEvents (midiMessages, 0, audioBuffer.getNumSamples(), 0);
break;
case midiInputNode:
midiMessages.addEvents (*graph->currentMidiInputBuffer, 0, buffer.getNumSamples(), 0);
midiMessages.addEvents (*graph->currentMidiInputBuffer, 0, audioBuffer.getNumSamples(), 0);
break;
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


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

@@ -318,12 +318,12 @@ public:
~AudioGraphIOProcessor();
const String getName() const override;
#if 0
void fillInPluginDescription (PluginDescription&) const override;
#endif
void prepareToPlay (double newSampleRate, int estimatedSamplesPerBlock) 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 producesMidi() const override;
@@ -336,7 +336,11 @@ public:
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)
};
@@ -345,8 +349,8 @@ public:
const String getName() const override;
void prepareToPlay (double, int) 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,
AudioSampleBuffer& cvOutBuffer,
MidiBuffer& midiMessages) override;
@@ -362,7 +366,11 @@ public:
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;
@@ -373,7 +381,7 @@ private:
friend class AudioGraphIOProcessor;
struct AudioProcessorGraphBufferHelpers;
ScopedPointer<AudioProcessorGraphBufferHelpers> audioBuffers;
ScopedPointer<AudioProcessorGraphBufferHelpers> audioAndCVBuffers;
MidiBuffer* currentMidiInputBuffer;
MidiBuffer currentMidiOutputBuffer;


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

@@ -19,13 +19,16 @@
#include "CarlaMIDI.h"
#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
#define DESCFUNCS_WITHOUTCV \
DESCFUNCS_WITHCV, 0, 0

static const NativePluginDescriptor sNativePluginDescriptors[] = {

@@ -46,7 +49,7 @@ static const NativePluginDescriptor sNativePluginDescriptors[] = {
/* label */ "audiogain",
/* maker */ "falkTX",
/* copyright */ "GNU GPL v2+",
DESCFUNCS
DESCFUNCS_WITHOUTCV
},
{
/* category */ NATIVE_PLUGIN_CATEGORY_UTILITY,
@@ -62,7 +65,7 @@ static const NativePluginDescriptor sNativePluginDescriptors[] = {
/* label */ "audiogain_s",
/* maker */ "falkTX",
/* copyright */ "GNU GPL v2+",
DESCFUNCS
DESCFUNCS_WITHOUTCV
},
{
/* category */ NATIVE_PLUGIN_CATEGORY_NONE,
@@ -78,7 +81,7 @@ static const NativePluginDescriptor sNativePluginDescriptors[] = {
/* label */ "bypass",
/* maker */ "falkTX",
/* copyright */ "GNU GPL v2+",
DESCFUNCS
DESCFUNCS_WITHOUTCV
},
{
/* category */ NATIVE_PLUGIN_CATEGORY_UTILITY,
@@ -94,7 +97,7 @@ static const NativePluginDescriptor sNativePluginDescriptors[] = {
/* label */ "lfo",
/* maker */ "falkTX",
/* copyright */ "GNU GPL v2+",
DESCFUNCS
DESCFUNCS_WITHOUTCV
},
{
/* category */ NATIVE_PLUGIN_CATEGORY_UTILITY,
@@ -110,7 +113,7 @@ static const NativePluginDescriptor sNativePluginDescriptors[] = {
/* label */ "midichanfilter",
/* maker */ "falkTX",
/* copyright */ "GNU GPL v2+",
DESCFUNCS
DESCFUNCS_WITHOUTCV
},
{
/* category */ NATIVE_PLUGIN_CATEGORY_UTILITY,
@@ -126,7 +129,7 @@ static const NativePluginDescriptor sNativePluginDescriptors[] = {
/* label */ "midichanab",
/* maker */ "Milk Brewster",
/* copyright */ "GNU GPL v2+",
DESCFUNCS
DESCFUNCS_WITHOUTCV
},
{
/* category */ NATIVE_PLUGIN_CATEGORY_UTILITY,
@@ -142,7 +145,7 @@ static const NativePluginDescriptor sNativePluginDescriptors[] = {
/* label */ "midigain",
/* maker */ "falkTX",
/* copyright */ "GNU GPL v2+",
DESCFUNCS
DESCFUNCS_WITHOUTCV
},
{
/* category */ NATIVE_PLUGIN_CATEGORY_UTILITY,
@@ -158,7 +161,7 @@ static const NativePluginDescriptor sNativePluginDescriptors[] = {
/* label */ "midijoin",
/* maker */ "falkTX",
/* copyright */ "GNU GPL v2+",
DESCFUNCS
DESCFUNCS_WITHOUTCV
},
{
/* category */ NATIVE_PLUGIN_CATEGORY_UTILITY,
@@ -174,7 +177,7 @@ static const NativePluginDescriptor sNativePluginDescriptors[] = {
/* label */ "midisplit",
/* maker */ "falkTX",
/* copyright */ "GNU GPL v2+",
DESCFUNCS
DESCFUNCS_WITHOUTCV
},
{
/* category */ NATIVE_PLUGIN_CATEGORY_UTILITY,
@@ -190,7 +193,7 @@ static const NativePluginDescriptor sNativePluginDescriptors[] = {
/* label */ "midithrough",
/* maker */ "falkTX",
/* copyright */ "GNU GPL v2+",
DESCFUNCS
DESCFUNCS_WITHOUTCV
},
{
/* category */ NATIVE_PLUGIN_CATEGORY_UTILITY,
@@ -206,7 +209,7 @@ static const NativePluginDescriptor sNativePluginDescriptors[] = {
/* label */ "miditranspose",
/* maker */ "falkTX",
/* copyright */ "GNU GPL v2+",
DESCFUNCS
DESCFUNCS_WITHOUTCV
},
{
/* category */ NATIVE_PLUGIN_CATEGORY_UTILITY,
@@ -222,7 +225,7 @@ static const NativePluginDescriptor sNativePluginDescriptors[] = {
/* label */ "midichannelize",
/* maker */ "falkTX",
/* copyright */ "GNU GPL v2+",
DESCFUNCS
DESCFUNCS_WITHOUTCV
},

// --------------------------------------------------------------------------------------------------------------------
@@ -245,7 +248,7 @@ static const NativePluginDescriptor sNativePluginDescriptors[] = {
/* label */ "audiofile",
/* maker */ "falkTX",
/* copyright */ "GNU GPL v2+",
DESCFUNCS
DESCFUNCS_WITHOUTCV
},

// --------------------------------------------------------------------------------------------------------------------
@@ -269,7 +272,7 @@ static const NativePluginDescriptor sNativePluginDescriptors[] = {
/* label */ "midifile",
/* maker */ "falkTX",
/* copyright */ "GNU GPL v2+",
DESCFUNCS
DESCFUNCS_WITHOUTCV
},
#ifdef HAVE_PYQT
{
@@ -289,7 +292,7 @@ static const NativePluginDescriptor sNativePluginDescriptors[] = {
/* label */ "midipattern",
/* maker */ "falkTX, tatch",
/* copyright */ "GNU GPL v2+",
DESCFUNCS
DESCFUNCS_WITHOUTCV
},
#endif

@@ -315,7 +318,7 @@ static const NativePluginDescriptor sNativePluginDescriptors[] = {
/* label */ "carlarack",
/* maker */ "falkTX",
/* copyright */ "GNU GPL v2+",
DESCFUNCS
DESCFUNCS_WITHOUTCV
},
{
/* category */ NATIVE_PLUGIN_CATEGORY_OTHER,
@@ -335,7 +338,7 @@ static const NativePluginDescriptor sNativePluginDescriptors[] = {
/* label */ "carlarack-nomidiout",
/* maker */ "falkTX",
/* copyright */ "GNU GPL v2+",
DESCFUNCS
DESCFUNCS_WITHOUTCV
},
{
/* category */ NATIVE_PLUGIN_CATEGORY_OTHER,
@@ -355,7 +358,7 @@ static const NativePluginDescriptor sNativePluginDescriptors[] = {
/* label */ "carlapatchbay",
/* maker */ "falkTX",
/* copyright */ "GNU GPL v2+",
DESCFUNCS
DESCFUNCS_WITHOUTCV
},
{
/* category */ NATIVE_PLUGIN_CATEGORY_OTHER,
@@ -375,7 +378,7 @@ static const NativePluginDescriptor sNativePluginDescriptors[] = {
/* label */ "carlapatchbay3s",
/* maker */ "falkTX",
/* copyright */ "GNU GPL v2+",
DESCFUNCS
DESCFUNCS_WITHOUTCV
},
{
/* category */ NATIVE_PLUGIN_CATEGORY_OTHER,
@@ -395,7 +398,7 @@ static const NativePluginDescriptor sNativePluginDescriptors[] = {
/* label */ "carlapatchbay16",
/* maker */ "falkTX",
/* copyright */ "GNU GPL v2+",
DESCFUNCS
DESCFUNCS_WITHOUTCV
},
{
/* category */ NATIVE_PLUGIN_CATEGORY_OTHER,
@@ -415,7 +418,7 @@ static const NativePluginDescriptor sNativePluginDescriptors[] = {
/* label */ "carlapatchbay32",
/* maker */ "falkTX",
/* copyright */ "GNU GPL v2+",
DESCFUNCS
DESCFUNCS_WITHOUTCV
},
{
/* category */ NATIVE_PLUGIN_CATEGORY_OTHER,
@@ -435,7 +438,30 @@ static const NativePluginDescriptor sNativePluginDescriptors[] = {
/* label */ "carlapatchbay64",
/* maker */ "falkTX",
/* 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

@@ -459,7 +485,7 @@ static const NativePluginDescriptor sNativePluginDescriptors[] = {
/* label */ "bigmeter",
/* maker */ "falkTX",
/* copyright */ "GNU GPL v2+",
DESCFUNCS
DESCFUNCS_WITHOUTCV
},
{
/* category */ NATIVE_PLUGIN_CATEGORY_UTILITY,
@@ -476,7 +502,7 @@ static const NativePluginDescriptor sNativePluginDescriptors[] = {
/* label */ "notes",
/* maker */ "falkTX",
/* copyright */ "GNU GPL v2+",
DESCFUNCS
DESCFUNCS_WITHOUTCV
},
#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,
.audioIns = 2,
.audioOuts = 2,
.cvIns = 0,
.cvOuts = 0,
.midiIns = 0,
.midiOuts = 0,
.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,
.audioIns = 1,
.audioOuts = 1,
.cvIns = 0,
.cvOuts = 0,
.midiIns = 0,
.midiOuts = 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,
.audioIns = 0,
.audioOuts = 0,
.cvIns = 0,
.cvOuts = 0,
.midiIns = 0,
.midiOuts = 0,
.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,
.audioIns = 0,
.audioOuts = 0,
.cvIns = 0,
.cvOuts = 0,
.midiIns = 1,
.midiOuts = 2,
.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,
.audioIns = 0,
.audioOuts = 0,
.cvIns = 0,
.cvOuts = 0,
.midiIns = 1,
.midiOuts = 1,
.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,
.audioIns = 0,
.audioOuts = 0,
.cvIns = 0,
.cvOuts = 0,
.midiIns = 1,
.midiOuts = 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,
.audioIns = 0,
.audioOuts = 0,
.cvIns = 0,
.cvOuts = 0,
.midiIns = 1,
.midiOuts = 1,
.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,
.audioIns = 0,
.audioOuts = 0,
.cvIns = 0,
.cvOuts = 0,
.midiIns = MAX_MIDI_CHANNELS,
.midiOuts = 1,
.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,
.audioIns = 0,
.audioOuts = 0,
.cvIns = 0,
.cvOuts = 0,
.midiIns = 1,
.midiOuts = MAX_MIDI_CHANNELS,
.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,
.audioIns = 0,
.audioOuts = 0,
.cvIns = 0,
.cvOuts = 0,
.midiIns = 1,
.midiOuts = 1,
.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,
.audioIns = 0,
.audioOuts = 0,
.cvIns = 0,
.cvOuts = 0,
.midiIns = 1,
.midiOuts = 1,
.paramIns = 2,


Loading…
Cancel
Save