VSTPlugin v0.4 released!

NOTE: Please upgrade to v0.4.1!

This is a new release of VSTPlugin - a UGen to load VST plugins in Supercollider on Windows, macOS and Linux.

Binaries can be downloaded here: https://git.iem.at/pd/vstplugin/-/releases

If possible, please report any issues at https://git.iem.at/pd/vstplugin/issues, otherwise leave a comment here.



  • automatic bit bridging (load 32-bit plugins on a 64-bit Server and vice versa).

  • VSTPluginController.open: mode argument for sandboxing (\sandbox) or bridging (\bridge). Both options allow plugins to crash safely without taking down the Server. This can be handy for buggy/unstable plugins (especially during live shows :slight_smile: ).

  • VSTPluginController.open: multiThreading argument for multithreading (process the plugin in a seperate worker thread to utilize more CPU cores)

  • VSTPlugin.ar: blockSize argument for reblocking. Some plugins might run more efficiently at higher block sizes.

  • VSTPlugin.ar: info argument can now be a symbol (get the plugin from the default Server)

  • VSTPluginController.collect method to get controllers for all VSTPlugin instances in a given SynthDef

  • VSTPluginController.latency to query current latency or VSTPluginController.latencyChanged callback function for latency change

  • VSTPluginController.pluginCrashed callback function for plugin crash (only sandboxed/bridged plugins)

  • VSTPluginController preset methods now also accept preset Events

  • VSTPluginController.preset method returns current preset

Improvements/Bug Fixes

  • VSTPlugin.ar now stores info and id arguments in SynthDef metadata, so they can be serialized to/from disk (e.g. in SynthDef.store )

  • fix VSTPlugin.searchMsg

  • improve general error handling: throw Errors/MethodErrors whenever possible/practical


  • you can only omit the id argument in VSTPlugin.ar if the SynthDef contains a single VSTPlugin instance

  • VSTPluginController preset methods are now async by default

  • VSTPluginDesc: deprecate isSynth and hasEditor in favor of synth and editor


I have just released VSTPlugin v0.4.1 which fixes a critical bug. Please upgrade!

1 Like

Hi @Spacechild1, I tried to update to VSTPlugin 0.4.1 from 0.2.0 but am getting “exception in GraphDef_Recv: UGen ‘VSTPlugin’ not installed.” I just swapped in the new vstplugin-master folder into the same Extensions folder where the old one was and recompiled. The help files do show up in the help window, though. I’m on SC 3.11.0 using macOS 10.14.6. Any obvious reason why this would be happening?

Any obvious reason why this would be happening?

Yes, it seems like you downloaded the source code and dropped it into the extension folder. You have to download the binaries instead (see the link on the top).

1 Like

Hi @Spacechild1,

Love this! Thank you! Is there a way that I can get at the ranges of the parameters that show up in .gui? For example if I wanted to make my own slider with those ranges?

Thank you!


Is there a way that I can get at the ranges of the parameters that show up in .gui ?

@tedmoore VST plugin parameters are always normalized to 0.0 - 1.0.

AFAICS parameters are all normalized 0 to 1, so there’s no need to set the slider’s range. (Edit: Christof’s message appeared while I was writing…)

It might be nice to get the range as a display courtesy for a number box next to the slider… I have no idea if VSTs publish that information to hosts though.


It might be nice to get the range as a display courtesy for a number box next to the slider… I have no idea if VSTs publish that information to hosts though.

It’s tricky and the situation is different for VST2 and VST3.

VST2: you can set the parameter either as a normalized float or as a string representation (the latter is not supported by all plugins). You can’t directly set the parameters as “plain” values, e.g. -60 for -60 dB or 90 for 90% Dry/Wet Mix, but you can obtain a VstParameterProperties struct, which tells you the min/max
values. You could use this info to map the plain values to/from the normalized range. However, from my experience, not all plugins support VstParameterProperties.

VST3: you can set the parameter only as a normalized float, but there are methods to convert normalized values to/from “plain” values or string representations. You can get a ParameterInfo struct to check for the number of steps and step count (in case of a discrete parameter). But these steps do not necessarily correspond to “plain” values, because the latter might use a different range and scale (e.g. logarithmic). This means you can’t naively calculate “plain” values from normalized values and vice versa, you have to use the relevant editor interface methods. From my understanding, the step count is mostly relevant to automation curves in a DAW (so they can snap to discrete steps in the case of discrete parameters).

