Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Widget display contradicting value in a drag: value set by UI vs value known to the DSP, that bubbles up there #718

Closed
p0nce opened this issue Oct 10, 2022 · 19 comments
Labels
Bug Reproduced bug.

Comments

@p0nce
Copy link
Collaborator

p0nce commented Oct 10, 2022

Sometimes incredibly annoying, not sure if someone else has it.

@p0nce p0nce added the Unconfirmed This issue describe a bug that hasn't been reproduced yet. label Oct 12, 2022
@p0nce
Copy link
Collaborator Author

p0nce commented Oct 20, 2022

Reproduced with Distort + vsthost64 on ~master

@p0nce p0nce added Bug Reproduced bug. and removed Unconfirmed This issue describe a bug that hasn't been reproduced yet. labels Oct 20, 2022
@p0nce p0nce changed the title Live + VST3 + dragging parameter => jumping param VST3 + dragging parameter => jumping param Oct 20, 2022
@p0nce
Copy link
Collaborator Author

p0nce commented Oct 20, 2022

Is it conflict between those two?
image
Source: https://forums.steinberg.net/t/clarification-of-parameter-handling-in-vst-3/201914/2

@p0nce
Copy link
Collaborator Author

p0nce commented Oct 24, 2022

Fix need backport to v12, when the fix exists

@p0nce
Copy link
Collaborator Author

p0nce commented Oct 25, 2022

  • Distort + VST2 + debug mode => no bug
  • Distort + VST3 + debug mode => yes bug
  • Distort + VST3 + release mode => yes bug, less often

@p0nce
Copy link
Collaborator Author

p0nce commented Oct 25, 2022

Is it buffer splitting? from Sep 2021

  • Distort + VST3 + debug mode + Dplug v11.0.0 => no bug

@p0nce
Copy link
Collaborator Author

p0nce commented Oct 25, 2022

Found an (unrelated?) pretty bad performance issue, parameter tracks are too large

@p0nce
Copy link
Collaborator Author

p0nce commented Oct 25, 2022

What happens is that double y1 = getParamNormalized(id); fails and return zero, it gets reinjected then
The ParamID seems bad

@p0nce
Copy link
Collaborator Author

p0nce commented Oct 26, 2022

The bad ParamID is VSTHost-only, there is nothing we can do unless they fix that bug.
On Ableton Live, it's a different thing.

@p0nce
Copy link
Collaborator Author

p0nce commented Oct 26, 2022

REAPER trace when dragging a slider

[9672] setFromGUI( 0.816920 )    // onMouseDrag setting the value
[9672] Param value = 0.816920   // drawing
[9672] setFromGUI( 0.820766 )    // onMouseDrag setting the value
[9672] Param value = 0.820766   // drawing
[9672] Parameter changes for ID = 3 // audio process
[9672] setFromGUI( 0.824612 )     // onMouseDrag setting the value
[9672] track 3  value[0] 0.820766   // process
[9672] setFromGUI( 0.828458 )     // onMouseDrag setting the value
[9672] track 3  value[1] 0.820766   // process
[9672] Param value = 0.828458      // drawing
[9672] track 3  value[2] 0.820766
[9672] setFromHost( 0.820766 ) with tag 0
[9672] setFromHost( 0.820766 ) with tag 0
[9672] setFromGUI( 0.824612 )
[9672] setFromHost( 0.820766 ) with tag 1

So even in REAPER, things are a bit unsynchronized because the UI change happens before the audio process, then process happens with former values.

@p0nce
Copy link
Collaborator Author

p0nce commented Oct 26, 2022

Ableton Trace:

[17680] setFromGUI( 0.353846 )    // UI moving slider in onMouseDrag
[17680] Param value = 0.353846    // draw
[17680] setFromGUI( 0.346154 )    // UI moving slider in onMouseDrag
[17680] setFromHost( 0.369230 ) with tag 17   // setParamNormalized
[17680] Param value = 0.369230  // draw slider
[17680] setFromGUI( 0.361538 )   // UI
[17680] setFromGUI( 0.261538 )   // UI
[17680] Parameter changes for ID = 3
[17680] setFromGUI( 0.253846 )
[17680] track 3  value[0] 0.361538   
[17680] setFromHost( 0.361538 ) with tag 17 // setParamNormalized
[17680] track 3  value[1] 0.361538
[17680] Param value = 0.361538
[17680] setFromHost( 0.361538 ) with tag 0  // audio callback
[17680] setFromHost( 0.361538 ) with tag 1   // audio callback
[17680] setFromGUI( 0.346154 )
[17680] setFromGUI( 0.353846 )
[17680] Param value = 0.353846
[17680] setFromGUI( 0.330769 )
[17680] Param value = 0.330769
[17680] Parameter changes for ID = 3
[17680] track 3  value[0] 0.353846

Ableton just have a little bit more of interplay, since the host is also sending setParamNormalized.
So why does VST2 doesn't have that in Ableton?

@p0nce
Copy link
Collaborator Author

p0nce commented Oct 26, 2022

In Reaper, dragging a slider in VST2 doesn't lead to a call to setFromHost.
In Ableton, dragging a slider in VST2 send a single setFromHost, but at the point where the Edit has finished.
Hence, slider movement is much more fluid in VST2.

@p0nce
Copy link
Collaborator Author

p0nce commented Oct 26, 2022

  • Does the problem also exist in LV2? => yeah
    REAPER trace:
[11540] Param value = 0.286893  // draw
[11540] setFromGUI( 0.282507 )
[11540] Param value = 0.282507 // draw
[11540] setFromGUI( 0.278121 )
[11540] Param value = 0.278121 // draw
[11540] setFromHost( 0.278121 ) with tag 15
[1896] DOLBY notifier : Receive NewSession Event
[11540] setFromGUI( 0.273735 )
[1896] DOLBY notifier: Process Name: reaper.exe
[11540] Param value = 0.273735 // draw
[11540] setFromGUI( 0.269349 )
[11540] setFromHost( 0.273735 ) with tag 15   // THIS COULD MAKE A MISDRAW
[1896] DOLBY notifier : Receive NewSession Event
[11540] setFromGUI( 0.264964 )
[11540] setFromHost( 0.269349 ) with tag 15
[11540] setFromGUI( 0.260578 )
[11540] Param value = 0.269349 // draw
[1896] DOLBY notifier: Process Name: reaper.exe
[1896] DOLBY notifier : Receive NewSession Event
[1896] DOLBY notifier: Process Name: reaper.exe
[11540] setFromHost( 0.260578 ) with tag 15
[1896] DOLBY notifier : Receive NewSession Event
[11540] Param value = 0.260578
[1896] DOLBY notifier: Process Name: reaper.exe
[11540] Param value = 0.260578
[11540] Param value = 0.260578
[1896] DOLBY notifier : Receive NewSession Event
[1896] DOLBY notifier: Process Name: reaper.exe
[11540] Param value = 0.260578
[11540] Param value = 0.260578
[1896] DOLBY notifier : Receive NewSession Event
[11540] Param value = 0.260578
[1896] DOLBY notifier: Process Name: reaper.exe
[11540] Param value = 0.260578
[11540] Param value = 0.260578
[1896] DOLBY notifier : Receive NewSession Event
[1896] DOLBY notifier: Process Name: reaper.exe
[11540] Param value = 0.260578
[11540] Param value = 0.260578
[1896] DOLBY notifier : Receive NewSession Event
[1896] DOLBY notifier: Process Name: reaper.exe
[11540] Param value = 0.260578
[11540] Param value = 0.260578

So there is some kind of need need for UI to ignore parameter values when set by the host, if the widget is dragging...

@p0nce p0nce changed the title VST3 + dragging parameter => jumping param Widget display contradicting value in a drag: value set by UI vs value known to the DSP, that bubbles up there Oct 26, 2022
@p0nce
Copy link
Collaborator Author

p0nce commented Oct 26, 2022

The fundamental problem is that parameter value as seen by the UI/user is different than parameter value as seen by the DSP/automation, and sometimes the state need to be separated for a while. On the plus side, the bug isn't terribly unworkable.

Having two IParameter interfaces for those could help.

@p0nce
Copy link
Collaborator Author

p0nce commented Oct 26, 2022

Summing up the issue:
image

Only a problem if the same widget sets and listen to one Parameter

@p0nce
Copy link
Collaborator Author

p0nce commented Oct 26, 2022

Ideas to fix that:

  • in onDraw, if isDragged, use last submitted value as ground truth instead of current parameter value
    => all widgets need to change, but only those where the problem shows. This can be a new Parameter accessor.
  • there is a valueForDSP and valueForUI storage for each parameter. setFromHost doesn't modify valueForUI during an edit. All widgets get parameter value with a special accessor. value() deprecated.
    => all widgets need to change

Thought: if we know the parameter is going to change to whatever the UI said, why not give the value given by the UI a higher priority? And refuse the host changes even for processing audio.

@p0nce
Copy link
Collaborator Author

p0nce commented Oct 26, 2022

What calls are used by Widget to get parameter values?

  • draw: getNormalized(), value(), valueAtomic()
  • animation: valueAtomic()
  • clic: value(), getNormalized()

@p0nce
Copy link
Collaborator Author

p0nce commented Oct 26, 2022

So, there is a simple solution to this, probably need much testing:

    /// From a normalized double [0..1], set the parameter value.
    void setFromHost(double hostValue)
    {
        if (isEdited())
            return; // If edited by a widget, REFUSE host changes, since they could be 
                    // "in the past" and we know we want newer values anyway.
        setNormalized(hostValue);
        notifyListeners();
    }

@p0nce
Copy link
Collaborator Author

p0nce commented Oct 26, 2022

  • REAPER and Live + VST3 => OK, now fluid
  • VST2 + REAPER and Live => OK

@p0nce
Copy link
Collaborator Author

p0nce commented Oct 26, 2022

Review all SetFromHost calls and see if that's sustenable => likely yes.

  • test on macOS
  • Backport eventually => no, too dangerous. In the new fix, calls to beginParamEdit/endParamEdit need to be perfectly balanced, this was only checked in debug before.

p0nce pushed a commit that referenced this issue Oct 26, 2022
…gin, parameter information (setFromHost) from the host is IGNORED.

This is super valuable, as it makes sliders and knobs smoother to use in all plugin formats, in all hosts (except VST2 who already dealt with that).
But needs additional testing before it can go live.
@p0nce p0nce closed this as completed Oct 27, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Bug Reproduced bug.
Projects
None yet
Development

No branches or pull requests

1 participant