Monday, April 6, 2009

VST plugins with Qt user interface

I recently did an spike on what we need to make VST plugins first class CLAM citizens. CLAM allows to visually build JACK and PortAudio based applications with Qt interfaces as well as GUI-less VST and LADSPA plugins. The more flashy feature of VST is user interfaces that are mostly built using VSTGUI. We are using Qt as interface for JACK and Portaudio based apps because we are using the nice features of Qt toolkit to dynamically bind the UI elements and the underlaying processing. Moreover, Qt styling features enables shinning designer-made interfaces. Why not being able to reuse the same interface for VST and JACK? That has been a long standing TODO in CLAM so now is time to address it.

In summary, we fully solved croscompiling vst's from linux and we even started using qt interfaces as vst gui. In that last point, there still is a lot of work to do, but the basic question on whether you can use qt to edit a vst plugin is now out of any doubt.

To make the spike simpler, and in order not to collide with other CLAM developers, currently working on it, i just left apart all the CLAM wrapping part, just addressing vst crosscompiling and Qt with the sdk examples.

Cross compilation was pretty easy. This time I found lot more documentation on mingw and even scons. Just by adding the crossmingw scons tool we are already using for the apps and i managed to get Linux cross-compiled plugins running on Wine.

Adding a regular vstgui user interface is just a matter of compiling vstgui sources along with the example editor that comes in the sdk.

Once there, we should address Qt. VSTGUI is just a full graphical toolkit implementing the 'editor interface' plus a toolkit with some provided widgets and, i guess, a way of automating the binding of controls to processing. So what we need for qt is to implement the AEffEditor interface using the qt toolkit instead. The first problem is about the graphical loop. You have to create a QApplication and calling qApp::processEvents() on the editor's idle method so that qt widgets get responsive. The problem then is that, if you don't provide a QWidget as parent to your interface, it becomes a top level window ignoring the host provided window that still appears as an empty one.

VST host provides such window as a native Windows handle. How do you create a widget on an existing window handle? Months ago trolls redirected me to a commercial solution. Not such a 'solution' for us, a FLOSS project. So i was digging in windows qt source code for a hack when i found the answer just at the public and multiplatform QWidget api. QWidget::create works like a charm. The following simple class is a native window wrapper you can use as a regular QWidget.


class QVstWindow : public QWidget
{
Q_OBJECT
public:
QVstWindow(WId handle) {create(handle);}
QVstWindow::~QVstWindow() {}
};

Still there are some issues: focus handling, reopening, drag&drop... But the basic mouse clicking and resizing works

Once i got that, loading a designer ui file was very easy.

As I said there are still many caveats to solve. A matter of playing with it and refining things. Here is a list of TODO's:

  • Communicate controls from and to the interface
  • Handle focus and other events properly
  • Build a CLAM network wrapper which reensembles more the one for LADSPA
  • Wiki documentation on how to build your own plugin
  • One button plugin generator like the one we have for LADSPA ;-)

I feel that there is more people around other projects interested in using Qt for VST plugins so this is also a call for collaborative research on pending issues, at least the generic ones. Contact us on the CLAM development list or for a broader audience in the Linux Audio Developers list.

4 comments:

FatButtLarry said...

Great article. Was linked here from this mailing list:

http://lmms.sourceforge.net/community.php

-Tres

pato said...

Hi,

it looks, that Qt/MFC migration has been LGPLed in the meantime, so it can make things easier for you. Are you still exploring this topic?

Vokimon said...

Great. I will take a look at it as soon as I have time. Meanwhile people from the Mixxx project has done improvements on my code and they are close to extend the solution for Mac-VST. I am waiting to see their modifications.

Jan K. said...

Greetings!

I have started investigating the possibilities of implementing VSTs in Qt. I tried QtAgain example which makes use of the mentioned QtWinMigrate solution.

But I'm not happy with that as it is not platform independent. I'd like my VSTs to work on PC and Mac if possible.

So I'd like to ask you how far have you got with this approach. Did you manage to solve mentioned problems and does it work on OS X ?

Thanks and cheers,
Jan, Czech rep.