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

Soft Takeover mode for MIDI learned parameters #7510

Closed
sjomae opened this issue Feb 7, 2024 · 26 comments · Fixed by #7639
Closed

Soft Takeover mode for MIDI learned parameters #7510

sjomae opened this issue Feb 7, 2024 · 26 comments · Fixed by #7639
Labels
Feature Request New feature request MIDI MIDI support related

Comments

@sjomae
Copy link

sjomae commented Feb 7, 2024

Some MIDI controllers have a 'snap mode' (Faderfox for instance), is this supported by Surge?

The synth or plugin hosts sends MIDI cc values to the controller. When in snap mode, the controller doesn't send MIDI data, until it reached / picked up the value which it got from the synth / host.

Does the standalone version have a MIDI Out? Couldn't test, cause the standalone didn't launch properly on Linux.

@mkruselj
Copy link
Collaborator

mkruselj commented Feb 7, 2024

This is not supported by Surge as it stands.

@sjomae
Copy link
Author

sjomae commented Feb 7, 2024

The problem with connecting a MIDI controller to Surge, seems that without a controller snap mode, all the values of the preset will be gone, cause the knobs of the controller have different values. If you turn them, values are adjusted to the current position of the controller knob, which are completely different then the chosen preset.

Could you turn this issue into a feature request?

@mkruselj
Copy link
Collaborator

mkruselj commented Feb 7, 2024

This is going to be better handled by MIDI 2.0 whenever that gets implemented at large (it seems this year might be an important one for MIDI 2.0!).

As it stands, we recommend using OSC for bidirectional synchronization of parameters.

@sjomae
Copy link
Author

sjomae commented Feb 7, 2024

Will look into OSC later. Are current MIDI controllers compatible with MIDI 2.0?

@mkruselj
Copy link
Collaborator

mkruselj commented Feb 7, 2024

There are only a few on the market currently: Roland A88, Korg Keystage, NI Kontrol S-series mk3.

@sjomae
Copy link
Author

sjomae commented Feb 7, 2024

Ok, that doesn't sound very hopeful. MIDI 2.0 will not be the solution for me in the near future I'm afraid. Will look into OSC.

You guys could still consider a MIDI 1 compatible MIDI Out though, but I'll leave that up to you. Thanks.

@mkruselj
Copy link
Collaborator

mkruselj commented Feb 7, 2024

As it stands we are now focusing our efforts on getting Shortcircuit XT out this year, so Surge updates are likely going to slow down as a consequence. Perhaps there could be a soft takeover mode added for each MIDI learned parameter (received MIDI value is checked against current parameter value and only if the incoming value has crossed the current value it would take on), but there is no immediate priority to implement this.

@baconpaul
Copy link
Collaborator

The fr would basically be that the cc crosses the preset value once before midi control kicks in?

@mkruselj
Copy link
Collaborator

mkruselj commented Feb 7, 2024

Yeah. And is optional per parameter.

@sjomae
Copy link
Author

sjomae commented Feb 8, 2024

The fr would basically be that the cc crosses the preset value once before midi control kicks in?

I think it's indeed useful when loading a preset. But also when changing the value with the mouse, instead of the controller, then the controller needs to know the changed value.

To get the best understanding of the feature, one could best just contact the creator of the Faderfox devices (see website). He seems to be responsive and has experience with different implementation in different software I suppose.

I had contact with him and he told me for instance:

"some programs like ableton live send only the last value after you don't send new values from the controller for a while."

@baconpaul
Copy link
Collaborator

Oh I see your controller gets midi in so you want surge to send midi out to reset your knobs. Kinda like an automated mixing board with motorized sliders

so the fr is really: on patch load for each midi mapped control send that cc value out the midi out (optionally)?

@sjomae
Copy link
Author

sjomae commented Feb 8, 2024

I just tested this 'snap mode' yesterday with a audio language. I send a midi cc message to the controller, let's say value 40. The current value of the knob is, let's say 127. With the controller in snap mode, when I turn the knob in the direction of value 40, the MIDI controller doesn't send any values, until the moment that it arrives at value 40, from that point the controller works normally (like in jump mode). These are just regular pot knobs, not motorized.

For this to work, the controller needs to have a value via MIDI indeed.

I would say, the MIDI controller needs the value when loading a preset (with MIDI learn settings saved) and when the user changes the value of the MIDI learned parameter with the mouse, instead of the controller. More general, at every moment of a possible mismatch between the MIDI learned value in Surge and the connected MIDI controller.

There are probably multiple ways to do this, see also the quote about Ableton Live:

"some programs like ableton live send only the last value after you don't send new values from the controller for a while."

