Cockos Incorporated Forums

Cockos Incorporated Forums (https://forum.cockos.com/index.php)
-   WDL users forum (https://forum.cockos.com/forumdisplay.php?f=32)
-   -   AAX and knobs (https://forum.cockos.com/showthread.php?t=190820)

Tunca 04-15-2017 04:50 AM

AAX and knobs
 
I have issue with AAX version's knobs.

Variable knobs working great but stepped knobs have lag and hard to turn.Any way to fix it?Is there any sensitivity setting?

Thanks.

earlevel 04-15-2017 11:32 AM

Quote:

Originally Posted by Tunca (Post 1832446)
I have issue with AAX version's knobs.

Variable knobs working great but stepped knobs have lag and hard to turn.Any way to fix it?Is there any sensitivity setting?

Thanks.

It's hard to understand your problem with so little information—"laggy" (does this mean response is delayed? I don't know what else it could mean) and "hard to turn" (you have to make multiple attempts? Perform unusual mouse movements?) are pretty vague. I'm wondering if you have a serious problem—I believe you're using my fork, and I'm shipping product with stepped knobs and haven't heard a complaint.

Or maybe you're saying that if you have a small number of positions (say, 3), you have to move the mouse far for it to click to the next step. That might account for "hard to turn", but certainly doesn't account for "laggy". Anyway, if it's this, and you want to change the behavior, override the behavior and make it what you want.

PS—There are no changes to knobs in the AAX version. I'm not sure if you mean that you only see the problem when running as AAX, works otherwise?

Tunca 04-15-2017 03:52 PM

Quote:

Originally Posted by earlevel (Post 1832626)
It's hard to understand your problem with so little information—"laggy" (does this mean response is delayed? I don't know what else it could mean) and "hard to turn" (you have to make multiple attempts? Perform unusual mouse movements?) are pretty vague. I'm wondering if you have a serious problem—I believe you're using my fork, and I'm shipping product with stepped knobs and haven't heard a complaint.

Or maybe you're saying that if you have a small number of positions (say, 3), you have to move the mouse far for it to click to the next step. That might account for "hard to turn", but certainly doesn't account for "laggy". Anyway, if it's this, and you want to change the behavior, override the behavior and make it what you want.

PS—There are no changes to knobs in the AAX version. I'm not sure if you mean that you only see the problem when running as AAX, works otherwise?

Thanks for reply.

Your're right.Laggy is wrong sentence.Small number of positions hard to turn.I have to move mouse far for it to click to next step.

I have no issue with other versions.But AAX has problem about stepped knobs.

earlevel 04-16-2017 10:34 AM

Quote:

Originally Posted by Tunca (Post 1832712)
Your're right.Laggy is wrong sentence.Small number of positions hard to turn.I have to move mouse far for it to click to next step.

I have no issue with other versions.But AAX has problem about stepped knobs.

There are no changes to knobs—you can do a diff yourself and see that.

There is a fix to broken parameter rounding that changes the step point, but not the distance the mouse needs to move (it simply provides consistent rounding—bad rounding in the original caused problems with Pro Tools automation of stepped parameters).

There is, however, some gearing in IPlug that's different for Pro Tools than other hosts, depending on which mouse button you're holding (unchanged in my fork). Take a look at IKnobControl::OnMouseDrag and see if that's what you're experiencing.

Tunca 04-16-2017 11:20 AM

Quote:

Originally Posted by earlevel (Post 1833009)
There are no changes to knobs—you can do a diff yourself and see that.

There is a fix to broken parameter rounding that changes the step point, but not the distance the mouse needs to move (it simply provides consistent rounding—bad rounding in the original caused problems with Pro Tools automation of stepped parameters).

There is, however, some gearing in IPlug that's different for Pro Tools than other hosts, depending on which mouse button you're holding (unchanged in my fork). Take a look at IKnobControl::OnMouseDrag and see if that's what you're experiencing.

I played with IKnobControl::OnMouseDrag but nothing changing.Looks like it's not affecting...

I tried all control parameters but no luck.

JD Young 04-16-2017 01:08 PM

Hi Tunca,

I've had this issue as well. I have not really looked into it, but I've noticed that if you initialze a parameter with an int or enum this weird behaviour can occur with the ISwitchControl in ProTools; depending on the exact number of switches/frames in the control/bitmap. If you initialize your parameter as a regular double though, the issue is gone. Altough I'd like to get to the bottom of this rather sonner than later, this quick fix should do the trick.

Cheers! JD

earlevel 04-16-2017 02:39 PM

Quote:

Originally Posted by JD Young (Post 1833075)
Hi Tunca,

I've had this issue as well. I have not really looked into it, but I've noticed that if you initialze a parameter with an int or enum this weird behaviour can occur with the ISwitchControl in ProTools; depending on the exact number of switches/frames in the control/bitmap. If you initialize your parameter as a regular double though, the issue is gone. Altough I'd like to get to the bottom of this rather sonner than later, this quick fix should do the trick.

I have an 11-step knob control, using an enum parameter (with my fork), works fine.

But that problem with AAX params sounds familiar with wdl/ol master—that only double params worked right. I fixed it in my fork. Which are you using?

I'm using double, int, and enum parameters in my plugin, and they work correctly with Pro Tools automation.

Tunca 04-17-2017 01:21 AM

Thanks JD Young.I will try double as stepped control.

Also i'm using earlevel branch but still same.

How did you do your plugins,earlevel? I can't figure it out.

earlevel 04-17-2017 12:05 PM

Quote:

Originally Posted by Tunca (Post 1833238)
How did you do your plugins,earlevel? I can't figure it out.

Most of my knob-related parameters are doubles, with one enum. (I also have two other enum parameters, and one int and one bool, but they are not knobs.) The enum controlled by knob is the only one similar to your situation.

Here's the code that configures the parameter, simplified for clarity:
Code:

// set the Mode parameter to an enum with 11 settings
GetParam(kMode)->InitEnum("Mode", 0, 11);

// configure the settings names
const char *modeNames[] = { "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11" };
for (int idx = 0; idx < 11; ++idx)
  GetParam(kMode)->SetDisplayText(idx, modeNames[idx]);

// create a knob control for Mode
IBitmap knob = pGraphics->LoadIBitmap(modeResID, modeResFile, 11);
pGraphics->AttachControl(new IKnobMultiControl(this, modeResLoc->h, modeResLoc->v, kMode, &knob));

Sorry, I don't have time at the moment to make and test an integer test case. I believe that I fixed the problems with integer parameters in AAX that are in wdl/ol master. All of my parameters automate correctly with my fork (but failed with wdl/ol master).

JD Young 04-17-2017 12:18 PM

Hi Earlevel,

I'm just using an older wdl/ol master version I have tweaked a little. I've found that it depends on the number of frames if I experience issues in ProTools. It all seemed to work for a while until a used a 4-frame sprite, and later on with other amounts as well. I'm rather busy at the moment as well, but it's on my todo list :)

