parameterMap.set without calling control's Lua function

The Lua code on my E1 receives a plugin value change from my DAW control plugin via a custom sysex message. At some point, that plugin value change will be applied to the E1 controller via

    parameterMap.set(1, PT_VIRTUAL, param, paramValue)

The preset uses controls calling a custom Lua function OnPotTwist when a control changes its value.
I expected this function to be called only when changing a control via the hardware pots. But it looks like the assigned function is also being called when parameterMap.set() is called.
This creates an unintended feedback loop between my DAW control plugin and the E1.

Is it somehow possible to set the parameterMap without calling a control’s assigned function?

short answer is not really. You can use a separate variable and store the incoming value there and then decide when to actually update the parameter map.

The E1 is designed to have the parameterMap as the center of the universe which is usually good.
However, you don’t have to use it. You can use direct midi messages called from functions associated with controls.

The parameterMap is great when you want to pull in a complete patch dump (for example), tweak values, and send back the entire patch. The parameterMap makes it easy to access and manage all the params associated with a device that way.

You might also want to look at the parameterMap.onChange() functionality because inside there you can see where the change request is coming from (MIDI, internal code, or an E1 control)

You can use a separate variable and store the incoming value there and then decide when to actually update the parameter map.

Yeah, for now, I settled with a similar workaround - a pot-value-hashmap that’ll be set and checked before setting the parameterMap. Look like this:

PotValues = 
{
    0,
    0,
    0,
    0,
    0,
    0,
    0,
    0,
    0,
    0,
    0,
    0,
}

-- this function is called when the DAW plugin changes a value and wants to inform the E1 about that change
function OnPluginParameterChanged(value)
    -- extract paramValue and paramId from value, irrelevant for this topic
    -- determine ID of knob, paramId is always a multiple of the active control set
    local activeControlSet = pages.getActiveControlSet()
    local knobId = (paramId / activeControlSet) + 1
    if PotValues[knobId] == value then
        --print("Received value already set. Not setting parameter map to prevent feedback loop!")
        return
    end
    
    -- set PotValues hashmap to plugin value of current knobId
    PotValues[knobId] = paramValue
    -- finally, set parameterMap
    parameterMap.set(1, PT_VIRTUAL, paramId, value)
end

-- this function is called when the user twists a knob on the E1
function OnPotTwist (valueObject, value)
    local parameterNumber = valueObject:getMessage():getParameterNumber()
    local activeControlSet = pages.getActiveControlSet()
    local knobId = (parameterNumber / activeControlSet) + 1
    if PotValues[knobId] == value then
        --print("Knob value already set. Not sending out message!")
        return
    end

    -- set PotValues hashmap to value currently set on the E1 to prevent feedback loop
    PotValues[knobId] = value
    -- send MIDI message to DAW
end

There are other things to consider for breaking up such feedback loops:

  • in OnPluginParameterChanged, check if the associated pot is touched and ignore incoming values (user is currently in control of the parameter via a physical knob and no one should overwrite that)
  • in the DAW control plugin, detect touched pot states and send the current plugin’s parameter value on untouch if the plugin’s value is different than the last incoming value from the E1

You can use direct midi messages called from functions associated with controls.

So setting a control to send 14bit MIDI messages will make it not send out a 14bit MIDI message when receiving it?

You might also want to look at the parameterMap.onChange() functionality because inside there you can see where the change request is coming from (MIDI, internal code, or an E1 control)

Interesting! So the control would still call a Lua function but that function would be empty. The code sending out the message would reside in parameterMap.OnChange() instead but only react to INTERNAL (E1 knobs?) and ignore LUA and MIDI.

Yes - I have examples using this technique. Time is very short tonight, but it is doable.

One thing to watch though is that the code/conditions can grow and become unwieldy inside the onChange() function.

Some forethought is recommended. lol

BTW - in general, when folks ask questions, sometimes it is helpful to see the bigger picture, so if they are comfortable in public (or PM), sending a link to the preset in progress, that might speed up some of the interactions.

Pot touch can be crazy. Take a look and play with this little example preset: variables and resets

1 Like

Thanks for example @oldgearguy !
It seems I should have chosen another “friend” to play around (Pot Touch - on this other thread)