VSTPlugin v0.2 test release

@Spacechild1 Thanks! It works really great.

I am having so much fun with this and I am immensely grateful that this exists.

I have run VSTPlugin.search and, I am aware that this is most likely for my own safety but I still need to ask this I’m sorry:

Any way I can get around certain plugins being black-listed?
Maybe if I understood more about why they’ve been put on this black list I could deal with it better.
Might it have something to do with how certain plugins introduce tons of latency? I would be ok with that.

Thanks again for your amazing work on this.

@t36s hey, what’s your OS?

Oops I forgot to write that.
Mac OS X, 10.12.6

…sorry to be dense - when making SynthDef how is the ‘info’ arg used ?

I was able to use parameter names with set and map but now trying to make a SynthDef that can respond to parameter names -

got “can’t resolve parameter name without info”

thanks! (And thanks so much for this plugin it is a joy)

@t36s hey, to answer your original question: files should get black-listed if they a) are not a VST plugin, b) have the wrong architecture or c) crash during probing.

Unfortunately, certain plugins don’t seem to like each other, meaning that if a certain plugin is loaded, another plugin might refuse to load. I won’t got too much into details, but I think I’ve more or less fixed this in the current development version. Can you please replace your VSTPlugin version with that one: https://git.iem.at/pd/vstplugin/-/jobs/7206/artifacts/download

First do VSTPlugin.clear; to clear the plugin dictionary and remove the cache file, then perform a new search with verbose: true and post the console output.

@semiquaver

I was able to use parameter names with set and map

This is possible because you’re calling methods on a VSTPluginController instance after loading a plugin, so the info is available.

On the other hand, the VSTPlugin instance in a SynthDef doesn’t know which plugin(s) you’re going to load, so you have to pass the plugin info explicitly to enable parameter name deduction. (Note that you can also omit the path argument in VSTPluginController.open.)

First you have to perform a VSTPlugin.search, then you can get the plugin info with VSTPlugin.plugins['MyPlugin'];.

This is actually explained in the documentation of VSTPlugin.ar. There’s also a code example.

1 Like

These are admittedly my most esoteric plugins that are failing, the strangest of them all being DtBlkFX:

-> VSTPlugin
searching in '/Users/t36s/Library/Audio/Plug-Ins/VST'...
found 0 plugins
searching in '/Library/Audio/Plug-Ins/VST'...
probing /Library/Audio/Plug-Ins/VST/Buff rice.vst... failed!
probing /Library/Audio/Plug-Ins/VST/Convolution reverb stereo.vst... failed!
probing /Library/Audio/Plug-Ins/VST/DtBlkFx.vst... failed!
probing /Library/Audio/Plug-Ins/VST/DtBlkFxS.vst... failed!
probing /Library/Audio/Plug-Ins/VST/Hum remover.vst... failed!
robing /Library/Audio/Plug-Ins/VST/Multiband freeverb.vst... failed!
found 6 plugins

A while back I found that someone has picked up the baton at least a little bit, and cleaned up the source code to some extent:

@t36s please send me the plugins in a PM and then let’s continue from there.

Over here when using vstis with Pbinds I’m getting sound early by a little less than 0.2s. Maybe latency is being adjusted for twice? Mac - latest SC

I guess you meant late? How do you control the Synth exactly? With a \midi Pbind?

Yes using \midi events - and not late, but early. if I put a vsti and a default \note Pbind together in a Ppar, the vsti sounds first! By 0.2s…

Check out my Pbind examples with combined midi/osc usage and latency compensation here

and some older ones here

I didn’t try with the latest version of Christof but it should basically work the same.

Thanks I’ll check these out!

Yes, the problem is that while most Pbind types schedule server messages using the Server latency, the \midi Pbind ignores the Server latency (because the destination is usually a MIDI device with its own latency value). This means that MIDI messages to VSTPlugin are sent without delay and therefore arrive earlier than scheduled OSC bundles (ca. 0.2 seconds = the default Server latency).

@dkmayer To be honest, I didn’t think about this and it really is a problem. I would like MIDI events to be scheduled properly in the context of Pbind \midi. Using the lag parameter is not ideal because it is scheduled on Sclang’s system clock - and not timestamped on the Server - and is therefore unprecise.

I see at least two solutions:

a) offer a dedicated \vstMidi event type which schedules the result of noteOnMsg, controlMsg, etc. based on the Server latency instead of directly calling noteOn, control, etc.
(maybe this is a chance to also ship a \vstSet event type)