JD

Tunca 04-17-2017 12:52 PM

Quote:

Originally Posted by earlevel (Post 1833463)
Most of my knob-related parameters are doubles, with one enum. (I also have two other enum parameters, and one int and one bool, but they are not knobs.) The enum controlled by knob is the only one similar to your situation.

Here's the code that configures the parameter, simplified for clarity:
Code:

// set the Mode parameter to an enum with 11 settings
GetParam(kMode)->InitEnum("Mode", 0, 11);

// configure the settings names
const char *modeNames[] = { "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11" };
for (int idx = 0; idx < 11; ++idx)
  GetParam(kMode)->SetDisplayText(idx, modeNames[idx]);

// create a knob control for Mode
IBitmap knob = pGraphics->LoadIBitmap(modeResID, modeResFile, 11);
pGraphics->AttachControl(new IKnobMultiControl(this, modeResLoc->h, modeResLoc->v, kMode, &knob));

Sorry, I don't have time at the moment to make and test an integer test case. I believe that I fixed the problems with integer parameters in AAX that are in wdl/ol master. All of my parameters automate correctly with my fork (but failed with wdl/ol master).

Thanks for examples.

For examples my parameter is Ratio.Should be like this?

Code:

GetParam(kRat)->InitEnum("Ratio", 0, 11);
Code:

