How to instantiate a custom VST GUI (no JUCE, no IPlug)?

DSP, Plug-in and Host development discussion.
User avatar
BlitBit
KVRist
179 posts since 28 Nov, 2013 from Germany

Post Tue Jan 09, 2018 1:15 pm

I am currently experimenting with writing my own little GUI framework using Cairo with FreeType2 (and later perhaps Harfbuzz) as the paiting back end. Unfortunately, the documentation on VST2.4 is rather sparse so I have some questions with regards to the protocol between a host and a VST concerning the GUI creation:
  • Which methods are called in which order (only a coarse overview)?
  • What are the parameters to these methods? In the headers I saw some void pointers going around in some methods. I assume that this is a HWND on Windows?
  • Does the host provide the parent window that my VST GUI window needs to become a child of or does it provide the window that my VST can directly paint on?
  • What's the type of the void pointer on Mac and Linux?
  • How can I communicate to the host that my window size has changed / needs to be changed? Both approaches would work for me: providing some predefined sizes or using dynamic resizing with a handle.
Thanks in advance to anyone who can help!

User avatar
syntonica
KVRist
424 posts since 25 Sep, 2014 from Specific Northwest

Re: How to instantiate a custom VST GUI (no JUCE, no IPlug)?

Post Tue Jan 09, 2018 2:55 pm

Look in aeffeditor.h for what to override. How you proceed from there is up to you.

Basically, you only need to provide the window size before opening the GUI window. To display the window, it's an HWND in Windows and an NSView on the Mac. It's passed as "void* parent" iirc, so you only need to add the needed cast to attach your GUI view.

Resizing is a pain. Before, I did it in my NSView class, but with adding Windows code in using a third-party utility, I gave up and am making the user close and reopen to get the new GUI size (I'm not a Windows programmer.) When resizing, you just send a message to the host asking if the size change is okay and get a yea or a nay back before resizing your view.

As an aside, I believe for the Mac AU, the plugin provides the NSView instance to the host to stuff into an NSWindow and display. I'm using a third-party wrapper to make my AU version.

hibrasil
KVRian
769 posts since 24 Jun, 2002 from Huddersfield, UK

Re: How to instantiate a custom VST GUI (no JUCE, no IPlug)?

Post Wed Jan 10, 2018 3:34 am

although you may not want to use IPlug, you might find it useful to know i've been updating it to allow any UI framework to sit on top.

https://github.com/olilarkin/wdl-ol/tree/iplugquake

haven't looked at window resizing yet. not looking forward to that
My Website | WDL-OL | Web Audio Modules - WAMs | Oli Larkin Plugin's Facebook
Available for Audio Dev tuition via Skype (IPlug/JUCE/C++)

User avatar
BlitBit
KVRist
179 posts since 28 Nov, 2013 from Germany

Re: How to instantiate a custom VST GUI (no JUCE, no IPlug)?

Post Fri Jan 12, 2018 10:30 am

Hi syntonica, hi hibrasil,

thanks for your replies! I already got some empty window going by just instantiating an AEffEditor and I already checked how IPlug is doing some things to get a better understanding of the protocol / interfaces. So I assume that I will have something running soon.

With regards to IPlug: I already have some small projects implemented with it but currently it's a rather fragile thing because I use MinGW and some CMake scripts that I wrote myself to build them. So there is always an uncertainty whether updating or changing branches will break my projects. That's also part of the reason why I am thinking about writing my own little GUI framework using Cairo because I hope that a smaller code base will give me more control and that it will also enable simple ports to Linux.

I saw in Oli's other thread that it's planned to implement CMake support. This would really help in my case because then I would not have to rely on my own crude build system. I don't want to register at an account at patreon but if I get IPlug build at some point without my own band aids then I might perhaps help with some implementations if that's something that's wanted.

Why is the branch called "quake" by the way? Because it is intended to run and be ported to any computing device like Quake? :)

hibrasil
KVRian
769 posts since 24 Jun, 2002 from Huddersfield, UK

Re: How to instantiate a custom VST GUI (no JUCE, no IPlug)?

Post Fri Jan 12, 2018 10:48 am

no.. there was a jucequake, and now there's an iplugquake :-)

contributions to iplug, bug fixes, documentation, features are much appreciated just as valuable as patrons
My Website | WDL-OL | Web Audio Modules - WAMs | Oli Larkin Plugin's Facebook
Available for Audio Dev tuition via Skype (IPlug/JUCE/C++)

mystran
KVRAF
4981 posts since 12 Feb, 2006 from Helsinki, Finland

Re: How to instantiate a custom VST GUI (no JUCE, no IPlug)?

Post Fri Jan 12, 2018 1:19 pm

