VST 3 Interfaces  VST 3.6.7
SDK for developing VST Plug-in
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Macros Groups Pages
Parameters and Automation

All parameter changes of a processing block.

Parameters

Representation of parameter values
A Plug-in parameter usually has more than one representation. The GUI of a Plug-in can display something that appears to be a single parameter, but it might control multiple processing parameters at the same time. Or the GUI representation displays a scale-transformed representation of a DSP-parameter.

Somewhere on the way from the GUI to the DSP-algorithm this transformation has to be performed. The host does not and must not know anything about DSP-parameters, but it is responsible for reporting parameter changes to the processor. According to this, the processor is the only place where a transformation can happen and all parameters always have to match the GUI representation.

Does this fit into the idea of separating GUI and processing? No problem so far - it is a separation of duties, nothing more. The processor component and the controller component have to work on the same internal Plug-in model. The controller knows how this model has to be presented in GUI. The processor knows how the model has to be translated into DSP-parameters.
The VST 3 interfaces suggest a normalized value representation for the a part of this model (the part that is exported as parameters). This means every value has to be inside the range from 0.0 to 1.0.
Parameter styles / 'Step Count'
Although values are transmitted in a normalized format, the host needs to know some details of the parameter's displayed GUI representation. When editing automation data for example, the host must know the nature of a parameter expressed in its 'step count' (see Steinberg::Vst::ParameterInfo::stepCount).

Step count semantics :
  • 0 : A continuous parameter. Any normalized value has an exact mapping (0 = there are no steps between the values)
  • 1 : A discrete parameter with 2 states like [on/off] [yes/no] etc. (1 = there is one step between these states)
  • 2 : A discrete parameter with 3 states [0,1,2] or [3,5,7] (2 = there are two steps between these states)
  • 3 : etc...
Conversion of normalized values
The controller and the processor have to deal with normalized parameter values.
  • Step count 0 : Continuous parameters simply need to be mapped accordingly
  • Step count n : Discrete parameters need a little bit more care
    • Normalize:
      double normalized = discreteValue / (double) stepCount;
    • Denormalize :
      int discreteValue = min (stepCount, normalized * (stepCount + 1));

Example: Step Count 3
valuerange.jpg



Automation

A host that supports parameter automation is dependent on a proper cooperation of the component owning these parameters. One intention in the design of the VST 3 interfaces was to reduce the amount of possible mistakes for an implementation. The separation of processor and controller enforces that all parameter changes have to be handled by the host in a defined way. And additionally this way allows the host to store the changes as automation data. Nevertheless there are some more things to consider:

No automated parameter must influence another automated parameter

The prime example for this is the automation of preset changes. A preset change can lead to the change of all 'normal' parameters. So if automation data already has been recorded for these parameters and the preset change is recorded as well: who wins? This question can not be answered and the problem can only be resolved by avoiding it. This is why automation of preset changes is not allowed by default.

Problems

A fix value range from 0.0 to 1.0 simplifies the handling of parameters in some ways, but there are problems:

Automation Recording

Automation recording is performed by the host of course. In doing so it is essential for the host to know the start and the end of a manipulation. Therefore the Plug-in must operate the Steinberg::Vst::IComponentHandler interface in the following way:

Sliders & Knobs
These kind of controls usually control continuous parameters and they are usually operated using the mouse. This common case is most simple to handle: On mouse-click-down call beginEdit (followed by performEdit when the control allows a jump), on mouse-drag call performEdit and on mouse-click-up call endEdit.

Trouble starts with the Mouse wheel: There simply is nothing like a defined start or end when the wheel is operated - each wheel event arrives out of the blue. The only way to enable proper automation recording in this case is the usage of a timer.

  • A dutiful Plug-in implementation should call beginEdit when the first wheel event is handled and start a timer (followed by the first call to performEdit). Further wheel events that arrive inside of the timeout interval are reported with performEdit and the timer is restarted. When the timeout period has passed without further events endEdit should be called and the timer can be removed.

  • But since it is the host's task to record automation data, one can say that it shall be the host's task to care about the timer in this case as well. This is the reason for the exception to the rule:

Mouse wheel events can be reported without beginEdit and endEdit to the host. The host must be prepared to receive a performEdit without a previous call of beginEdit for a parameter and handle the timeout itself.
Buttons / Radio Groups / Popup Menus
These kind of controls usually control discrete parameters and simply switch the state of something. A proper handling is to call beginEdit, performEdit and endEdit in a row. The affected parameter has to be exported to the host with the correct step count since discrete parameters have to be handled differently than continuous parameters in regard to automation.

Mouse wheel handling usually is not supported for buttons, but sometimes for pop-up menus. Discrete parameters do not require the usage of a timer in order to be recorded correctly.

So the Plug-in should call the 3 functions in a row for each wheel event - again the other option is to omit beginEdit and endEdit, only make sure to report the discrete nature of the parameter to the host correctly.
Text Input
For reporting the results of any text input value change, regardless if a continuous or a discrete parameter is affected, always call beginEdit, performEdit and endEdit in a row.

Automation Playback

In VST 3, automation playback is the task of the Plug-in and it is the host's task to provide the automation data. The only way for a parameter change to arrive in the processor is the processing call. Indeed, receiving parameter changes from the edit controller and playing back automation data is one and the same thing.
Of course the need to do all transformations from the normalized GUI representation to the DSP representation produces some overhead. Performing sample accurate automation requires even more overhead, since the DSP value must be calculated for each single sample. While this can not be avoided totally, it is the choice of the Plug-in implementation of how much processing time should be spent on automation accuracy. The host always transmits value changes in a way that allows a sample accurate reconstruction of the underlying automation curve. The Plug-in is responsible for the realization.

GUI playback
The host is responsible for updating the Plug-in GUI when automation data is transmitted to the processor. This is realized by frequent calls of Steinberg::Vst::IEditController::setParamNormalized.


Steinberg::Vst::IParameterChanges
- [host imp]

This interface is used to transmit any changes that shall be applied to paramaters in the current processing block. A change can be caused by GUI interaction as well as automation. They are transmitted as a list of queues (IParamValueQueue) containing only queues for paramaters that actually did change.

See also
IParamValueQueue, ProcessData
Steinberg::Vst::IParamValueQueue
Queue of changes for a specific parameter.
  • [host imp]
  • [released: 3.0.0]

The change queue can be interpreted as segment of an automation curve. For each processing block a segment with the size of the block is transmitted to the processor. The curve is expressed as sampling points of a linear approximation of the original automation curve. If the original already is a linear curve it can be transmitted precisely. A non-linear curve has to be converted to a linear approximation by the host. Every point of the value queue defines a linear section of the curve as a straight line from the previous point of a block to the new one. So the Plug-in can calculate the value of the curve for any sample position in the block.

Implicit Points:
In each processing block the section of the curve for each parameter is transmitted. In order to reduce the amount of points, the point at block position 0 can be omitted.

Jumps:
A jump in the automation curve has to be transmitted as two points: one with the old value and one with the new value at the next sample position.

automation.jpg
See also
IParameterChanges, ProcessData


Back to Contents

Empty

Copyright ©2017 Steinberg Media Technologies GmbH. All Rights Reserved. This documentation is under this license.