From c935ce4e5d6a65ec55a57e2bf7c9ac7d74abdb8d Mon Sep 17 00:00:00 2001 From: falkTX Date: Sun, 14 May 2023 01:19:31 +0200 Subject: [PATCH] Setup VST3 audio buffers properly Signed-off-by: falkTX --- source/backend/plugin/CarlaPluginVST3.cpp | 341 ++++++++++++++-------- source/discovery/carla-discovery.cpp | 23 +- source/utils/CarlaVst3Utils.hpp | 4 +- 3 files changed, 244 insertions(+), 124 deletions(-) diff --git a/source/backend/plugin/CarlaPluginVST3.cpp b/source/backend/plugin/CarlaPluginVST3.cpp index c66167cfa..e9439b931 100644 --- a/source/backend/plugin/CarlaPluginVST3.cpp +++ b/source/backend/plugin/CarlaPluginVST3.cpp @@ -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.data[i].rindex)); + } + } + + ~carla_v3_input_param_changes() + { + for (uint32_t i=0; iget_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( - 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(parameterId), + static_cast(paramIndex), ¶mInfo) == 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(parameterId), + static_cast(paramIndex), ¶mInfo) == 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(normalized)); + fEvents.paramInputs->setParamValue(paramIndex, static_cast(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(normalized)); + fEvents.paramInputs->setParamValue(paramIndex, static_cast(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(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; jget_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(busInfo.channel_count); + cvIns += static_cast(numChannels); else - aIns += static_cast(busInfo.channel_count); + aIns += static_cast(numChannels); } - for (int32_t j=0; jget_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(busInfo.channel_count); - else - aOuts += static_cast(busInfo.channel_count); - } + const int32_t numChannels = busInfo.channel_count; + CARLA_SAFE_ASSERT_BREAK(numChannels >= 0); - for (int32_t j=0; jget_parameter_info(fV3.controller, j, ¶mInfo) == 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(numChannels); + else + aOuts += static_cast(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, ¶mInfo) == V3_OK); + CARLA_SAFE_ASSERT_BREAK(v3_cpp_obj(fV3.controller)->get_parameter_info(fV3.controller, + j, ¶mInfo) == 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(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; jget_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; jget_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(pData->audioIn.count + pData->cvIn.count), - 0, { bufferAudioIn } - }; - v3_audio_bus_buffers processOutputs = { - static_cast(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(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(frames), - static_cast(pData->audioIn.count + pData->cvIn.count), - static_cast(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; diff --git a/source/discovery/carla-discovery.cpp b/source/discovery/carla-discovery.cpp index ceda46aa3..bbfc3f3c3 100644 --- a/source/discovery/carla-discovery.cpp +++ b/source/discovery/carla-discovery.cpp @@ -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; bget_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); diff --git a/source/utils/CarlaVst3Utils.hpp b/source/utils/CarlaVst3Utils.hpp index 1f5c052d4..759697da1 100644 --- a/source/utils/CarlaVst3Utils.hpp +++ b/source/utils/CarlaVst3Utils.hpp @@ -158,11 +158,11 @@ const char* tuid2str(const v3_tuid iid) noexcept // -------------------------------------------------------------------------------------------------------------------- template -void* v3_create_class_ptr() +T** v3_create_class_ptr() { T** const clsptr = new T*; *clsptr = new T; - return static_cast(clsptr); + return clsptr; } // --------------------------------------------------------------------------------------------------------------------