Parameters linking best practices

Hi guys,
when making a stereo plugin with separate controls for Left and Right channels, I also have an option to link both channels. Currently I’m using a timer in my parameters class to asynchronously set the value of both master and slave parameter, but there’s an issue when we record automations and the plugin doesn’t respond as expected. We suffer glitches in the UI and sometimes the parameters are set to a wrong value.

The linkable parameters are set as MetaParameter (the isMetaParameter method returns true when those parameters are used).

In my setValue method I have:

if(paramID == "myLeft" || paramID == "myRight")
{
   if(isLinked && !isBusy)
   {
      isBusy = true;
      startTimer(1.0);
   }
   isBusy = false;
}

then, for the timerCallback I have:

if(isLinked)
{
  if(paramID == "myLeft")
   processor.myRightParam->setValue(value);
 else if(paramID == "myRight")
   processor.myLeftParam->setValue(value);
}
stopTimer();

What should be the best way to get parameters linking working without messing up?

Thanks!

That is to be expected. The timerCallback() is not working in realtime. It’s call depends of the GUI thread being available. And in case of an offline bounce, it will miss most of the times.

For meta parameters there is no need for async calls, and the GUI should only reflect the current state. If you use ButtonAttachments etc. the setting is taken care of.

Also if you have mutual exclusive states “on”:“off” or “left”:“right” it is best to have one bool parameter only, and deduce the opposite state by negating.

If you have mutual multiple states, it is best to use an integer and AudioParameterChoice…

Why use a timer at all? I’d simply directly update the parameter if linked. You already have a flag which will avert a feedback loop.

The timerCallback I’m referring is the one I have in my parameters class, so it’s not working in the GUI thread. The need of using a timer is to avoid ProTools crashing when parameters are working together at the same time.

1 Like

There is a misunderstanding about threads. The location in memory is irrelevant to which thread is calling a method. E.g. the AudioProcessor class, prepareToPlay is called from the GUI thread, while the processBlock is called by the audio thread.

The timer class is designed to be ALWAYS called on the message thread. It posts it’s call through the MessageManager.

If you don’t want this, you can use the HighResolutionTimer, which is called from it’s own dedicated thread.

If you want it to be executed synchronous from the audio thread, just call it from processBlock.

Thanks, the HighResolutionTimer works way better than the standard one.