The only things that work consistently and unambiguously are normalized float values and strings, so I restricted myself to that. Parameter automation via UGen inputs and Busses always has to use normalized floats because I can’t distinguish between “plain” and normalized values (both are just numbers). Regarding the set and get methods, I could add something like a set_plain and get_plain method to set/get plain parameter values, but I’m not sure it would be worth the effort…

However, I could add the number of steps and step count to the parameter infos (see VSTPluginDesc.parameters) and provide helper methods to convert between normalized values and discrete steps.

In the generic GUI editor, I have a text field next to each slider which shows the actual parameter value. Note that this text field is not only a display - you can also enter values! (However, this doesn’t work with all VST2 plugins)

Thanks @jamshark70, that is the question I was trying to ask!

And thank you @Spacechild1 for the detailed response! For what I was thinking, a get_plain and set_plane wouldn’t be necessary. I actually went and checked in the VSTPluginDesc.parameters because I thought I would find some control spec type of info there. Adding what you can might be really useful if anyone is trying to control the VST via something other than the .gui or .editor. That way they could also display scaled values.

Currently, I’m going to go forward just using 0 to 1. It’ll serve my purposes. Thanks!

That way they could also display scaled values.

Not really, the additional parameter info would only help with discrete parameters (e.g. a “mode” parameter with 5 modes). You can’t easily calculate “plain” values from normalized values, because you don’t know the range and scaling. That’s why VST3 plugins have a special method for converting between “plain” and normalized parameter values.

1 Like

Amazing plugin that I am excited to use. But VSTPlugin.search is showing me nothing (windows 10). Is there a way to manually configure or something? My VSTs are in the usual place “/CommonFiles/VST3…”


oh the server has to be running for the search to work! My bad. I’ll leave the post up in case anyone runs into another issue and stumbles across this thread. Feel free to delete if you think that’s appropriate.


greetings I get the following error after doing controller.readProgram

any idea what this means? TIA!

ERROR: Primitive '_BasicPut' failed.
Index out of range.
Instance of Array {    (0x7fb15a975e78, gc=DC, fmt=01, flg=00, set=02)
  indexed slots [1]
      0 : "SynfulOrchestra"
		arg this = <instance of PrimitiveFailedError>
		arg this = nil
		arg error = <instance of PrimitiveFailedError>
		arg this = <instance of Thread>
		arg error = <instance of PrimitiveFailedError>
		arg this = <instance of PrimitiveFailedError>
		arg this = [*1]
	< FunctionDef in Method VSTPluginController:init >
		arg msg = [*20]
		var index = -2138638976
		var name = "SynfulOrchestra"
		arg this = <instance of OSCArgsMatcher>
		arg testMsg = [*20]
		arg time = 82327.549499717
		arg addr = <instance of NetAddr>
		arg recvPort = 57120
		var msgArgs = [*19]
		arg this = <instance of OSCFuncAddrMessageMatcher>
		arg msg = [*20]
		arg time = 82327.549499717
		arg testAddr = <instance of NetAddr>
		arg recvPort = 57120
	< FunctionDef in Method Collection:collectInPlace >
		arg item = <instance of OSCFuncAddrMessageMatcher>
		arg i = 0
		arg this = [*2]
		arg function = <instance of Function>
		var i = 0
		arg this = [*2]
		arg function = <instance of Function>
		arg this = <instance of FunctionList>
		arg args = [*4]
		var res = nil
		arg this = <instance of OSCMessageDispatcher>
		arg msg = [*20]
		arg time = 82327.549499717
		arg addr = <instance of NetAddr>
		arg recvPort = 57120
		arg this = <instance of Main>
		arg time = 82327.549499717
		arg replyAddr = <instance of NetAddr>
		arg recvPort = 57120
		arg msg = [*20]
^^ The preceding error dump is for ERROR: Primitive '_BasicPut' failed.
Index out of range.
RECEIVER: [ SynfulOrchestra ]

@semiquaver I have sent you a PM, in case you haven’t seen it.