Updating parameters and control labels dynamically

I’d like to update one control and its respective parameter when another is clicked, but I can’t find a good way to do this. Specifically, when a knob that controls a synthesis parameter is clicked, the sliders that control the strength of each of the modulators should change their values to those that correspond to the parameter of the control that was clicked. (e.g. Filter cutoff is modulated by 50% of its range by Envelope 1, so when the Filter Cutoff knob is clicked, the Envelope 1 modulation depth moves to 0.5.) I tried calling GetUI()->GetControlWithTag(kCtrlTag)->SetValueFromDelegate(val) from the MetaParamTest example or GetDelegate()->SendParameterValueFromDelegate(paramIdx, val) in the knob click event, but these only change the position of the slider handle and not the label - and from what I can tell, they don’t update the parameter either.

Another possibility would be creating parameters for every modulatable parameter in turn, storing the modulation depth for each modulator for that parameter, and then changing the parameter index of the depth slider. However, this unfortunately didn’t work either.

I think the function I want is SetParameterValue, but I can’t figure out how to call it, since I don’t know which object in the program is of type IPlugAPIBase. (I’m rather new to C++ and am still figuring out the IPlug class hierarchy)

Thanks in advance!

I’ve found similar difficulties when trying to update the graphics of a control. The main problem is that you don’t have a variable where the instance of the control is stored, because they are instantiated inside the AttachControl() function when the UI layout function is defined, and you never interact with them ever again.

The workaround I’ve been using is to create a derivative class of the control I want to change and add pointer variables so that even after the UI creation, I still have access to some of its contents. The main thing is to have a pointer to a boolean that tells the control that it’s “dirty” and therefore needs to be redrawn. Other pointer variables can access text, or other values you want to refresh.

@radiofarmer

If you want to have controls that control multiple parameters this should be declared using a std::initialiser list for the param indices in your IControl.

IVXYPadControl is one example of this (you can see it in IPlugControls example).

You can then use Set() with a valIdx to set specific parameters from the control. Other controls can be bound to the same parameter and everything will update correctly without having to do your own messaging.

Likely for what you are trying to do you’ll need to roll your own drawing (that way you can display whatever label you like according to what you need.

@Ric - in general I’d advise against that approach - You can get pointers to controls using GetControlWithTag() (you’ll need to set a suitable tag when you attach the control). In general I wouldn’t set the control dirty from the outside either - I’d either update a related parameter correctly and let iPlug2 do the messaging, or call a custom method on the control that updates some state and then that method of the control sets itself dirty.

1 Like

Is there an advantage to constructing the control with multiple parameters as opposed to simply changing the parameter that it’s linked to? Or is there some canonical methodology for dealing with modulators, since that’s a pretty standard VSTi feature?

In the meantime I was able to get this method of this sort working:

GetUI()->GetControlWithTag(tagOfTargetControl)->SetParamIdx(idxOfTargetParameter);

This is called by the class for knobs who can be modulated.

I think you’re thinking about this the wrong way based on what I’ve read. Your modulation should all happen on the DSP side. If you want to show a modulation in the UI you need to design IControls that can display modulation

i.e. You shouldn’t modulate parameters

I think @olilarkin may have misunderstood - my understanding is that you just want to use one modulation control and update which amount it is displaying based on another interaction (you aren’t modulating parameters). For that SetParamIdx() should work fine. It strikes me that this method doesn’t call SetDirty(), but I think maybe it should - Oli?

yeah i guess i misunderstood, but this is how i would do what i misunderstood anyway…

tst

I agree with Alex and I made the change on master branch.

@AlexHarker has the right interpretation - the modulation magnitudes are stored as parameters, and the actual modulation occurs in the DSP class.

The OnMsgFromDelegate example should come in handy though. Thanks!

And you’re absolutely right. I quickly tried what I proposed and it didn’t even work. It does work though with display controls that don’t involve parameters, which is what I’ve used it for, but obviously this is not the case.

And another thing. I think you need to make sure to add the meta flag (0x10) on parameters that potentially change the state of other parameters. At least Logic complained about that until I changed it.