Again, how this should be best implemented in the software, is a question I can't fully answer, I'm not an expert in this area. I would honestly just contact the maker of Faderfox devices, to get the best picture of the problem and the best solution for it, avoiding any pitfalls, which exists, from scratch.

edit: typo, 80 must be 40.

@mkruselj
Copy link
Collaborator

mkruselj commented Feb 8, 2024

Yeah I reckon both features are good to have, but I was thinking soft takeover would be a simpler thing to implement.

EDIT: What you explained above is literally what soft takeover is, actually... There is no MIDI out necessary for this actually - it can be done entirely on Surge end. Sending all MIDI learns out on patch change is a separate feature.

@sjomae
Copy link
Author

sjomae commented Feb 8, 2024

So, then you just ignore controller MIDI cc messages which differs from the current value?

@mkruselj
Copy link
Collaborator

mkruselj commented Feb 8, 2024

Yup, until you meet and cross over the current parameter value as you tweak your MIDI controller.

@baconpaul
Copy link
Collaborator

Cool thanks for helping me understand

@sjomae
Copy link
Author

sjomae commented Feb 8, 2024

Yup, until you meet and cross over the current parameter value as you tweak your MIDI controller.

I think it should be only meet (40), not crossover(41) right? At 40, the user can turn the knob in the opposite direction (39). :)

@mkruselj
Copy link
Collaborator

mkruselj commented Feb 8, 2024

It depends from which direction you're coming of course, it would work from both directions. Here's some pseudocode:

function setParamValueViaMIDI(incomingValue) // incomingValue expected range 0.f ... 1.f
{
    if (softTakeOver)
    {
      switch (softTakeoverStatus)
      {
        case takeover_status_waiting_for_value:
          if (softValue < incomingValue)
            softTakeoverStatus = takeover_status_waiting_below;
          else if (softValue > incomingValue)
            softTakeoverStatus = takeover_status_waiting_above;
          else
            softTakeoverStatus = takeover_status_locked;

        case takeover_status_waiting_below:
          if (incomingValue <= softValue + 1.0e-3f)
            softTakeoverStatus = takeover_status_locked;

        case takeover_status_waiting_above:
          if (incomingValue >= softValue - 1.0e-3f)
            softTakeoverStatus = takeover_status_locked;
      }

      if (softTakeoverStatus != takeover_status_locked)
        return;
    }

    softValue = incomingValue;

    changeParamValueNow(incomingValue);
}

softValue would be initialized as -1.f so that it always needs to seek the param value from the get go.

@baconpaul
Copy link
Collaborator

this->setParameterSmoothed(i, fval);

That’s the rough location where you would want to put code to that effect

@sjomae
Copy link
Author

sjomae commented Feb 8, 2024

Can't it just check if the incoming value is equal to the currently set value? If so, change wait_for_first_matching_value to false?

@baconpaul
Copy link
Collaborator

And add your takeover state to the Param so you can just blam it into the if

I would also make it a global option if I was doing it in 13 lifecycle and check that option when constructed as an atomic - doing it Param by Param has streaming impacts and ui impacts which I think are too gnarly

@mkruselj
Copy link
Collaborator

mkruselj commented Feb 8, 2024

Can't it just check if the incoming value is equal to the currently set value? If so, change wait_for_first_matching_value to false?

That's what the code is doing but it is not enough to check for equalness, because you are not guaranteed to receive continuous stream of values. Say param value is 40, but your MIDI controller is at 80, and it's sending: 70, 60, 45, 20. 40 might never be hit. This is why you have to check both directions always, and also have some error margin due to floating point shenanigans etc.

@baconpaul
Copy link
Collaborator

Yes the fp stuff is important since Param sliders are not quantized to 1/127 so you need an imputed midi cc for the Param from the 01 value

@sjomae
Copy link
Author

sjomae commented Feb 8, 2024

I see. One day you guys need to help me with learning C++ I suppose. ;)

@baconpaul
Copy link
Collaborator

Ha yeah! This is more just “the Param has higher resolution than a controller” and “controllers skip values” meaning == isn’t the right comparison

@mkruselj mkruselj changed the title MIDI Out / controller snap mode Soft Takeover mode for MIDI learned parameters Feb 14, 2024
@mkruselj mkruselj added Feature Request New feature request and removed Discussion labels Feb 14, 2024
@mkruselj
Copy link
Collaborator

@baconpaul Some beginning effort is in mkruselj/soft-takeover-attempt. I'm missing some tricks, it's not quite working out well :(

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Feature Request New feature request MIDI MIDI support related
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants