ASPiK SDK
Parameter Smoothing

Parameter Smoothing OFF
When parameter smoothing is turned off, the parameter’s value will remain fixed and constant during the entire buffer processing cycle. This means that we are wasting CPU cycles by recalculating the cooked volume value on each audio frame. We really only need to calculate it once per buffer cycle and we can make use of the function PluginCore::postUpdatePluginParameter that will be called during the buffer pre-processing phase. Since this function is external to the processAudioFrame function, we will need to declare the cooked volume value as a member variable of the PluginCore object in the plugincore.h file:

private:
 // — Continuous Plugin Variables
double volume_dB = 0.0;

 // — cooked volume value PluginCore::postUpdatePluginParameter()
double volumeCooked = 0.0;

 // — Discrete Plugin Variables
int enableMute = 0;

 etc . . .

Then, in PluginCore::postUpdatePluginParameter we will decode the parameter controlID, and cook the incoming raw data. Because of our clever controlID enumeration naming convention, we don’t need to look up the controlID, we simply use the enumeration which is the same as the variable name (controlID::volume_dB):

bool PluginCore::postUpdatePluginParameter(int32_t controlID, double controlValue, ParameterUpdateInfo& paramInfo)
{
 // — decode the controlID
switch(controlID)
 {
  case controlID::volume_dB:
  {
   // — cooked variables
   volumeCooked = pow(10.0, volume_dB / 20.0);
   return true; // handled
  }

 default:
  return false; // not handled
 }

 return false;
}

Now, we can remove the cooking calculation from the frame processing function (we’ll just comment it out):

// — convert dB to raw NOW DONE IN postUpdatePluginParameter
// — double volumeCooked = pow(10.0, volume_dB / 20.0);
double volume_L = volumeCooked;
double volume_R = volumeCooked;
etc…

Parameter Smoothing ON
When parameter smoothing or VST3 sample accurate automation is enabled, the value of the volume_dB variable is going to be smoothed and updated on each sample interval at the top of the processAudioFrame function. However, both the normal parameter smoothing and VST3 sample accurate updating methods will call our postUpdatePluginParameter function after the smoothing operation has occurred. With our cooking code in postUpdatePluginParameter, there is nothing else to do! The volume_dB value will be smoothed and updated at the top of each frame processing cycle and we will recalculate our cooked value afterwards. The VST3 sample accurate update process overrides the ordinary parameter smoothing so that the parameter is not smoothed or updated twice, therefore you don’t need to worry about your cooking code being called unnecessarily.

There may be situations where you do not want to perform the post-update cooking function based on whether the parameter was changed during 1) the normal buffer cycle process, 2) a parameter smoothing operation, 3) a VST sample accurate update or 4) the user loading a preset. You might want to experiment with CPU usage rates or have other plugin-specific issues to deal with. For example, if the cooking process is CPU intensive because of some plugin option that the user has chosen, you might opt to disable the cooking in this situation. The third argument in the postUpdatePluginParameter function is a ParameterUpdateInfo structure that delivers information about how and why the function is being called. You can examine the member variables and use them to alter your logic for the cooking process.

struct ParameterUpdateInfo {
 <SNIP snip="" snip>="">

bool isSmoothing;
bool isVSTSampleAccurateUpdate;
bool loadingPreset;
bool boundVariableUpdate;
bool bufferProcUpdate;

 <SNIP snip="" snip>="">
};

These boolean flags are fairly straightforward to figure out by their names, but here the logic used.

isSmoothing: ordinary parameter smoothing
isVST3SampleAccurateUpdate: a VST3 sample accurate automation update
loadingPreset: the user loaded a preset in the host DAW
boundVariableUpdate: the variable binding operation has occurred
bufferProcUpdate: updating at the top of the buffer process cycle