What makes a well-behaved Host?

DSP, Plugin and Host development discussion.
Post Reply New Topic
RELATED
PRODUCTS

Post

Greetings all. I have been working on adding VST hosting capability to my app for some time now.

Now that it is close to release, I'm trying to iron a few last compatibility issues and would appreciate a reality check on exactly how a host is supposed to behave. The context for now is WIndows 32-bit with VST 2.4 only.

My host works reliably with most plugins, but there are still a handful where it has serious issues:

- freezing on the audio thread during interaction with the editor
- access violations when closing the editor window
- failed operation and access violations during Set/GetChunk

As we all know, the VST spec leaves a lot unsaid, but from fairly extensive research in this forum and elsewhere, I have gathered and implemented the following golden rules:

- plugin must be loaded on the UI thread
- editor window must be created on the UI thread
- effProcessEvents must be dispatched on the audio thread, just before processReplacing
- other dispatches should not be on audio thread
- care should be taken to avoid concurrency between processReplacing and any other operation
- effIdle should be dispatched regularly (20~50 ms) from a UI timer and to effEditIdle when the window is open

But I'm obviously still missing something. As a point of reference, I have tried my misbehaving plugins with Hermann Sieb's excellent VST Host (1.56) and they are working OK there.

I have done a comparative trace analysis between VST Host and my host using Plugin Consultant, and the event sequence and thread contexts look very similar, so I guessing it must be something to do with the content of the data exchange.

I've tried many rearrangements, but there's a still a couple of things I'm wondering about:

- most of my dispatch calls from the sequencer are done on a worker thread, but I'm guessing that's pretty normal

- the only values I supply to audioMasterGetTime are the sampleRate, samplePos and nanoSeconds. This is appropriately indicated in the flags. Everything else in VstTimeInfo is zeroed.

I read some commentary about some plugins requiring the musical time fields in VstTimeInfo, but since the midi event timing is specified completely in VstMidiEvent.deltaFrames from the start of the current buffer, I can't understand their relevance, and don't know what to supply here.

At the point of dispatch to the plugin, my audio thread has no awareness of the musical timing of the original sequence, and in many cases, there often simply isn't one, where transport is not running and midi events are simply being generated interactively.

Could this be the cause of my problems? I tried returning a NULL pointer to audioMasterGetTime, and the plugin froze at a later point than usual, which is making me wonder.

If I have no particular musical timing to supply, which fields in VstTimeInfo at are considered necessary to return, and what are safe values to use?

Are there any other behaviours or constraints that a host should observe to avoid trouble?

Thank you all in advance for your thoughts!
Stephen Clarke
ChordWizard Software
www.chordwizard.com

Post

If you'd like, you can send me your Host and I'll check with my VST plugins. Maybe it crashes, and we could dive into the offending code. Even better, maybe you could get in touch with the author of an offending plugin...

Post

Hey Eduur, thanks for the reply. Would be great to get feedback on compatibility with your plugins.

The app is called Songtrix, and it's currently beta testing, you can download a free copy at

http://www.chordwizard.net

This goes for all other plugin developers too! Please feel to take it for a spin, let us know how you get on.
Stephen Clarke
ChordWizard Software
www.chordwizard.com

Post

Also, I have managed to resolve the issues I described above with several plugins.

One of the most important changes was to supply a non-zero VstTimeInfo.ppqPos in response to audioMasterGetTime.

Apparently some plugins really choke when they don't get this, even if its declared as absent (with no kVstPpqPosValid flag). Seems to me that's a fault with the plugins, but I've started a new thread to explore this.
Stephen Clarke
ChordWizard Software
www.chordwizard.com

Post

Good news from me.. I tested two plugins, which are slightly different from each other. In Reaper one crashes, and the other behaves well. In your host, I get the same result. (Since they are almost the same I am using the good behaving one in my personal setup). So we could dive in this. If you'd like, use my email which I used to register and if we find something interesting, we'll report back to KVR...

Post

Can't offer more detail than in this message because it was a few years ago and I've forgotten more specific details than here described--

I worked on a host where it was inconvenient or nonsensical to return meaningful realtime tempo information. So I would always report a tempo of 125 BPM with a PPQN of 480. Then when ppqPos was requested I would just return the millisecond count since playback started, or last plugin initialization started, or whatever.

125 BPM at 480 PPQN is 1 millisecond per Tick, so it was an accurate count and my program had to keep up with milliseconds anyway for other purposes.

Of course this could cause some tempo-aware plugins to always play drums at 125 BPM regardless, or always do tempo-dependent delay loops at 125 BPM regardless, or whatever. But at least it returned "meaningful" time information to the plugins.

Post Reply

Return to “DSP and Plugin Development”