Getting good performance with Windows VSTs in Linux

VST_logoI do all my music making in Linux, but it’s no secret that the number of available plugins is vastly larger for the Windows platform than for Linux. Luckily, Alexandre Bique has made the nifty vst-bridge that enables you to make a bridge from a Linux VST host to a Windows VST plugin. I won’t go into the details of how to use it, since this is already well covered in its README, and is not very complicated to begin with.

What I want to talk about is getting good performance out of it. It has recently received some patches that make it better at performing in realtime, but there are some caveats, and I am going to talk about two in particular.

First off, let’s talk about threads: Each thread has a priority, and one of those priorities is realtime priority. This level is typically utilized by jackd to gain maximum priority so that audio will be prioritized and not lag or stutter. It is usually utilized by DAWs as well, for the threads that deal with audio. Many of the readers will likely be familiar with this if you’ve dealt with Linux audio. Typically realtime priority is avoided for most other threads, in particular the ones that render user interfaces. Rendering a user interface is slow, and you don’t want that process to steal resources from the audio, causing it to skip.

In a normal plugin scenario, this is what happens. The DAW gives exactly one realtime thread to the plugin, where it can process its audio. And in addition the plugin may create its own additional threads if it needs them, such as for drawing the user interface. It can also create additional audio processing threads, but then it needs to ensure on its own that this thread is scheduled with realtime priority.

And here lies a problem: vst-bridge knows how create one realtime thread, and make the plugin use it, but if the plugin makes additional threads, vst-bridge does not know that it should schedule it as a realtime thread, even if the plugin asks for it. Actually, I’m lying, it’s wine that doesn’t know. Because the plugin is a Windows binary, it asks using an emulated Windows call, which is not implemented in wine yet. It would be possible to implement it, but the realtime interfaces in Windows and Linux to not map well to one another, so some considerations would have to be taken here, and this has not been done yet.

The effect this has on plugins is that if the plugin just uses its given audio thread, performance is good. If it tries to create its own threads, performance is bad. The latter is usually what happens if the plugin has a configuration setting of the type “use 2 cores” or “use 4 cores”, or something similar. The counter intuitive thing is that the more cores you add, the worse the performance gets, because you are adding more non-realtime threads that hold up the audio. What you need to do when using vst-bridge, is to disable this feature entirely, if possible. This will force the plugin to use the one thread that’s given to it, which is realtime.

The second thing I want to talk about is wineserver. Wineserver is a special process which wine needs while running. Since it is a separate process, wine needs to communicate with it, and it uses a special directory for this, where it creates temporary files during this communication. The folder is /tmp/.wine-$UID, where $UID is the UID, or ID number, of your user account.

Unfortunately, using a folder with temporary files like this, means that those files will be periodically sync’ed to disk, and this is another operation which is slow when we are talking about realtime threads. You really don’t want any realtime thread to wait for that, which can take several hundred milliseconds, usually much longer than the audio buffer period. But that is just what wine will do!

The solution, or at least mitigation, is to put this directory on a tmpfs, or RAM disk if you will. Put this in the /etc/fstab file of you system (assuming your UID is 1000):

tmpfs /tmp/.wine-1000 tmpfs mode=0700,uid=1000,gid=1000,noauto,nosuid 0 0

This will allow you to easily mount this directory before invoking any plugins with:

mount /tmp/.wine-1000

You can also set it to auto instead of noauto to have it mounted at boot, but many distributions will delete the directory when you reboot, so this may not always work. Unfortunately the directory location can not be condigured in wine.

Make sure that wineserver is not running when mounting the directory!

Wineserver does not itself have realtime threads, so this is not guaranteed to be rock solid if wine has to wait for wineserver. But for me it has gone a very long way in eliminating the dreaded “xruns”, or audio skips, in my setup. After these two steps I went from several xruns per minute, to basically none! Of course it depends on what you do, and very heavy plugins can still cause xruns.

So to conclude, when working with vst-bridge, two tricks that give better realtime performance are:

  • Disable all options in the plugin configuration of the form “Use X number of cores”, or “Use multithreading”. Set it to “Single core” or “disable multithreading”, or whatever the plugin calls it, if it has it at all (Kontakt Player is an example of one that does)
  • Mount /tmp/.wine-$UID on a tmpfs before launching any plugins

Hope it helps!

This entry was posted in Software. Bookmark the permalink.

Leave a Reply

Your email address will not be published. Required fields are marked *


*