BlitBit wrote: [*] Which methods are called in which order (only a coarse overview)?
Host should first call getRect(), then open(void*).
[*] What are the parameters to these methods? In the headers I saw some void pointers going around in some methods. I assume that this is a HWND on Windows?
You get HWND and NSView as parameter for open() depending on platform.
[*] Does the host provide the parent window that my VST GUI window needs to become a child of or does it provide the window that my VST can directly paint on?
You want to use the window that you get as the parent (eg. superview or parent HWND) for the editor window (or "view" in Cocoa) that you create. You can then either build the UI into that editor window/view, or use it as a parent for further windows.

If you do everything in one window/view, then that's all you need, but in some hosts you can run into problems if you add more than one child to the host window, so if your editor code involves more than one window/view, you still want just one "editor" window/view that can then acts as the parent for rest of your GUI hierarchy.
[*] What's the type of the void pointer on Mac and Linux?
NSView to use as a superview for the view you create.
[*] How can I communicate to the host that my window size has changed / needs to be changed? Both approaches would work for me: providing some predefined sizes or using dynamic resizing with a handle.[/list]
In theory you just call resizeWindow() on the plugin (and in theory this works even if you do it in response to some mouse-dragging, but in practice I've noticed some issues doing this). In practice it works "most of the time" in "most hosts" sometimes depending on weird stuff like whether the plugin editor has it's own window or embedded into another window (eg. Reaper can do both and IIRC resize only works reliably when it's on it's own window). Usually closing and reopening the editor will work even in hosts having problems though.

You might also want to update the rectangle as returned by getRect() so that the window will reopen with the correct size and also resize the actual window you've created (eg. SetWindowPos() on windows), since host will normally only resize the parent that contains the editor, not the editor itself. :)
If you'd like Signaldust to return, please ask Katinka Tuisku to resign.

User avatar
BlitBit
KVRist
179 posts since 28 Nov, 2013 from Germany

Re: How to instantiate a custom VST GUI (no JUCE, no IPlug)?

Post Sun Jan 21, 2018 12:55 pm

Thanks for all the help! I managed to get something running this weekend. :)

Here's the current state with some prototypical test renderings:
Cairo-VST.png
You do not have the required permissions to view the files attached to this post.

hibrasil
KVRian
769 posts since 24 Jun, 2002 from Huddersfield, UK

Re: How to instantiate a custom VST GUI (no JUCE, no IPlug)?

Post Sun Jan 21, 2018 1:15 pm

cool! are you using the opengl backend?
My Website | WDL-OL | Web Audio Modules - WAMs | Oli Larkin Plugin's Facebook
Available for Audio Dev tuition via Skype (IPlug/JUCE/C++)

User avatar
BlitBit
KVRist
179 posts since 28 Nov, 2013 from Germany

Re: How to instantiate a custom VST GUI (no JUCE, no IPlug)?

Post Sun Jan 21, 2018 2:07 pm

hibrasil wrote:cool! are you using the opengl backend?
No, I don't use the OpenGL backend. Currently I perform the following steps during the rendering:
  1. Take the device context of the window and create a compatible copy of it.
  2. Create a bitmap that the copied context can use to draw on.
  3. Let Cairo draw on the copied context.
  4. Blit the copy to the widget context and destroy all the extra resources.
Right now I just want to set up a small and simple widget framework that I can use to draw some controls. However, if I should run into performance problems I might investigate other backends. But right now I render the full window at 50 Hz and the CPU in REAPER still shows 0.0%. The three circles are rotating but it's still a very simple scene of course.

mystran
KVRAF
4981 posts since 12 Feb, 2006 from Helsinki, Finland

Re: How to instantiate a custom VST GUI (no JUCE, no IPlug)?

Post Mon Jan 22, 2018 6:27 pm

BlitBit wrote: But right now I render the full window at 50 Hz and the CPU in REAPER still shows 0.0%. The three circles are rotating but it's still a very simple scene of course.
While this scene probably doesn't use a huge amount of CPU, make sure you're not looking a the host "CPU meter" because it's usually not really a CPU meter at all (even if it said "CPU" next to it), but rather an audio performance meter that shows the percentage of the audio block time that was spent actually processing it (both of which are real-time units, not CPU time).

The goal of such a meter is to try to give you an estimate of how much more you can do before you start to get audio glitches. If you make your plugin sleep() in the audio process() callback, it won't spend any actual CPU but still max out the host meters. If your audio code returns quickly while your GUI is spending 100% of all the cores on the system, the host meter should still show essentially 0%.

If you are already looking at some real CPU meter (eg. task manager or process explorer or whatever) then ignore what I just said... but if you're looking at the host meter, you're probably not seeing any of the GUI impact in it at all.
If you'd like Signaldust to return, please ask Katinka Tuisku to resign.

Return to “DSP and Plug-in Development”