VSTPlugin v0.1.0 released!

I’m happy to announce the first stable release of VSTPlugin!





(for the Linux users: in case the pre-built binaries don’t work because of a C++ ABI mismatch, consider building from source)

If possible, send bug reports to https://git.iem.at/pd/vstplugin/issues (needs an GitHub or gmail account) because it’s easier for me to track them. Otherwise just post them here.


VSTPlugin v0.1.0 is largely compatible to the last test release (VstPlugin pre-release) but the naming convention has changed from Vst to VST, e.g. VstPlugin => VSTPlugin. Better late than never :slight_smile:.

Other important changes/additions:

  • plugins are now probed in a seperate process, so opening a bad plugin shouldn’t crash the Server.
  • searched plugins are now simply stored by their name (instead of the relative file path). Subfolders are still searched but the folder names are not prepended anymore. This means you can have “SomePlugin” anywhere in your search paths and.open("SomePlugin") will just work.
    Another advantage is that the actual file name can differ across platforms and architectures because the plugin name is platform independent (e.g. “SomePlugin.vst”, “SomePlugin.so”, “SomePlugin_win32.dll” and “SomePlugin_x64.dll” can all be opened as “SomePlugin”).
    In the (rather unlikely) case of nameclashes, you have to resort to opening the plugin via its file path.

thanks for all your effort!

oooh, quite exciting!

Here some more examples I’d like to share, Patterns, LFO control and combined with the combo organ and a light reverb, related to examples given here:


1.) VST Instrument LFO control

// Download ComboV organ, move to VST directory


SynthDef(\vst_pb, { |out = 0, pitchBend = 0.5, pan|
	var sig = VSTPlugin.ar(
		// do pitchbend for all pitches
		params: ([(11..22), pitchBend ! 12]).flop.flat
	Out.ar(out, Pan2.ar(sig, pan));

// start 2 Synths

~synths = { Synth(\vst_pb) } ! 2;

~ctrls = ~synths.collect { |x| VSTPluginController(x) };

// define your path
~path = "/Library/Audio/Plug-Ins/VST/ComboV";

// for some reason two must not be done at once

~ctrls[0].open(~path, action: { ~ctrls[1].open(~path) });

~buses = { Bus.control(s, 1) } ! 2;

p = Pbind(
    \type, \midi,
	\midiout, ~ctrls[0].midi,
	\legato, 1.5,
	\dur, 3,
	\midinote, Pxrand((48..70), inf)

q = Pbind(\midinote, Pxrand((71..90), inf), \midiout, ~ctrls[1].midi) <> p;

// set panning LR
~synths[0].set(\pan, -1);
~synths[1].set(\pan, 1);

// map pitchBend to buses
~synths[0].map(\pitchBend, ~buses[0]);
~synths[1].map(\pitchBend, ~buses[1]);

// start Patterns
x = Ptpar([0, p, 1.5, q]).play

// phase-shifted vibrato via LFOs that play to buses
~pitchBends = [
	{ Out.kr(~buses[0], SinOsc.kr(SinOsc.kr(0.05, -pi/2).curverange(0.1, 20, 5), -pi/2).range(0, 1)) }.play,
	{ Out.kr(~buses[1], SinOsc.kr(SinOsc.kr(0.05, pi/2).curverange(0.1, 20, 5), -pi/2).range(0, 1)) }.play

// cleanup





2.) VST FXs

light reverb, download and install (Windows and OSX)


// reverb fx:
SynthDef.new(\reverb, { arg out, in;
    Out.ar(out, VSTPlugin.ar(In.ar(in, 2), 2));

// open 2 DX Reverbs with guis > need two fx buses
~fxBus1 = Bus.audio(s, 2);
~fxBus2 = Bus.audio(s, 2);
~fx1 = VSTPluginController(~vstFx1 = Synth(\reverb, [in: ~fxBus1]));
~fx2 = VSTPluginController(~vstFx2 = Synth(\reverb, [in: ~fxBus2]));

// SynthDef for sequence 1
SynthDef(\sawPerc_2ch, { |out, freq = 400, att = 0.005, rel = 0.05,
	amp = 0.5, pan = 0|
	var sig = Pan2.ar(Saw.ar(freq, amp), pan);
		sig * EnvGen.ar(Env.perc(att, rel), doneAction: 2)

p = Pbind(
	\instrument, \sawPerc_2ch,
	\amp, 0.5,
	\out, ~fxBus1,
	\pan, Pwhite(-1.0, 1),
	\dur, Pstutter(Pwhite(1, 4), Prand([0.2, 0.1, 0.1], inf)),
	\att, Pwhite(0.005, 0.01),
	\rel, Pwhite(0.01, 0.05),
	\midinote, Pstutter(Pwhite(1, 4), Pwhite(45, 65))

x = p.play(quant: 0.1)

// VST for sequence 2

// vsti with pan option
SynthDef(\vst, { |out = 0, pan = 0|
	var sig = VSTPlugin.ar(nil, 1);
	Out.ar(out, Pan2.ar(sig, pan));

// start Synth und controller
// play to bus

~vstSrc = Synth(\vst, [out: ~fxBus2]);

~ctrl = VSTPluginController.new(~vstSrc);

// load organ instrument from your path and open gui



// MIDI Pattern

// for syncing (MIDI vs OSC latency!)
~lag = 0.09;

q = Pbind(
    \type, \midi,
    \midiout, ~ctrl.midi,
	\dur, Pstutter(Pwhite(1, 4), Prand([0.2, 0.1, 0.1], inf)),
	\out, ~fxBus2,
	\legato, 0.3,
	\lag, Pfunc { ~lag },
	// high values -> rests
	\midinote, Pstutter(Pwhite(1, 4), Pwhite(70, 100))

y = q.play(quant: 0.1)

// change organ timbre and reverbs with guis

// cleanup


1 Like

Oh, this is a bug! Fixed it right now. Don’t hesitate to report if you notice any kind of odd behavior!

EDIT: the bug only manifests when trying to open two or more different plugins which are not in the plugin dictionary (yet). Plugins added with VSTPlugin.search are not affected, that’s why I haven’t noticed it :-/.

@dkmayer to avoid confusion you could change the example to use VSTPlugin.search(verbose: true); before each example and then open them simply like ~ctrls[0].open("ComboV");
That’s actually the preferred way to open plugins, using the full path is rarely necessary.

I’ll add your examples to the next release!

Thanks Christof, that prior search exactly adresses the point where I felt somehow uncomfortable.

This is amazing! Thanks so much Christof! I do have one question. I have some waves plugins which are “bundled?” in WaveShell1-VST 10.0.vst. These are not being found by VSTPlugin.search. Is there any way to load these?

@Daniel_Peterson actually I’m planning to release a test version of v0.2 in a few hours on the forum and it will finally support VST2 shell plugins! I’ve successfully tested “Waves” on Windows, but I’m curious if it also works for you on the Mac. The initial search/probing for “Waves” takes quite some time (around 1 1/2 minutes on my Laptop), but the next time you start the Server and do VSTPlugin.search, it will be almost instantaneous (because I cache the plugin info in a hidden text file). So watch out for the test release and give me some feedback!


1 Like