Signed-off-by: falkTX <falktx@falktx.com>tags/v2.1-rc1
@@ -1104,6 +1104,14 @@ typedef enum { | |||
*/ | |||
ENGINE_CALLBACK_PATCHBAY_PORT_GROUP_CHANGED = 45, | |||
/*! | |||
* A parameter's CV controlled status has changed. | |||
* @a pluginId Plugin Id | |||
* @a value1 Parameter index | |||
* @a value2 New CV controlled status (boolean) | |||
*/ | |||
ENGINE_CALLBACK_PARAMETER_CV_CONTROLLED_STATUS_CHANGED = 46, | |||
} EngineCallbackOpcode; | |||
/* ------------------------------------------------------------------------------------------------------------ | |||
@@ -941,6 +941,14 @@ CARLA_EXPORT void carla_set_option(uint pluginId, uint option, bool yesNo); | |||
CARLA_EXPORT void carla_set_parameter_value(uint pluginId, uint32_t parameterId, float value); | |||
#ifndef BUILD_BRIDGE | |||
/*! | |||
* Change a plugin's parameter cv controlled status. | |||
* @param pluginId Plugin | |||
* @param parameterId Parameter index | |||
* @param cv_controlled New CV controlled Status | |||
*/ | |||
CARLA_EXPORT void carla_set_parameter_cv_controlled(uint pluginId, uint32_t parameterId, bool cv_controlled); | |||
/*! | |||
* Change a plugin's parameter MIDI channel. | |||
* @param pluginId Plugin | |||
@@ -591,6 +591,11 @@ public: | |||
*/ | |||
void setParameterValueByRealIndex(int32_t rindex, float value, bool sendGui, bool sendOsc, bool sendCallback) noexcept; | |||
/*! | |||
* Change parameter's @a parameterId CV controlled status. | |||
*/ | |||
void setParameterAsCvControl(uint32_t parameterId, bool cv_controlled, bool sendOsc, bool sendCallback) noexcept; | |||
/*! | |||
* Set parameter's @a parameterId MIDI channel to @a channel. | |||
* @a channel must be between 0 and 15. | |||
@@ -1984,6 +1984,19 @@ void carla_set_parameter_value(uint pluginId, uint32_t parameterId, float value) | |||
} | |||
#ifndef BUILD_BRIDGE | |||
void carla_set_parameter_cv_controlled(uint pluginId, uint32_t parameterId, bool cv_controlled) | |||
{ | |||
CARLA_SAFE_ASSERT_RETURN(gStandalone.engine != nullptr,); | |||
CarlaPlugin* const plugin(gStandalone.engine->getPlugin(pluginId)); | |||
CARLA_SAFE_ASSERT_RETURN(plugin != nullptr,); | |||
carla_debug("carla_set_parameter_cv_controlled(%u, %u, %s)", pluginId, parameterId, bool2str(cv_controlled)); | |||
CARLA_SAFE_ASSERT_RETURN(parameterId < plugin->getParameterCount(),); | |||
return plugin->setParameterAsCvControl(parameterId, cv_controlled, true, false); | |||
} | |||
void carla_set_parameter_midi_channel(uint pluginId, uint32_t parameterId, uint8_t channel) | |||
{ | |||
CARLA_SAFE_ASSERT_RETURN(gStandalone.engine != nullptr,); | |||
@@ -2074,6 +2074,18 @@ bool CarlaEngineNativeUI::msgReceived(const char*const msg) noexcept | |||
fEngine->setParameterValueFromUI(pluginId, parameterId, value); | |||
} | |||
} | |||
else if (std::strcmp(msg, "set_parameter_cv_controlled") == 0) | |||
{ | |||
uint32_t pluginId, parameterId; | |||
bool cv_controlled; | |||
CARLA_SAFE_ASSERT_RETURN(readNextLineAsUInt(pluginId), true); | |||
CARLA_SAFE_ASSERT_RETURN(readNextLineAsUInt(parameterId), true); | |||
CARLA_SAFE_ASSERT_RETURN(readNextLineAsBool(cv_controlled), true); | |||
if (CarlaPlugin* const plugin = fEngine->getPlugin(pluginId)) | |||
plugin->setParameterAsCvControl(parameterId, cv_controlled, true, false); | |||
} | |||
else if (std::strcmp(msg, "set_parameter_midi_channel") == 0) | |||
{ | |||
uint32_t pluginId, parameterId, channel; | |||
@@ -1670,6 +1670,49 @@ void CarlaPlugin::setParameterValueByRealIndex(const int32_t rindex, const float | |||
} | |||
} | |||
void CarlaPlugin::setParameterAsCvControl(uint32_t parameterId, bool cv_controlled, bool sendOsc, bool sendCallback) noexcept | |||
{ | |||
if (pData->engineBridged) { | |||
CARLA_SAFE_ASSERT_RETURN(!sendOsc && !sendCallback,); | |||
} else { | |||
CARLA_SAFE_ASSERT_RETURN(sendOsc || sendCallback,); // never call this from RT | |||
} | |||
CARLA_SAFE_ASSERT_RETURN(parameterId < pData->param.count,); | |||
CARLA_SAFE_ASSERT_RETURN(pData->param.data[parameterId].type == PARAMETER_INPUT,); | |||
CARLA_SAFE_ASSERT_RETURN(pData->param.data[parameterId].hints & PARAMETER_CAN_BE_CV_CONTROLLED,); | |||
CARLA_SAFE_ASSERT_RETURN(pData->event.portIn != nullptr,); | |||
if (cv_controlled) | |||
{ | |||
char strBuf[STR_MAX+1]; | |||
carla_zeroChars(strBuf, STR_MAX+1); | |||
if (! getParameterName(parameterId, strBuf)) | |||
std::snprintf(strBuf, STR_MAX, "Param %u", parameterId); | |||
const uint portNameSize = pData->engine->getMaxPortNameSize(); | |||
if (portNameSize < STR_MAX) | |||
strBuf[portNameSize] = '\0'; | |||
CarlaEngineCVPort* const cvPort = | |||
(CarlaEngineCVPort*)pData->client->addPort(kEnginePortTypeCV, strBuf, true, parameterId); | |||
cvPort->setRange(pData->param.ranges[parameterId].min, pData->param.ranges[parameterId].max); | |||
pData->event.portIn->addCVSource(cvPort, parameterId); | |||
} | |||
else | |||
{ | |||
pData->event.portIn->removeCVSource(parameterId); | |||
} | |||
#ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH | |||
pData->engine->callback(sendCallback, sendOsc, | |||
ENGINE_CALLBACK_PARAMETER_CV_CONTROLLED_STATUS_CHANGED, | |||
pData->id, | |||
static_cast<int>(parameterId), | |||
cv_controlled ? 1 : 0, | |||
0, 0.0f, nullptr); | |||
#endif | |||
} | |||
void CarlaPlugin::setParameterMidiChannel(const uint32_t parameterId, const uint8_t channel, const bool sendOsc, const bool sendCallback) noexcept | |||
{ | |||
if (pData->engineBridged) { | |||
@@ -1121,6 +1121,7 @@ public: | |||
pData->param.data[j].type = PARAMETER_INPUT; | |||
pData->param.data[j].hints |= PARAMETER_IS_ENABLED; | |||
pData->param.data[j].hints |= PARAMETER_IS_AUTOMABLE; | |||
pData->param.data[j].hints |= PARAMETER_CAN_BE_CV_CONTROLLED; | |||
needsCtrlIn = true; | |||
// MIDI CC value | |||
@@ -1221,28 +1222,6 @@ public: | |||
portName.truncate(portNameSize); | |||
pData->event.portIn = (CarlaEngineEventPort*)pData->client->addPort(kEnginePortTypeEvent, portName, true, 0); | |||
#if 0 | |||
// Parameter as CV | |||
for (uint32_t i=0; i < params && i < 32; ++i) | |||
{ | |||
const int32_t rindex = pData->param.data[i].rindex; | |||
CARLA_SAFE_ASSERT_CONTINUE(rindex >= 0); | |||
if (pData->param.data[i].type != PARAMETER_INPUT) | |||
continue; | |||
if (fDescriptor->PortNames[rindex] == nullptr || fDescriptor->PortNames[rindex][0] == '\0') | |||
continue; | |||
portName = fDescriptor->PortNames[rindex]; | |||
portName.truncate(portNameSize); | |||
CarlaEngineCVPort* const cvPort = | |||
(CarlaEngineCVPort*)pData->client->addPort(kEnginePortTypeCV, portName, true, i); | |||
cvPort->setRange(pData->param.ranges[i].min, pData->param.ranges[i].max); | |||
pData->event.portIn->addCVSource(cvPort, i); | |||
} | |||
#endif | |||
} | |||
if (needsCtrlOut) | |||
@@ -2564,6 +2564,7 @@ public: | |||
{ | |||
pData->param.data[j].hints |= PARAMETER_IS_ENABLED; | |||
pData->param.data[j].hints |= PARAMETER_IS_AUTOMABLE; | |||
pData->param.data[j].hints |= PARAMETER_CAN_BE_CV_CONTROLLED; | |||
needsCtrlIn = true; | |||
} | |||
@@ -2794,28 +2795,6 @@ public: | |||
portName.truncate(portNameSize); | |||
pData->event.portIn = (CarlaEngineEventPort*)pData->client->addPort(kEnginePortTypeEvent, portName, true, 0); | |||
#if 0 | |||
// Parameter as CV | |||
for (uint32_t i=0; i < params && i < 32; ++i) | |||
{ | |||
const int32_t rindex = pData->param.data[i].rindex; | |||
CARLA_SAFE_ASSERT_CONTINUE(rindex >= 0 && rindex < static_cast<int32_t>(fRdfDescriptor->PortCount)); | |||
if (pData->param.data[i].type != PARAMETER_INPUT) | |||
continue; | |||
if (fRdfDescriptor->Ports[rindex].Name == nullptr || fRdfDescriptor->Ports[rindex].Name[0] == '\0') | |||
continue; | |||
portName = fRdfDescriptor->Ports[rindex].Name; | |||
portName.truncate(portNameSize); | |||
CarlaEngineCVPort* const cvPort = | |||
(CarlaEngineCVPort*)pData->client->addPort(kEnginePortTypeCV, portName, true, i); | |||
cvPort->setRange(pData->param.ranges[i].min, pData->param.ranges[i].max); | |||
pData->event.portIn->addCVSource(cvPort, i); | |||
} | |||
#endif | |||
} | |||
if (needsCtrlOut) | |||
@@ -839,6 +839,7 @@ public: | |||
pData->param.data[j].hints |= PARAMETER_IS_ENABLED; | |||
pData->param.data[j].hints |= PARAMETER_USES_CUSTOM_TEXT; | |||
pData->param.data[j].hints |= PARAMETER_CAN_BE_CV_CONTROLLED; | |||
if ((pData->hints & PLUGIN_USES_OLD_VSTSDK) != 0 || dispatcher(effCanBeAutomated, ij) == 1) | |||
pData->param.data[j].hints |= PARAMETER_IS_AUTOMABLE; | |||
@@ -873,28 +874,6 @@ public: | |||
portName.truncate(portNameSize); | |||
pData->event.portIn = (CarlaEngineEventPort*)pData->client->addPort(kEnginePortTypeEvent, portName, true, 0); | |||
#if 0 | |||
// Parameter as CV | |||
char strBuf[STR_MAX]; | |||
for (uint32_t i=0; i < params && i < 32; ++i) | |||
{ | |||
if (pData->param.data[i].type != PARAMETER_INPUT) | |||
continue; | |||
carla_zeroChars(strBuf, STR_MAX); | |||
dispatcher(effGetParamName, static_cast<int32_t>(i), 0, strBuf); | |||
if (strBuf[0] == '\0') | |||
std::snprintf(strBuf, STR_MAX-1, "Parameter %u", i+1U); | |||
CarlaEngineCVPort* const cvPort = | |||
(CarlaEngineCVPort*)pData->client->addPort(kEnginePortTypeCV, strBuf, true, i); | |||
cvPort->setRange(pData->param.ranges[i].min, pData->param.ranges[i].max); | |||
pData->event.portIn->addCVSource(cvPort, i); | |||
} | |||
#endif | |||
} | |||
if (needsCtrlOut) | |||
@@ -796,6 +796,12 @@ ENGINE_CALLBACK_PATCHBAY_PORT_GROUP_REMOVED = 44 | |||
# @see PatchbayPortGroupHints | |||
ENGINE_CALLBACK_PATCHBAY_PORT_GROUP_CHANGED = 45 | |||
# A parameter's CV controlled status has changed. | |||
# @a pluginId Plugin Id | |||
# @a value1 Parameter index | |||
# @a value2 New CV controlled status (boolean) | |||
ENGINE_CALLBACK_PARAMETER_CV_CONTROLLED_STATUS_CHANGED = 46 | |||
# ------------------------------------------------------------------------------------------------------------ | |||
# NSM Callback Opcode | |||
# NSM callback opcodes. | |||
@@ -2030,6 +2036,14 @@ class CarlaHostMeta(object): | |||
def set_parameter_value(self, pluginId, parameterId, value): | |||
raise NotImplementedError | |||
# Change a plugin's parameter cv controlled status. | |||
# @param pluginId Plugin | |||
# @param parameterId Parameter index | |||
# @param cv_controlled New CV controlled Status | |||
@abstractmethod | |||
def set_parameter_cv_controlled(self, pluginId, parameterId, cv_controlled): | |||
raise NotImplementedError | |||
# Change a plugin's parameter MIDI cc. | |||
# @param pluginId Plugin | |||
# @param parameterId Parameter index | |||
@@ -2427,6 +2441,9 @@ class CarlaHostNull(CarlaHostMeta): | |||
def set_parameter_value(self, pluginId, parameterId, value): | |||
return | |||
def set_parameter_cv_controlled(self, pluginId, parameterId, cv_controlled): | |||
return | |||
def set_parameter_midi_channel(self, pluginId, parameterId, channel): | |||
return | |||
@@ -2739,6 +2756,9 @@ class CarlaHostDLL(CarlaHostMeta): | |||
self.lib.carla_set_parameter_value.argtypes = [c_uint, c_uint32, c_float] | |||
self.lib.carla_set_parameter_value.restype = None | |||
self.lib.carla_set_parameter_cv_controlled.argtypes = [c_uint, c_uint32, c_bool] | |||
self.lib.carla_set_parameter_cv_controlled.restype = None | |||
self.lib.carla_set_parameter_midi_channel.argtypes = [c_uint, c_uint32, c_uint8] | |||
self.lib.carla_set_parameter_midi_channel.restype = None | |||
@@ -3058,6 +3078,9 @@ class CarlaHostDLL(CarlaHostMeta): | |||
def set_parameter_value(self, pluginId, parameterId, value): | |||
self.lib.carla_set_parameter_value(pluginId, parameterId, value) | |||
def set_parameter_cv_controlled(self, pluginId, parameterId, cv_controlled): | |||
self.lib.carla_set_parameter_cv_controlled(pluginId, parameterId, cv_controlled) | |||
def set_parameter_midi_channel(self, pluginId, parameterId, channel): | |||
self.lib.carla_set_parameter_midi_channel(pluginId, parameterId, channel) | |||
@@ -3458,6 +3481,9 @@ class CarlaHostPlugin(CarlaHostMeta): | |||
self.sendMsg(["set_parameter_value", pluginId, parameterId, value]) | |||
self.fPluginsInfo[pluginId].parameterValues[parameterId] = value | |||
def set_parameter_cv_controlled(self, pluginId, parameterId, cv_controlled): | |||
self.sendMsg(["set_parameter_cv_controlled", pluginId, parameterId, cv_controlled]) | |||
def set_parameter_midi_channel(self, pluginId, parameterId, channel): | |||
self.sendMsg(["set_parameter_midi_channel", pluginId, parameterId, channel]) | |||
self.fPluginsInfo[pluginId].parameterData[parameterId]['midiCC'] = channel | |||
@@ -313,6 +313,8 @@ const char* EngineCallbackOpcode2Str(const EngineCallbackOpcode opcode) noexcept | |||
return "ENGINE_CALLBACK_PATCHBAY_PORT_GROUP_REMOVED"; | |||
case ENGINE_CALLBACK_PATCHBAY_PORT_GROUP_CHANGED: | |||
return "ENGINE_CALLBACK_PATCHBAY_PORT_GROUP_CHANGED"; | |||
case ENGINE_CALLBACK_PARAMETER_CV_CONTROLLED_STATUS_CHANGED: | |||
return "ENGINE_CALLBACK_PARAMETER_CV_CONTROLLED_STATUS_CHANGED"; | |||
} | |||
carla_stderr("CarlaBackend::EngineCallbackOpcode2Str(%i) - invalid opcode", opcode); | |||