Random questions from me about vst
-
- KVRAF
- Topic Starter
- 7400 posts since 17 Feb, 2005
I just realized these two values are a parameter to the base AudioEffect class, which is allocated in VSTPluginMain. So it look like I'll have to make a temp allocation to store them until effOpen. (unless that's not even useful?)
- KVRist
- 347 posts since 20 Apr, 2005 from Moscow, Russian Federation
to the base AudioEffect class, which is allocated in VSTPluginMain.
Well, counting that the inheritance chain is YourPluginClass : AudioEffectX : AudioEffect, I'm not sure what you mean with that (as it sounds like allocating AudioEffect separately from your plugin object).
So it look like I'll have to make a temp allocation to store them until effOpen.
If you don't override setSampleRate/setBlockSize, the SDK code already stores the values on its own (audioeffect.h):
So in simple case you may just reuse these functions/values (or totally ignore them - it's all up to you).
Well, counting that the inheritance chain is YourPluginClass : AudioEffectX : AudioEffect, I'm not sure what you mean with that (as it sounds like allocating AudioEffect separately from your plugin object).
So it look like I'll have to make a temp allocation to store them until effOpen.
If you don't override setSampleRate/setBlockSize, the SDK code already stores the values on its own (audioeffect.h):
Code: Select all
virtual void setSampleRate (float sampleRate) { this->sampleRate = sampleRate; }
virtual void setBlockSize (VstInt32 blockSize) { this->blockSize = blockSize; }
-
- KVRAF
- Topic Starter
- 7400 posts since 17 Feb, 2005
I conceded and made the allocation in VSTPluginMain, even though it seems unnecessary, it had to be done, and it's only a small allocation. There was no other way to do it that wouldn't have introduced subtle multi-threading bugs (or rather pitfalls, deadlocks). Also, I did avoid doing any conditional logic in the dispatch, so that's more useful overall.
I was under the impression that effOpen could be used as a constructor for the plugin instance, but that is wrong. The only reason it is wrong is because there may be calls to other dispatches before effOpen, which IMHO is not the correct way to do things. The SDK itself says to do plugin initialization in effOpen, not construction. So allocating the plugin instance in effOpen is just not possible in any reasonable manner. Although AFAIK, all deconstruction must be done in effClose. However, I make deallocations in VSTPluginMain if and only if the allocations return null.
Will a host plugin scan call effClose if it also calls VSTPluginMain? That's a potential memory leak here. The host is given the pointer to the AEffect allocation, so technically it could free it, but there's a second allocation for the plugin instance.. only freed in effClose.
I was under the impression that effOpen could be used as a constructor for the plugin instance, but that is wrong. The only reason it is wrong is because there may be calls to other dispatches before effOpen, which IMHO is not the correct way to do things. The SDK itself says to do plugin initialization in effOpen, not construction. So allocating the plugin instance in effOpen is just not possible in any reasonable manner. Although AFAIK, all deconstruction must be done in effClose. However, I make deallocations in VSTPluginMain if and only if the allocations return null.
Will a host plugin scan call effClose if it also calls VSTPluginMain? That's a potential memory leak here. The host is given the pointer to the AEffect allocation, so technically it could free it, but there's a second allocation for the plugin instance.. only freed in effClose.
-
- KVRAF
- Topic Starter
- 7400 posts since 17 Feb, 2005
I decided to just make one allocation in VSTPluginMain that is the sizeof the AEffect struct and my plugin struct. Then just stuff the offset into user field, I suppose this is how it works.
- KVRist
- 347 posts since 20 Apr, 2005 from Moscow, Russian Federation
Will a host plugin scan call effClose if it also calls VSTPluginMain?
A host is obligated to call effClose in pair with effOpen (it should not call effClose w/o prior effOpen).
A host is obligated to call effClose in pair with effOpen (it should not call effClose w/o prior effOpen).
- KVRist
- 347 posts since 20 Apr, 2005 from Moscow, Russian Federation
I can't recall any major hosts doing that, but it's nothing in SDK that says it can't.
-
- KVRian
- 1273 posts since 9 Jan, 2006
Long time since I used the VST3 SDK directly, so might be out of date/plain incorrect.
Due to the separation of plugin components in VST3 there was an issue that GUI changes that tool place, in cases where the audio engine was suspended, would never be seen by the processor component. The solution in the SDK was that the host should send a dummy audio block - ie blockSize 0, so the processor could recieve the GUI updates.
The best part was the Steinberg hosts didn't follow their own advice and you would indeed loose updates that took place while audio was suspended.
Are VST3 hosts still expected to send these dummy blocks? Also I'm assuming Steinberg corrected their own host behaviour, but is that the case, Cubase had this issue for some years IIRC, or did everyone just move to single component effects to circumvent the problem?
- KVRist
- 347 posts since 20 Apr, 2005 from Moscow, Russian Federation
I am specifically targeting vst version 2.4, so I suppose there is none of the separation of components you mention.
But hosts (with VST3 support) barely handle VST2 via separate code branch with its own mechanics. Usually it's just some thin VST3->VST2 wrapper code, so if a VST3-oriented host uses such kludge it's most likely to be seen in a VST2 plugin as well.
But hosts (with VST3 support) barely handle VST2 via separate code branch with its own mechanics. Usually it's just some thin VST3->VST2 wrapper code, so if a VST3-oriented host uses such kludge it's most likely to be seen in a VST2 plugin as well.
- KVRAF
- 7890 posts since 12 Feb, 2006 from Helsinki, Finland
One must already allocate the plugin itself in VSTPluginMain and effClose is the only possible place to deallocate it (and this is what the VST2 SDK classes do as well), so you can safely assume that effClose is always called. As for what to do with effOpen, I personally don't have the slightest clue, as I've never used it for anything.
Note that if you need to do allocations that depend on sampling rate and/or block size, then you really need to do them every time either sampling rate or block size changes... because this can happen multiple times during the lifetime of the plugin.
After such changes you will get a resume() though, so what I've done for ages now is simply track whether or not a reconfiguration is needed and then do the reallocations in resume() if necessary. In theory this is "bad" but in practice it doesn't really make a whole lot of difference, since resume() is already typically expected to reset the plugin state, which tends to involve lengthy buffer clears and what not, so worrying about audio glitches here is kinda futile IMHO.
- KVRAF
- 7890 posts since 12 Feb, 2006 from Helsinki, Finland
The host cannot free the plugin, because it doesn't know which allocator was used, from what heap it was allocated from and typically doesn't even have access to the correct deallocation function.camsr wrote: ↑Sat Sep 21, 2019 9:01 pm Will a host plugin scan call effClose if it also calls VSTPluginMain? That's a potential memory leak here. The host is given the pointer to the AEffect allocation, so technically it could free it, but there's a second allocation for the plugin instance.. only freed in effClose.
Also there is really no "second allocation" because you should create your plugin in VSTPluginMain and you should destroy it in effClose. As I already noted in the previous post, I don't have the slightest clue what you would possibly want to do with effOpen, except return 0 for success.
- KVRist
- 347 posts since 20 Apr, 2005 from Moscow, Russian Federation
mystran
One must already allocate the plugin itself in VSTPluginMain and effClose is the only possible place to deallocate it
True (So my answer was sort of misleading. My bad).
I don't have the slightest clue what you would possibly want to do with effOpen, except return 0 for success.
It's not difficult to guess what they had in mind in 1996(!). (The idea was:) In VSTPluginMain you initialize some minimally required resources and defer any heavy initialization (e.g. large sample tables, long delay buffers etc etc.) to effOpen. So that a minimalistic scanning would go as fast as possible.
Obviously since then the common approach drifted'n'polished due to real-world usage experience (so that during scanning many hosts actually try to dig into plugin as deeper as possible (down to making the scanned plugin to process a few dummy buffers) to detect and ban buggy plugins earlier).
Still... not putting all the eggs into the very entry function might be not so bad idea.
One must already allocate the plugin itself in VSTPluginMain and effClose is the only possible place to deallocate it
True (So my answer was sort of misleading. My bad).
I don't have the slightest clue what you would possibly want to do with effOpen, except return 0 for success.
It's not difficult to guess what they had in mind in 1996(!). (The idea was:) In VSTPluginMain you initialize some minimally required resources and defer any heavy initialization (e.g. large sample tables, long delay buffers etc etc.) to effOpen. So that a minimalistic scanning would go as fast as possible.
Obviously since then the common approach drifted'n'polished due to real-world usage experience (so that during scanning many hosts actually try to dig into plugin as deeper as possible (down to making the scanned plugin to process a few dummy buffers) to detect and ban buggy plugins earlier).
Still... not putting all the eggs into the very entry function might be not so bad idea.