VST Bank Support

Hi Jules, Jucers,
The current framework does not support vst bank load and save.
I have made some changes so this functionality is supported.
Regards
Koull (Kyriacos)

//********************
//file juce_VstWrapper.cpp
VstInt32 getChunk (void** data, bool isPreset)
{
chunkMemory.setSize (0);
//filter->getStateInformation (chunkMemory);
//kk changed to support both presets and banks
filter->getStateInformation (chunkMemory,isPreset);
data = (void) chunkMemory;

    // because the chunk is only needed temporarily by the host (or at least you'd
    // hope so) we'll give it a while and then free it in the timer callback.
    chunkMemoryTime = JUCE_NAMESPACE::Time::getApproximateMillisecondCounter();

    return chunkMemory.getSize();
}

VstInt32 setChunk (void* data, VstInt32 byteSize, bool isPreset)
{
chunkMemory.setSize (0);
chunkMemoryTime = 0;

    if (byteSize > 0 && data != 0)
    	//filter->setStateInformation (data, byteSize);
	//kk changed to support both presets and banks
	filter->setStateInformation (data, byteSize, isPreset);

    return 0;
}

//*************************
//file juce_AudioFilterBase.h
virtual void JUCE_CALLTYPE getStateInformation (JUCE_NAMESPACE::MemoryBlock& destData) = 0;
//kk overload to support vst banks
virtual void JUCE_CALLTYPE getStateInformation (JUCE_NAMESPACE::MemoryBlock& destData, bool isPreset) = 0;

/** This must restore the plugin's state from a block of data previously created
    using getStateInformation().

    See also the helper function getXmlFromBinary() for loading settings as XML.
*/
	virtual void JUCE_CALLTYPE setStateInformation (const void* data, int sizeInBytes) = 0;
//kk overload to support vst banks
virtual void JUCE_CALLTYPE setStateInformation (const void* data, int sizeInBytes, bool isPreset) = 0;

//****************************
//file DemoJuceFilter.h
void JUCE_CALLTYPE getStateInformation (JUCE_NAMESPACE::MemoryBlock& destData);
void JUCE_CALLTYPE setStateInformation (const void* data, int sizeInBytes);

//kk vst bank support
void JUCE_CALLTYPE getStateInformation (JUCE_NAMESPACE::MemoryBlock& destData, bool isPreset);
void JUCE_CALLTYPE setStateInformation (const void* data, int sizeInBytes, bool isPreset);

//**********************
//file DemoJuceFilter.cpp
//kk example how to save/load banks and presets
void DemoJuceFilter::getStateInformation (JUCE_NAMESPACE::MemoryBlock& destData, bool isPreset)
{
if (isPreset)
{
getStateInformation(destData);
}
else //complete bank
{
XmlElement xmlState (T(“KK_BANK”));

   xmlState.setAttribute (T("Version"), "1.1.0");

   String sMyParameter = "MyParameter";


   for (int i=0; i<this->getNumPrograms(); i++)
   {
	

		xmlState.setAttribute (sMyParameter  + String(i), programs[i]->fMyParameter);

   }

   copyXmlToBinary (xmlState, destData);
}

}

void DemoJuceFilter::setStateInformation (const void* data, int sizeInBytes, bool isPreset)
{
if (isPreset)
{
setStateInformation(data, sizeInBytes);
}
else
{
String sMyParameter = “MyParameter”;

	XmlElement* const xmlState = getXmlFromBinary (data, sizeInBytes);

	if (xmlState != 0)
	{
		// check that it's the right type of xml..
		if (xmlState->hasTagName (T("KK_BANK")))
		{
			for (int i=0; i<this->getNumPrograms(); i++)
			{
				programs[i]->fMyParameter = (float) xmlState->getDoubleAttribute (sMyParameter  + String(i), fMyParameter);

			}

			sendChangeMessage (this);
		}
	}
	delete xmlState;
}

}

That’s interesting - I didn’t realise that’s how it worked. Not surprising, as of course the VST headers don’t actually say what “isPreset” is for.

I’ll merge something similar into my code, but will change “isPreset” to “onlyStoreCurrentProgramData”, so that it’s clear what’s actually happening!

great

yep gr8 ! that was i thing i had overseen a lot of times… the pity of using too much the AudioFilterBase, that let you forget about the underlying implementations :slight_smile: