Browse Source

Setup VST3 audio buffers properly

Signed-off-by: falkTX <falktx@falktx.com>
pull/1775/head
falkTX 1 year ago
parent
commit
c935ce4e5d
Signed by: falkTX <falktx@falktx.com> GPG Key ID: CDBAA37ABC74FBA0
3 changed files with 244 additions and 124 deletions
  1. +224
    -117
      source/backend/plugin/CarlaPluginVST3.cpp
  2. +18
    -5
      source/discovery/carla-discovery.cpp
  3. +2
    -2
      source/utils/CarlaVst3Utils.hpp

+ 224
- 117
source/backend/plugin/CarlaPluginVST3.cpp View File

@@ -316,6 +316,9 @@ private:

return V3_INVALID_ARG;
}

CARLA_DECLARE_NON_COPYABLE(carla_v3_attribute_list)
CARLA_PREVENT_HEAP_ALLOCATION
};

struct carla_v3_message : v3_message_cpp {
@@ -469,6 +472,7 @@ private:
}

CARLA_DECLARE_NON_COPYABLE(carla_v3_bstream)
CARLA_PREVENT_HEAP_ALLOCATION
};

// --------------------------------------------------------------------------------------------------------------------
@@ -508,6 +512,7 @@ private:
}

CARLA_DECLARE_NON_COPYABLE(carla_v3_host_application)
CARLA_PREVENT_HEAP_ALLOCATION
};

// --------------------------------------------------------------------------------------------------------------------
@@ -565,6 +570,7 @@ private:
}

CARLA_DECLARE_NON_COPYABLE(carla_v3_input_param_value_queue)
// CARLA_PREVENT_HEAP_ALLOCATION
};

struct carla_v3_input_param_changes : v3_param_changes_cpp {
@@ -595,8 +601,25 @@ struct carla_v3_input_param_changes : v3_param_changes_cpp {
changes.get_param_data = get_param_data;
changes.add_param_data = add_param_data;

for (uint32_t i=0; i<paramData.count; ++i)
CARLA_ASSERT(paramCount != 0);

carla_zeroStructs(updatedParams, paramCount);

for (uint32_t i=0; i<paramCount; ++i)
{
carla_zeroStruct(updatedParams[i]);
queue[i] = new carla_v3_input_param_value_queue(static_cast<v3_param_id>(paramData.data[i].rindex));
}
}

~carla_v3_input_param_changes()
{
for (uint32_t i=0; i<paramCount; ++i)
delete queue[i];

delete[] updatedParams;
delete[] pluginExposedQueue;
delete[] queue;
}

// called during start of process, gathering all parameter update requests so far
@@ -904,6 +927,7 @@ private:
}

CARLA_DECLARE_NON_COPYABLE(carla_v3_run_loop)
CARLA_PREVENT_HEAP_ALLOCATION
};

// --------------------------------------------------------------------------------------------------------------------
@@ -966,6 +990,7 @@ private:
}

CARLA_DECLARE_NON_COPYABLE(carla_v3_component_handler)
CARLA_PREVENT_HEAP_ALLOCATION
};

// --------------------------------------------------------------------------------------------------------------------
@@ -1011,6 +1036,7 @@ private:
}

CARLA_DECLARE_NON_COPYABLE(carla_v3_plugin_frame)
CARLA_PREVENT_HEAP_ALLOCATION
};

// --------------------------------------------------------------------------------------------------------------------
@@ -1130,7 +1156,7 @@ public:
{
}

uint32_t getParameterScalePointCount(uint32_t parameterId) const noexcept override
uint32_t getParameterScalePointCount(const uint32_t paramIndex) const noexcept override
{
}
*/
@@ -1147,21 +1173,21 @@ public:
std::free(fLastChunk);

carla_v3_bstream stream;
carla_v3_bstream* streamPtr = &stream;
carla_v3_bstream* const streamPtr = &stream;
v3_bstream** const v3stream = (v3_bstream**)&streamPtr;

stream.canWrite = true;

if (v3_cpp_obj(fV3.component)->get_state(fV3.component, (v3_bstream**)&streamPtr))
if (v3_cpp_obj(fV3.component)->get_state(fV3.component, v3stream) == V3_OK)
{
*dataPtr = fLastChunk = stream.buffer;
runIdleCallbacksAsNeeded(false);
return stream.size;
}
else
{
*dataPtr = fLastChunk = nullptr;
runIdleCallbacksAsNeeded(false);
return 0;
}

*dataPtr = fLastChunk = nullptr;
runIdleCallbacksAsNeeded(false);
return 0;
}

// ----------------------------------------------------------------------------------------------------------------
@@ -1198,20 +1224,22 @@ public:
return options;
}

float getParameterValue(const uint32_t parameterId) const noexcept override
float getParameterValue(const uint32_t paramIndex) const noexcept override
{
CARLA_SAFE_ASSERT_RETURN(fV3.controller != nullptr, 0.0f);
CARLA_SAFE_ASSERT_RETURN(parameterId < pData->param.count, 0.0f);
CARLA_SAFE_ASSERT_RETURN(paramIndex < pData->param.count, 0.0f);

// FIXME use pending RT value?

const v3_param_id v3id = pData->param.data[parameterId].rindex;
const double normalized = v3_cpp_obj(fV3.controller)->get_parameter_normalised(fV3.controller, v3id);
const v3_param_id paramId = pData->param.data[paramIndex].rindex;
const double normalized = v3_cpp_obj(fV3.controller)->get_parameter_normalised(fV3.controller, paramId);

return static_cast<float>(
v3_cpp_obj(fV3.controller)->normalised_parameter_to_plain(fV3.controller, v3id, normalized));
v3_cpp_obj(fV3.controller)->normalised_parameter_to_plain(fV3.controller, paramId, normalized));
}

/* TODO
float getParameterScalePointValue(uint32_t parameterId, uint32_t scalePointId) const noexcept override
float getParameterScalePointValue(uint32_t paramIndex, uint32_t scalePointId) const noexcept override
{
}
*/
@@ -1239,37 +1267,39 @@ public:
return true;
}

bool getParameterName(const uint32_t parameterId, char* const strBuf) const noexcept override
bool getParameterName(const uint32_t paramIndex, char* const strBuf) const noexcept override
{
CARLA_SAFE_ASSERT_RETURN(fV3.controller != nullptr, 0.0f);
CARLA_SAFE_ASSERT_RETURN(parameterId < pData->param.count, false);
CARLA_SAFE_ASSERT_RETURN(paramIndex < pData->param.count, false);

v3_param_info paramInfo = {};
CARLA_SAFE_ASSERT_RETURN(v3_cpp_obj(fV3.controller)->get_parameter_info(fV3.controller,
static_cast<int32_t>(parameterId),
static_cast<int32_t>(paramIndex),
&paramInfo) == V3_OK, false);

strncpy_utf8(strBuf, paramInfo.title, STR_MAX);
return true;
}

/* TODO
bool getParameterSymbol(uint32_t parameterId, char* strBuf) const noexcept override
bool getParameterSymbol(const uint32_t paramIndex, char* strBuf) const noexcept override
{
CARLA_SAFE_ASSERT_RETURN(paramIndex < pData->param.count, false);

std::snprintf(strBuf, STR_MAX, "%d", pData->param.data[paramIndex].rindex);
return true;
}
*/

bool getParameterText(const uint32_t parameterId, char* const strBuf) noexcept override
bool getParameterText(const uint32_t paramIndex, char* const strBuf) noexcept override
{
CARLA_SAFE_ASSERT_RETURN(fV3.controller != nullptr, false);
CARLA_SAFE_ASSERT_RETURN(parameterId < pData->param.count, false);
CARLA_SAFE_ASSERT_RETURN(paramIndex < pData->param.count, false);

const v3_param_id v3id = pData->param.data[parameterId].rindex;
const double normalized = v3_cpp_obj(fV3.controller)->get_parameter_normalised(fV3.controller, v3id);
const v3_param_id paramId = pData->param.data[paramIndex].rindex;
const double normalized = v3_cpp_obj(fV3.controller)->get_parameter_normalised(fV3.controller, paramId);

v3_str_128 paramText;
CARLA_SAFE_ASSERT_RETURN(v3_cpp_obj(fV3.controller)->get_parameter_string_for_value(fV3.controller,
v3id,
paramId,
normalized,
paramText) == V3_OK, false);

@@ -1277,19 +1307,19 @@ public:
strncpy_utf8(strBuf, paramText, STR_MAX);
else
std::snprintf(strBuf, STR_MAX, "%.12g",
v3_cpp_obj(fV3.controller)->normalised_parameter_to_plain(fV3.controller, v3id, normalized));
v3_cpp_obj(fV3.controller)->normalised_parameter_to_plain(fV3.controller, paramId, normalized));

return true;
}

bool getParameterUnit(const uint32_t parameterId, char* const strBuf) const noexcept override
bool getParameterUnit(const uint32_t paramIndex, char* const strBuf) const noexcept override
{
CARLA_SAFE_ASSERT_RETURN(fV3.controller != nullptr, false);
CARLA_SAFE_ASSERT_RETURN(parameterId < pData->param.count, false);
CARLA_SAFE_ASSERT_RETURN(paramIndex < pData->param.count, false);

v3_param_info paramInfo = {};
CARLA_SAFE_ASSERT_RETURN(v3_cpp_obj(fV3.controller)->get_parameter_info(fV3.controller,
static_cast<int32_t>(parameterId),
static_cast<int32_t>(paramIndex),
&paramInfo) == V3_OK, false);

strncpy_utf8(strBuf, paramInfo.units, STR_MAX);
@@ -1297,11 +1327,12 @@ public:
}

/* TODO
bool getParameterGroupName(uint32_t parameterId, char* strBuf) const noexcept override
bool getParameterGroupName(const uint32_t paramIndex, char* const strBuf) const noexcept override
{
}

bool getParameterScalePointLabel(uint32_t parameterId, uint32_t scalePointId, char* strBuf) const noexcept override
bool getParameterScalePointLabel(const uint32_t paramIndex,
const uint32_t scalePointId, char* const strBuf) const noexcept override
{
}
*/
@@ -1328,45 +1359,45 @@ public:
// ----------------------------------------------------------------------------------------------------------------
// Set data (plugin-specific stuff)

void setParameterValue(const uint32_t parameterId, const float value,
void setParameterValue(const uint32_t paramIndex, const float value,
const bool sendGui, const bool sendOsc, const bool sendCallback) noexcept override
{
CARLA_SAFE_ASSERT_RETURN(fV3.controller != nullptr,);
CARLA_SAFE_ASSERT_RETURN(parameterId < pData->param.count,);
CARLA_SAFE_ASSERT_RETURN(paramIndex < pData->param.count,);
CARLA_SAFE_ASSERT_RETURN(fEvents.paramInputs != nullptr,);

const v3_param_id v3id = pData->param.data[parameterId].rindex;
const float fixedValue = pData->param.getFixedValue(parameterId, value);
const v3_param_id paramId = pData->param.data[paramIndex].rindex;
const float fixedValue = pData->param.getFixedValue(paramIndex, value);
const double normalized = v3_cpp_obj(fV3.controller)->plain_parameter_to_normalised(fV3.controller,
v3id,
paramId,
fixedValue);

// report value to component (next process call)
fEvents.paramInputs->setParamValue(parameterId, static_cast<float>(normalized));
fEvents.paramInputs->setParamValue(paramIndex, static_cast<float>(normalized));

// report value to edit controller
v3_cpp_obj(fV3.controller)->set_parameter_normalised(fV3.controller, v3id, normalized);
v3_cpp_obj(fV3.controller)->set_parameter_normalised(fV3.controller, paramId, normalized);

CarlaPlugin::setParameterValue(parameterId, fixedValue, sendGui, sendOsc, sendCallback);
CarlaPlugin::setParameterValue(paramIndex, fixedValue, sendGui, sendOsc, sendCallback);
}

void setParameterValueRT(const uint32_t parameterId, const float value, const uint32_t frameOffset,
void setParameterValueRT(const uint32_t paramIndex, const float value, const uint32_t frameOffset,
const bool sendCallbackLater) noexcept override
{
CARLA_SAFE_ASSERT_RETURN(fV3.controller != nullptr,);
CARLA_SAFE_ASSERT_RETURN(parameterId < pData->param.count,);
CARLA_SAFE_ASSERT_RETURN(paramIndex < pData->param.count,);
CARLA_SAFE_ASSERT_RETURN(fEvents.paramInputs != nullptr,);

const v3_param_id v3id = pData->param.data[parameterId].rindex;
const float fixedValue = pData->param.getFixedValue(parameterId, value);
const v3_param_id paramId = pData->param.data[paramIndex].rindex;
const float fixedValue = pData->param.getFixedValue(paramIndex, value);
const double normalized = v3_cpp_obj(fV3.controller)->plain_parameter_to_normalised(fV3.controller,
v3id,
paramId,
fixedValue);

// report value to component (next process call)
fEvents.paramInputs->setParamValue(parameterId, static_cast<float>(normalized));
fEvents.paramInputs->setParamValue(paramIndex, static_cast<float>(normalized));

CarlaPlugin::setParameterValueRT(parameterId, fixedValue, frameOffset, sendCallbackLater);
CarlaPlugin::setParameterValueRT(paramIndex, fixedValue, frameOffset, sendCallbackLater);
}

void setChunkData(const void* data, std::size_t dataSize) override
@@ -1378,14 +1409,16 @@ public:
CARLA_SAFE_ASSERT_RETURN(dataSize > 0,);

carla_v3_bstream stream;
carla_v3_bstream* streamPtr = &stream;
carla_v3_bstream* const streamPtr = &stream;
v3_bstream** const v3stream = (v3_bstream**)&streamPtr;

stream.buffer = const_cast<void*>(data);
stream.size = dataSize;
stream.canRead = true;

if (v3_cpp_obj(fV3.component)->set_state(fV3.component, (v3_bstream**)&streamPtr) == V3_OK)
if (v3_cpp_obj(fV3.component)->set_state(fV3.component, v3stream) == V3_OK)
{
v3_cpp_obj(fV3.controller)->set_state(fV3.controller, (v3_bstream**)&streamPtr);
v3_cpp_obj(fV3.controller)->set_state(fV3.controller, v3stream);
pData->updateParameterValues(this, true, true, false);
}

@@ -1699,43 +1732,58 @@ public:
CARLA_SAFE_ASSERT(numEventOutputBuses >= 0);
CARLA_SAFE_ASSERT(numParameters >= 0);

uint32_t aIns, aOuts, cvIns, cvOuts, params;
aIns = aOuts = cvIns = cvOuts = params = 0;
uint32_t aIns, aOuts, cvIns, cvOuts;
aIns = aOuts = cvIns = cvOuts = 0;

bool needsCtrlIn, needsCtrlOut;
needsCtrlIn = needsCtrlOut = false;

for (int32_t j=0; j<numAudioInputBuses; ++j)
fBuses.createNew(numAudioInputBuses, numAudioOutputBuses);

for (int32_t b=0; b<numAudioInputBuses; ++b)
{
v3_bus_info busInfo = {};
CARLA_SAFE_ASSERT_BREAK(v3_cpp_obj(fV3.component)->get_bus_info(fV3.component, V3_AUDIO, V3_INPUT, j, &busInfo) == V3_OK);
CARLA_SAFE_ASSERT_BREAK(busInfo.channel_count >= 0);
carla_zeroStruct(fBuses.inputs[b]);
CARLA_SAFE_ASSERT_BREAK(v3_cpp_obj(fV3.component)->get_bus_info(fV3.component,
V3_AUDIO, V3_INPUT, b, &busInfo) == V3_OK);

const int32_t numChannels = busInfo.channel_count;
CARLA_SAFE_ASSERT_BREAK(numChannels >= 0);

if ((busInfo.flags & V3_DEFAULT_ACTIVE) == 0x0) {
CARLA_SAFE_ASSERT_BREAK(v3_cpp_obj(fV3.component)->activate_bus(fV3.component,
V3_AUDIO, V3_INPUT, b, true) == V3_OK);
}

fBuses.inputs[b].num_channels = numChannels;

if (busInfo.flags & V3_IS_CONTROL_VOLTAGE)
cvIns += static_cast<uint32_t>(busInfo.channel_count);
cvIns += static_cast<uint32_t>(numChannels);
else
aIns += static_cast<uint32_t>(busInfo.channel_count);
aIns += static_cast<uint32_t>(numChannels);
}

for (int32_t j=0; j<numAudioOutputBuses; ++j)
for (int32_t b=0; b<numAudioOutputBuses; ++b)
{
v3_bus_info busInfo = {};
CARLA_SAFE_ASSERT_BREAK(v3_cpp_obj(fV3.component)->get_bus_info(fV3.component, V3_AUDIO, V3_OUTPUT, j, &busInfo) == V3_OK);
CARLA_SAFE_ASSERT_BREAK(busInfo.channel_count >= 0);
carla_zeroStruct(fBuses.outputs[b]);
CARLA_SAFE_ASSERT_BREAK(v3_cpp_obj(fV3.component)->get_bus_info(fV3.component,
V3_AUDIO, V3_OUTPUT, b, &busInfo) == V3_OK);

if (busInfo.flags & V3_IS_CONTROL_VOLTAGE)
cvOuts += static_cast<uint32_t>(busInfo.channel_count);
else
aOuts += static_cast<uint32_t>(busInfo.channel_count);
}
const int32_t numChannels = busInfo.channel_count;
CARLA_SAFE_ASSERT_BREAK(numChannels >= 0);

for (int32_t j=0; j<numParameters; ++j)
{
v3_param_info paramInfo = {};
CARLA_SAFE_ASSERT_BREAK(v3_cpp_obj(fV3.controller)->get_parameter_info(fV3.controller, j, &paramInfo) == V3_OK);
if ((busInfo.flags & V3_DEFAULT_ACTIVE) == 0x0) {
CARLA_SAFE_ASSERT_BREAK(v3_cpp_obj(fV3.component)->activate_bus(fV3.component,
V3_AUDIO, V3_OUTPUT, b, true) == V3_OK);
}

if ((paramInfo.flags & (V3_PARAM_IS_BYPASS|V3_PARAM_IS_HIDDEN|V3_PARAM_PROGRAM_CHANGE)) == 0x0)
++params;
fBuses.outputs[b].num_channels = numChannels;

if (busInfo.flags & V3_IS_CONTROL_VOLTAGE)
cvOuts += static_cast<uint32_t>(numChannels);
else
aOuts += static_cast<uint32_t>(numChannels);
}

if (aIns > 0)
@@ -1761,17 +1809,17 @@ public:
if (numEventOutputBuses > 0)
needsCtrlOut = true;

if (params > 0)
if (numParameters > 0)
{
pData->param.createNew(params, false);
pData->param.createNew(numParameters, false);
needsCtrlIn = true;
}

if (aOuts + cvIns > 0)
if (aOuts + cvOuts > 0)
{
fAudioAndCvOutBuffers = new float*[aOuts + cvIns];
fAudioAndCvOutBuffers = new float*[aOuts + cvOuts];

for (uint32_t i=0; i < aOuts + cvIns; ++i)
for (uint32_t i=0; i < aOuts + cvOuts; ++i)
fAudioAndCvOutBuffers[i] = nullptr;
}

@@ -1800,7 +1848,8 @@ public:

portName.truncate(portNameSize);

pData->audioIn.ports[j].port = (CarlaEngineAudioPort*)pData->client->addPort(kEnginePortTypeAudio, portName, true, j);
pData->audioIn.ports[j].port = (CarlaEngineAudioPort*)pData->client->addPort(kEnginePortTypeAudio,
portName, true, j);
pData->audioIn.ports[j].rindex = j;
}

@@ -1825,7 +1874,8 @@ public:

portName.truncate(portNameSize);

pData->audioOut.ports[j].port = (CarlaEngineAudioPort*)pData->client->addPort(kEnginePortTypeAudio, portName, false, j);
pData->audioOut.ports[j].port = (CarlaEngineAudioPort*)pData->client->addPort(kEnginePortTypeAudio,
portName, false, j);
pData->audioOut.ports[j].rindex = j;
}

@@ -1850,7 +1900,8 @@ public:

portName.truncate(portNameSize);

pData->cvIn.ports[j].port = (CarlaEngineCVPort*)pData->client->addPort(kEnginePortTypeCV, portName, true, j);
pData->cvIn.ports[j].port = (CarlaEngineCVPort*)pData->client->addPort(kEnginePortTypeCV,
portName, true, j);
pData->cvIn.ports[j].rindex = j;
}

@@ -1875,29 +1926,38 @@ public:

portName.truncate(portNameSize);

pData->cvOut.ports[j].port = (CarlaEngineCVPort*)pData->client->addPort(kEnginePortTypeCV, portName, false, j);
pData->cvOut.ports[j].port = (CarlaEngineCVPort*)pData->client->addPort(kEnginePortTypeCV,
portName, false, j);
pData->cvOut.ports[j].rindex = j;
}

for (uint32_t j=0; j < params; ++j)
for (int32_t j=0; j < numParameters; ++j)
{
v3_param_info paramInfo = {};
CARLA_SAFE_ASSERT_BREAK(v3_cpp_obj(fV3.controller)->get_parameter_info(fV3.controller, j, &paramInfo) == V3_OK);
CARLA_SAFE_ASSERT_BREAK(v3_cpp_obj(fV3.controller)->get_parameter_info(fV3.controller,
j, &paramInfo) == V3_OK);

char strBuf[200];
strncpy_utf8(strBuf, paramInfo.title, 128);
carla_stdout("param %d | %d '%s' %d", j, paramInfo.param_id, strBuf, paramInfo.flags);

const v3_param_id v3id = paramInfo.param_id;
pData->param.data[j].index = j;
pData->param.data[j].rindex = v3id;
const v3_param_id paramId = paramInfo.param_id;
pData->param.data[j].index = static_cast<uint32_t>(j);
pData->param.data[j].rindex = paramId;

if (paramInfo.flags & (V3_PARAM_IS_BYPASS|V3_PARAM_IS_HIDDEN|V3_PARAM_PROGRAM_CHANGE))
continue;

double min, max, def, step, stepSmall, stepLarge;

min = v3_cpp_obj(fV3.controller)->normalised_parameter_to_plain(fV3.controller, v3id, 0.0);
max = v3_cpp_obj(fV3.controller)->normalised_parameter_to_plain(fV3.controller, v3id, 1.0);
def = v3_cpp_obj(fV3.controller)->normalised_parameter_to_plain(fV3.controller, v3id,
min = v3_cpp_obj(fV3.controller)->normalised_parameter_to_plain(fV3.controller, paramId, 0.0);
max = v3_cpp_obj(fV3.controller)->normalised_parameter_to_plain(fV3.controller, paramId, 1.0);
def = v3_cpp_obj(fV3.controller)->normalised_parameter_to_plain(fV3.controller, paramId,
paramInfo.default_normalised_value);

carla_stdout("param %d | %d '%s' %d %f %f %f", j, paramInfo.param_id, strBuf, paramInfo.flags,
min, max, def);

if (min >= max)
max = min + 0.1;

@@ -1954,7 +2014,7 @@ public:
pData->param.ranges[j].stepLarge = stepLarge;
}

if (params > 0)
if (numParameters > 0)
{
fEvents.paramInputs = new carla_v3_input_param_changes(pData->param);
fEvents.paramOutputs = new carla_v3_output_param_changes;
@@ -1973,7 +2033,8 @@ public:
portName += "events-in";
portName.truncate(portNameSize);

pData->event.portIn = (CarlaEngineEventPort*)pData->client->addPort(kEnginePortTypeEvent, portName, true, 0);
pData->event.portIn = (CarlaEngineEventPort*)pData->client->addPort(kEnginePortTypeEvent,
portName, true, 0);
#ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH
pData->event.cvSourcePorts = pData->client->createCVSourcePorts();
#endif
@@ -1993,7 +2054,8 @@ public:
portName += "events-out";
portName.truncate(portNameSize);

pData->event.portOut = (CarlaEngineEventPort*)pData->client->addPort(kEnginePortTypeEvent, portName, false, 0);
pData->event.portOut = (CarlaEngineEventPort*)pData->client->addPort(kEnginePortTypeEvent,
portName, false, 0);
fEvents.eventOutputs = new carla_v3_output_event_list;
}

@@ -2053,20 +2115,24 @@ public:
for (int32_t j=0; j<numAudioInputBuses; ++j)
{
v3_bus_info busInfo = {};
CARLA_SAFE_ASSERT_BREAK(v3_cpp_obj(fV3.component)->get_bus_info(fV3.component, V3_AUDIO, V3_INPUT, j, &busInfo) == V3_OK);
CARLA_SAFE_ASSERT_BREAK(v3_cpp_obj(fV3.component)->get_bus_info(fV3.component,
V3_AUDIO, V3_INPUT, j, &busInfo) == V3_OK);

if ((busInfo.flags & V3_DEFAULT_ACTIVE) == 0x0) {
CARLA_SAFE_ASSERT_BREAK(v3_cpp_obj(fV3.component)->activate_bus(fV3.component, V3_AUDIO, V3_INPUT, j, true) == V3_OK);
CARLA_SAFE_ASSERT_BREAK(v3_cpp_obj(fV3.component)->activate_bus(fV3.component,
V3_AUDIO, V3_INPUT, j, true) == V3_OK);
}
}

for (int32_t j=0; j<numAudioOutputBuses; ++j)
{
v3_bus_info busInfo = {};
CARLA_SAFE_ASSERT_BREAK(v3_cpp_obj(fV3.component)->get_bus_info(fV3.component, V3_AUDIO, V3_OUTPUT, j, &busInfo) == V3_OK);
CARLA_SAFE_ASSERT_BREAK(v3_cpp_obj(fV3.component)->get_bus_info(fV3.component,
V3_AUDIO, V3_OUTPUT, j, &busInfo) == V3_OK);

if ((busInfo.flags & V3_DEFAULT_ACTIVE) == 0x0) {
CARLA_SAFE_ASSERT_BREAK(v3_cpp_obj(fV3.component)->activate_bus(fV3.component, V3_AUDIO, V3_OUTPUT, j, true) == V3_OK);
CARLA_SAFE_ASSERT_BREAK(v3_cpp_obj(fV3.component)->activate_bus(fV3.component,
V3_AUDIO, V3_OUTPUT, j, true) == V3_OK);
}
}

@@ -2533,7 +2599,8 @@ public:
// ------------------------------------------------------------------------------------------------------------
}

bool processSingle(const float* const* const inBuffer, float** const outBuffer, const uint32_t frames, const uint32_t timeOffset)
bool processSingle(const float* const* const inBuffer, float** const outBuffer,
const uint32_t frames, const uint32_t timeOffset)
{
CARLA_SAFE_ASSERT_RETURN(frames > 0, false);

@@ -2603,23 +2670,26 @@ public:

fEvents.prepare();

v3_audio_bus_buffers processInputs = {
static_cast<int32_t>(pData->audioIn.count + pData->cvIn.count),
0, { bufferAudioIn }
};
v3_audio_bus_buffers processOutputs = {
static_cast<int32_t>(pData->audioOut.count + pData->cvOut.count),
0, { bufferAudioOut }
};
for (int32_t b = 0, j = 0; b < fBuses.numInputs; ++b)
{
fBuses.inputs[b].channel_buffers_32 = const_cast<float**>(bufferAudioIn + j);
j += fBuses.inputs[b].num_channels;
}

for (int32_t b = 0, j = 0; b < fBuses.numOutputs; ++b)
{
fBuses.outputs[b].channel_buffers_32 = bufferAudioOut + j;
j += fBuses.outputs[b].num_channels;
}

v3_process_data processData = {
pData->engine->isOffline() ? V3_OFFLINE : V3_REALTIME,
V3_SAMPLE_32,
static_cast<int32_t>(frames),
static_cast<int32_t>(pData->audioIn.count + pData->cvIn.count),
static_cast<int32_t>(pData->audioOut.count + pData->cvOut.count),
&processInputs,
&processOutputs,
fBuses.numInputs,
fBuses.numOutputs,
fBuses.inputs,
fBuses.outputs,
fEvents.paramInputs != nullptr ? (v3_param_changes**)&fEvents.paramInputs : nullptr,
fEvents.paramOutputs != nullptr ? (v3_param_changes**)&fEvents.paramOutputs : nullptr,
fEvents.eventInputs != nullptr ? (v3_event_list**)&fEvents.eventInputs : nullptr,
@@ -2638,8 +2708,11 @@ public:
// Post-processing (dry/wet, volume and balance)

{
const bool doDryWet = (pData->hints & PLUGIN_CAN_DRYWET) != 0 && carla_isNotEqual(pData->postProc.dryWet, 1.0f);
const bool doBalance = (pData->hints & PLUGIN_CAN_BALANCE) != 0 && ! (carla_isEqual(pData->postProc.balanceLeft, -1.0f) && carla_isEqual(pData->postProc.balanceRight, 1.0f));
const bool doDryWet = (pData->hints & PLUGIN_CAN_DRYWET) != 0
&& carla_isNotEqual(pData->postProc.dryWet, 1.0f);
const bool doBalance = (pData->hints & PLUGIN_CAN_BALANCE) != 0
&& ! (carla_isEqual(pData->postProc.balanceLeft, -1.0f)
&& carla_isEqual(pData->postProc.balanceRight, 1.0f));
const bool isMono = (pData->audioIn.count == 1);

bool isPair;
@@ -2658,7 +2731,8 @@ public:
for (uint32_t k=0; k < frames; ++k)
{
bufValue = inBuffer[c][k+timeOffset];
fAudioAndCvOutBuffers[i][k] = (fAudioAndCvOutBuffers[i][k] * pData->postProc.dryWet) + (bufValue * (1.0f - pData->postProc.dryWet));
fAudioAndCvOutBuffers[i][k] = (fAudioAndCvOutBuffers[i][k] * pData->postProc.dryWet)
+ (bufValue * (1.0f - pData->postProc.dryWet));
}
}

@@ -2681,14 +2755,14 @@ public:
if (isPair)
{
// left
fAudioAndCvOutBuffers[i][k] = oldBufLeft[k] * (1.0f - balRangeL);
fAudioAndCvOutBuffers[i][k] = oldBufLeft[k] * (1.0f - balRangeL);
fAudioAndCvOutBuffers[i][k] += fAudioAndCvOutBuffers[i+1][k] * (1.0f - balRangeR);
}
else
{
// right
fAudioAndCvOutBuffers[i][k] = fAudioAndCvOutBuffers[i][k] * balRangeR;
fAudioAndCvOutBuffers[i][k] += oldBufLeft[k] * balRangeL;
fAudioAndCvOutBuffers[i][k] += oldBufLeft[k] * balRangeL;
}
}
}
@@ -2818,10 +2892,10 @@ public:
CARLA_SAFE_ASSERT_RETURN(fV3.controller != nullptr,);
CARLA_SAFE_ASSERT_RETURN(index < pData->param.count,);

const v3_param_id v3id = pData->param.data[index].rindex;
const v3_param_id paramId = pData->param.data[index].rindex;
const double normalized = v3_cpp_obj(fV3.controller)->plain_parameter_to_normalised(fV3.controller,
v3id, value);
v3_cpp_obj(fV3.controller)->set_parameter_normalised(fV3.controller, v3id, normalized);
paramId, value);
v3_cpp_obj(fV3.controller)->set_parameter_normalised(fV3.controller, paramId, normalized);
}

// ----------------------------------------------------------------------------------------------------------------
@@ -3447,6 +3521,39 @@ private:
CARLA_DECLARE_NON_COPYABLE(PluginPointers)
} fV3;

struct Buses {
int32_t numInputs;
int32_t numOutputs;
v3_audio_bus_buffers* inputs;
v3_audio_bus_buffers* outputs;

Buses()
: numInputs(0),
numOutputs(0),
inputs(nullptr),
outputs(nullptr) {}

~Buses()
{
delete[] inputs;
delete[] outputs;
}

void createNew(const int32_t numAudioInputBuses, const int32_t numAudioOutputBuses)
{
delete[] inputs;
delete[] outputs;

numInputs = numAudioInputBuses;
numOutputs = numAudioOutputBuses;

inputs = numAudioInputBuses > 0 ? new v3_audio_bus_buffers[numAudioInputBuses] : nullptr;
outputs = numAudioOutputBuses > 0 ? new v3_audio_bus_buffers[numAudioOutputBuses] : nullptr;
}

CARLA_DECLARE_NON_COPYABLE(Buses)
} fBuses;

struct Events {
carla_v3_input_param_changes* paramInputs;
carla_v3_output_param_changes* paramOutputs;


+ 18
- 5
source/discovery/carla-discovery.cpp View File

@@ -1435,6 +1435,9 @@ private:
}

static v3_result V3_API carla_create_instance(void*, v3_tuid, v3_tuid, void**) { return V3_NOT_IMPLEMENTED; }

CARLA_DECLARE_NON_COPYABLE(carla_v3_host_application)
CARLA_PREVENT_HEAP_ALLOCATION
};

struct carla_v3_param_value_queue : v3_param_value_queue_cpp {
@@ -1454,6 +1457,9 @@ private:
static int32_t V3_API carla_get_point_count(void*) { return 0; }
static v3_result V3_API carla_get_point(void*, int32_t, int32_t*, double*) { return V3_NOT_IMPLEMENTED; }
static v3_result V3_API carla_add_point(void*, int32_t, double, int32_t*) { return V3_NOT_IMPLEMENTED; }

CARLA_DECLARE_NON_COPYABLE(carla_v3_param_value_queue)
CARLA_PREVENT_HEAP_ALLOCATION
};

struct carla_v3_param_changes : v3_param_changes_cpp {
@@ -1471,6 +1477,9 @@ private:
static int32_t V3_API carla_get_param_count(void*) { return 0; }
static v3_param_value_queue** V3_API carla_get_param_data(void*, int32_t) { return nullptr; }
static v3_param_value_queue** V3_API carla_add_param_data(void*, v3_param_id*, int32_t*) { return nullptr; }

CARLA_DECLARE_NON_COPYABLE(carla_v3_param_changes)
CARLA_PREVENT_HEAP_ALLOCATION
};

struct carla_v3_event_list : v3_event_list_cpp {
@@ -1488,6 +1497,9 @@ private:
static uint32_t V3_API carla_get_event_count(void*) { return 0; }
static v3_result V3_API carla_get_event(void*, int32_t, v3_event*) { return V3_NOT_IMPLEMENTED; }
static v3_result V3_API carla_add_event(void*, v3_event*) { return V3_NOT_IMPLEMENTED; }

CARLA_DECLARE_NON_COPYABLE(carla_v3_event_list)
CARLA_PREVENT_HEAP_ALLOCATION
};

static bool v3_exit_false(const V3_EXITFN v3_exit)
@@ -1585,7 +1597,8 @@ static bool do_vst3_check(lib_t& libHandle, const char* const filename, const bo

// get factory info
v3_factory_info factoryInfo = {};
CARLA_SAFE_ASSERT_RETURN(v3_cpp_obj(factory1)->get_factory_info(factory1, &factoryInfo) == V3_OK, v3_exit_false(v3_exit));
CARLA_SAFE_ASSERT_RETURN(v3_cpp_obj(factory1)->get_factory_info(factory1, &factoryInfo) == V3_OK,
v3_exit_false(v3_exit));

// get num classes
const int32_t numClasses = v3_cpp_obj(factory1)->num_classes(factory1);
@@ -1806,12 +1819,12 @@ static bool do_vst3_check(lib_t& libHandle, const char* const filename, const bo
CARLA_SAFE_ASSERT_BREAK(v3_cpp_obj(component)->get_bus_info(component,
V3_AUDIO, V3_INPUT, b, &busInfo) == V3_OK);

inputsBuffers[b].num_channels = busInfo.channel_count;

if ((busInfo.flags & V3_DEFAULT_ACTIVE) == 0x0) {
CARLA_SAFE_ASSERT_BREAK(v3_cpp_obj(component)->activate_bus(component,
V3_AUDIO, V3_INPUT, b, true) == V3_OK);
}

inputsBuffers[b].num_channels = busInfo.channel_count;
}

for (int32_t b=0; b<numAudioOutputBuses; ++b)
@@ -1821,12 +1834,12 @@ static bool do_vst3_check(lib_t& libHandle, const char* const filename, const bo
CARLA_SAFE_ASSERT_BREAK(v3_cpp_obj(component)->get_bus_info(component,
V3_AUDIO, V3_OUTPUT, b, &busInfo) == V3_OK);

outputsBuffers[b].num_channels = busInfo.channel_count;

if ((busInfo.flags & V3_DEFAULT_ACTIVE) == 0x0) {
CARLA_SAFE_ASSERT_BREAK(v3_cpp_obj(component)->activate_bus(component,
V3_AUDIO, V3_OUTPUT, b, true) == V3_OK);
}

outputsBuffers[b].num_channels = busInfo.channel_count;
}

CARLA_SAFE_ASSERT_BREAK(v3_cpp_obj(component)->set_active(component, true) == V3_OK);


+ 2
- 2
source/utils/CarlaVst3Utils.hpp View File

@@ -158,11 +158,11 @@ const char* tuid2str(const v3_tuid iid) noexcept
// --------------------------------------------------------------------------------------------------------------------

template<class T>
void* v3_create_class_ptr()
T** v3_create_class_ptr()
{
T** const clsptr = new T*;
*clsptr = new T;
return static_cast<void*>(clsptr);
return clsptr;
}

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


Loading…
Cancel
Save