View Full Version : update parameter value
debian
04-04-2010, 11:38 PM
in my ProcessDoubleReplacing i try to update a control with this:
GetGUI()->SetControlFromPlug(mPatternID, 1.0);
The GUI is changed but when later doing
ParamPat = GetParam(kPatternSw)->Value();
The value has not beeing updated.
How do i also update the value of the parameter kPatternSw?
Edit:
I'm sorry, I found it right after posting....
GetParam(kPatternSw)->Set(value);
Don't answer this tread :)
bvesco
04-06-2010, 08:54 AM
I will answer anyway because it makes sense to understand why SetControlFromPlug does not set the parameter. Dig around on the control and you'll also see something like SetControlFromGUI. The difference between these two methods is that fromPlug does not set the corresponding param and fromGui does set the param value. fromGui is meant to be called whenever the user "physically" interacts with your plugin and there's no way for the plugin to know the parameter was changed except to be notified by the gui. fromPlug is when your internal plugin wants to update the control to change a knob position in an automated way (it turns "by itself" with no interaction from the user). Since the plugin itself is changing the control it "knows" the parameter needs changed (or that the parameter already changed) so there is no need for a callback from the gui to change it.
So why not call fromGui inside your doubleReplacing method and have it change the control and the param? The gui and plugin run on separate threads with the gui running at lower priority. Waiting for the callback from the gui to change the param could take a "long" time (long in terms of processing cycles). You might not get the callback from the gui until after the current doubleReplacing call is finished, so you can't count on it for "realtime" updates.
Nowhk
04-22-2016, 10:18 AM
I will answer anyway because it makes sense to understand why SetControlFromPlug does not set the parameter. Dig around on the control and you'll also see something like SetControlFromGUI. The difference between these two methods is that fromPlug does not set the corresponding param and fromGui does set the param value. fromGui is meant to be called whenever the user "physically" interacts with your plugin and there's no way for the plugin to know the parameter was changed except to be notified by the gui. fromPlug is when your internal plugin wants to update the control to change a knob position in an automated way (it turns "by itself" with no interaction from the user). Since the plugin itself is changing the control it "knows" the parameter needs changed (or that the parameter already changed) so there is no need for a callback from the gui to change it.
So why not call fromGui inside your doubleReplacing method and have it change the control and the param? The gui and plugin run on separate threads with the gui running at lower priority. Waiting for the callback from the gui to change the param could take a "long" time (long in terms of processing cycles). You might not get the callback from the gui until after the current doubleReplacing call is finished, so you can't count on it for "realtime" updates.
I bump this topic because I've faced the same problem. If I call these:
GetGUI()->SetParameterFromPlug(knbID_Tempo, randomValue, true);
GetParam(knbID_Tempo)->SetNormalized(randomValue);
OnParamChange(knbID_Tempo);
I'll update both the control (gui) and the value.
Anyway, I'd like to follow the bvesco suggestion. But using this:
SetParameterFromGUI(knbID_Tempo, randomValue);
it updates only the value, not the GUI (i.e. the knob position/frame doesn't move). Where am I wrong?
earlevel
04-22-2016, 01:27 PM
I bump this topic because I've faced the same problem. If I call these:
GetGUI()->SetParameterFromPlug(knbID_Tempo, randomValue, true);
GetParam(knbID_Tempo)->SetNormalized(randomValue);
OnParamChange(knbID_Tempo);
I'll update both the control (gui) and the value.
Anyway, I'd like to follow the bvesco suggestion. But using this:
SetParameterFromGUI(knbID_Tempo, randomValue);
it updates only the value, not the GUI (i.e. the knob position/frame doesn't move). Where am I wrong?
I'm a bit uncertain of what you're saying here. First, bvesco was talking about SetControlXX and you're talking about SetParameterXX Also, your parameter index, "knbID_Tempo", seems to imply a control index (but may be a parameter index as well). And when you say "control" and "value", I think you mean "control" and "parameter" (they both have values, and they may be different). Finally, the calling context is unclear, but I'd think that you probably want GetGUI()->SetParameterFromPlug, assuming that you want to set the parameter and have the control update too—but not enough info.
Nowhk
04-22-2016, 01:44 PM
Hi earlevel, thanks for the help and reply.
I'm a bit uncertain of what you're saying here. First, bvesco was talking about SetControlXX and you're talking about SetParameterXX Also, your parameter index, "knbID_Tempo", seems to imply a control index (but may be a parameter index as well). And when you say "control" and "value", I think you mean "control" and "parameter" (they both have values, and they may be different).
Yeah, maybe I've a general misunderstanding of terms and methods :)
For Control I mean my knob (IKnobMultiControlText in my case).
For Value I mean the value of the Control (GetParam(knbID_Tempo)->Value()).
What's the differences between "parameter index" and "control index"? Or even better: what's the difference between Parameter and Control in general in IPlug?
In my case, knbID_Tempo is the "parameter" index. Control index will be... what?
Finally, the calling context is unclear, but I'd think that you probably want GetGUI()->SetParameterFromPlug, assuming that you want to set the parameter and have the control update too—but not enough info.
I'd like to update Control Value (i.e. set 45.2 for example) and the Control GUI (i.e. the knob bitmap corresponding to 45.2).
Tried with just:
GetGUI()->SetParameterFromPlug(knbID_Tempo, 45.2, true);
but it just refresh/update GUI, not the ->Value(). That's why I followed it with:
GetParam(paramID)->SetNormalized(randomValue);
OnParamChange(paramID);
I'm calling all of these within OPC case statement (inside the main IPlug instance), after clicking a button (which is a IContactControl control).
Basically, when I click it (GetParam(btnID_Random)->Int() == 1) I want to random the knob value (RandomControl() is the function where the change should happen):
void MIDITest::OnParamChange(int paramID) {
IMutexLock lock(this);
switch (paramID)
{
case knbID_Tempo:
{
knbValue_Tempo = GetParam(knbID_Tempo)->Value();
break;
}
case btnID_Random:
{
if (GetParam(btnID_Random)->Int() == 1) {
RandomControl(knbID_Tempo);
}
break;
}
default:
break;
}
}
The question is (as bvesco suggested): isn't there a single command that will update both (gui and value)?
earlevel
04-22-2016, 03:46 PM
Pressed for time and might not get another chance soon, so just quick notes after a brief look:
OK, mainly I want to impress the difference between controls and parameters:
A parameter is an entity that holds a value that your processing algorithm (or other plugin function) can use; its value can be changed by the plug-in (in response to a control change, host automation, loading a preset, etc.).
A control is the GUI-related entity that the user can use to set a parameter (automatically if the control is linked to a parameter), and which the plugin can set (automatically if the control is linked to a parameter) to indicate something to the user.
OK, I can see now that by the control's value you mean the value of parameter linked to the control. Remember, both controls and parameters have values, and they needn't be the same—a control can go from 0-1, linearly, and control a parameter that goes from 0-1000 ms on a curve, for instance.
Anyway, you are taking the right route in changing the parameter, and so I think you are basically asking how to change the parameter and ensure that all controls (there can be more than one) that are linked to it get updated to reflect the change.
I'm not following, on a quick read, why you think the parameter ("value") is not getting updated (though the GUI is)—sorry, I'll have to take another look later.
Nowhk
04-23-2016, 12:43 AM
Wow, what a confusion I did about this :) Thanks for helping me.
So in my case, here I'm defining a Parameter (without any "fixed" index):
GetParam(knbID_Tempo)->InitDouble("Tempo", 300., 10.0, 522., 1., " bpm");
which value goes from 10 to 522, linking it to a Control (with "fixed" index knbID_Tempo) which value goes from 0 to 1.
Right? So what I'm doing here:
GetGUI()->SetParameterFromPlug(knbID_Tempo, 0.45, true);
is to change the Parameter value by Control index, setting to it the normalized value (between [0,1], that's why normalization=true) to 0.45.
After calling it, I correctly see that Control (GUI) change. My problem is that if immediatly look at the (linked) Parameter value of that Control:
memset(buffer, 0, 255);
sprintf(buffer, "new val: %.5f", GetParam(knbID_Tempo)->Value());
txtLabel->SetTextFromPlug(buffer);
the value is not changed (its still 300, i.e. the first-default value). And it is not just "graphic": if I play the plug, I can hear the audio (tempo in this case) it is not changed. It changes only if I tweek the knob manually with mouse.
Maybe I'm missing somethings more?
P.S. knbID_Tempo is a IKnobMultiControlText Control. Should I ovveride some method? I don't think so... base class methods should be already ok.
earlevel
04-23-2016, 01:32 AM
Frankly, it's confusing—there really needs to be at least a one-line explanation in the code of what key functions do, and their intended use for non-obvious ones. The confusing part here is that, from the plugin, you can call SetParameterFromGUI, or GetGUI()->SetParameterFromPlug. So you're either calling XXFromPlug from the GUI, or XXFromGUI from the plug. Without a clue as to the intent. Arg...
I think I'm probably doing something functionally similar to you. I called SetParameterFromGUI (and nothing else), and everything works great as AAX. But I'm stumped at the moment, since it doesn't work right compiled as an standalone app (I have no intention of it being an app—I was just checking some things). I suppose that's because I'm getting some redundant feedback as AAX, but not as app. Anyway, I looked at using GetGUI()->SetParameterFromPlug instead, but if you look at the code for that function, it doesn't set the param. That doesn't seem to make sense, by the function name. Obviously, you could also set the param separately, but still, you have to wonder the intent.
Nowhk
04-23-2016, 01:39 AM
Frankly, it's confusing—there really needs to be at least a one-line explanation in the code of what key functions do, and their intended use for non-obvious ones. The confusing part here is that, from the plugin, you can call SetParameterFromGUI, or GetGUI()->SetParameterFromPlug. So you're either calling XXFromPlug from the GUI, or XXFromGUI from the plug. Without a clue as to the intent. Arg...
I think I'm probably doing something functionally similar to you. I called SetParameterFromGUI (and nothing else), and everything works great as AAX. But I'm stumped at the moment, since it doesn't work right compiled as an standalone app (I have no intention of it being an app—I was just checking some things). I suppose that's because I'm getting some redundant feedback as AAX, but not as app. Anyway, I looked at using GetGUI()->SetParameterFromPlug instead, but if you look at the code for that function, it doesn't set the param. That doesn't seem to make sense, by the function name. Obviously, you could also set the param separately, but still, you have to wonder the intent.
Yes, its confusing. That's why I up the topic :)
It's also confusing why, using GetGUI()->SetParameterFromPlug, I need to pass the "control id" to make (at least) the GUI change. Shouldn't be used paramIdx there? (since is SetParameterFromPlug and not SetControlFromPlug).
I think we need both SetParameterFromPlug and GetParam(paramID)->SetNormalized to change GUI and set value. But so, at this point, what's the real difference between GetGUI()->SetParameterFromPlug and GetGUI()->SetControlFromPlug?
earlevel
04-23-2016, 09:19 AM
It's also confusing why, using GetGUI()->SetParameterFromPlug, I need to pass the "control id" to make (at least) the GUI change. Shouldn't be used paramIdx there? (since is SetParameterFromPlug and not SetControlFromPlug).
No, you pass the parameter index. That's why I mentioned earlier that it was troubling that the name of the index you were passing sounded like it was a control index. Look at the code. In the case of SetParameterFromPlug, it's even called paramIdx.
I think we need both SetParameterFromPlug and GetParam(paramID)->SetNormalized to change GUI and set value. But so, at this point, what's the real difference between GetGUI()->SetParameterFromPlug and GetGUI()->SetControlFromPlug?
What it does is reasonably clear (from looking at the code). But the intended use is not so transparent (the comment for IGraphics::SetParameterFromPlug is confusing).
IPlugBase::SetParameterFromGUI is the most obvious—it sets the parameter, informs the host, and sends the parameter change to the plugin. IGraphics::SetParameterFromGUI updates associated controls and calls IPlugBase::SetParameterFromGUI to set the param, but only if the if the control value has changed.
So, GetGUI()->SetParameterFromPlug is the call you want.
Edited: Didn't have the explanation of IGraphics::SetParameterFromGUI correct.
earlevel
04-24-2016, 01:00 PM
Looking around the forum, I see the purpose of IGraphics::SetParameterFromGUI has been a mystery for a long time (Oli asked a few years ago about the cryptic comment in the header, and got no reply)...anyway, to continue from my last message:
Again, I found that just calling IPlugBase::SetParameterFromGUI did the job for my AAX plugin—obviously a side effect of the interface with the host.
However, the same is not true of running as an app, and I check AU as well. And that's expected if you look at IPlugBase::SetParameterFromGUI—there is no path to update the associated controls. IGraphics::SetParameterFromGUI is pretty much the opposite; despite its name, it doesn't set a parameter, but sets the controls associated with the parameter.
The bottom line is that you can call both of these with the same calling parameters, and you'll always get the parameter and the associated controls updated.
Nowhk
04-25-2016, 12:47 AM
Looking around the forum, I see the purpose of IGraphics::SetParameterFromGUI has been a mystery for a long time (Oli asked a few years ago about the cryptic comment in the header, and got no reply)...anyway, to continue from my last message:
Again, I found that just calling IPlugBase::SetParameterFromGUI did the job for my AAX plugin—obviously a side effect of the interface with the host.
However, the same is not true of running as an app, and I check AU as well. And that's expected if you look at IPlugBase::SetParameterFromGUI—there is no path to update the associated controls. IGraphics::SetParameterFromGUI is pretty much the opposite; despite its name, it doesn't set a parameter, but sets the controls associated with the parameter.
The bottom line is that you can call both of these with the same calling parameters, and you'll always get the parameter and the associated controls updated.
Im using VST. So what should I use? SetParameterFromPlug + SetNormalized (my old code) or the couple SetParameterFromGui from IPlugBase and IGraphics?
i.e. whats the difference between SetNormalized and IPlugBase::SetParameterFromGUI?
Still confusing...
TBProAudio
04-25-2016, 10:03 AM
This works for sure:
// Constructor
GetParam(kParamIdx)->InitInt("", mVal, 0, 1, "");
IBitmap = pGraphics->LoadIBitmap(BUTTON_ID, BUTTON_FN, N);
pGraphics->AttachControl(new ISwitchControl(this, X, Y, kParamIdx, &button_kParamIdx));
// ProcessDoubleReplacing
GetGUI()->SetParameterFromPlug(kParamIdx, 0.0, false);
earlevel
04-25-2016, 10:38 AM
This works for sure:
// Constructor
GetParam(kParamIdx)->InitInt("", mVal, 0, 1, "");
IBitmap = pGraphics->LoadIBitmap(BUTTON_ID, BUTTON_FN, N);
pGraphics->AttachControl(new ISwitchControl(this, X, Y, kParamIdx, &button_kParamIdx));
// ProcessDoubleReplacing
GetGUI()->SetParameterFromPlug(kParamIdx, 0.0, false);
First, what branch are you using that has three parameters for IGraphics::SetParameterFromGUI? What is that "false" for?
Second, why call it in ProcessDoubleReplacing? That doesn't seem like a good idea.
earlevel
04-25-2016, 10:49 AM
Im using VST. So what should I use? SetParameterFromPlug + SetNormalized (my old code) or the couple SetParameterFromGui from IPlugBase and IGraphics?
i.e. whats the difference between SetNormalized and IPlugBase::SetParameterFromGUI?
Still confusing...
Sorry for my earlier post, I was coding a complicated control and tried to write that note from memory and messed up...
If everything is right and typical, you just need to call GetGUI()->SetParameterFromPlug for the parameter. (Probably—you haven't put up your code so I'm guessing. An exception would be if you're doing something unusual—the parameter isn't sent if the control doesn't change value, and it's possible in some unusual cases that you need it to be.)
Nowhk
04-25-2016, 10:54 AM
Sorry for my earlier post, I was coding a complicated control and tried to write that note from memory and messed up...
If everything is right and typical, you just need to call GetGUI()->SetParameterFromPlug for the parameter. (Probably—you haven't put up your code so I'm guessing. An exception would be if you're doing something unusual—the parameter isn't sent if the control doesn't change value, and it's possible in some unusual cases that you need it to be.)
See my first reply :) Yes, Ive already did this, but it updates only GUI, not the parameter itself (i.e. the value). For that, it changes only using SetNormalized later. And yes, I'm sending a new value to the parameter, not the one it has. Or do you mean that I also need to change value of the "control id"?
Honestly, I don't know what control id is. Ive just the parameter id :O
TBProAudio
04-25-2016, 10:56 AM
First, what branch are you using that has three parameters for IGraphics::SetParameterFromGUI? What is that "false" for?
WDL Next branch
Second, why call it in ProcessDoubleReplacing? That doesn't seem like a good idea.
If you need to update from ProcessDoubleReplacing then this code should work for you.
earlevel
04-25-2016, 01:12 PM
WDL Next branch
OK, adds ability send non-normalized param...
If you need to update from ProcessDoubleReplacing then this code should work for you.
Still seems like a potential problem from PDR (InformHostOfParamChange, etc.).
Nowhk
04-28-2016, 12:21 AM
If everything is right and typical, you just need to call GetGUI()->SetParameterFromPlug for the parameter. (Probably—you haven't put up your code so I'm guessing. An exception would be if you're doing something unusual—the parameter isn't sent if the control doesn't change value, and it's possible in some unusual cases that you need it to be.)
Ok, so I've cheched what GetGUI()->SetParameterFromPlug(knbID_Tempo, 0.45, true); will do, watching the code.
There's pControl->SetValueFromPlug(value); inside it, which should set mValue (if mValue != value). But to the control, not the param. Also, it doesn't call InformHostOfParamChange at all.
Instead, IPlugBase::SetParameterFromGUI set value (SetNormalized), inform host (InformHostOfParamChange) and recall OnParamChange. It exclusively acts on Param, not the control.
Thus, the way to go I think is to use both:
GetGUI()->SetParameterFromPlug(paramID, randomValue, true);
SetParameterFromGUI(paramID, randomValue);
Still confusing, but I get a better idea on what these functions do ;) Thanks!
earlevel
04-28-2016, 12:34 AM
Ok, so I've cheched what GetGUI()->SetParameterFromPlug(knbID_Tempo, 0.45, true); will do, watching the code.
There's pControl->SetValueFromPlug(value); inside it, which should set mValue (if mValue != value). But to the control, not the param. Also, it doesn't call InformHostOfParamChange at all.
Instead, IPlugBase::SetParameterFromGUI set value (SetNormalized), inform host (InformHostOfParamChange) and recall OnParamChange. It exclusively acts on Param, not the control.
Thus, the way to go I think is to use both:
GetGUI()->SetParameterFromPlug(paramID, randomValue, true);
SetParameterFromGUI(paramID, randomValue);
You have to follow the code a little farther downstream. GetGUI()->SetParameterFromPlug calls SetValueFromUserInput, which calls SetDirty(pushParamToPlug = true), which calls SetParameterFromGUI. So you only need the first call.
Nowhk
04-28-2016, 12:46 AM
You have to follow the code a little farther downstream. GetGUI()->SetParameterFromPlug calls SetValueFromUserInput, which calls SetDirty(pushParamToPlug = true), which calls SetParameterFromGUI. So you only need the first call.
I think we have different version of IPlug/WDL-OL. This is the function I have inside IGraphics.cpp:
void IGraphics::SetParameterFromPlug(int paramIdx, double value, bool normalized)
{
if (!normalized)
{
IParam* pParam = mPlug->GetParam(paramIdx);
value = pParam->GetNormalized(value);
}
int i, n = mControls.GetSize();
IControl** ppControl = mControls.GetList();
for (i = 0; i < n; ++i, ++ppControl)
{
IControl* pControl = *ppControl;
if (pControl->ParamIdx() == paramIdx)
{
//WDL_MutexLock lock(&mMutex);
pControl->SetValueFromPlug(value);
// Could be more than one, don't break until we check them all.
}
// now look for any auxilliary parameters
int auxParamIdx = pControl->AuxParamIdx(paramIdx);
if (auxParamIdx > -1) // there are aux params
{
pControl->SetAuxParamValueFromPlug(auxParamIdx, value);
}
}
}
The function you mean (maybe) is commented here (old version?!?!?) and is called SetParameterFromGUI:
//void IGraphics::SetParameterFromGUI(int paramIdx, double normalizedValue)
//{
// int i, n = mControls.GetSize();
// IControl** ppControl = mControls.GetList();
// for (i = 0; i < n; ++i, ++ppControl) {
// IControl* pControl = *ppControl;
// if (pControl->ParamIdx() == paramIdx) {
// pControl->SetValueFromUserInput(normalizedValue);
// // Could be more than one, don't break until we check them all.
// }
// }
//}
earlevel
04-28-2016, 01:13 AM
I think we have different version of IPlug/WDL-OL. This is the function I have inside IGraphics.cpp...
Looks good from what you posted. Check out the for loop in SetParameterFromPlug. It finds the controls associated with the parameter, and calls pControl->SetValueFromPlug(value). SetValueFromPlug calls SetDirty, if the control value changes. SetDirty calls SetParameterFromGUI.
Nowhk
04-28-2016, 01:19 AM
Looks good from what you posted. Check out the for loop in SetParameterFromPlug. It finds the controls associated with the parameter, and calls pControl->SetValueFromPlug(value). SetValueFromPlug calls SetDirty, if the control value changes. SetDirty calls SetParameterFromGUI.
Yes, but it call SetDirty with "false":
if (mValue != value)
{
mValue = value;
SetDirty(false);
Redraw();
}
which won't do anything more:
void IControl::SetDirty(bool pushParamToPlug)
{
mValue = BOUNDED(mValue, mClampLo, mClampHi);
mDirty = true;
if (pushParamToPlug && mPlug && mParamIdx >= 0)
{
mPlug->SetParameterFromGUI(mParamIdx, mValue);
IParam* pParam = mPlug->GetParam(mParamIdx);
if (mValDisplayControl)
{
char str[32];
pParam->GetDisplayForHost(str);
((ITextControl*)mValDisplayControl)->SetTextFromPlug(str);
}
if (mNameDisplayControl)
{
((ITextControl*)mNameDisplayControl)->SetTextFromPlug((char*) pParam->GetNameForHost());
}
}
}
Here's the "trouble" I think...
vBulletin® v3.8.11, Copyright ©2000-2025, vBulletin Solutions Inc.