b) add a latency member to VSTPluginController. If it is not nil, VSTPlugin.sendMidi (called under hood by Pbind \midi resp. VSTPluginMIDIProxy) would schedule the MIDI message as a bundle instead of sending it immediately.

Personally, I tend to a) because it is more consistent. Usually, “plain” methods are sent immediately, and the *Msg variants return OSC messages which can be scheduled in bundles. I would like to keep this principle in VSTPluginController.

I’d love to hear your opinion, Daniel!

Timing issues are delicate and I don’t dare to give an apodictic answer at this time of the day (late here). But from my tests with accuracy of Pbind in combination with OffsetOut (Imperfection of language-based timing) and a recent thread about a supposed difference between server and client timing (which then turned out to have its reason in the test itself: TempoClock in Linux is inaccurate compared to Mac/Windows · Issue #4580 · supercollider/supercollider · GitHub) it seems that the difference between system clock and server clock is not relevant, non-sample accuracy in realtime (so maybe wrong to call it inaccuracy) comes from the calibration between server clock and audio hardware clock. Here another audio application is involved which makes things even more opaque. IMO a test in order to find the syncing lagtime should suffice in most practical cases.
Alternatively you might adjust latency per Event, but this will not make things better if the syncing problem lies outside SC and I suppose also not in the other case.

Hi, I think I was not very clear. You’re of course right that system clock VS server clock is irrelevant for OSC bundles, e.g. the following two lines should be equivalent:

SystemClock.sched(0.1, { s.sendBundle(0.1, ['/foo', 1, 2, 3]) }); // total latency of 0.2 s
s.sendBundle(0.2, ['/foo', 1, 2, 3]) ; // total latency of 0.2 s

But even the following doesn’t really work:

SystemClock.sched(0.2, { s.sendBundle(0, ['/foo', 1, 2, 3]) }); // total latency of 0.2 s + some delay

because the message is scheduled with 0 latency. When the OSC bundle arrives at the Server, it will already be too late (the timestamp is in the past).

Another problem is that Pbind \midi - unlike other Pbind types - directly calls instance methods instead of scheduling OSC messages as bundles, so this is what actually happens under the hood with lag: 0.2:

SystemClock.sched(0.2, { ~midiout.noteOn(0, 60, 127) }); // noteOn internally calls s.sendMsg!

The message is only delayed in the language, but not scheduled on the Server. Also, the actual delay will be more than 0.2 s because it takes some indeterminate amount of time for the message to arrive at the Server (where it is executed immediately). This is what I meant with “imprecise”.

This is the behavior I want for Pbind + VSTPluginController:

server.sendBundle(server.latency, ~midiout.noteOnMsg(0, 60, 127));

My plan is now to write custom Event types, e.g. \vstmidi for MIDI messages and \vstset for setting parameters, which do the right thing under the hood. Does this sound alright?

I don’t see a real problem in the first case. It’s expected behaviour that latency 0 is imprecise. We can go down to something like 0.03 sec or so, 0.05 is safe in most environments and if the bundle latency is above, everything is fine, no matter how the overall latency is divided between language and server clock.

But concerning the second point I agree: MIDI-triggering like this was probably never regarded as a common sequencing usage before your VST extension, so this sounds reasonable.

What’s still foggy to me is if there’s possibly an additional source of imprecision that has to do with the plugin embedding, but I can’t say anything about this, you know better.

When the OSC message is dispatched, the MIDI data is immediately sent to the plugin and subsequently processed in the next perform routine. In theory, VSTPlugin even allows sample-accurate scheduling of MIDI messages, but I think few plugins actually support this.

BTW, VSTPlugin now also supports per-note detuning and I have found at least one VST3 plugin which actually supports this: https://www.pianoteq.com/ It is not part of the MIDI standard and Pbind \midi naturally just rounds the final ~detunedFreq to an Integer, but my \vstmidi Pbind could keep the fractional value and pass it to noteOnMsg. This means you can easily play microtonal music on certain VSTis :slight_smile:

Cool ! Just to add, even if the VSTi doesn’t support it you have several options to do it with pitchbend (with setting per event or using different instances of differently detuned VSTis) and thanks to the linkage to SC even with a pitchshift added in the SynthDef. These options also apply to spatial positioning and movement, the Pbind examples mentioned above (VSTPlugin v0.2 test release - #31 by dkmayer) show some possibilities. SC + VST rocks !