prepareToPlay in vst3


#1


Hi!


I"m still fairly new to Juce, so please pardon any newbishness :)

Are all the calls to AudioProcessor::prepareToPlay in vst3 necessary?  I'm seeing 6 calls when I load the plugin. The first 3 calls have the default settings that were hard coded in the JuceVST3Component constructor (1024 block size, 44100 sample rate).   After the ProcessSetup struct gets filled in correctly in VST3PluginInstance::prepareToPlay , AudioProcessor::prepareToPlay gives correct data.  I'm worried about having to uncesssarily do setup and tear down for each of those calls.  

When I load the VST2 plugin, there's only one prepareToPlay call and the params given to the plugin are correct.

The vst3 calls are always through preparePlugin.  I commented out all the calls except for the preparePlugin call in JuceVST3Component::SetActive and that seems to work, though I may have broken something I'm not aware of.   I read SetActive is where Steinberg recommends we do our allocations and such.  Also works with the JuceVST3Component::setBusArrangements call alone.

Also I notice that in VST3, VST3PluginInstance::prepareToPlay only gets called once while AudioProcessor::prepareToPlay gets called the 6 times on load.  It's only after that point that the latter gives the updated info.
Here's stacks for the successive times prepareToPlay gets called in vst3:

Stack 1
     Plugin.vst3!AudioProcessor::prepareToPlay(double hostSampleRate, int samplesPerBlock) Line 115    C++
     Plugin.vst3!juce::JuceVST3Component::preparePlugin(double sampleRate, int bufferSize) Line 1822    C++
>    Plugin.vst3!juce::JuceVST3Component::initialize(Steinberg::FUnknown * hostContext) Line 849    C++
     Plugin Host.exe!juce::VST3Classes::DescriptionFactory::findDescriptionsAndPerform(const juce::File & file) Line 1015    C++
     Plugin Host.exe!juce::VST3Classes::VST3ModuleHandle::open(const juce::File & f, const juce::PluginDescription & description) Line 1359    C++
     Plugin Host.exe!juce::VST3Classes::VST3ModuleHandle::findOrCreateModule(const juce::File & file, const juce::PluginDescription & description) Line 1323    C++
     Plugin Host.exe!juce::VST3PluginFormat::createInstanceFromDescription(const juce::PluginDescription & description, double __formal, int __formal) Line 2488    C++
     Plugin Host.exe!juce::AudioPluginFormatManager::createPluginInstance(const juce::PluginDescription & description, double rate, int blockSize, juce::String & errorMessage) Line 89    C++
     Plugin Host.exe!FilterGraph::createNodeFromXml(const juce::XmlElement & xml) Line 322    C++
     Plugin Host.exe!FilterGraph::restoreFromXml(const juce::XmlElement & xml) Line 398    C++
     Plugin Host.exe!FilterGraph::loadDocument(const juce::File & file) Line 233    C++
     Plugin Host.exe!juce::FileBasedDocument::loadFrom(const juce::File & newFile, bool showMessageOnFailure) Line 79    C++
     Plugin Host.exe!PluginHostApp::initialise(const juce::String & __formal) Line 83    C++
     Plugin Host.exe!juce::JUCEApplicationBase::initialiseApp() Line 261    C++
     Plugin Host.exe!juce::JUCEApplication::initialiseApp() Line 88    C++
     Plugin Host.exe!juce::JUCEApplicationBase::main() Line 234    C++
     Plugin Host.exe!WinMain(HINSTANCE__ * __formal, HINSTANCE__ * __formal, char * __formal, int __formal) Line 119    C++

