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!
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:
There are three different ways to automate plugin parameters (listed with increasing precedence):
params
argument of VSTPlugin: *ar
Use -get and -getn to obtain current parameter values:
-set, -map and -get also accept parameter names instead of indices:
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!
Generally, there are two kind of GUIs:
This will run a native window on the Server (in a seperate thread).
You can change parameters by moving the sliders or entering values into the text fields (don't supported by all plugins). Additionally, you can browse for plugins, select programs and read/write preset files. See -gui and VSTPluginGui for more information.
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:
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
\set
.\vst | the VSTPluginController instance |
\params | an (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.
\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
\midi
Event type.
Event keys:
\vst | the VSTPluginController instance |
\midicmd | the MIDI method (see below) |
\chan | the MIDI channel; the default is 0 |
\midinote | MIDI pitch for \noteOn , \noteOff and \polyTouch ;
may be a fractional value (= microtonal), see VSTPluginMIDIProxy: -noteOn. |
\amp | amplitude (0.0 - 1.0) for \noteOn and \noteOff |
\ctlNum | CC number for \control |
\control | CC value for \control |
\val | value argument for \touch and \bend |
\polyTouch | touch value for \polyTouch |
\progNum | program number for \program |
\array | UInt8Array for \sysex |
Possible values for \midicmd
:
\noteOn | note-on message (= default);
automatically schedules (This can be disabled by setting |
\noteOff | note-off message |
\control | CC message |
\bend | pitch bend |
\touch | channel after-touch |
\touch | polyphonic after-touch |
\program | program change |
\allNotesOff | turn all notes off |
\sysex | SysEx 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.
\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.
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:
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.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!async
option is automatically set to true
because of thread safety concerns.Create a new VSTPluginController for a given Synth.
synth | |
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. |
Initially, no VST plugin is loaded and the UGen is automatically bypassed (i.e. the input is just passed through).
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.
synth |
the Synth, see -new |
ids |
an Array of IDs referring to VSTPlugin instances in the SynthDef, or |
synthDef |
the SynthDef (optional), see -new |
wait |
the default wait time, see -wait. |
open a VST plugin.
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 | ||||||
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.
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. |
This method is realtime-safe because the VST plugin is opened asynchronously (in the NRT thread).
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 |
editor |
request the VST editor. |
multiThreading |
enable multithreading. |
mode |
select a run mode. |
the message for an open command (see -open).
whether a plugin is currently open.
close the current plugin (but don't free the Synth!). You can open another plugin later.
This will automatically bypass the plugin (i.e. the input is just passed through).
Just like -open, this method is realtime-safe.
a Function or FunctionList to be called when the plugin subprocess crashes.
You could use this callback to automatically reopen the plugin, for example.
open the plugin browser dialog.
show/hide the VST editor window.
The plugin has to be opened with editor: true
.
move the editor window to the given position.
resize the editor window to the given width and height.
creates a generic Qt GUI (see VSTPluginGui).
parent |
the parent. If |
bounds |
the bounds. |
params |
show/hide parameters. Set to |
a new VSTPluginGui instance.
the (static) plugin description (see VSTPluginDesc).
the current processing latency in samples.
multiThreading
and blockSize
arguments for -open).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 the plugin state.
async |
see Realtime Safety. |
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
.
the wait time between OSC messages (in seconds).
-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.
the number of parameters.
Set plugin parameters.
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.
With setMsg
you can schedule sample accurate parameter changes for plugins which support this (some, but not all VST3 plugins).
set sequential ranges of parameters.
This method expects pairs of parameter index and Array of values (numbers or strings/symbols), see -set.
map parameters to control or audio busses.
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.
Each parameter can only be mapped to one control bus channel at the time.
map
will override automation via UGen arguments.returns a bundle containing control and/or audio bus mapping messages. Takes the same arguments as map
.
map parameters to control busses. The arguments are triples of parameter index/name, control bus index and number of channels. See map.
map parameters to audio busses. The arguments are triples of parameter index/name, audio bus index and number of channels. See map.
Unmap parameters from a control bus.
Pass all the parameters you want to unmap. Calling the method without arguments will unmap all parameters.
get the current value of a plugin parameter.
index |
the index/name of the parameter. |
action |
a function that will receive the requested value. |
get a sequential range of parameter values.
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. |
a Function or FunctionList to be called when parameters are automated in the VST editor.
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.
An Array containing the current state ([value, display]
) of each parameter. Only valid if a plugin is currently loaded!
VST plugins often contain factory presets which are called programs.
the number of available built-in plugin programs.
select a built-in program or get the current program number.
get/set the name of the current program (VST2 only).
An Array containing the current name of each program. Only valid if a plugin is currently loaded!
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).
load/save VST presets.
preset |
a preset Event, name or index (see VSTPluginDesc: -presets). You can create a new preset by passing a non-existing preset name to |
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! |
Create an OSC message for loading a preset. See also -readProgramMsg.
savePresetMsg
method because we wouldn't be able to update the preset list.preset |
a preset Event, name or index (see VSTPluginDesc: -presets). |
async |
see above. |
delete a VST preset.
preset |
the preset Event, name or index. |
true
on success or false
on failure.
delete a VST preset.
preset |
the old preset Event, name or index |
name |
the new preset name. |
true
on success or false
on failure.
the current preset (Event) or nil
(= no preset).
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!
read/write program files.
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! |
same as above, but for VST2 .fxb bank files.
Create an OSC message for reading/writing a program file, or exchanging program data via a Buffer.
dest |
| ||||
async |
see above. |
the OSC message.
same as above, but for VST2 .fxb bank files.
Set/get the raw plugin state. This is useful if you want to build your own custom preset system.
set the new program/bank state as an Int8Array.
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! |
get the current program/bank state as an Int8Array.
action |
a function that will receive the data - or |
async |
see above. |
Internally, the program data is exchanged via temp files.
send the new program/bank state as an Int8Array.
data |
the raw plugin data. |
wait |
temporarily overwrites -wait if not |
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! |
receive the current program/bank state as an Int8Array.
wait |
temporarily overwrites -wait if not |
timeout |
the number of seconds to wait before giving up. |
action |
a function that will receive the data. |
async |
see above. |
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.
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!
send a system exclusive message as an Int8Array.
a Function or FunctionList to be called when receiving MIDI messages from the plugin.
The 3 bytes of the MIDI message are passed as invidual arguments:
a Function or FunctionList to be called when receiving SysEx messages from the plugin.
The SysEx data is passed to the action as an Int8Array.
set the transport playing state to true or false. Only necessary for VST plugins which do some kind of sequencing.
set the tempo in BPM (beats per minute).
set the time signature, e.g. 3/4 -> num = 3, denom = 4.
set the current transport position (in quarter notes).
get the current transport position (in quarter notes).
action |
a function that will receive current transport position. |
query the plugin for special capabilities.
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.
|
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.
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. |
The following code is needed for most examples:
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:
This is how you would create a simple master FX section:
Automate parameters via control busses
Automate parameters inside the SynthDef:
Automate parameters with a Pbind of type \vst_set
:
You can easily play VST instruments with a Pbind of event type \vst_midi
:
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.