const char *ratioNames[] = { "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11" };
for (int idx = 0; idx < 11; ++idx)
  GetParam(kRat)->SetDisplayText(idx, ratioNames[idx]);

I did like this but can't figure this section.

Code:

IBitmap knob = pGraphics->LoadIBitmap(ratioResID, ratioResFile, 11);
pGraphics->AttachControl(new IKnobMultiControl(this, ratioResLoc->h, ratioResLoc->v, kRatio, &knob));


earlevel 04-17-2017 01:52 PM

How are you creating your control and attaching it? Please show your code.

Tunca 04-17-2017 02:48 PM

Quote:

Originally Posted by earlevel (Post 1833509)
How are you creating your control and attaching it? Please show your code.

enum ELayout

Code:


 kRatX = 355,
 kRatY = 26,
 kKnob3Frames = 4,

IPlugInstanceInfo

Code:

GetParam(kRat)->InitEnum("Ratio", 0, 3);
Code:

const char *ratioNames[] = { "2", "4", "10", "20"};
for (int idx = 0; idx < 3; ++idx)
  GetParam(kRat)->SetDisplayText(idx, ratioNames[idx]);

OnParamChange

Code:

IBitmap knob = pGraphics->LoadIBitmap(ratioResID, ratioResFile, 4);
pGraphics->AttachControl(new IKnobMultiControl(this, ratioResLoc->h, ratioResLoc->v, kRatio, &knob));

But getting error with OnParamChange section.Not accepting 'ratio' name.

earlevel 04-17-2017 03:45 PM

You need to change the two values 3 to 4. You have four values, not three.

>But getting error with OnParamChange section.Not accepting 'ratio' name.

I don't know what this means.

Tunca 04-18-2017 03:34 AM

Quote:

Originally Posted by earlevel (Post 1833561)
You need to change the two values 3 to 4. You have four values, not three.

>But getting error with OnParamChange section.Not accepting 'ratio' name.

I don't know what this means.

I'm writing this one;

Code:

IBitmap knob = pGraphics->LoadIBitmap(ratioResID, ratioResFile, 11);
  pGraphics->AttachControl(new IKnobMultiControl(this, ratioResLoc->h, ratioResLoc->v, kRat, &knob));

instead of this one;

Code:

IBitmap knob3 = pGraphics->LoadIBitmap(RAT_ID, RAT_FN, kKnob3Frames);
 
  pGraphics->AttachControl(new IKnobMultiControl(this, kRatX, kRatY, kRat, &knob3));

But getting "Use of undeclared identifier 'ratioResFile'" , "Use of undeclared identifier 'ratioResID'" , "Use of undeclared identifier 'ratioResLoc'".

earlevel 04-18-2017 10:47 AM

Quote:

Originally Posted by Tunca (Post 1833700)
But getting "Use of undeclared identifier 'ratioResFile'" , "Use of undeclared identifier 'ratioResID'" , "Use of undeclared identifier 'ratioResLoc'".

You hadn't given any code, therefore I had no chance of knowing the variable and constant names you were using. So I made up my own. "ratioResID" is just shorthand for "ratio [your parameter] resource ID". Obviously, now that you've shown it, it's RAT_ID. And ratioResFile is RAT_FN.

Tunca 04-20-2017 02:06 PM

Thanks for all helps! Finally figured it out.

Thanks.

bozmillar 11-13-2017 05:58 PM

Hey Trunca,

What did you end up doing to fix this? This has always bugged me that I can't make stepped knobs Ints or Enums because mouse drag gets all screwy.

Tunca 11-14-2017 12:31 PM

Quote:

Originally Posted by bozmillar (Post 1912209)
Hey Trunca,

What did you end up doing to fix this? This has always bugged me that I can't make stepped knobs Ints or Enums because mouse drag gets all screwy.

Hi!

I fixed my issue like this...(Actually really idiotically solution)

Example from my compressor;

My compressor has 6 steps ratio knob.