Stack 2
>    Plugin.vst3!AudioProcessor::prepareToPlay(double hostSampleRate, int samplesPerBlock) Line 115    C++
     Plugin.vst3!juce::JuceVST3Component::preparePlugin(double sampleRate, int bufferSize) Line 1822    C++
     Plugin.vst3!juce::JuceVST3Component::initialize(Steinberg::FUnknown * hostContext) Line 849    C++
     Plugin Host.exe!juce::VST3Classes::VST3PluginInstance::fetchComponentAndController(Steinberg::IPluginFactory * factory, const long numClasses) Line 2264    C++
     Plugin Host.exe!juce::VST3Classes::VST3PluginInstance::initialise() Line 1645    C++
     Plugin Host.exe!juce::VST3PluginFormat::createInstanceFromDescription(const juce::PluginDescription & description, double __formal, int __formal) Line 2492    C++
     Plugin Host.exe!juce::AudioPluginFormatManager::createPluginInstance(const juce::PluginDescription & description, double rate, int blockSize, juce::String & errorMessage) Line 89    C++
     Plugin Host.exe!FilterGraph::createNodeFromXml(const juce::XmlElement & xml) Line 322    C++
     Plugin Host.exe!FilterGraph::restoreFromXml(const juce::XmlElement & xml) Line 398    C++
     Plugin Host.exe!FilterGraph::loadDocument(const juce::File & file) Line 233    C++
     Plugin Host.exe!juce::FileBasedDocument::loadFrom(const juce::File & newFile, bool showMessageOnFailure) Line 79    C++
     Plugin Host.exe!PluginHostApp::initialise(const juce::String & __formal) Line 83    C++
     Plugin Host.exe!juce::JUCEApplicationBase::initialiseApp() Line 261    C++
     Plugin Host.exe!juce::JUCEApplication::initialiseApp() Line 88    C++
     Plugin Host.exe!juce::JUCEApplicationBase::main() Line 234    C++
     Plugin Host.exe!WinMain(HINSTANCE__ * __formal, HINSTANCE__ * __formal, char * __formal, int __formal) Line 119    C++

Stack 3
>    Plugin.vst3!AudioProcessor::prepareToPlay(double hostSampleRate, int samplesPerBlock) Line 115    C++
     Plugin.vst3!juce::JuceVST3Component::preparePlugin(double sampleRate, int bufferSize) Line 1822    C++
     Plugin.vst3!juce::JuceVST3Component::setupProcessing(Steinberg::Vst::ProcessSetup & newSetup) Line 1533    C++
     Plugin Host.exe!juce::VST3Classes::VST3PluginInstance::setupIO() Line 2378    C++
     Plugin Host.exe!juce::VST3Classes::VST3PluginInstance::initialise() Line 1657    C++
     Plugin Host.exe!juce::VST3PluginFormat::createInstanceFromDescription(const juce::PluginDescription & description, double __formal, int __formal) Line 2492    C++
     Plugin Host.exe!juce::AudioPluginFormatManager::createPluginInstance(const juce::PluginDescription & description, double rate, int blockSize, juce::String & errorMessage) Line 89    C++
     Plugin Host.exe!FilterGraph::createNodeFromXml(const juce::XmlElement & xml) Line 322    C++
     Plugin Host.exe!FilterGraph::restoreFromXml(const juce::XmlElement & xml) Line 398    C++
     Plugin Host.exe!FilterGraph::loadDocument(const juce::File & file) Line 233    C++
     Plugin Host.exe!juce::FileBasedDocument::loadFrom(const juce::File & newFile, bool showMessageOnFailure) Line 79    C++
     Plugin Host.exe!PluginHostApp::initialise(const juce::String & __formal) Line 83    C++
     Plugin Host.exe!juce::JUCEApplicationBase::initialiseApp() Line 261    C++
     Plugin Host.exe!juce::JUCEApplication::initialiseApp() Line 88    C++
     Plugin Host.exe!juce::JUCEApplicationBase::main() Line 234    C++
     Plugin Host.exe!WinMain(HINSTANCE__ * __formal, HINSTANCE__ * __formal, char * __formal, int __formal) Line 119    C++

 

