VSTPluginController:
Filter:
vstplugin/Classes (extension) | Server > Abstractions

VSTPluginController
ExtensionExtension

Client-side representation of a VSTPlugin UGen instance

Description

This class is used to control a specific VSTPlugin instance in a Synth, so you can open plugins, automate parameters, change programs, send MIDI messages, etc.

Have a look at the examples at the bottom!

Introduction

Here's a quick example showing a simple insert effect on a 2-channel audio bus:

If you have more than one instance of VSTPlugin in your SynthDef, you need to give them unique IDs so that VSTPluginController can find the right instance:

With JITLib you have to use VSTPluginNodeProxyController:

Parameter Automation

There are three different ways to automate plugin parameters (listed with increasing precedence):

Use -get and -getn to obtain current parameter values:

-set, -map and -get also accept parameter names instead of indices:

Preset Management

Select built-in FX programs with -program:

The easiest way to manage user presets are the -savePreset and -loadPreset methods. Because they use standardized preset folder locations, presets can be simply referred to by name:

Internally, preset files use the standard .fxp/.fxp (VST2) or .vstpreset (VST3) format, recognized by most DAWs and VST hosts. You can save presets to your own folders with the following methods:

It's also possible to get/set the raw plugin state as an Int8Array:

The data has the same binary format as the preset files. You can use these methods to build your own preset management!

GUI

Generally, there are two kind of GUIs:

Scheduling

Generally, synchronous methods, like -set or -map, simply send an OSC message to the Server. This is fine for interactive use, but if you need accurate timing, commands have to be scheduled as OSC bundles (see also Scheduling and Server timing).

Here are two basic ways how to schedule methods with Server latency:

Sequencing

VSTPlugin defines two custom Event types which are typically used with Pbind. Like with (most) other Event types, commands are scheduled as OSC bundles with Server latency.

\vst_set
sets one or more plugin parameters to the specified values; the interface is similar to \set.
\vstthe VSTPluginController instance
\paramsan (optional) Array of parameter names or indices that should be looked up in the Event

a) Explicit look up (names or indices):

b) Automatic lookup (indices only)

This is slightly less efficient than explicit lookup.

WARNING: Before VSTPlugin v0.6, parameter names have been looked up automatically if you omitted the \params key. This feature has been removed!

Pattern composition with automatic lookup is straight forward:

Pattern composition with explicit lookup also possible, but less flexible:

See Automation for more examples.

\vst_midi
send MIDI messages; the interface is very similar to the \midi Event type.

Event keys:

\vstthe VSTPluginController instance
\midicmdthe MIDI method (see below)
\chanthe MIDI channel; the default is 0
\midinoteMIDI pitch for \noteOn, \noteOff and \polyTouch;

may be a fractional value (= microtonal), see VSTPluginMIDIProxy: -noteOn.

\ampamplitude (0.0 - 1.0) for \noteOn and \noteOff
\ctlNumCC number for \control
\controlCC value for \control
\valvalue argument for \touch and \bend
\polyTouchtouch value for \polyTouch
\progNumprogram number for \program
\arrayUInt8Array for \sysex

Possible values for \midicmd:

\noteOnnote-on message (= default);

automatically schedules \noteOff messages based on the note duration.

(This can be disabled by setting \hasGate to false.)

\noteOffnote-off message
\controlCC message
\bendpitch bend
\touchchannel after-touch
\touchpolyphonic after-touch
\programprogram change
\allNotesOffturn all notes off
\sysexSysEx message

Each \midicmd has a corresponding method in VSTPluginMIDIProxy.

See Pattern Guide 08: Event Types and Parameters: MIDI output for more details on MIDI commands.

See VST Instruments for examples.

NOTE: Always prefer \vst_midi over \midi because the latter doesn't schedule OSC bundles!

Tip: You can play Pbinds of type \vst_midi and \vst_set in parallel with Ppar.

Realtime Safety

VSTPlugin tries its best to be as realtime safe as possible. Plugins are always opened/closed asynchronously in the NRT thread. Some methods, like -loadPreset and -savePreset, offer two options via the async parameter:

  1. async: true means that the plugin method is called on the NRT resp. UI thread and will never block the Server. However, plugin processing is temporarily suspended and you can't call other methods until the command has finished.
  2. async: false means that the plugin method is simply called on the RT thread. The advantage is that the command is performed synchronously and plugin processing doesn't have to be suspended. Depending on the plugin, this might be just fine - or block the Server. You have to test yourself!
NOTE: If the plugin is opened with the VST GUI editor, the async option is automatically set to true because of thread safety concerns.

Class Methods

.new

Create a new VSTPluginController for a given Synth.

Arguments:

synth

the Synth containing the VSTPlugin you want to control.

id

a Symbol which uniquely identifies the VSTPlugin in the SynthDef.

NOTE: If this is the only VSTPlugin instance in the SynthDef, the id argument can be omitted.
synthDef

the synth's SynthDef. You can omit this argument if the SynthDef has been added to the global SynthDescLib, e.g. with SynthDef: -add or SynthDef: -store. In this case, the SynthDef will be automatically deduced from the synth argument.

wait

the default wait time, see -wait.

Discussion:

Initially, no VST plugin is loaded and the UGen is automatically bypassed (i.e. the input is just passed through).

.collect

Same as -new, but returns an Event of VSTPluginControllers, with their IDs used as keys. This is useful if you have a SynthDef containing several VSTPlugin instances.

Arguments:

synth

the Synth, see -new

ids

an Array of IDs referring to VSTPlugin instances in the SynthDef, or nil (= collect all).

synthDef

the SynthDef (optional), see -new

wait

the default wait time, see -wait.

Discussion:

Instance Methods

.open

open a VST plugin.

Arguments:

path

the plugin key or file path.

- Opening plugins by key requires that the plugin has already been probed (e.g. as a result of VSTPlugin: *search).

- Alternatively, you can use a file path (with or without extension). Relative paths are resolved to the standard VST directories (see VSTPlugin: *search); this is done recursively, which means you don't necessarily have to specify any subfolders.

NOTE: This method only works for files which contain a single plugin (all VST 2.x plugins - except for shell plugins - and many VST 3 plugins).

- If the VSTPlugin UGen holds a plugin description (see VSTPlugin: *ar), the path argument can be deduced and therefore omitted.

editor

enable/disable the VST plugin editor.

NOTE: On macOS this only works with SuperCollider 3.11 and above!
NOTE: Some (buggy) plugins don't work correctly without the VST editor.
verbose

post the plugin info to the console if loaded successfully.

action

a function that will be called with the object itself and a Boolean (success/fail) when the operation has completed.

NOTE: You must not use Server: -sync to wait for completion! If you prefer to write sequential code instead of callbacks, you may use a Condition resp. CondVar and signal it from the action function.
multiThreading

process the plugin in a seperate worker thread to utilize more CPU cores. See also VSTPlugin: *initDSPThreads.

NOTE: This option is ignored for Supernova, which already offers multithreading with ParGroup.
NOTE: Multithreading introduces a delay of 1 block!
mode

select a run mode.

\autonormal mode (default).
\sandboxrun the plugin in a dedicated subprocess. This means that the plugin can safely crash without taking down the whole Server! This is useful for buggy plugins or safe experimentation.
\bridgerun the plugin in a shared subprocess. This uses less memory and possibly less CPU, but if one plugin crashes, it will inevitably take down all other plugins in the same process.

NOTE: All run modes except for \auto incur some fixed CPU overhead, which is less significant for larger blocksizes (see ServerOptions: -blockSize or the blockSize argument in VSTPlugin: -ar).

See also VSTPlugin: Bridging and Sandboxing.

Discussion:

This method is realtime-safe because the VST plugin is opened asynchronously (in the NRT thread).

.openMsg

Arguments:

path

the plugin name/key or file path. Relative paths are resolved to the standard VST directories.

If the VSTPlugin UGen holds a plugin description (see VSTPlugin: *ar), the path argument can be deduced and therefor ommitted.

editor

request the VST editor.

multiThreading

enable multithreading.

mode

select a run mode.

Returns:

the message for an open command (see -open).

.isOpen

Returns:

whether a plugin is currently open.

.close

.closeMsg

close the current plugin (but don't free the Synth!). You can open another plugin later.

Discussion:

This will automatically bypass the plugin (i.e. the input is just passed through).

Just like -open, this method is realtime-safe.

.pluginCrashed

a Function or FunctionList to be called when the plugin subprocess crashes.

Discussion:

You could use this callback to automatically reopen the plugin, for example.

NOTE: This is only meant for bridged or sandboxed plugins, because a normal plugin would simply crash the server.

.browse

open the plugin browser dialog.

.editor

.editorMsg

show/hide the VST editor window.

Discussion:

The plugin has to be opened with editor: true.

NOTE: On macOS this only works on SuperCollider 3.11 and above!

.moveEditor

.moveEditorMsg

move the editor window to the given position.

.resizeEditor

.resizeEditorMsg

resize the editor window to the given width and height.

NOTE: This only works for VST3 plugins with a resizable editor.

.gui

creates a generic Qt GUI (see VSTPluginGui).

Arguments:

parent

the parent. If nil, the GUI is created in a new toplevel window.

bounds

the bounds.

params

show/hide parameters. Set to false, if you only need to show the preset manager!

Returns:

a new VSTPluginGui instance.

.info

Returns:

the (static) plugin description (see VSTPluginDesc).

.latency

Returns:

the current processing latency in samples.

NOTE: The reported value includes the additional latency caused by multithreading and reblocking (see the multiThreading and blockSize arguments for -open).

.latencyChanged

a Function or FunctionList to be called when the plugin's processing latency changes. The function receives the new latency as its only argument. See also -latency.

.reset

.resetMsg

reset the plugin state.

Arguments:

async

see Realtime Safety.

Discussion:

Depending on the plugin, reset can involve expensive operations, like clearing a large delay line, and might not be realtime-safe, so be careful with setting async to false.

.synth

Returns:

the Synth containing the currently controlled VSTPlugin instance.

.synthIndex

Returns:

the index of the VSTPlugin instance within the Synth.

.wait

the wait time between OSC messages (in seconds).

Discussion:

-1 allows an OSC roundtrip between packets.

0 is not safe with UDP, but is probably ok with TCP.

Some methods may require lots of OSC messages (e.g. when changing programs, the UGen has to send the new state of all parameters). VSTPluginController waits for the given time after a certain number of bytes to avoid messages getting dropped. This is mostly relevant for UDP connections, especially for remote Servers, high network traffic and plugins with a large number of parameters.

The wait time can be changed anytime.

Parameters

.numParameters

Returns:

the number of parameters.

.set

.setMsg

Set plugin parameters.

Discussion:

This method expects pairs of parameter index/name and value. Each value should be either a number between 0.0 and 1.0 or a string/symbol.

NOTE: Some plugins don't support setting parameters by strings, others only allow it for certain parameters.

NOTE: The parameter(s) will be automatically unmapped from any control bus, see -map.

With setMsg you can schedule sample accurate parameter changes for plugins which support this (some, but not all VST3 plugins).

.setn

.setnMsg

set sequential ranges of parameters.

Discussion:

This method expects pairs of parameter index and Array of values (numbers or strings/symbols), see -set.

.map

map parameters to control or audio busses.

Discussion:

This methods expects pairs of parameter index/name and bus. In case of multi-channel busses the channels are mapped to a sequential range of parameters starting at the given index/name.

The bus argument can be simply an integer referring to a control bus. If you want to map an audio bus, you have to explicitly pass an audio Bus object.

Parameters are updated whenever the data in the bus changes.

NOTE: Only map to an audio bus if you need sample accurate automation and the plugin actually supports it (some, but not all VST3 plugins).

Each parameter can only be mapped to one control bus channel at the time.

NOTE: setting a parameter with -set or -setn will automatically unmap it from any control bus.
NOTE: map will override automation via UGen arguments.

.mapMsg

returns a bundle containing control and/or audio bus mapping messages. Takes the same arguments as map.

.mapn

.mapnMsg

map parameters to control busses. The arguments are triples of parameter index/name, control bus index and number of channels. See map.

.mapan

.mapanMsg

map parameters to audio busses. The arguments are triples of parameter index/name, audio bus index and number of channels. See map.

.unmap

.unmapMsg

Unmap parameters from a control bus.

Discussion:

Pass all the parameters you want to unmap. Calling the method without arguments will unmap all parameters.

.get

get the current value of a plugin parameter.

Arguments:

index

the index/name of the parameter.

action

a function that will receive the requested value.

Discussion:

.getn

get a sequential range of parameter values.

Arguments:

index

the starting index/name.

count

the number of sequential parameter values. -1 will return all parameters starting from index.

action

a function that will receive the requested values as an Array.

Discussion:

.parameterAutomated

a Function or FunctionList to be called when parameters are automated in the VST editor.

Discussion:

The action receives the parameter index and value. This can be helpful if you want to know the index of a parameter in the editor.

NOTE: Some plugins link parameters, so that changing one parameter will lead to several other parameters being "automated". In that case it is not possible to determine which parameter has been automated manually.

.parameterCache

An Array containing the current state ([value, display]) of each parameter. Only valid if a plugin is currently loaded!

Programs

VST plugins often contain factory presets which are called programs.

NOTE: Some VST2 plugins allow to change the name and state of the built-in programs and save all programs as a bank file (see -writeBank).

.numPrograms

Returns:

the number of available built-in plugin programs.

.program

.programMsg

select a built-in program or get the current program number.

.programName

.programNameMsg

get/set the name of the current program (VST2 only).

.programCache

An Array containing the current name of each program. Only valid if a plugin is currently loaded!

Presets

Simple preset management.

Presets are stored at pre-defined file system locations, so they can be simply referred to by name or index (see VSTPluginDesc: -presets).

NOTE: Since the VST3 preset locations are actually standardized, any VST3 presets created with VSTPlugin should be available in other applications and vice versa.
WARNING: This only works with local Servers (for now)!

.loadPreset

.savePreset

load/save VST presets.

Arguments:

preset

a preset Event, name or index (see VSTPluginDesc: -presets).

You can create a new preset by passing a non-existing preset name to savePreset.

action

a function that will be called with the object itself and a Boolean (success/fail) when the operation has completed.

async

where to perform the plugin method, see Realtime Safety.

NOTE: The file IO itself is always performed asynchronously!

.loadPresetMsg

Create an OSC message for loading a preset. See also -readProgramMsg.

NOTE: There is no equivalent savePresetMsg method because we wouldn't be able to update the preset list.

Arguments:

preset

a preset Event, name or index (see VSTPluginDesc: -presets).

async

see above.

.deletePreset

delete a VST preset.

Arguments:

preset

the preset Event, name or index.

Returns:

true on success or false on failure.

.renamePreset

delete a VST preset.

Arguments:

preset

the old preset Event, name or index

name

the new preset name.

Returns:

true on success or false on failure.

.preset

Returns:

the current preset (Event) or nil (= no preset).

Preset Files

Read/write VST2 .fxp/.fxb files or VST3 .vstpreset files.

This is useful if you want to save your presets to a non-standard location, e.g. relative to your project.

The preset files are in a standard format which is recogized by every decent DAW or VST host. This means you can freely exchange presets between different applications!

.readProgram

.writeProgram

read/write program files.

Arguments:

path

an absolute file path.

The file extension is arbitrary but it is good practice to use .fxp for VST2 program files and .vstpreset for VST3 preset files.

action

a function that will be called with the object itself and a Boolean (success/fail) when the operation has completed.

async

where to perform the plugin method, see Realtime Safety.

NOTE: The file/buffer IO itself is always performed asynchronously!

.writeBank

.readBank

same as above, but for VST2 .fxb bank files.

.readProgramMsg

.writeProgramMsg

Create an OSC message for reading/writing a program file, or exchanging program data via a Buffer.

Arguments:

dest
Stringpreset file to be read or written.
Buffer or Integerexchange program data between a Client and a (remote) Server via a Buffer.

readProgramMsg: the Buffer should contain the preset data with each float representing a single byte; it has to be allocated and freed by the Client.

writeProgramMsg: the Buffer should be initially empty. The UGen will fill the Buffer on the Server, the Client can then read the data and free the Buffer.

async

see above.

Returns:

the OSC message.

.readBankMsg

.writeBankMsg

same as above, but for VST2 .fxb bank files.

Preset Data

Set/get the raw plugin state. This is useful if you want to build your own custom preset system.

NOTE: The Bank methods only work with VST2 plugins.

.setProgramData

.setBankData

set the new program/bank state as an Int8Array.

Arguments:

data

the raw plugin data.

action

a function that will be called with the object itself and a Boolean (success/fail) when the operation has completed.

async

where to perform the plugin method, see Realtime Safety.

NOTE: The data transfer itself is always performed asynchronously!

.getProgramData

.getBankData

get the current program/bank state as an Int8Array.

Arguments:

action

a function that will receive the data - or nil if the method failed.

async

see above.

Discussion:

Internally, the program data is exchanged via temp files.

WARNING: This only works with a local Server!

.sendProgramData

.sendBankData

send the new program/bank state as an Int8Array.

Arguments:

data

the raw plugin data.

wait

temporarily overwrites -wait if not nil.

action

a function that will be called with the object itself and a Boolean (success/fail) when the operation has completed.

async

where to perform the plugin method, see Realtime Safety.

NOTE: The data transfer itself is always performed asynchronously!

.receiveProgramData

.receiveBankData

receive the current program/bank state as an Int8Array.

Arguments:

wait

temporarily overwrites -wait if not nil.

timeout

the number of seconds to wait before giving up.

action

a function that will receive the data.

async

see above.

Discussion:

Contrary to -setProgramData, -getProgramData etc., the methods above also work with remote Servers because the data is streamed via OSC messages. This means it is not 100% reliable when using UDP.

MIDI

.midi

MIDI interface for VSTPluginController.

Returns:

an instance of VSTPluginMIDIProxy.

.sendMidi

.sendMidiMsg

send a raw MIDI message with 2-3 bytes (status, data1, data2) and an optional detune argument in cent (not supported by all VST instruments!). MIDI messages can be scheduled sample accurately when sent as bundles!

.sendSysex

.sendSysexMsg

send a system exclusive message as an Int8Array.

.midiReceived

a Function or FunctionList to be called when receiving MIDI messages from the plugin.

Discussion:

The 3 bytes of the MIDI message are passed as invidual arguments:

.sysexReceived

a Function or FunctionList to be called when receiving SysEx messages from the plugin.

Discussion:

The SysEx data is passed to the action as an Int8Array.

Transport

.setPlaying

.setPlayingMsg

set the transport playing state to true or false. Only necessary for VST plugins which do some kind of sequencing.

WARNING: Transport playback is disabled by default!

.setTempo

.setTempoMsg

set the tempo in BPM (beats per minute).

.setTimeSignature

.setTimeSignatureMsg

set the time signature, e.g. 3/4 -> num = 3, denom = 4.

.setTransportPos

.setTransportPosMsg

set the current transport position (in quarter notes).

.getTransportPos

get the current transport position (in quarter notes).

Arguments:

action

a function that will receive current transport position.

VST2 only

.canDo

query the plugin for special capabilities.

Arguments:

what

a string describing the capability. Some of these are documented in the VST SDK, but others are not.

action

a function that will be called with an Integer result.

1yes
-1no
0don't know

.vendorMethod

.vendorMethodMsg

Access special functionality of a plugin which is not available via the standard parameter interface. Check the documentation of the plugin to see what kind of data it expects.

Arguments:

index

an Integer.

value

an Integer.

ptr

some arbitrary data as an Int8Array.

opt

a Float.

action

a function that will be called with an Integer result. The meaning depends on the VST plugin.

async

see Realtime Safety.

Examples

The following code is needed for most examples:

Serial FX chains

How to build a serial FX chain on an audio bus:

You can also create fixed FX chains by using several VSTPlugins inside a SynthDef:

Master FX section

This is how you would create a simple master FX section:

Automation

Automate parameters via control busses

NOTE: Parameter automation will not be visible in the Qt GUI (due to performance reasons)

Automate parameters inside the SynthDef:

Automate parameters with a Pbind of type \vst_set:

VST Instruments

You can easily play VST instruments with a Pbind of event type \vst_midi:

Non-Realtime Synthesis

Many methods of VSTPluginController have a corresponding *Msg version, returning a Server message which can be added to a Score for non-realtime synthesis.

The following code snippet will create a short soundfile with two random melodies played by VST instruments and processed with VST effects; it can be executed in a single block.