I'm using "Double" instead of "Int".So i can turn it easily.

Code:

  GetParam(kRat)->InitDouble("Ratio", 0, 0, 5,1);
  GetParam(kRat)->SetShape(1.);

Then using this in process section.

Code:

    int Rat = GetParam(kRat)->Value();
    if (Rat == 0) mRat = 1.5;
    else if (Rat == 1) mRat = 2.0;
    else if (Rat == 2) mRat = 3.0;
    else if (Rat == 3) mRat = 4.0;
    else if (Rat == 4) mRat = 5.0;
    else if (Rat == 5) mRat = 10.0;

I can't find any other easy solution.I hope it helps.

Thanks.

bozmillar 11-14-2017 01:10 PM

Shoot. That's what I've been doing too. It comes with it's own set of issues due to the way parameters round in different places, but it's better than the crazy knob dragging.

Tunca 11-14-2017 01:28 PM

Yes,still has issue but better.For me best...

earlevel 11-14-2017 06:47 PM

Quote:

Originally Posted by bozmillar (Post 1912209)
Hey Trunca,

What did you end up doing to fix this? This has always bugged me that I can't make stepped knobs Ints or Enums because mouse drag gets all screwy.

Hey, Boz, taking a guess at what you're experiencing, stop me if this sounds right...

If you make a knob with a few steps, mouse drags become unintuitive as you run through the steps to one limit and then back. Yes?

If so, I mentioned my fix for that in a reply to another thread: https://forum.cockos.com/showpost.ph...0&postcount=14

Essentially: few discrete steps, with pinned extremes, when used relative drags at each GUI update...doesn't behave right. I made mine relative to the initial mouse down.

I have a couple of controls that do this, one being a knob. But its easier to understand the issue if I explain the non-knob:

I have a control that is a note-value icon (8th, 16th...) on the UI. Mouse down on it, and it becomes a popup menu of horizontal choices. Picture side-by-side squares with different note values. When the menu pops up, its initial position is shifted left or right so that the current choice lands over the button—so that the mouse is sitting on it—and it's highlighted. After it's up, it doesn't move—the highlight changes to track the horizontal mouse position. Drag the mouse to the left, the highlight shift to the next box over (release the mouse, that's the new setting).

Of course, the user drag can overshoot the left or right side, and you want the furthest left or right choice to be highlighted, even when the mouse moves far away. (The same as when you over-drag a knob—you pin at min or max frame.)

Consider how my control would behave on over-drag if I used the standard tracking. Say I drag to the left so far I'm now four inches past the left edge of the control. The left-most choice is highlighted. Now, without releasing the mouse, I start dragging back to the right—it would switch to the next choice while the mouse is still more than three inches from the control. Yuck. Instead, I base all moves on the difference between the current mouse position and the initial mouse-down. Stepped knobs benefit similarly with a more logical feel.

earlevel 11-15-2017 12:07 AM

1 Attachment(s)
A very small video, showing both controls being worked. (I made it into a 250 KB animated gif to display in the post...by the forum only allows 64 KB...)

bozmillar 11-15-2017 09:51 PM

Here's a demonstration of the issue.

Here are two versions of the same plugin, one AAX and one VST. The knob parameter is initialized as an enum. It's a stepped knob with 5 settings. When trying to move the knob in the AAX version, it's super screwy. It's like the knob moves based on the speed of the mouse movement rather than the distance of the mouse movement.

How it should work (VST):

http://bozrecords.com/mp3s/screencaps/VST%20Enum.gif

How it works as AAX:

http://bozrecords.com/mp3s/screencaps/AAX%20Enum.gif

The only way I've found to get the AAX knob to work is to initialize it as a double instead of int or enum.

earlevel 11-16-2017 12:35 AM

Quote:

Originally Posted by bozmillar (Post 1913086)
Here's a demonstration of the issue.

Oh, I see...it doesn't happen for me, but then again I fixed issues with AAX parameters in my fork. I do remember that stepped controls were hell in Pro Tools automation in the wdl-ol version I started with, and this looks familiar. Maybe that's it?

earlevel 11-16-2017 11:03 AM