Max blockSize gets set (stack)
     Plugin Host.exe!juce::VST3Classes::VST3PluginInstance::prepareToPlay(double newSampleRate, int estimatedSamplesPerBlock) Line 1706    C++
     Plugin Host.exe!juce::AudioProcessorGraph::Node::prepare(double newSampleRate, int newBlockSize, juce::AudioProcessorGraph * graph, juce::AudioProcessor::ProcessingPrecision precision) Line 973    C++
>    Plugin Host.exe!juce::AudioProcessorGraph::buildRenderingSequence() Line 1337    C++
     Plugin Host.exe!juce::AudioProcessorGraph::handleAsyncUpdate() Line 1374    C++
     Plugin Host.exe!juce::AsyncUpdater::AsyncUpdaterMessage::messageCallback() Line 34    C++
     Plugin Host.exe!juce::WindowsMessageHelpers::dispatchMessageFromLParam(__int64 lParam) Line 49    C++
     Plugin Host.exe!juce::MessageManager::dispatchNextMessageOnSystemQueue(bool returnIfNoPendingMessages) Line 118    C++
     Plugin Host.exe!juce::MessageManager::runDispatchLoop() Line 130    C++
     Plugin Host.exe!juce::JUCEApplicationBase::main() Line 244    C++
     Plugin Host.exe!WinMain(HINSTANCE__ * __formal, HINSTANCE__ * __formal, char * __formal, int __formal) Line 119    C++



Stack 4 (correct values now)
>    Plugin.vst3!AudioProcessor::prepareToPlay(double hostSampleRate, int samplesPerBlock) Line 115    C++
     Plugin.vst3!juce::JuceVST3Component::preparePlugin(double sampleRate, int bufferSize) Line 1822    C++
     Plugin.vst3!juce::JuceVST3Component::setupProcessing(Steinberg::Vst::ProcessSetup & newSetup) Line 1533    C++
     Plugin Host.exe!juce::VST3Classes::VST3PluginInstance::prepareToPlay(double newSampleRate, int estimatedSamplesPerBlock) Line 1710    C++
     Plugin Host.exe!juce::AudioProcessorGraph::Node::prepare(double newSampleRate, int newBlockSize, juce::AudioProcessorGraph * graph, juce::AudioProcessor::ProcessingPrecision precision) Line 973    C++
     Plugin Host.exe!juce::AudioProcessorGraph::buildRenderingSequence() Line 1337    C++
     Plugin Host.exe!juce::AudioProcessorGraph::handleAsyncUpdate() Line 1374    C++
     Plugin Host.exe!juce::AsyncUpdater::AsyncUpdaterMessage::messageCallback() Line 34    C++
     Plugin Host.exe!juce::WindowsMessageHelpers::dispatchMessageFromLParam(__int64 lParam) Line 49    C++
     Plugin Host.exe!juce::MessageManager::dispatchNextMessageOnSystemQueue(bool returnIfNoPendingMessages) Line 118    C++
     Plugin Host.exe!juce::MessageManager::runDispatchLoop() Line 130    C++
     Plugin Host.exe!juce::JUCEApplicationBase::main() Line 244    C++
     Plugin Host.exe!WinMain(HINSTANCE__ * __formal, HINSTANCE__ * __formal, char * __formal, int __formal) Line 119    C++


