1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482
|
TITLE:: VSTPlugin
summary:: load VST plugins as UGens
related:: Classes/VSTPluginController, Classes/VSTPluginNodeProxyController, Classes/VSTPluginDesc, Classes/VSTPluginGui, Guides/HOA_IEM
categories:: UGens>FX
DESCRIPTION::
This UGen represents a single VST plugin instance on the link::Classes/Server::. See the helpfile of link::Classes/VSTPluginController:: for how to control it from the SuperCollider language.
VSTPlugin also has class methods to scan a Server for plugins and cache the info in the Client, see link::#Plugin Management::.
CLASSMETHODS::
PRIVATE:: prQuery, prQueryMsg, prQueryLocal, prQueryRemote, prSearchLocal, prSearchRemote, prMakeDest, prMakeTmpPath, prAddPlugin, prParseIni, prParseInfo, prGetLine, prParseCount, prParseKeyValuePair, kr, platformExtension, reset
METHOD:: ar
create a UGen instance.
note::The method signature has changed in v0.5!::
ARGUMENT:: input
The UGen inputs for the plugin to process.
Possible types:
list::
## a single UGen (= mono)
code::
VSTPlugin.ar(SinOsc.ar(200));
::
## an Array of UGens (= stereo/multichannel)
code::
VSTPlugin.ar([ SinOsc.ar(100), SinOsc.ar(200) ]);
::
## code::nil:: (= no input, e.g. VST instruments).
## an Array link::Classes/Ref:: (= multi-bus, see below)
::
emphasis::Multiple input busses::
Some VST3 plugins have multiple input busses. If you pass an Array of UGens, they will be automatically distributed over several busses.
___
Alternatively, you can pass a link::Classes/Ref:: to an Array of inputs. This allows you to pick a subset of channels for each bus. Also, you can skip a bus with 0 or code::nil::.
code::
// bus 0: 2ch, bus 1: -, bus 2: 1ch
VSTPlugin.ar(`[ [ SinOsc.ar(100), SinOsc.ar(200) ], nil, SinOsc.ar(300) ]);
::
note::You can check the available input busses with link::Classes/VSTPluginDesc#-inputs::.::
ARGUMENT:: numOut
The number of output channels.
In the simple case, this is a fixed number greater than 0.
The result is either a single link::Classes/OutputProxy:: (mono) or an Array of OutputProxies (stereo/multichannel), just like a regular link::Classes/MultiOutUGen::.
code::
// mono output, returns a VSTPlugin
VSTPlugin.ar(numOut: 1);
// stereo output, returns [ OutputProxy, OutputProxy ]
VSTPlugin.ar(numOutput: 2);
::
emphasis::Multiple output busses::
If the plugin has multiple output busses, the UGen outputs will be automatically distributed over several busses.
___
Alternatively, you can pass a link::Classes/Ref:: to an Array of channel numbers. This allows you to pick a subset of channels for each bus. Also, you can skip a bus with 0 or code::nil::.
The result is an Array of output busses, where each bus is an Array of link::Classes/OutputProxy::.
note::Skipped output busses are omitted from the Array!::
code::
// bus 0: 2ch, bus 1: -, bus 2: 1ch
var sig = VSTPlugin.ar(numOut: `[2, nil, 1]);
sig[0]; // bus 0 [ OutputProxy, OutputProxy ]
sig[1]; // bus 2 (bus 1 is omitted!) [ OutputProxy ]
sig.flat; // all bus channels in a row
::
note::You can check the available output busses with link::Classes/VSTPluginDesc#-outputs::.::
ARGUMENT:: bypass
change the bypass state. If bypass is non-zero, then processing is suspended and each input is passed straight to its corresponding output.
table::
## 0 || off (processing)
## 1 || hard bypass; processing is suspended immediately and the plugin's own bypass method is called (if available). Good plugins will do a short crossfade, others will cause a click.
## 2 || soft bypass; if the plugin has a tail (e.g. reverb or delay), it will fade out. This doesn't call the plugin's bypass method, so we can always do a nice crossfade.
::
ARGUMENT:: params
An optional Array of parameter controls in pairs of index and value. Both can be automated.
code::
// 'p1' controls parameter 1.
// 'p2' controls a parameter whose index can be set dynamically with 'idx'.
SynthDef(\test, { arg in, p1, p2, idx;
var sig = VSTPlugin.ar(In.ar(in, 2), 1,
params: [1, p1, idx, p2]);
Out.ar(0, sig);
});
::
You can set the index to a negative value to "unmap" the parameter.
note::emphasis::params:: overrides any automation of the same parameters by link::Classes/VSTPluginController#-set::, but it can itself be overriden with
link::Classes/VSTPluginController#-map::.
::
You can automate parameters with either control and audio rate UGens, but the latter is more CPU expensive and only makes sense
if the plugin actually supports sample accurate automation (some, but not all VST3 plugins).
ARGUMENT:: id
A Symbol which uniquely identifies the UGen within the SynthDef, so it can be found by link::Classes/VSTPluginController::.
note::If this is the only VSTPlugin instance in the SynthDef, the id argument can be omitted.::
code::
(
// two FX in parallel:
SynthDef(\test, { arg bus;
var sig = VSTPlugin.ar(In.ar(in, 2), 2, id: \eq);
sig = VSTPlugin.ar(sig, 2, id: \chorus);
ReplaceOut.ar(out, sig);
}).add;
)
// There are two ways to control individual plugins:
// 1) get individual VSTPluginControllers
(
~synth = Synth(\test, [\in, ~in, \out, ~out]);
~eq = VSTPluginController.new(~synth, \eq).open("myEQ");
~chorus = VSTPluginController.new(~synth, \chorus).open("myChorus");
)
// 2) get Event with VSTPluginControllers mapped to IDs
(
~fx = VSTPluginController.collect(Synth(\test));
~fx.eq.open("myEQ");
~fx.chorus.open("myChorus");
)
::
ARGUMENT:: info
An optional link::Classes/VSTPluginDesc:: instance; the plugin must have been successfully probed (e.g. with link::Classes/VSTPlugin#*search::).
Alternatively, you can provide a plugin emphasis::key:: as a Symbol, in which case the VSTPluginDesc will be taken from the default Server's plugin dictionary.
If you know in advance which VST plugin you want to load, this allows you to use parameter names instead of indices
code::
(
SynthDef(\chorus, { arg bus;
// 'GChorus' is a shortcut for VSTPlugin.plugins['GChorus']
var sig = VSTPlugin.ar(In.ar(bus, 2), 2, params: [Depth: 0.5, Mix: 0.9], info: 'GChorus');
ReplaceOut.ar(bus, sig);
}).add;
)
::
Also, you can omit the code::path:: argument when opening plugins:
code::
~fx = VSTPluginController(Synth(\chorus)).open; // will open 'GChorus'
::
ARGUMENT:: blockSize
Run the plugin with a certain block size (in samples). The default is code::nil:: (= no reblocking).
Some plugins run more efficiently with larger blocksizes. (This is generally true for bridged/sandboxed plugins.) Instead of globally changing the Server block size, you can selectively reblock VSTPlugin instances.
note::Reblocking causes a delay of code::N - M:: samples, where N is the desired block size and M is the Server block size.::
SUBSECTION:: Plugin Management
All VST plugin information is cached in the Client. This is done mainly for performance reasons but it can be also handy for end users
because it's possible to investigate plugins without actually creating any instances.
The plugin info is stored as a link::Classes/VSTPluginDesc:: instance under its key (see link::Classes/VSTPluginDesc#-key::) and can be retrieved with link::#*plugins::.
METHOD:: plugins
get information about (probed) VST plugins on a Server.
ARGUMENT:: server
the Server. If this is code::nil::, the default Server is assumed.
RETURNS:: an link::Classes/IdentityDictionary:: containing the descriptions of all VST plugins on the Server as instances of link::Classes/VSTPluginDesc::.
DISCUSSION::
The dictionary can be simply indexed with plugin keys (see link::Classes/VSTPluginDesc#-key::).
code::
// search in default paths
VSTPlugin.search(s);
VSTPlugin.plugins(s)['AwesomePlugin'].print;
// for the default server this can be shortend to:
VSTPlugin.search;
VSTPlugin.plugins['AwesomePlugin'].print;
::
METHOD:: pluginList
get all available plugins on a Server.
ARGUMENT:: server
the Server. If code::nil::, the default Server is assumed.
ARGUMENT:: sorted
whether the Array should be sorted alphabetically (by name).
RETURNS:: an Array of link::Classes/VSTPluginDesc:: instances.
METHOD:: pluginKeys
get the keys of all plugins on a given Server.
ARGUMENT:: server
the Server. If code::nil::, the default Server is assumed.
RETURNS:: an Array of plugin keys.
DISCUSSION::
This method only considers the keys stored in the plugin descriptions,
not the additional keys in the plugin dictionary.
METHOD:: print
post all available plugins.
ARGUMENT::
the Server. If code::nil::, the default Server is assumed.
DISCUSSION::
The plugins are posted in alphabetical order in the following format:
code::key (vendor) [path]::
SUBSECTION:: Searching for plugins
METHOD:: search
Scan a local or remote Server for VST plugins and cache the info in the Client.
note::The method signature has changed in v0.5!::
ARGUMENT:: server
The server to scan for plugins. If code::nil::, the default Server is used.
ARGUMENT:: dir
an (optional) Array of custom plugin directories.
If code::nil::, the standard VST search paths are used:
table::
## VST 2.x ||
table::
## Windows || list::
## %ProgramFiles%\VSTPlugins
## %ProgramFiles%\Steinberg\VSTPlugins
## %ProgramFiles%\Common Files\VST2
## %ProgramFiles%\Common Files\Steinberg\VST2
::
## macOS || list::
## ~/Library/Audio/Plug-Ins/VST
## /Library/Audio/Plug-Ins/VST
::
## Linux || list::
## ~/.vst
## /usr/local/lib/vst
## /usr/lib/vst
::
::
## VST 3.x ||
table::
## Windows || list::
## %ProgramFiles%\Common Files\VST3
::
## macOS || list::
## ~/Library/Audio/Plug-Ins/VST3
## /Library/Audio/Plug-Ins/VST3
::
## Linux || list::
## ~/.vst3
## /usr/local/lib/vst3
## /usr/lib/vst3
::
::
::
note::here, emphasis::%ProgramFiles%:: stands for "C:\Program Files" on a 64 bit Server and "C:\Program Files (x86)" on a 32 bit Server.::
ARGUMENT:: options
an (optional) Event with advanced search options.
list::
## code::\save:: (Boolean)
write results to the cache file (default: true).
## code::\parallel:: (Boolean)
probe plugins in parallel (default: true).
This can be significantly faster, but it can also make your computer almost unresponsive for the duration of the search because of the full CPU utilization.
## code::\timeout:: (Float)
the number of seconds to wait for a single plugin before it is regarded as being stuck and ignored; default is code::nil:: (= no timeout).
## code::\exclude:: (Array)
a list of directories or files to exclude from the search.
## code::\cacheFileDir:: (String)
cache file directory.
Set this if you want to save the cache file in a custom directory.
::
Example:
code::
VSTPlugin.search(options: ( timeout: 20, parallel: false, save: false, exclude: [ "/plugin/dir/a", "/plugin/dir/b" ]))
::
ARGUMENT:: verbose
post a message for each found plugin.
The message contains the file path, name and probe result ("ok" or error message).
ARGUMENT:: wait
The wait time between OSC messages.
-1 allows an OSC roundtrip between packets.
0 is not safe with UDP, but is probably ok with TCP.
note::This is only relevant for remote Servers (local Servers will send the plugin description via temp files).::
ARGUMENT:: action
a function to be called after the search has finished.
DISCUSSION::
Directories are searched recursively. For each valid VST plugin, the information is stored in a dictionary on the Client
and can be retrieved with its key (see link::#Plugin Management::).
If a plugin can't be probed ("... failed!") it either means it's not a valid VST plugin, dependencies are missing or it has the wrong CPU architecture (and can't be bridged).
A new search doesn't automatically clear the dictionary, but existing keys are overwritten. You can clear the dictionary explicitly with link::#*clear::.
For efficiency, search results are written to a cache file (on the Server's computer) to significantly speed up subsequent searches
(cached plugins don't have to probed again). Many DAWs use a similar strategy. If you want to search directories without updating the cache, set code::save:: to code::false::.
NOTE::
The very first search in a directory usually takes a couple of seconds, but if you have many (heavy) plugins, the process can take significantly longer. However, subsequent searches will finish very quickly because the info has been cached.
::
WARNING::
Shell plugins like "Waves" contain hundreds of (heavy) sub-plugins. On my machine, the very first search takes several minutes(!), so be patient :-)
::
METHOD:: searchMsg
ARGUMENT:: dir
(see above)
ARGUMENT:: options
(see above)
ARGUMENT:: verbose
(see above)
ARGUMENT:: dest
a) nil: don't write search results (the default)
b) String: name of a temp file where the search results should be written to.
c) link::Classes/Buffer:: or bufnum: the plugin will fill the Buffer
on the Server, the Client can then read the data (each float representing a single byte) and free the Buffer.
The Buffer should be initially empty!
RETURNS:: the message for a emphasis::search:: command (see link::#*search::).
DISCUSSION::
Sending the message to the Server will emphasis::not:: update any info in the Client!
Mostly useful for NRT synthesis.
METHOD:: stopSearch
Stop a running search.
ARGUMENT:: server
the Server. If code::nil::, the default Server is assumed.
METHOD:: stopSearchMsg
RETURNS:: the message for a emphasis::stopSearch:: command (see link::#*stopSearch::).
METHOD:: readCache
Read the plugin cache file from a custom directory.
ARGUMENT:: server
the Server. If code::nil::, the default Server is assumed.
ARGUMENT:: dir
the directory containing the cache file.
METHOD:: readCacheMsg
ARGUMENT:: dir
(see above)
RETURNS:: the message for a emphasis::readCache:: command (see link::#*readCache::).
METHOD:: readPlugins
get the descriptions of all locally cached plugins. For this to work, you have to call link::#*search:: at least once (with code::save: true::), then the plugin description will be available without starting a Server.
ARGUMENT:: dir
(optional) cache file directory. If code::nil::, the default cache file location will be used.
RETURNS:: an link::Classes/IdentityDictionary:: containing all plugin descriptions as link::Classes/VSTPluginDesc:: instances.
METHOD:: clear
Deletes all cached plugin descriptions for a given Server.
ARGUMENT:: server
the Server. If this is code::nil::, the default Server is assumed.
ARGUMENT:: remove
whether you want to also remove the cache file.
METHOD:: clearMsg
ARGUMENT:: remove
(see above)
RETURNS:: the message for a emphasis::clear:: command (see link::#*clear::).
DISCUSSION::
Sending the message to the Server will emphasis::not:: clear the Client plugin dictionary!
subsection:: Bridging and Sandboxing
Usually, you can only run plugins with the same CPU architecture as the host application.
Since VSTPlugin v0.4, however, it is possible to run 32-bit plugins on a 64-bit Server and vice versa! Such incompatible plugins will automatically run in a shared subprocess (= bit bridging), which incurs some CPU overhead.
Since VSTPlugin v0.5 it is also possible to run Windows plugins on Linux with Wine.
note::Bridging/sandboxing can also be explictly enabled for native plugins, see the code::mode:: argument in link::Classes/VSTPluginController#-open::.::
For more information, see the emphasis::Bridging/sandboxing:: section in the README.
subsection:: Multithreading
METHOD:: initDSPThreads
Set the number of DSP threads for multithreaded plugin processing (see code::multiThreading:: argument for link::Classes/VSTPluginController#-open::).
By default, this is the number of logical CPUs.
This method only takes effect if it is called emphasis::before:: any (multithreaded) plugins have been opened.
ARGUMENT:: server
the Server. If code::nil::, the default Server is assumed.
ARGUMENT:: numThreads
the number of DSP threads; code::nil:: means default.
METHOD:: initDSPThreadsMsg
ARGUMENT:: numThreads
(see above)
RETURNS:: the message for a emphasis::initDSPThreads:: command (see link::#*initDSPThreads::).
INSTANCEMETHODS::
|