I think it's something like this:

Pro Tools echoes parameter changes. For most plugins/hosts, you want to change the IPlug parameter, and tell the host you changed it. With AAX, you want to tell the host the parameter needs changing, and it will tell the plugin to update the parameter. So, you need to override with IPlugAAX::SetParameterFromGUI, same as the original except eliminating OnParamChange.

To complicate matters, the integer rounding is bad, so you end up in a disagreement with threshold param values. Your jerky action, unless you move the mouse fast enough to blow past the thresholds, is due to that fight. You increase the knob value from 0 till it clicks over to 1. You update the knob and parameter, and pass that to PT via IPlugAAX—which interprets the value as 0. PT sends back a param change of 0.

IPlugAAX::EffectInit:

Code:

  param = new AAX_CParameter<int>(paramID->Get(),
    AAX_CString(p->GetNameForHost()),
    (int)p->GetDefault(),
    AAX_CLinearTaperDelegate<int>((int)p->GetMin(), (int)p->GetMax()),  <-- was
    AAX_CStateTaperDelegate<int>((int)p->GetMin(), (int)p->GetMax()),  <-- should be

I think that was the main offender. Somewhat related to int/bool/enum issues is that GetDisplayForHost was broken. I think that's in my pull requests to Oli. I was working from wdl-ol of a couple years back.

Those are the related things in my GIT repository, but I'll double check—seems I did some more changes to IPlugAAX.

random_id 11-16-2017 04:33 PM

Around line 267 in IPlugAXX.cpp is the following:
Code:

    if (GetGUI())
    {
      GetGUI()->SetParameterFromPlug(paramIdx, iValue, true);
    }

I commented this out and it helps. I have been updating to the latest Youlean code, so I haven't gotten to fully test AAX yet.

I also overrode OnMouseUp, OnMouseDown, OnMouseWheel, and OnMouseDrag for my switch control. I made the switch change only when the OnMouseUp happens, the control is dragged, or the wheel is used. I use a simple bool (isMouseClick) to prevent the control from firing twice with drags. I also have some switches that work reverse and/or horizontal, so that is the other junk in there.

This is what I am using for a few of my switches.
Code:

              LVC_Switch::LVC_Switch(IPlugBase * pPlug, int L, int T, int paramIdx, IBitmap * pBitmap, bool isreverse, bool isvertical, IChannelBlend::EBlendMethod blendMethod)
                    : ISwitchControl(pPlug, L, T, paramIdx, pBitmap, blendMethod)
                {
                    isReverse = isreverse;
                    isVertical = isvertical;
                    mValue = GetParam()->GetNormalized();
                    isMouseClick = false;
                }

                bool LVC_Switch::Draw(IGraphics* pGraphics) {
                    int i = 1;
                    if (mBitmap->N > 1)
                    {
                        i = 1 + int(0.5 + mValue * (double)(mBitmap->N - 1));
                        i = BOUNDED(i, 1, mBitmap->N);
                    }

                    return pGraphics->DrawBitmap(mBitmap, &mDrawRECT, i, &mBlend);
                }
                void LVC_Switch::OnMouseWheel(int x, int y, IMouseMod * pMod, int d)
                {
                    isMouseClick = false;
                    if (isReverse) d = -d;
                    mValue += (double)BOUNDED(d, -1., 1.) / (double)(mBitmap->N - 1);
                    SetDirty();
                }

                void LVC_Switch::OnMouseDrag(int x, int y, int dX, int dY, IMouseMod * pMod)
                {
                    isMouseClick = false;
                    if (!isVertical) {
                        if (!isReverse) dY = -dY;
                        mValue += (double)BOUNDED(dY * 0.025, -1., 1.) / (double)(mBitmap->N - 1);
                    }
                    else {
                        if (isReverse) dX = -dX;
                        mValue += (double)BOUNDED(dX * 0.025, -1., 1.) / (double)(mBitmap->N - 1);
                    }
                    SetDirty();
                }

                void LVC_Switch::OnMouseUp(int x, int y, IMouseMod * pMod)
                {
                    if (isMouseClick) {
                        {
                            if (mBitmap->N > 1)
                            {
                                mValue += 1.0 / (double)(mBitmap->N - 1);
                            }
                            else
                            {
                                mValue += 1.0;
                            }

                            if (mValue > 1.001)
                            {
                                mValue = 0.0;
                            }
                            SetDirty();
                        }
                    }
                    isMouseClick = false;
                }

                void LVC_Switch::OnMouseDown(int x, int y, IMouseMod * pMod)
                {
                    isMouseClick = true;
                }


earlevel 11-18-2017 01:21 PM

At the risk of sounding insistent, I'll try to recap the important points:

1) If you don't fix the fundamental AAX parameter problems, you will at some point have automation quirks, if you don't already.

2) If you fix the double-call of OnParamChange via AAX / Pro Tools, compared to other plugins, you won't have to do funny things elsewhere to stop its effects due to double calls.

3) I think the best way to handle discrete steps is as I described. It's not a hack—"it works a lot better when I do this"—there is a logical reason it is more natural.

The first two are about fixing AAX, which is a must if you support AAX. This thread is about different knob behaviors with AAX, and mostly covers hacks to get acceptable behavior. Why not fix AAX? (I understand that part of the thread is not necessarily isolated to AAX, but that's covered in my point 3, universal for all plugin types.)

I don't know what everyone is using, but in the current wdl-ol master, for bool/enum parameter types, IPlugAAX calls AAX_CLinearTaperDelegate—it should be AAX_CStateTaperDelegate, and I think you can understand that from the names.

For #2, I already mentioned PT's different behavior that requires an override to not call OnParamChange twice. It's a simple fix, better than adding code to guard against it in individual controls.

I also rewrote GetDisplayForHost, which was a mess (yes I could have removed sprintf, wasn't trying to save the world here). I think that it affected automation display in PT in some cases, IIRC, but caused problems in general anyway.

See my long-standing pull request for wdl-ol. The commits are independent.

As for #3, you can do your control any way you want, but please take the time to understand what I'm doing. It's not a hack to make things acceptable, it's a logical way for such controls to work, and it behaves exactly like a similarly-stepped GUI control that you'd been using for decades behaves—the pop-up menu.

Let's say you want a knob with five step positions. A natural behavior is to have it switch at a certain drag distance—say, 1 cm, for each next step. Mousedown on the control (the controls saves the current x,y and value—"the anchor"), drag—onmousedrag gets called repeatedly, each time looking at the current x or y and seeing how far it has moved from the anchor, and changing the value/SetDirty if needed, pinned to min/max. On mouseup, you don't need to do anything. Same as rolling down a menu, going too far, going back. The regular knob mouse behavior is wrong for this type of control because it's not anchored on the original click, so the switching is not consistent. You don't notice on continuous controls, but it's a killer with limited steps.

earlevel 11-18-2017 04:25 PM

That was too long-winded—should have split the AAX issues and control description into two messages, sorry.

There are a few more changes for AAX parameters that aren't in the pull request, it's just the minimum to fix the problem discussed in this thread. I won't go into much detail here, leave it for an AAX-fix discussion thread for anyone pursuing fixing AAX in their fork/branch, with enums. For integers, this change is also needed in IPlugAAX.cpp:

Code:

case IParam::kTypeInt:
...
  AAX_CLinearTaperDelegate<int,1>((int)p->GetMin(), (int)p->GetMax()),

Note the change from <int> to <int,1>.

Background: My plugin was originally TDM, so this AAX version had exact functionality as top priority. That includes automation in old Pro Tools projects—the existing automation had to give the same plugin settings, so any rounding had to be 100% correct. There are other changes I made, fixes for broken transport support, adding control highlight support, shortened parameter-name support, etc.

I'm not on a crusade here, I don't have a lot of free time and I'll shut up if there is no interest. To be blunt: If your AAX isn't behaving right, it's because IPlug has some things wrong. Some plugins will be lucky and work right, but in general AAX won't work right for an arbitrary feature set.


All times are GMT -7. The time now is 02:58 AM.

Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2017, vBulletin Solutions Inc.