Stack 5
>    Plugin.vst3!AudioProcessor::prepareToPlay(double hostSampleRate, int samplesPerBlock) Line 115    C++
     Plugin.vst3!juce::JuceVST3Component::preparePlugin(double sampleRate, int bufferSize) Line 1822    C++
     Plugin.vst3!juce::JuceVST3Component::setBusArrangements(unsigned __int64 * inputs, long numIns, unsigned __int64 * outputs, long numOuts) Line 1489    C++
     Plugin Host.exe!juce::VST3Classes::VST3PluginInstance::prepareToPlay(double newSampleRate, int estimatedSamplesPerBlock) Line 1720    C++
     Plugin Host.exe!juce::AudioProcessorGraph::Node::prepare(double newSampleRate, int newBlockSize, juce::AudioProcessorGraph * graph, juce::AudioProcessor::ProcessingPrecision precision) Line 973    C++
     Plugin Host.exe!juce::AudioProcessorGraph::buildRenderingSequence() Line 1337    C++
     Plugin Host.exe!juce::AudioProcessorGraph::handleAsyncUpdate() Line 1374    C++
     Plugin Host.exe!juce::AsyncUpdater::AsyncUpdaterMessage::messageCallback() Line 34    C++
     Plugin Host.exe!juce::WindowsMessageHelpers::dispatchMessageFromLParam(__int64 lParam) Line 49    C++
     Plugin Host.exe!juce::MessageManager::dispatchNextMessageOnSystemQueue(bool returnIfNoPendingMessages) Line 118    C++
     Plugin Host.exe!juce::MessageManager::runDispatchLoop() Line 130    C++
     Plugin Host.exe!juce::JUCEApplicationBase::main() Line 244    C++
     Plugin Host.exe!WinMain(HINSTANCE__ * __formal, HINSTANCE__ * __formal, char * __formal, int __formal) Line 119    C++

Stack 6
>    Plugin.vst3!AudioProcessor::prepareToPlay(double hostSampleRate, int samplesPerBlock) Line 115    C++
     Plugin.vst3!juce::JuceVST3Component::preparePlugin(double sampleRate, int bufferSize) Line 1822    C++
     Plugin.vst3!juce::JuceVST3Component::setActive(unsigned char state) Line 925    C++
     Plugin Host.exe!juce::VST3Classes::VST3PluginInstance::prepareToPlay(double newSampleRate, int estimatedSamplesPerBlock) Line 1746    C++
     Plugin Host.exe!juce::AudioProcessorGraph::Node::prepare(double newSampleRate, int newBlockSize, juce::AudioProcessorGraph * graph, juce::AudioProcessor::ProcessingPrecision precision) Line 973    C++
     Plugin Host.exe!juce::AudioProcessorGraph::buildRenderingSequence() Line 1337    C++
     Plugin Host.exe!juce::AudioProcessorGraph::handleAsyncUpdate() Line 1374    C++
     Plugin Host.exe!juce::AsyncUpdater::AsyncUpdaterMessage::messageCallback() Line 34    C++
     Plugin Host.exe!juce::WindowsMessageHelpers::dispatchMessageFromLParam(__int64 lParam) Line 49    C++
     Plugin Host.exe!juce::MessageManager::dispatchNextMessageOnSystemQueue(bool returnIfNoPendingMessages) Line 118    C++
     Plugin Host.exe!juce::MessageManager::runDispatchLoop() Line 130    C++
     Plugin Host.exe!juce::JUCEApplicationBase::main() Line 244    C++
     Plugin Host.exe!WinMain(HINSTANCE__ * __formal, HINSTANCE__ * __formal, char * __formal, int __formal) Line 119    C++


VST2 stack:
>    Plugin.dll!AudioProcessor::prepareToPlay(double hostSampleRate, int samplesPerBlock) Line 115    C++
     Plugin.dll!JuceVSTWrapper::resume() Line 690    C++
     Plugin.dll!AudioEffect::dispatcher(int opcode, int index, int value, void * ptr, float opt) Line 189    C++
     Plugin.dll!AudioEffectX::dispatcher(int opcode, int index, int value, void * ptr, float opt) Line 318    C++
     Plugin.dll!JuceVSTWrapper::dispatcher(int opCode, int index, int value, void * ptr, float opt) Line 1457    C++
     Plugin.dll!AudioEffect::dispatchEffectClass(AEffect * e, int opCode, int index, int value, void * ptr, float opt) Line 55    C++
     Plugin Host.exe!juce::VSTPluginInstance::dispatch(const int opcode, const int index, const int value, void * const ptr, float opt) Line 1351    C++
     Plugin Host.exe!juce::VSTPluginInstance::setPower(const bool on) Line 1937    C++
     Plugin Host.exe!juce::VSTPluginInstance::prepareToPlay(double rate, int samplesPerBlockExpected) Line 959    C++
     Plugin Host.exe!juce::AudioProcessorGraph::Node::prepare(double newSampleRate, int newBlockSize, juce::AudioProcessorGraph * graph, juce::AudioProcessor::ProcessingPrecision precision) Line 973    C++
     Plugin Host.exe!juce::AudioProcessorGraph::buildRenderingSequence() Line 1337    C++
     Plugin Host.exe!juce::AudioProcessorGraph::handleAsyncUpdate() Line 1374    C++
     Plugin Host.exe!juce::AsyncUpdater::AsyncUpdaterMessage::messageCallback() Line 34    C++
     Plugin Host.exe!juce::WindowsMessageHelpers::dispatchMessageFromLParam(long lParam) Line 49    C++
     Plugin Host.exe!juce::MessageManager::dispatchNextMessageOnSystemQueue(bool returnIfNoPendingMessages) Line 118    C++
     Plugin Host.exe!juce::MessageManager::runDispatchLoop() Line 130    C++
     Plugin Host.exe!juce::JUCEApplicationBase::main() Line 244    C++
     Plugin Host.exe!WinMain(HINSTANCE__ * __formal, HINSTANCE__ * __formal, char * __formal, int __formal) Line 119    C++

 


#2

This could just be an artefact of the demo plugin host - I think it will scan the plugin (i.e. load and open a temporary instance). Have you tried it in a proper host?


#3

Cubase 6 calls prepareToPlay 3 times.  The first time is with the uninitialized default values, then the other 2 times are valid.

Are all 3 of these necessary or could I comment out the extra preparePlugin calls (besides SetActive)in juce's code?

 

The PluginHost sample's scan might explain the two extra calls from initialise and setupProcessing.The call from setBusArrangements only happens within the Plugin Host sample as well.  I'm not sure why I don't get that one from Cubase.

 

Cubase Stack 1  (with default values)
>    Alpine.vst3!RvsplayerAudioProcessor::prepareToPlay(double sampleRate, int samplesPerBlock) Line 110    C++
     Alpine.vst3!juce::JuceVST3Component::preparePlugin(double sampleRate, int bufferSize) Line 1822    C++
     Alpine.vst3!juce::JuceVST3Component::initialize(Steinberg::FUnknown * hostContext) Line 849    C++


Cubase Stack 2  (with correct values)
>    Alpine.vst3!RvsplayerAudioProcessor::prepareToPlay(double sampleRate, int samplesPerBlock) Line 110    C++
     Alpine.vst3!juce::JuceVST3Component::preparePlugin(double sampleRate, int bufferSize) Line 1822    C++
     Alpine.vst3!juce::JuceVST3Component::setupProcessing(Steinberg::Vst::ProcessSetup & newSetup) Line 1533    C++


Cubase Stack 3
>    Alpine.vst3!RvsplayerAudioProcessor::prepareToPlay(double sampleRate, int samplesPerBlock) Line 110    C++
     Alpine.vst3!juce::JuceVST3Component::preparePlugin(double sampleRate, int bufferSize) Line 1822    C++
     Alpine.vst3!juce::JuceVST3Component::setActive(unsigned char state) Line 925    C++
 


#4

I'll have a look. Thanks for reporting.


#5

This just bit us. Took us a while to figure out what was happening.

Is it really necessary to force the plugin to do a prepareToPlay call at 44.1 kHz before immediately calling it again with the real sample rate? That seems like a bug.

Our DSP library has a Singleton sampleRate, so loading a second instance of a plugin at higher sampling rates was causing chaos in the first instance.