+means that this event is played life (not in playback from a sequencer track).
+ This allows the Plug-In to handle these flagged events with higher priority, especially when the Plug-In has a big latency (AEffect::initialDelay)
+User-defined speaker types, to be extended in the negative range. Will be handled as their corresponding speaker types with abs values: e.g abs(kSpeakerU1) == kSpeakerL, abs(kSpeakerU2) == kSpeakerR)
Called when the Maximun block size changes (always in a suspend state). Note that the sampleFrames in Process Calls could be smaller than this block size, but NOT bigger.
+The constructor of your class is passed a parameter of the type audioMasterCallback. The actual mechanism in which your class gets constructed is not important right now. Effectively your class is constructed by the hosting application, which passes an object of type audioMasterCallback that handles the interaction with the plug-in. You pass this on to the base class' constructor and then can forget about it.
+
Parameters:
+
+
audioMaster
Passed by the Host and handles interaction
+
numPrograms
Pass the number of programs the plug-in provides
+
numParams
Pass the number of parameters the plug-in provides
+
+
+
MyPlug::MyPlug (audioMasterCallback audioMaster)
+: AudioEffectX (audioMaster, 1, 1) // 1 program, 1 parameter only
+{
+ setNumInputs (2); // stereo in
+ setNumOutputs (2); // stereo out
+ setUniqueID ('MyPl'); // you must change this for other plug-ins!
+ canProcessReplacing (); // supports replacing mode
+}
+
+Host stores plug-in state. Returns the size in bytes of the chunk (plug-in allocates the data array).
+
+
Parameters:
+
+
data
should point to the newly allocated memory block containg state data. You can savely release it in next suspend/resume call.
+
isPreset
true when saving a single program, false for all programs
+
+
+
Note:
If your plug-in is configured to use chunks (see AudioEffect::programsAreChunks), the Host will ask for a block of memory describing the current plug-in state for saving. To restore the state at a later stage, the same data is passed back to AudioEffect::setChunk. Alternatively, when not using chunk, the Host will simply save all parameter values.
+Stuff name with the name of the current program. Limited to kVstMaxProgNameLen.
+
+The program name is displayed in the rack, and can be edited by the user.
+
Parameters:
+
+
name
A string up to 24 char
+
+
+
Warning:
Please be aware that the string lengths supported by the default VST interface are normally limited to 24 characters. If you copy too much data into the buffers provided, you will break the Host application.
+Process 32 bit (single precision) floats (always in a resume state).
+
+This process method must be provided. It takes input data, applies its pocessing algorithm, and then puts the result to the output by overwriting the output buffer.
+
Parameters:
+
+
inputs
An array of pointers to the data
+
outputs
An array of pointers to where the data can be written to
+
sampleFrames
Number of sample frames to process
+
+
+
Warning:
Never call any Mac OS 9 functions (or other functions which call into the OS) inside your audio process function! This will crash the system when your plug-in is run in MP (multiprocessor) mode. If you must call into the OS, you must use MPRemoteCall () (see Apples' documentation), or explicitly use functions which are documented by Apple to be MP safe. On Mac OS X read the system header files to be sure that you only call thread safe functions.
+
+
+
+
+
+
+
+
+
void AudioEffect::programsAreChunks
+
(
+
bool
+
state = true
+
)
+
[virtual]
+
+
+
+
+
+
+Program data is handled in formatless chunks (using getChunk-setChunks).
+
+Called when the Maximun block size changes (always in a suspend state). Note that the sampleFrames in Process Calls could be smaller than this block size, but NOT bigger.
+
+This is called by the Host, and tells the plug-in that the maximum block size passed to processReplacing() will be blockSize.
+
Parameters:
+
+
blockSize
Maximum number of sample frames
+
+
+
Warning:
You must process exactlysampleFrames number of samples in inside processReplacing, not more!
+Set the number of inputs the plug-in will handle. For a plug-in which could change its IO configuration, this number is the maximun available inputs.
+
+This number is fixed at construction time and can't change until the plug-in is destroyed.
+Set the number of outputs the plug-in will handle. For a plug-in which could change its IO configuration, this number is the maximun available ouputs.
+
+This number is fixed at construction time and can't change until the plug-in is destroyed.
+Parameters are the individual parameter settings the user can adjust. A VST Host can automate these parameters. Set parameter index to value.
+
Parameters:
+
+
index
Index of the parameter to change
+
value
A float value between 0.0 and 1.0 inclusive
+
+
+
Note:
Parameter values, like all VST parameters, are declared as floats with an inclusive range of 0.0 to 1.0. How data is presented to the user is merely in the user-interface handling. This is a convention, but still worth regarding. Maybe the VST-Host's automation system depends on this range.
+Called after a control has changed in the editor and when the associated parameter should be automated.
+
+
Parameters:
+
+
index
parameter index
+
float
parameter value
+
+
+
Note:
An important thing to notice is that if the user changes a parameter in your editor, which is out of the Host's control if you are not using the default string based interface, you should call setParameterAutomated (). This ensures that the Host is notified of the parameter change, which allows it to record these changes for automation.
+Stuff the name field of the current program with name. Limited to kVstMaxProgNameLen.
+
+The program name is displayed in the rack, and can be edited by the user.
+
Parameters:
+
+
name
A string up to 24 char
+
+
+
Warning:
Please be aware that the string lengths supported by the default VST interface are normally limited to 24 characters. If you copy too much data into the buffers provided, you will break the Host application.
+
+
+
+
+
+
+
+
+
virtual void AudioEffect::setSampleRate
+
(
+
float
+
sampleRate
+
)
+
[inline, virtual]
+
+
+
+
+
+
+Called when the sample rate changes (always in a suspend state).
+
+Must call this! Set the plug-in's unique identifier. The Host uses this to identify the plug-in, for instance when it is loading effect programs and banks. On Steinberg Web Page you can find an UniqueID Database where you can record your UniqueID, it will check if the ID is already used by an another vendor. You can use CCONST('a','b','c','d') (defined in VST 2.0) to be platform independent to initialize an UniqueID.
Called one time before the start of process call. This indicates that the process call will be interrupted (due to Host reconfiguration or bypass state when the plug-in doesn't support softBypass).
+Reports what the plug-in is able to do (plugCanDos in audioeffectx.cpp).
+
+Report what the plug-in is able to do. In general you can but don't have to report whatever you support or not support via canDo. Some application functionality may require some specific reply, but in that case you will probably know. Best is to report whatever you know for sure. A Host application cannot make assumptions about the presence of the new 2.x features of a plug-in. Ignoring this inquiry methods and trying to access a 2.x feature from a 1.0 plug, or vice versa, will mean the plug-in or Host application will break. It is not the end-users job to pick and choose which plug-ins can be supported by which Host.
+Reports what the Host is able to do (hostCanDos in audioeffectx.cpp).
+
+Asks Host if it implements the feature text. A plug-in cannot assume a 2.x feature is available from the Host. Use this method to ascertain the environment in which the plug-in finds itself. Ignoring this inquiry methods and trying to access a 2.x feature in a 1.0 Host will mean your plug-in or Host application will break. It is not the end-users job to pick and choose which plug-ins can be supported by which Host.
+Feed the to speaker properties with the same values than from 's ones. It is assumed here that to exists yet, ie this function won't allocate memory for the speaker (this will prevent from having a difference between an Arrangement's number of channels and its actual speakers...)
+A plug-in is like a black box processing some audio coming in on some inputs (if any) and going out of some outputs (if any). This may be used to do offline or real-time processing, and sometimes it may be desirable to know the current context.
+Fill midiProgramName with information for 'thisProgramIndex'.
+
+Ask plug-in if MidiPrograms are used and if so, query for names, numbers (ProgramChange-Number + BankSelect-Number), categories and keynames of each MIDI Program, on each MIDI-channel. If this function is called, your plug-in has to read MidiProgramName::thisProgramIndex, fill out the other fields with the information assigned to a certain MIDI Program and return the number of available MIDI Programs on that MIDI Channel.
+
Note:
plug-in canDo "midiProgramNames". No effect, if 0 is returned.
+
Warning:
don't mix concepts: the MIDI Programs are totally independent from all other programs present in VST. The main difference is, that there are upto 16 simultaneous active MIDI Programs (one per channel), while there can be only one active "VST"-Program. (You should see the "VST"-Program as the one single main global program, which contains the entire current state of the plug-in.) This function can be called in any sequence.
+This opcode is only called, if the plug-in is of type kPlugCategShell, in order to extract all included sub-plugin´s names.
+
+
Parameters:
+
+
name
Points to a char buffer of size 64, which is to be filled with the name of the plug-in including the terminating zero
+
+
+
Returns:
Return the next plug-in's uniqueID
+
Note:
Example of Implementation
+ //---From the Host side : if found plugin is a Shell category-----------
+ if (effect->getCategory () == kPlugCategShell)
+ {
+ // scan shell for subplugins
+ char tempName[64] = {0};
+ VstInt32 plugUniqueID = 0;
+ while ((plugUniqueID = effect->dispatchEffect (effShellGetNextPlugin, 0, 0, tempName)) != 0)
+ {
+ // subplug needs a name
+ if (tempName[0] != 0)
+ {
+ ...do what you want with this tempName and plugUniqueID
+ }
+ }
+ }
+ //---From the Host side : Intanciate a subplugin of a shell plugin---
+ // retreive the uniqueID of this subplugin the host wants to load
+ // set it to the host currentID
+ currentID = subplugInfo->uniqueID;
+ // call the its shell plugin (main function)
+ main ();
+ // the shell plugin will ask for the currentUniqueID
+ // and should return the chosen subplugin
+ ...
+ //---From the plugin-Shell Side: for enumeration of subplugins---------
+ category = kPlugCategShell;
+ ->can ask the host if "shellCategory" is supported
+ // at start (instanciation) reset the index for the getNextShellPlugin call.
+ myPluginShell::index = 0;
+ // implementation of getNextShellPlugin (char* name);
+ VstInt32 myPluginShell::getNextShellPlugin (char* name)
+ {
+ strcpy (name, MyNameTable[index]);
+ return MyUniqueIDTable[index++];
+ }
+ ....
+ //---From the plugin-Shell Side: when instanciation-----
+ VstInt32 uniqueID = host->getCurrentUniqueID ();
+ if (uniqueID == 0) // the host instanciates the shell
+ {}
+ else // host try to instanciate one of my subplugin...identified by the uniqueID
+ {}
+
+Returns number of MIDI input channels used [0, 16].
+
+Called by the host application to determine how many MIDI input channels are actually used by a plugin e.g. to hide unused channels from the user. For compatibility with VST 2.3 and below, the default return value 0 means 'not implemented' - in this case the host assumes 16 MIDI channels to be present (or none at all).
+
Returns:
Number of MIDI input channels: 1-15, otherwise: 16 or no MIDI channels at all (0)
+
Note:
The VST 2.x protocol is limited to a maximum of 16 MIDI channels as defined by the MIDI Standard. This might change in future revisions of the API.
+Returns number of MIDI output channels used [0, 16].
+
+Called by the host application to determine how many MIDI output channels are actually used by a plugin e.g. to hide unused channels from the user. For compatibility with VST 2.3 and below, the default return value 0 means 'not implemented' - in this case the host assumes 16 MIDI channels to be present (or none at all).
+
Returns:
Number of MIDI output channels: 1-15, otherwise: 16 or no MIDI channels at all (0)
+
Note:
The VST 2.x protocol is limited to a maximum of 16 MIDI channels as defined by the MIDI Standard. This might change in future revisions of the API.
+Returns the Audio (maybe ASIO) output latency values.
+
+While inputLatency is probably not of concern, outputLatency may be used in conjunction with getTimeInfo(). samplePos of VstTimeInfo is ahead of the 'visual' sequencer play time by the output latency, such that when outputLatency samples have passed by, our processing result becomes audible.
+A plug-in will request time info by calling the function getTimeInfo() which returns a VstTimeInfo pointer (or NULL if not implemented by the Host). The mask parameter is composed of the same flags which will be found in the flags field of VstTimeInfo when returned, that is, if you need information about tempo. The parameter passed to getTimeInfo() should have the kVstTempoValid flag set. This request and delivery system is important, as a request like this may cause significant calculations at the application's end, which may take a lot of our precious time. This obviously means you should only set those flags that are required to get the information you need. Also please be aware that requesting information does not necessarily mean that that information is provided in return. Check the flags field in the VstTimeInfo structure to see if your request was actually met.
+
Parameters:
+
+
filter
A mask indicating which fields are requested, as some items may require extensive conversions. See the flags in VstTimeInfo
+
+
+
Returns:
A pointer to a VstTimeInfo structure or NULL if not implemented by the Host
+
+
+
+
+
+
+
+
+
bool AudioEffectX::getVendorString
+
(
+
char *
+
text
+
)
+
[inline, virtual]
+
+
+
+
+
+
+Fill text with a string identifying the vendor.
+
+Return true if the MidiProgramNames, MidiKeyNames or MidiControllerNames had changed on this MIDI channel.
+
+Ask plug-in for the currently active program on a certain MIDI Channel. Just like getMidiProgramName(), but MidiProgramName::thisProgramIndex has to be filled out with the currently active MIDI Program-index, which also has to be returned.
+
Parameters:
+
+
channel
+
+
+
Returns:
+
true: if the MidiProgramNames, MidiKeyNames or MidiControllerNames had changed on this channel
+Tell Host numInputs and/or numOutputs and/or initialDelay (and/or numParameters: to be avoid) have changed.
+
+The Host could call a suspend() (if the plug-in was enabled (in resume() state)) and then ask for getSpeakerArrangement() and/or check the numInputs and numOutputs and initialDelay and then call a resume().
+"to" is deleted, then created and initialized with the same values as "from" ones ("from" must exist).
+
+to is deleted, then created and initialized with the same values as from (must exist!). It's notably useful when setSpeakerArrangement() is called by the Host.
Events are always related to the current audio block. For each process cycle, processEvents() is called once before a processReplacing() call (if new events are available).
+Used for variable I/O processing (offline processing like timestreching).
+
+If called with varIo NULL, returning true indicates that this call is supported by the plug-in. Host will use processReplacing otherwise. The Host should call setTotalSampleToProcess before starting the processIO to inform the plug-in about how many samples will be processed in total. The Host should provide an output buffer at least 5 times bigger than input buffer.
+For 'soft-bypass' (this could be automated (in Audio Thread) that why you could NOT call iochanged (if needed) in this function, do it in fxidle).
+
+process still called (if Supported) although the plug-in was bypassed. Some plugs need to stay 'alive' even when bypassed. An example is a surround decoder which has more inputs than outputs and must maintain some reasonable signal distribution even when being bypassed. A CanDo 'bypass' allows to ask the plug-in if it supports soft bypass or not.
+
Note:
This bypass feature could be automated by the Host (this means avoid to much CPU requirement in this call)
+If the plug-in supports SoftBypass and it has a latency (initialDelay), in Bypassed state the plug-in has to used the same latency value.
+
Parameters:
+
+
onOff
+
+
+
Returns:
+
true: supports SoftBypass, process will be called, the plug-in should compensate its latency, and copy inputs to outputs
false: doesn't support SoftBypass, process will not be called, the Host should bypass the process call
+Set the plug-in's speaker arrangements. If a (VST >= 2.3) plug-in returns true, it means that it accepts this IO arrangement. The Host doesn't need to ask for getSpeakerArrangement(). If the plug-in returns false it means that it doesn't accept this arrangement, the Host should then ask for getSpeakerArrangement() and then can (optional) recall setSpeakerArrangement().
+Called one time before the start of process call. This indicates that the process call will be interrupted (due to Host reconfiguration or bypass state when the plug-in doesn't support softBypass).
+
+Convert a string representation to a parameter value.
+
+Especially useful for plug-ins without user interface. The application can then implement a text edit field for the user to set a parameter by entering text.
+
Parameters:
+
+
index
Index of the parameter
+
text
A textual description of the parameter's value. A NULL pointer is used to check the capability (return true).
+
+
+
Returns:
true on success
+
Note:
Implies setParameter (). text==0 is to be expected to check the capability (returns true)
+Essentially, a VST Plug-in is a pure audio processing component, and not an audio application: It is a component that is utilized within a host application. This host application provides the audio streams that are processed by the plug-in's code.
+Generally speaking, a VST plug-in it can take a stream of audio data, apply a process to the audio, and return the result to the host application. A VST Plug-In performs its process normally using the processor of the computer; It does not necessarily need dedicated digital signal processors. The audio stream is broken down into a series of blocks. The host supplies the blocks in sequence. The host and its current environment control the block-size. The VST Plug-In maintains the status of all its own parameters relating to the running process: The host does not maintain any information about what the plug-in did with the last block of data it processed.
+From the host application’s point of view, a VST Plug-In is a black box with an arbitrary number of inputs, outputs (MIDI or Audio), and associated parameters. The host needs no implicit knowledge of the plug-in's process to be able to use it. The plug-in process can use whatever parameters it wishes, internally to the process, but depending on the capabilities of the host, it can allow the changes to user parameters to be automated by the host.
+The source code of a VST Plug-In is platform independent, but the delivery system depends on the platform architecture:
+
+
On the Windows platform, a VST Plug-In is a multi-threaded DLL (Dynamic Link Library). A standard (default) folder for the VST Plug-Ins is defined in the registry under "HKEY_LOCAL_MACHINE\SOFTWARE\VST\VSTPluginsPath".
+
On Mac OS X, a VST Plug-In is a Bundle. You define the Plug-In's name in the plist.info file with the CFBundleName key.
+
On BeOS and SGI (under MOTIF, UNIX), a VST Plug-In is a shared Library.
+
+To learn more about VST you can subscribe to the VST Developer Mailing List - check the 3rd Party Developer Support section at www.steinberg.net.
+Audio processing in the plug is accomplished by one of 3 methods, namely process (), processReplacing () and processDoubleReplacing (). While process () takes input data, applies its processing algorithm, and then adds the result to the output (accumulating), processReplacing () and processDoubleReplacing (), overwrite the output buffer.
+
Note:
The accumulating process mode is deprecated in VST 2.4. Please implement processReplacing (mandatory!) and processDoubleReplacing (optional).
+Audio data processed by VST Plug-Ins is 32 bit (single precision) and optionally 64 bit (double precision) floating-point data. The default used range is from -1.0 to +1.0 inclusive [-1.0, +1.0] (where 1.0 corresponds to 0dB, 0.5 to -6dB and 0.0 to -oodB). Note that an effect could generate values above this range.
+All parameters - the user parameters, acting directly or indirectly on that data, as automated by the host, are 32 bit floating-point data. They must always range from 0.0 to 1.0 inclusive [0.0, +1.0], regardless of their internal or external representation.
+If you want to develop a VST Plug-In, you may prefer to go straight to the code examples now. These are very simple examples in which you will learn most of the important basic concepts just by reading a few lines of code. As a Plug-In developer you actually need to know very little about hosting a Plug-In. You should concentrate on the AudioEffect (VST 1.0) and AudioEffectX (VST 2.x extensions) base classes.
Note:
Never edit any of the SDK source files. Never ever. The host application relies on them being used as they are provided. Anything can be added or changed by overriding in your private classes derived from AudioEffectX.
+All user-interface issues are entirely separated from the audio processing issues. At its simplest there is an option where you can avoid providing a user interface at all. In this case the host requests character strings from the Plug-In representing each of the parameters. The host can use the separate ASCII strings for the value, the label, and the units of the parameters to construct its own user interface. This is how the simple code-examples, AGain & ADelay, work. This is also often a good way to develop a VST Plug-In, it offers a very short development cycle to start to test the algorithm. The proper interface can come later.
+The next user interface level is provided when the Plug-In defines its own editor. This allows practically any user interface to be defined. A negative aspect is that then you can quickly land up in platform specifics when dealing with the nuts an bolts of the interface issues, even though the audio process, the concepts and methodology remain platform independent.
+The final option is to use a portable framework for creating sophisticated user interfaces. This framework takes the form of the VSTGUI Library files that are available for almost all supported VST platforms. The VSTGUI Library classes and their usage is described in separate documentation.
The Steinberg VST Plug-In Software Development Kit can be used freely subject to certain licensing conditions by anyone interested in developing Plug-Ins, or to extend an application so that it’s capable of hosting VST Plug-Ins. When you chose to receive the VST Plug-In SDK you declared yourself to be in agreement with the Licensing conditions.
+These notes don’t replace the licensing agreement in any way, but quickly explain what you can and cannot do with the Steinberg VST Plug-In Software Development Kit.
+In the beginning of VST the Plug-In's GUI was attached at the left-top corner without a mechanism for the host to move it. This and the evolution of the macintosh platform makes it necessary to change this old behaviour. The modern way on Mac OS X to do UI design with C/C++ is to use HIViews and window compositing.
+ The VST SDK 2.4 requires the Plug-In to attach one HIView to the window and that this HIView can be moved around and that it can be embedded into other subviews.
+ Hosts which implement VST 2.4 need to provide a window to the Plug-In which is composited if the Plug-In itself uses 2.4. If the Plug-In uses an earlier VST SDK it should provide a non composited window.
+You need to use Carbon Events now, which you register on the HIView, not on the window if possible. But don't remove these opcodes from your editor yet, if you want your Plug-In to work in 2.3 hosts.
+Now there is a conflict situation that some VST 2.3 hosts may not work with HIViews and window compositing. You should map the mac specific effEdit* opcodes internaly to the same functions you call if you receive one of the appropriate Carbon Events (VSTGUI does this automatically). You also need to define VST_FORCE_DEPRECATED=0 as a preprocessor definition to get the effEdit* opcodes.
+With revision 1 of SDK 2.4 the default value for VST_FORCE_DEPRECATED is zero, if you build for ppc machines.
+The VSTMonitor Plug-In provided with this SDK is dedicated to "monitor" the communications between a VST Plug-In and the host which instanciates it: it keeps track of all the calls made by the host to the Plug-In's dispatcher, and of all the calls made by the Plug-In to the host's audiomaster. This is useful to record the sequence of calls done by any host to a VST Plug-In while loading it. Besides VSTMonitor has a "trigger" function which lets the user trigger (via a pop-up menu) any call to the host's audiomaster, to see how the host reacts (and notably to see if the function is implemented by the host...).
+You will find this plug-in in the VSTPlug-ins folder dedicated to each platform. You only need to put it directly in your own VST plug-ins folder in order to make it work.
+Calls made by the host to the plug-in are shown in grey, calls from the plug-in to the host are displayed in red. Internal (to the plug-in) calls are shown in blue.
+All the GUI buttons don't correspond to "real" parameters declared to the host, in order to prevent from disturbing the monitoring. Nevertheless, 3 "real" parameters and 2 programs are declared "publically" (although they are not used internally) to let you see how they are handled by the host.
+
Note:
Many hosts, while loading, open each Vst plug-in, for example to check their IO configuration. This is "hidden" to the user (as the plug-in is always closed as soon as the information needed has been recorded by the host), but VstMonitor can record even those calls, and display them the next time it is opened "normally" in the sequencer. That's why while the host is loading, an alert window may be automatically opened (on Windows platform), asking if the user want to keep track of "what has happened" (and although he has not explicitly opened the plug-in). On Mac, things recorded are kept by default (use Reset -see below- to delete them).
+VstMonitor's buttons:
+
+
display : by default, comms (a "comm" means a call to the dispatcher or audiomaster) are not automatically displayed when they occur. Clicking on this button causes the displaying.
+
reset : used to erase all the comms recorded.
+
export : export as a .txt file all the comms recorded,
+
trigger : a pop-up menu from which you can select a call to the host you would like to trigger VstMonitor's options :
+
filters : the user can choose to filter (ie not display, as they are always recorded in the background) some coms. In order to do that, you simply need to right-click (in the display) on the comm you want to filter. This comm is then added to the "filter menu" (one of the buttons beneath the display). Clicking on the name of a function in this menu cause the filter to be removed. Some filters are set by default, notably those which concern parameters (setParameter...), but can be unset via the menu.
+
function's params : the user can choose to display the parameters of the calls
+
function's returned value : the user can choose to display the "result" of th call (it means the value returned, and pointers which have been filled if necessary).
+
continuous display : set this if you want the synchronous display of the comms.
+The diagrams below illustrate the most important calling sequences taking place between VST host application and plug-in. This is of interest to plug-in developers as well as to host developers.
+In general, processEvents(), startProcess(), stopProcess(), process(), processReplacing() and processDoubleReplacing() are called from a time-critical high priority thread (except for offline processing).
+ To satisfy realtime constraints for low latency audio processing, memory allocations and lock-based syncronisation should be avoided.
+ The same applies to setParameter() and setProgram() when playing automation from host. Any others functions are called from UI thread in general.
+ The host takes care that processing and setup functions are isolated from each other. setSampleRate(), setBlockSize(), setProcessPrecision(), etc. calls occur only in suspended state, i.e. before resume() is called.
registered unique identifier (register it at Steinberg 3rd party support Web). This is used to identify a plug-in during save+load of preset and project.
+registered unique identifier (register it at Steinberg 3rd party support Web). This is used to identify a plug-in during save+load of preset and project.
+
+Speaker Properties. The origin for azimuth is right (as by math conventions dealing with radians). The elevation origin is also right, visualizing a rotation of a circle across the -pi/pi axis of the horizontal circle. Thus, an elevation of -pi/2 corresponds to bottom, and a speaker standing on the left, and 'beaming' upwards would have an azimuth of -pi, and an elevation of pi/2. For user interface representation, grads are more likely to be used, and the origins will obviously 'shift' accordingly.
+
SMPTE offset (in SMPTE subframes (bits; 1/80 of a frame)). The current SMPTE position can be calculated using samplePos, sampleRate, and smpteFrameRate.
VstTimeInfo::samplePos :Current Position. It must always be valid, and should not cost a lot to ask for. The sample position is ahead of the time displayed to the user. In sequencer stop mode, its value does not change. A 32 bit integer is too small for sample positions, and it's a double to make it easier to convert between ppq and samples.
+VstTimeInfo::ppqPos : At tempo 120, 1 quarter makes 1/2 second, so 2.0 ppq translates to 48000 samples at 48kHz sample rate. .25 ppq is one sixteenth note then. if you need something like 480ppq, you simply multiply ppq by that scaler.
+VstTimeInfo::barStartPos : Say we're at bars/beats readout 3.3.3. That's 2 bars + 2 q + 2 sixteenth, makes 2 * 4 + 2 + .25 = 10.25 ppq. at tempo 120, that's 10.25 * .5 = 5.125 seconds, times 48000 = 246000 samples (if my calculator servers me well :-).
+VstTimeInfo::samplesToNextClock : MIDI Clock Resolution (24 per Quarter Note), can be negative the distance to the next midi clock (24 ppq, pulses per quarter) in samples. unless samplePos falls precicely on a midi clock, this will either be negative such that the previous MIDI clock is addressed, or positive when referencing the following (future) MIDI clock.
+SMPTE offset (in SMPTE subframes (bits; 1/80 of a frame)). The current SMPTE position can be calculated using samplePos, sampleRate, and smpteFrameRate.
+
The VSTGUI interfaces & libraries were created by Yvan Grabit and Michael Schmidt (additional development Matthias Juwan, Arne Scheffler). The time they have invested has really made the huge inroads into cross-platform code compatibility.
+Thanks too, to Philippe Goutier who provided the VST Offline Interface.
+Not forgetting Dave Nicholson, Julien Junod, Pierre Jean Camillieri, Janne Roeper, Rene Hansen who did some additional typing.
+There were many more people involved in the creation of this interface, not all of whom can be mentioned here. We extend our thanks not just to the Steinberg Staff and Associates that contributed but also to the many other developers from other parties have helped with their input - mainly all the nice people on the VST Plug-In DEVELOPER MAILING LIST
+Thanks to all of you for having made this possible.
The VST offline interface is a powerful API that allows a Plug-In to freely read
+ audio files open in the host, to transform them or to generate new audio files.
+ The main features are:
+
+
+ The Plug-In controls reading/writing of audio samples
+ by sending commands to the host (this approach is the reverse of the mechanism
+ used in the real-time interface).
+
+
+ A Plug-In can read, simultaneously and with
+ random-access, any number of files open in the host.
+
+
+ A Plug-In can overwrite part or all of any open file
+ in the host, with random access.
+
+
+ A Plug-In can create one or more files (temporary
+ ones or not).
+
+
+ Any file created by the Plug-In can be freely re-read
+ and overwritten, with random access, during the process.
+
+
+ Thanks to "delayed overwriting", original samples in
+ source files are preserved in all cases and can be read again, at will and at
+ any time during a process.
+
+
+ Not only audio can be read/written in files: markers
+ can be created; sample selection can be set; edit cursor can be moved.
+ Moreover, custom parameters can be written along a file, with a time stamp,
+ and read again later, by the same Plug-In or another one.
+
+
+ No stereo assumption: could be used for multi-channel
+ files, if the host supports it.
+
+
+ An offline Plug-In can be used as a file transformer,
+ as a file analyzer or as a file generator.
+
+
+ An offline Plug-In does not deal directly with file
+ i/o and file formats: it just sends read and write commands with float
+ buffers, resulting in great simplification.
+
+
+ An offline-capable Plug-In is notified by the host anytime a change occurs in
+ the set of files available for editing (new open file, transformed file, new
+ marker created in a file, etc.). This allows the Plug-In, if necessary, to
+ update its user interface according to the context (e.g. new file with the
+ focus; or to show a list of files to pick from; etc.).
+
+
+
Declaring an offline Plug-In
+
The host knows if a given Plug-In supports the offline interface through the
+ canDo function, as follows:
+
+
+
+ If canDo ("offline") is true, the Plug-In supports
+ the offline interface
+
+
+ If canDo ("noRealTime") is true, the Plug-In only supports the offline
+ interface
+
+
Overview of the interface
+
Three structures are dedicated to the offline interface:
An offline process results from a nested sequence of calls, as follows:
+
+
+ The host calls offlineNotify, passing an array of
+ VstAudioFile structures that describe all files that can be read and written.
+ There is also a "start" argument that indicates to the Plug-In whether the
+ process should begin or not. The "start" argument is true e.g. after the user
+ presses the "Process" button (which should be under the host control). The
+ "start" argument is false if the call results from any change in the file
+ environment of the host.
+
+
+ In its implementation of offlineNotify, the Plug-In
+ states which file(s) it wants to read and write, by setting flags in the
+ VstAudioFile structures. Then the Plug-In calls the function offlineStart. The
+ last argument of offlineStart allows the Plug-In to create one or more new
+ files.
+
+
+ In its implementation of offlineStart, the host
+ initializes an array of VstOfflineTask structures, one for each file to read
+ or/and write. Then the host calls: offlinePrepare.
+
+
+ In its implementation of offlinePrepare, the Plug-In
+ continues the initialization of the VstOfflineTask structures (eg. set the
+ sample rate and number of channels in new files).
+
+
+ If offlinePrepare returns true, the host finalizes
+ the preparation of the VstOfflineTask structures (eg. allocate i/o audio
+ buffers), then calls offlineRun.
+
+
+ In its implementation of offlineRun, the Plug-In can call the host functions
+ offlineRead and offlineWrite at will, until its audio processing is completed.
+ The approach is therefore opposite to the realtime interface: the Plug-In here
+ instructs the host about which files to read and write, in which order, at
+ which rate. A small diagram can illustrate the nested sequence of calls.
+ Functions in red are called by the host and implemented by the Plug-In.
+ Functions in blue are called by the Plug-In and implemented by the host.
+
+
+
+
offlineNotify
+
{
+
+
+
offlineStart
+
+
{
+
+
offlinePrepare
+
offlineRun
+
{
+
+
+
. ..
+
offlineRead
+
offlineWrite
+
. ..
+
+
+
}
+
+
}
+
+
}
+
+
+
+
Details of the interface
+
struct VstAudioFile
+
This structure describes an audio file already open in the host. This
+ description is systemindependent: no file path is specified. A Plug-In does not
+ query the host about available files; instead, it gets informed about the
+ available files when the host calls the function offlineNotify.
+
+ Note: there is an option, however, to force the host to send a notification
+ (see kVstOfflineQueryFiles).
+
+ The host sets all the members of this structure, unless notified otherwise.
+
+
+
VstInt32 flags
+
See enum VstAudioFileFlags. Both host and Plug-In can set flags.
+
void* hostOwned
+
Any data private to host.
+
void* plugOwned
+
Any data private to Plug-In. This value is (optionally) set by the Plug-In in
+ its implementation of offlineNotify. This value is then copied by the host into
+ the VstOfflineTask structure (plugOwned member), when offlineStart is called
+ (this allows the Plug-In, if necessary, to make a link between the
+ offlineNotify call and the offlinePrepare/offlineRun calls).
+
char name[100]
+
+
Name of the file (no path, just name without any file extension). This can be
+ used by the Plug-In to display in its user interface the list of all files
+ available for processing. This is useful if the Plug-In requires the user to
+ select more than one file to perform its job (eg. mixer, file comparer,
+ etc...).
+
VstInt32 uniqueId
+
This value identifies a file instance in the host, during a session. Not two
+ file instances must ever get the same ID during a session. If a file gets
+ closed and is reopen later, it must be attributed an ID that was never
+ attributed so far during the session. From the host side, this can be easily
+ implemented with a simple global counter. This ID can be a useful reference for
+ a Plug-In, if its user interface maintains a list of files that the user can
+ select.
+
double sampleRate
+
sample rate of the file
+
VstInt32 numChannels
+
number of channels: 1 for mono, 2 for stereo, etc...
+
double numFrames
+
number of frames in the audio file
+
VstInt32 format
+
reserved for future. Currently 0.
+
double editCursorPosition
+
frame index of the edit cursor, or -1 if no such cursor exists. This member
+ represents the "edit-cursor" position, if any, but never the "playback-cursor"
+ position.
+
double selectionStart
+
frame index of first selected frame, or -1 if there is no selection
+
double selectionSize
+
number of frames in selection. Zero if no selection.
+
VstInt32 selectedChannelsMask
+
Bit mask describing which channels are selected. One bit per channel. Eg. value
+ 3 means that both channels of a stereo file are selected.
+
+
VstInt32 numMarkers
+
number of markers in the file. The Plug-In can use offlineRead to get details
+ about the markers.
+
+
VstInt32 timeRulerUnit
+
If the Plug-In needs to display time values, it might be nice to match the unit
+ system selected by the user for the file in the host. This is the reason why
+ this member, and the following ones, are provided. Possible values: 0:
+ undefined 1: samples units 2: hours/minutes/seconds/milliseconds 3: smpte 4:
+ measures and beats
+
+
double timeRulerOffset
+
frame offset of the time ruler for the window that displays the audio file.
+ Usually 0 but could be negative or positive.
+
+
double tempo
+
-1 if not used by the file's time ruler, else BPM units.
+
+
VstInt32 timeSigNumerator
+
-1 if not used by the file's time ruler, else number of beats per measure
+
+
VstInt32 timeSigDenominator
+
-1 if not used by the file's time ruler, else number of beats per whole note
+
+
VstInt32 ticksPerBlackNote
+
-1 if not used by the file's time ruler, else sequencer resolution
+
+
VstInt32 smpteFrameRate
+
-1 if not used by the file's time ruler, else refers to VstTimeInfo for
+ the meaning.
+
+
+
+
+
enum VstAudioFileFlags
+
This refers to the possible flags for the member flag of the structure
+ VstAudioFile:
+
The host sets its flags before calling offlineNotify. The Plug-In sets its flags
+ in its implementation of offlineNotify, before calling offlineStart.
+
+
+
+
+
+
kVstOfflineReadOnly
+
+
+
Set by host. Means that the file can't be modified, it can only be read. If the
+ Plug-In tries to write it later, the host should return false from
+ offlineWrite.
+
+
+
kVstOfflineNoRateConversion
+
+
+
Set by host. Means that the file can't have its sample rate modified.
+
+
kVstOfflineNoChannelChange
+
+
+
Set by host. Means that the number of channels can't be changed (eg. the host
+ might not allow an in-place mono to stereo conversion).
+
+
+
kVstOfflineCanProcessSelection
+
+
Set by the Plug-In if its process can be applied to a limited part of a file. If
+ no selection exists, the entire file range is used. The host checks this flag
+ and, accordingly, initializes the members positionToProcessFrom and
+ numFramesToProcess in the structure VstOfflineTask. Setting this flag is a
+ common case, but a counter example is e.g. a sample rate converter (the sample
+ rate is global to a file and can't be applied to a limited part of a file).
+
+
kVstOfflineNoCrossfade
+
+
Consider the case of a Plug-In transforming only a part of a file. To avoid a
+ click at the edges (between the processed part and the non-processed part) the
+ host might perform a short crossfade with the old samples, according to user
+ preferences. However, a Plug-In might want to reject this option for some
+ reasons (eg. the Plug-In performs a local glitch restoration and wants to
+ perform the crossfade itself). In that case, the Plug-In should set this flag
+ to instruct the host not to perform any crossfade.
+
+
kVstOfflineWantRead
+
+
If the Plug-In wants to read the file, it should set this flag. E.g. a
+ signal-generator Plug-In would never set that flag. If this flag is not set and
+ the Plug-In tries to read the file later, the host should return false from
+ offlineRead.
+
kVstOfflineWantWrite
+
If the Plug-In wants to overwrite part or the entire file, it should set this
+ flag. E.g. an analyzer plugin would never set that flag. Note: as an
+ alternative, the Plug-In can choose to create a new file, rather than
+ overwriting the source file (see offlineStart). If this flag is not set and the
+ Plug-In tries to write the file later, the host should return false from
+ offlineWrite.
+
kVstOfflineWantWriteMarker
+
+
If the Plug-In wants to modify or create markers in the file, it should set this
+ flag. If this flag is not set and the Plug-In tries to move or create a marker
+ later, the host should return false from offlineWrite.
+
+
kVstOfflineWantMoveCursor
+
If the Plug-In wants to move the edit-cursor of the file, it should set this
+ flag. If this flag is not set and the Plug-In tries to move the edit-cursor
+ later, the host should return false from offlineWrite.
+
kVstOfflineWantSelect
+
+
If the Plug-In wants to select samples in the file, it should set this flag. If
+ this flag is not set and the Plug-In tries to select samples later, the host
+ should return false from offlineWrite.
+
+
+
+
+
+
struct VstOfflineTask
+
This structure is used in offlinePrepare, offlineRun, offlineRead and
+ offlineWrite functions. Its main purpose is to be a parameter-holder to
+ instruct the host to read/write an existing file, or to write a new file.
+ However, it can also be used as a parameter-holder for other purposes, as we
+ shall see later (see VstOfflineOption). Thus, certain members of this structure
+ have a different meaning according to the option selected when calling
+ offlineRead and offlineWrite. For the sake of simplicity, we now mainly cover
+ the common case of reading/writing audio samples.
+
+ An important principle to understand from the beginning, is that each file
+ which is read or/and written is associated with a single VstOfflineTask
+ structure.
+
+
+
+
char processName[96]
+
+
Set by Plug-In in offlinePrepare. The host to label the process can
+ use this name. E.g. the host might display that name in a menu entry called
+ "Undo ....".
+
+ If the process uses multiple VstOfflineTask structures, only the first one
+ needs to have this field set (or all other VstOfflineTask structures should
+ have the same label).
+
+ This field might be erased later during the process, therefore the host should
+ make a copy of it.
+
+
+
double readPosition
+
+
Position, as frames, of the read "head" in the audio file. Set both by
+ Plug-In and host:
+
+ This value should be set by the Plug-In, before calling offlineRead, to
+ instruct the host.
+
+ On the other hand, the host updates the value to reflect the read position
+ after the call to offlineRead.
+
+
+
double writePosition
+
+
Position, as frames, of the write "head" in the audio file. Set both
+ by Plug-In and host:
+
+ This value should be set by the Plug-In, before calling offlineWrite, to
+ instruct the host.
+
+ On the other hand, the host updates the value to reflect the write position
+ after the call to offlineWrite.
+
+
+
VstInt32 readCount
+
Number of audio frames to read.
+
+ Set by Plug-In, before calling offlineRead.
+
+ When returning from offlineRead, readCount contains the number of actually read
+ frames. If the Plug-In tries to read beyond the end of the file (not considered
+ as an error), the float buffers are completed with blank frames by the host. In
+ that case, the number of blank frames is returned in the member value. In other
+ words, the sum (readCount + value) after the call is equal to the value of
+ readCount before the call.
+
+
+
VstInt32 writeCount
+
+
Number of audio frames to write.
+
+ Set by Plug-In, before calling offlineWrite.
+
+ Never set by the host. If the host can't write the samples because of a
+ disk-full situation, the host should return false from offlineWrite.
+
+
+
VstInt32 sizeInputBuffer
+
+
Size, as frames, of the audio input buffer.
+
+ Set by host before calling offlineRun.
+
+ This value remains unchanged during the whole process. A Plug-In can't read
+ more than this number of samples in a single call to offlineRead.
+
+
+
VstInt32 sizeOutputBuffer
+
+
Size, as frames, of the audio output buffer.
+
+ Set by host before calling offlineRun.
+
+ This value remains unchanged during the whole process. A Plug-In can't write
+ more than this number of samples in a single call to offlineWrite.
+
+
+
void* inputBuffer
+
+
void* outputBuffer
+
+
Both set by host, before calling offlineRun. The actual type of the
+ pointer depends on the channel mode: if the Plug-In has set the flag
+ kVstOfflineInterleavedAudio, then the type is float* (array of interleaved
+ samples). In the other case, the type is float** (array of array of samples).
+ The latter is the standard case.
+
+
+
double positionToProcessFrom
+
+
double numFramesToProcess
+
+
Set by host, according to the flags set in enum VstAudioFileFlags. This defines
+ the frame range that the Plug-In should read for its process.
+
+ If required for its algorithm, the Plug-In is allowed to read before and after
+ this range (if the range is a subset of the file), but only that range of
+ samples should be transformed.
+
+
+
double maxFramesToWrite
+
+
Set by Plug-In in offlinePrepare. This value could be used by the host for
+ optimization purposes (to select a proper write algorithm), and also to check
+ if the disk space is sufficient before starting the process.
+ If the Plug-In writes no audio, this value should be 0.
+
+ If the number of written samples is the same as the number of read samples,
+ this value should be equal to numFramesToProcess.
+
+ If the Plug-Ins does not know exactly the number of frames, this value should
+ be an approximate value, large enough for sure, but as small as possible (if
+ the Plug-In later tries to write more frames than this number, an error would
+ be issued by the host).
+
+ If the Plug-Ins does not know at all, this value should be -1 (this is the
+ default value of this member).
+
+
+
void* extraBuffer
+
+
This is set by the Plug-In. This is a buffer which is used to read/write other
+ data than audio. Meaning depends on the offlineRead/offlineWrite option (see
+ VstOfflineOption).
+
+
+
VstInt32 value
+
+
Set by Plug-In or host. Meaning depends on the offlineRead/offlineWrite option
+ (see VstOfflineOption).
+
+
+
VstInt32 index
+
+
Set by Plug-In or host. Meaning depends on the offlineRead/offlineWrite option
+ (see VstOfflineOption).
+
+ This value is also optionally set by the Plug-In during offlinePrepare, as
+ follows:
+
+ If the Plug-In generates a new file out of an existing file, then it should
+ initialize this value with the index of the VstOfflineTask structure
+ corresponding to the source file. This is not mandatory, but this info could be
+ of interest for the host. Be default, index is -1 when offlinePrepare is
+ called.
+
+
+
double numFramesInSourceFile
+
+
Number of frames in source file. This is set by the host in offlineStart.
+
+ This value is only set for existing source files.
+
+ If the VstOfflineTask structure refers to a file created by the host on behalf
+ of the Plug-In, this value is 0.
+
+
+
double sourceSampleRate
+
+
Sample rate of the source file. Set by host.
+
+ If the VstOfflineTask structure refers to a file created by the host on behalf
+ of the Plug-In, this value is 0. In that case, the Plug-In must initialize this
+ value when offlinePrepare is called (in that case, same value as
+ destinationSampleRate).
+
+
+
double destinationSampleRate
+
+
Sample rate of the destination file. Set by Plug-In in offlinePrepare (but
+ previously initialized by host as sourceSampleRate).
+
+ If the VstOfflineTask structure refers to a file created by the host on behalf
+ of the Plug-In, this value is 0. In that case, the Plug-In must initialize this
+ value when offlinePrepare is called (in that case, same value as
+ sourceSampleRate).
+
+
VstInt32 numSourceChannels
+
+
Number of channels in the source file. Set by host.
+
+ Note: if the mode kVstOfflineCanProcessSelection is active, and if only one
+ channel of a stereo file is selected, then numSourceChannels should be set to
+ 1. In that case, the file appears as a mono file from the Plug-In point of
+ view.
+
+ If the VstOfflineTask structure refers to a file created by the host on behalf
+ of the Plug-In, this value is 0. In that case, the Plug-In must initialize this
+ value when offlinePrepare is called (in that case, same value as
+ numDestinationChannels).
+
+
+
VstInt32 numDestinationChannels
+
+
Number of channels in the destination file. Set by Plug-In in offlinePrepare
+ (but previously initialized by host as numSourceChannels). This value is
+ required for the host to allocate the proper outputBuffer. If the
+ VstOfflineTask structure refers to a file created by the host on behalf of the
+ Plug-In, this value is 0. In that case, the Plug-In must initialize this value
+ when offlinePrepare is called (in that case, same value as numSourceChannels).
+
+
+
VstInt32 sourceFormat
+
+
Reserved for future.
+
+ Set by host.
+
+
+
VstInt32 destinationFormat
+
+
Reserved for future.
+
+ Set by Plug-In.
+
+
+
char outputText [512]
+
+
There are three uses for this member:
+
+ If the Plug-In has instructed the host to create a new file (see offlineStart),
+ then the Plug-In can optionally provide its name in this member, with a fully
+ qualified path (this file name must be selected by the user from the Plug-In
+ user interface). In that case, the file is saved by the host in the default
+ audio file format for the platform (this could also be a host specific option).
+ This name has to be initialized when offlinePrepare is called.
+
+ Note: the host, if a demo version, might reject this option!
+
+ If outputText is empty (common case), then the host creates the file in a
+ folder dedicated to temporary files. Later, it's up to the user to save the
+ file from the host.
+
+ Before returning from a function with false, the Plug-In can set the flag
+ kVstOfflinePlugError and then (over)write the outputText member. In that case,
+ the host should display the message to the user. If the host sets the flag
+ kVstOfflineUnvalidParameter, then the host might as well fill up the outputText
+ member, to give a hint to the Plug-In, for pure debugging purposes.
+
+
+
double progress
+
+
Set by Plug-In to inform the host about the current progress of the whole
+ operation. The value must be in the range 0 to 1. If the value is not in this
+ range (e.g. -1), the host must ignore it.
+
+ The Plug-In should, if possible, update this value each time before calling
+ offlineRead and offlineWrite (this would give the host enough occasions to
+ update a progress indicator to give feedback to the user).
+
If the process has to perform several "passes", the progress value is
+ allowed to go from 0 to 1 several times. However, ideally, a single 0 to 1 pass
+ is better for the user's feedback.
+
+ The progress value is meant to be global: if there are several VstOfflineTask
+ involved, the progress value should be "independent" from each task (yet, this
+ global progress should be set in each VstOfflineTask structure passed to
+ VstOfflineTask and offlineWrite calls).
+
+
+
VstInt32 progressMode
+
+
Reserved for the future.
+
+
+
char progressText[100]
+
+
Set by Plug-In, to describe what's going on. Can be updated any time. Optional.
+
+
+ Any data private to host void* plugOwned Any data private to Plug-In. This
+ value is firstly initialized by the host, in offlineStart, with the value of
+ the member plugOwned from the structure VstAudioFile (if the VstOfflineTask
+ corresponds to an existing file).
+
+
+
+
enum VstOfflineTaskFlags
+
+
+
kVstOfflineUnvalidParameter
+
+
Sets by host if the Plug-In passes an unvalid parameter. In that case, the host
+ might fill up the member outputText, to give a hint to the Plug-In, for
+ debugging purposes.
+
+
+
kVstOfflineNewFile
+
+
Set by the host to indicate that this VstOfflineTask represents a task that
+ creates/reads/writes a new file.
+
+
+
kVstOfflinePlugError
+
+
If an error happens in the Plug-In itself (not an error notified by the host),
+ then the Plug-In could optionally set this flag before returning false from its
+ function to indicate to the host that the member outputText (now) contains a
+ description of the error. The host is then in charge of displaying the message
+ to the user. The Plug-In should never try to display itself an error message
+ from the offlineRun function, since offlineRun could happen in a background
+ task.
+
+
kVstOfflineInterleavedAudio
+
+
The Plug-In should set this flag if it wants to get data in interleaved format.
+ By default, this is not the case.
+
+
+
kVstOfflineTempOutputFile
+
+
The Plug-In should set this flag in offlinePrepare, if the file to create must
+ be a temporary one. In that case, the file is deleted at the end of the process
+ (else, the file is usually open by the host at the end of the process).
+
+ This flag can obviously be set only for a new file, not for an existing file.
+
+
+
kVstOfflineFloatOutputFile
+
+
If the Plug-In needs creating a file made of float samples, this flag should be
+ set. Else, the default file format is dependant on the host (could be 16 bit,
+ 24 bit, float...). This can be useful if the Plug-In needs to store temporary
+ results to disk, without fear of clipping.
+
+
+ kVstOfflineRandomWrite
+
+
If the Plug-In needs to write randomly (not sequentially) a file, it should set
+ this flag. This flag should also be set if the file is to be written
+ sequentially more than once. This is a hint for the host to select a proper
+ writing procedure. If this flag is not set, the host could return false from
+ offlineWrite, if the Plug-In attempts a non-sequential writing.
+
+
+
kVstOfflineStretch
+
+
If the Plug-In time-stretches part or all of a file (eg. resampling), it should
+ set this flag. This instructs the host to move and stretch the relative file
+ markers, if any, to match the change. This also is of great importance in mode
+ "process-selection" (see kVstOfflineCanProcessSelection), as it instructs the
+ host to replace only the selection, whatever the number of written samples.
+ Let's take an example: if there are 10000 selected input samples (from 0 to
+ 9999) and 20000 samples are output by the Plug-In, then: 1) if the flag
+ kVstOfflineStretch is set: the host simply replaces the samples 0-9999 with the
+ new 20000 samples, and also moves/stretches the file markers as required. Note
+ that this requires the host to "push" the samples above position 20000 (to
+ insert the 10000 new samples). 2) if the flag kVstOfflineStretch is not set:
+ the host replaces the samples 0-19999 with the new 20000 samples (eg. echo
+ Plug-In that reads samples beyond the end of the selection, to merge the tail
+ of the echo).
+
+
+
kVstOfflineNoThread
+
+
The host might either create a background thread to run the process, or run it
+ inside the main application thread. The Plug-In does not decide about this.
+ However, it can happen that a process is so short that creating a thread would
+ be a waste of time. In that case, the Plug-In can set this flag as a hint to
+ the host.
+
+
struct VstAudioFileMarker
+
+
+
double position
+
+
Position of the marker
+
+
+
char name[32]
+
+
Name of the marker
+
+
+
VstInt32 type
+
+
The host might not support all types. We currently define:
+
+ 0: undefined
+
+ 1: generic marker
+
+ 2: temporary marker (not saved with the file)
+
+ 3: loop start marker
+
+ 4: loop end marker
+
+ 5: section start (whatever "section" might mean for the host)
+ 6: section end
+
+
+
VstInt32 id
+
+
This value is set by the host to identify a marker in a file. It can be any
+ value but 0, which is reserved to indicate a new marker (see option
+ kVstOfflineMarker). Not two markers can ever get the same ID for a given file.
+
+
+
+
enum VstOfflineOption
+
+
The functions offlineRead and offlineWrite have an argument (VstOfflineOption)
+ that allows to read/write different types of data. Let's see what these options
+ are:
+
+
+
kVstOfflineAudio
+
+
Use this option to read/write audio samples. See also description of
+ VstOfflineTask.
+
+ Reading can happen randomly. This means that any time during the process, a
+ Plug-In is allowed to jump at any frame position and read from that point.
+
+ Random reading can occur either in a read-only file or in a file currently
+ being written.
+
+ If a Plug-In tries to read beyond the end of the file (not to be considered as
+ an error by the host), the buffers are completed with blank samples by the
+ host. See comments about readCount on that subject.
+
+ Writing can happen randomly. This means that a file can be (over)written any
+ number of times and in any order. See kVstOfflineRandomWrite.
+
+ If writing is to happen at a position beyond the end of the file, the host must
+ extend the file as required and fill the gap with zeroes.
+
+ Delayed overwriting. When a Plug-In tries to overwrite part of an existing
+ source file, the host should in fact write the samples in a separate file. When
+ the process is finished, it's up to the host to actually replace the source
+ samples. This feature is required to let to the Plug-In have the possibility to
+ read the original samples at any time during a process.
+ One important consequence of the above feature is that any writing, whatever
+ the situation, always occur in a new - possibly temporary - file. This is why
+ all write positions that a Plug-In ever specifies, should always relate to the
+ origin Zero.
+
+ E.g. if a Plug-In wants to overwrite samples [10000-19999], it should specify
+ write position in the range [0-9999]. It's up to the host to do the rest,
+ later, to achieve the desired effect.
+
+ A Plug-In can never "overwrite" before the position given by the member
+ positionToProcessFrom; it is only possible to overwrite a continuous block
+ starting from positionToProcessFrom. If the Plug-In starts overwriting after
+ positionToProcessFrom, the gap if filled up with blank samples.
+
+ To ease the undo/redo handling of the host (usually based on audio blocks),
+ there is a rule to obey when "overwriting" a source file:
+
+ Only one continuous segment of a source file can be overwritten during a single
+ task. E.g. it is not allowed to overwrite samples 0 to 10000 then samples 50000
+ to 60000, hoping that intermediary samples are preserved. If a Plug-In does so,
+ the result is undefined. However, if a Plug-In really needs to do so, it must
+ simply transfer itself the intermediary samples.
+
kVstOfflinePeaks
+
+
The Plug-In UI might need to display part or all of a file. Reading a whole file
+ (for display purposes) is a time consuming operation; this is why most hosts
+ maintain a "peak file" that stores a "summary" of the audio file. With the
+ kVstOfflinePeaks option, a Plug-In can benefit from this host
+ functionality. This option is only to be used with offlineRead, not
+ offlineWrite. The required parameters of VstOfflineTask are the following ones:
+
+
+
+
+ positionToProcessFrom: set by Plug-In. The frame
+ index to display from.
+
+
+ numFramesToProcess: set by Plug-In. The number of
+ frames to display.
+
+
+ writeCount: set by host. This represents how many
+ elements of pixel information have been stored by the host in the
+ buffer.
+
+
+ value: set by Plug-In. This is the zoom factor: it
+ represents the desired number of frames to display per screen pixel.
+
+
+ index: set by host, see further.
+
+
+ inputBuffer: set by host. The elements of the array are not 32 bit float
+ values, but pairs of 16 bit integers.
+
+ An element of the array could be represented as follows:
+
+ struct { int16 y1; int16 y2; }
+
+ There are two ways to interpret the data written by the host into the buffer:
+
+ If the member index is set to 0 by the host, then the sound view is much
+ "compressed". In that case, a peak at a given position is represented by a
+ vertical line below and above the horizontal axis of the display. The value y1
+ represents the positive coordinate, above the axis, and the y2 coordinate, the
+ negative value below the axis.
+
+ y1 is always in the range 0 to 32767. It has to be scaled by the Plug-In,
+ according to its display's height.
+
+ y2 is always in the range -32767 to 0. It has to be scaled by the Plug-In,
+ according to its display's height. If the member index is set to 1 by the host,
+ then the sound view is less "compressed" and should be displayed as a
+ continuous curve.
+ In this case, y1 is always in the range -32767 to 32767. It has to be scaled by
+ the Plug-In, according to its display's height.
+
+ y2 is always 0 and should be ignored.
+
+ Note: since the buffer that is used with this option is the buffer normally
+ used for audio samples, the pixel data is interleaved or not, according to the
+ mode kVstOfflineInterleavedAudio, as selected for that VstOfflineTask
+ structure.
+
+ It is only possible to call this function on a source file, not on a file being
+ written during a process. If the host does not implement this function,
+ offlineRead returns false. The Plug-In could then read itself the audio
+ (kVstOfflineAudio option) to display the wave.
+
+
kVstOfflineParameter
+
+ If the host supports this option, the Plug-In can read and write parameters
+ along the audio-file. A "parameter" is a float value or byte array. Each
+ parameter is attributed an index (e.g. if there are 3 float values and 2
+ arrays, the indexes go from 0 to 4).
+
+ Examples of use: parameter automation; storage of meta-information (e.g. pitch)
+ usable by the same plugin, later during the same process, or in another process
+ by another Plug-In, etc.
+
+ The host is free to implement the underlying parameter storage, as it likes.
+ However, it is easy to understand that parameters should be stored in a sorted
+ vector, each one attached to a frame index.
+
+ The parameters are usually maintained in RAM by the host, therefore the Plug-In
+ should not over-use this feature and for instance write one parameter per
+ sample!
+
+ The host might choose to save the parameters into a project-file, or to embed
+ them into the audio file header, or not to save them at all (ie. all parameters
+ get erased when the audio file closes).
+
+
+
Writing parameters with offlineWrite:
+
+ processName: name of the parameter family.
+
+
+ If a Plug-In X writes parameters to a file, then a Plug-In Y can retrieve the
+ parameters only if it provides the right family name.
+
+ The name must be made unique enough, to prevent any clash.
+
+ This member only needs to be set for the first parameter to record during the
+ process.
+
+ If this first parameter belongs to a new family, the host destroys all
+ previously stored parameters.
+
+
+
+ value: version of the parameter family.
+
+
+ Freely under the control of the Plug-In. This member only needs to be set for
+ the first parameter to record during the process.
+
+
+
+ index: index of parameter to write.
+
+
+
+ writeCount: 0 if writing a float parameter, else byte size of the
+ parameter array.
+
+
+
+ extraBuffer: buffer allocated by the Plug-In to pass the parameter.
+
+
+ For writing a float, this pointer is actually a float* pointer, else this is a
+ pointer to the array.
+
+ If this pointer is NULL, then the parameter at that position, if any, is
+ deleted. If this pointer is NULL and the writePosition is negative, all
+ parameters are erased.
+
+
+
+ writePosition: position where to write the parameter.
+
+
+ Since parameters are not stored "inside" the audio samples, it does not matter
+ if the write position is temporarily beyond the end of the audio file.
+ For the sake of simplicity (when reading back later), it is not possible to
+ write more than one parameter at a given position. If this happens, the old
+ parameter gets erased. If this parameter is negative and extraBuffer is NULL,
+ all parameters get erased.
+
+
+
Reading parameters with offlineRead:
+
+ At the beginning, the Plug-In is usually ignorant about what parameters are
+ stored, and where. The first call to offlineRead is therefore a special one, as
+ follows:
+
+ The Plug-In initializes the member extraBuffer to 0 and the member readPosition
+ to the position it wants to get informed about (usually, 0). When returning
+ from offlineRead, the host has initialized the following parameters:
+
+
+
+ processName: name of the parameter family, or nothing if no recorded
+ parameter.
+
+
+ If the name of this parameter family is not supported by the Plug-In, the
+ Plug-In should not try to read the parameters.
+
+
+
+ value: version of the recorded parameter family. Might be useful for
+ the Plug-In.
+
+
+
+ readPosition: the frame index at which the next parameter is found
+ (this value was unchanged by the host if there was already a parameter there).
+
+
+
+ readCount: if the parameter is an array, this is its size (as bytes),
+ else the value is 0.
+
+
+
+ index: the index of the parameter, or -1 if no parameter was found.
+
+
+ In order to retrieve the parameters one by one, the Plug-In can then use
+ offlineRead in the following way:
+
+
+
+ Input parameters, as set by the Plug-In before
+ calling offlineRead.
+
+
+ readCount: should be 0 when retrieving a float
+ parameter, else indicates the size of the buffer, as bytes, to receive the
+ array.
+
+
+ extraBuffer: buffer allocated by the Plug-In to
+ receive the parameter. If the parameter is a float, this pointer is actually a
+ float* pointer, else this is a pointer to an array.
+
+
+ readPosition: position where to read the parameter.
+ If there is no parameter at this position, the host returns false.
+
+
+ index: index of the parameter to retrieve.
+
+
+ Output parameters, as set by the host after calling
+ offlineRead:
+
+
+ index: index of the next parameter, else -1.
+
+
+ readPosition: position of next recorded parameter, or
+ -1 if no more parameter. This is an useful hint for the Plug-In, to make it
+ easy and fast to retrieve sequentially all recorded parameters.
+
+
+ readCount: if the next parameter is a float, this value is 0. If it is an
+ array, this value is the byte-size of this array.
+
+
+
kVstOfflineMarker
+
+ With this option, the Plug-In can create one or more markers in the file, or
+ move existing ones.
+
+ To know which markers currently exist in a given file, the Plug-In can use
+ offlineRead, with the following parameters:
+
+
+
+ extraBuffer: buffer allocated by the Plug-In, to
+ receive a copy of the markers. If this value is NULL, then offlineRead sets
+ the number of markers into the member readCount. This is a way for the Plug-In
+ to know how many markers exist in the file, and therefore to allocate a proper
+ buffer size (and call again offlineRead).
+
+
+ readCount: the size of the buffer (number of VstAudioFileMarker elements). If
+ this size is not equal to the current number of markers, the offlineRead
+ function should return false.
+
+ To write new markers:
+
+
+
+ extraBuffer: a buffer allocated by the Plug-In that
+ holds the markers to create, and only them.
+
+
+ writeCount: the number of markers in the buffer. Important: the member id of a
+ marker to create must be 0. When returning from the offlineWrite function, the
+ id of the marker has been initialized by the host (it could be reused by the
+ Plug-In to move the marker later).
+
+ To move existing markers:
+
+
+
+ extraBuffer: a buffer allocated by the Plug-In that
+ holds the markers to move. These markers must have been previously retrieved
+ through offlineRead. The host identifies the markers to move by checking the
+ id member of the markers. The position member of a marker structure represents
+ the new position that a marker should adopt. If position is -1, then the host
+ deletes the markers.
+
+
+ writeCount: the number of markers in the buffer.
+
+ To copy markers from one file to another:
+
+ If the Plug-In creates a new file out of a source file, it might be convenient
+ to copy the source file markers into the new file. In this case, the Plug-In
+ can call the offlineWrite function with the following parameters:
+
+
+
+ extraBuffer: NULL
+
+
+ index: index of the VstOfflineTask structure that corresponds to the source
+ file.
+
+
+
+
kVstOfflineCursor
+
+ By calling offlineRead with this option, the Plug-In retrieves the file's
+ edit-cursor position:
+
+
+
+ readPosition: position of the cursor, or -1 if no
+ edit-cursor
+
+
+ index: bit mask describing on which channel(s) lies the edit-cursor.
+
+ To move the edit cursor to a certain location, the Plug-In should initialize
+ the following members:
+
+
+
+ writePosition: position of the cursor
+
+
+ index: bit mask describing on which channel(s) should lie the edit-cursor. -1
+ means all channels. If the host does not support the placement of the
+ edit-cursor on individual channels, it should ignore this parameter. It's worth
+ noting that "edit-cursor" position does not mean "playback-cursor"
+ position.
+
+
+
kVstOfflineSelection
+
+ By calling offlineRead with this option, the Plug-In retrieves the current
+ sample selection in the file:
+
+
+
+ positionToProcessFrom: the first selected frame, or
+ -1
+
+
+ numFramesToProcess: the size of the selection, or
+ 0
+
+
+ index: bit mask describing which channel(s) are selected
+
+ To set a selection in the file, the Plug-In should initialize the above
+ members.
+
+ If the host does not support the selection of individual channels, it should
+ ignore index and select all channels.
+
+ If the host does not support sample selections, offlineWrite should return
+ false.
+
kVstOfflineQueryFiles
+
+
If the Plug-In desires to get notified about which files are available in the
+ host, it should call offlineRead with this option.
+
+ The first parameter of offlineRead (VstOfflineTask*) should be NULL. On
+ receiving this call, the host should call, immedialty or later, offlineNotify,
+ with the start parameter set to false. In other words, the
+ kVstOfflineQueryFiles option is a way to force the host to call offlineNotify,
+ in order to get informed about open files (normally, the host only calls
+ offlineNotify if a change happens in the set of open files). It is important to
+ insist on the fact that the host is free to call kVstOfflineQueryFiles
+ asynchronously, ie. not immediatly when kVstOfflineQueryFiles is called.
+
+ Normally, this option is only used if the Plug-In needs to be notified about
+ the file information, in order to update its user interface.
The host calls this Plug-In function in two cases:
+
+
+
+
+ When the Plug-In's process is to be executed. E.g.
+ the user has pressed the "Process" button. In that case, the "start" parameter
+ is true.
+
+
+ Anytime a change happens in the set of files open in the host. In that case,
+ the "start" parameter is false.
+
+
+ The purpose of this notification is to give the Plug-In a chance to update its
+ user interface according to the host environment.
+
+ For example:
+
+ The Plug-In might display the list of all files available for processing; this
+ list needs to be updated if a new file is open or closed in the host.
+ The Plug-In might display some information about the file with the focus: this
+ needs to change if a new file gains the focus.
+
+ Etc...
+
+ Tip: since the VstAudioFile structure contains
+ parameters that are likely to often change, such as cursor position or sample
+ selection, the offlineNotify function might be called often. Therefore, a good
+ design for a Plug-In that needs to update its user interface would be to cache
+ the VstAudioFile settings, so as to actually update its user interface only
+ when really required (eg. if the Plug-In does not care about the editcursor
+ position in a file. It should not update its user-interface only if the
+ edit-cursor position happens to move in a file).
+
+
+ The host as aparameter passes an array of VstAudioFile structures.
+
+ The number of elements in this array is given by the parameter numAudioFiles.
+
+ numAudioFiles is 0 if there is no open file in the host, and in that case, the
+ parameter "ptr" is NULL.
+
+ The first element of the array always represents the file with the focus.
+
+ If the "start" argument is true, the Plug-In should start the process by
+ calling offlineStart. Else, the Plug-In might, or might not, starts a read-only
+ process, to update its user-interface. See offlineStart.
+
+
Whatever the state of the start argument, the Plug-In should return false from
+ the function if it can't process the file(s) open in the host. E.g. if the
+ Plug-In only works with stereo files, and the file with the focus is mono, the
+ Plug-In should return false from this function. This allows the host, for
+ instance, to disable the process button of the user interface.
+
+ Important: the Plug-In should not initialize anything internally at this
+ stage. All internal initialization and cleanup required for the process should
+ happen inside offlineRun, and only there.
The host calls this function so that the Plug-In complements the
+ VstOfflineTask structure(s). If everything is fine, the function should
+ return true. Important: the Plug-In should not initialize anything
+ internally at this stage. All internal initialization and cleanup required for
+ the process should happen inside offlineRun, and only
+ there.
+
+
This function is called by the host once the VstOfflineTask structure(s) is(are)
+ ready. Within this function, the Plug-In does its audio processing and calls
+ offlineRead and offlineWrite at will. If
+ any error is detected during this procedure, the function should return false.
+
+ Important: all internal initialization and cleanup required for the
+ process should happen inside offlineRun, and only
+ there. E.g. if the Plug-In should allocate some memory, this should be done
+ inside this function (as well as the deallocation).
+
+
When the function offlineNotify is called, the
+ Plug-In might decide to start a process. For this purpose, the Plug-In has to
+ decide which file(s) to process, and also if some new file(s) should be
+ created.
+
+ By setting the member flag of each VstAudioFile structure,
+ the Plug-In instructs the host about which file(s) should be processed. In many
+ cases, only the first VstAudioFile element (the focused file) is concerned.
+
+ The parameter numAudioFiles is simply the one passed from offlineNotify.
+
+ The parameter numNewAudioFiles is the number of files that the Plug-In want to
+ create.
+
+ E.g. if the Plug-In selects one file from the VstAudioFile array and sets the
+ value of numNewAudioFiles to 1, the host will create two VstOfflineTask
+ structures. By convention, all VstOfflineTask structures corresponding to new
+ files are placed by the host at the end of the array passed to offlineRun (ie,
+ the front of the array corresponds to already existing files).
+
+ It is not allowed for a Plug-In to call offlineStart if the Plug-In is not
+ itself called with offlineNotify. This is to ensure a synchronous protocol with
+ the host. If the Plug-In would call offlineStart asynchronously, maybe the
+ VstAudioFile structures would not be valid anymore at that time, resulting in
+ an undefined behaviour.
+
+
This function is called by the Plug-In to read data. See enum VstOfflineOption
+ to see what kind of data can be read, apart audio samples.
+
About the parameter readSource:
+
As already seen, a single VstOfflineTask structure can be used both to read an
+ existing file, and to overwrite it. Moreover, the offline specification states
+ that it is possible, at any time, to read both the original samples and the new
+ ones (the "overwritten" samples). This is the reason for the readSource
+ parameter: set it to true to read the original samples and to false to read the
+ recently written samples.
+
+
This function is called by the Plug-In to write data.
+
+ See enum VstOfflineOption to see what kind of
+ data can be written, apart audio samples.
+
+
+
+
+In general, VST Plug-Ins present a flat, unsorted list of parameters to the host application, and finally to the user.
+The VST Parameters Structure XML definition provides an easy way to structure parameters of existing VST Plug-Ins hierarchically, without having to recompile the Plug-In binary.
+
+
+
+Windows:
+
+The host application searches for a .vstxml file next to the Plug-In DLL (e.g. if your Plug-In is in '...\Vstplugins\MyEffect.dll' the corresponding XML file must be named '...\Vstplugins\MyEffect.vstxml').
+Alternatively, the Parameter Structure XML can be embedded in the DLL as a resource (resource type VSTXML, resource identifier 1).
+Please note that an external .vstxml file always overrides the embedded resource!
+
+
+
+Mac OS X:
+
+The .vstxml file is in the Resources Folder of the bundle and its name is constructed from the CFBundleName.
+
+ corresponds to zero-based index in flat parameter list.
+ can either be an integer constant (e.g. "100") or an expression which evaluates
+ to an integer (e.g. "offset + 1").
+ See Relative Parameter Addressing for details.
+
+
+
+
+ name
+
+
+ parameter name visible to the user (e.g. "Volume").
+
+
+
+
+ label
+
+
+ parameter label visible in generic editor or on remote control (e.g. "dB")
+
+
+
+
+ shortName
+
+
+ short parameter name, displayed on remote controls.
+ can be a list of several names of different lengths, separated by colons
+ (e.g. "OSC Frequ., OSCFrq., Frq"). The host application selects best fitting string
+ for current remote displays.
+
+
+
+
+ type
+
+
+ user defined (see ValueType)
+ or predefined value type. Default type is a linear fader between 0.0 and 1.0
+
+ Predefined types:
+ - switch : parameter toggles between 0 and 1
+
+
+
+
+ numberOfStates
+
+
+ defines how many states this parameter can have:
+
+
+ state N = [N / numberOfStates, (N + 1) / numberOfStates[
+ state N = (long)(value * numberOfStates)
+
+
+
+
+
+ defaultValue
+
+
+ default value normalized between [0.0, 1.0]
+
+
+
+
+
+
Remarks:
+
+
+Most VST Plug-Ins already provide parameter attributes like name, label, etc. and support string conversion.
+The XML description always overwrites Plug-In -provided attributes!
+Everything not described in XML is taken from the Plug-In at runtime.
+
+Groups are used to create hierarchical parameter structures. A <Group> either contains <Param> tags directly,
+or is defined by a Template.
+
+
+
Attributes:
+
+
+
+
+
+ name
+
+
+ group name visible to the user (e.g. "Channel 1", "LFO Section",...)
+
+
+
+
+ template
+
+
+ Name of template defining this group (optional).
+
+
+
+
+ values
+
+
+ List of arguments passed to the template
+ (see Relative Parameter Addressing for details).
+
+ Each arguments consists of a name and an integer value (e.g. "offset=100").
+ Multiple arguments are separated by semicolons, whitespaces are ignored
+ (e.g. "offset1=100; offset2=100").
+
+
+
+
+
+
+
+
+
Template
+
+
+
+
+
+ <Templatename="..."/>
+
+
+
+
+
+
+Assume a Plug-In with 16 channels, each consisting of an identical set of parameters. You only have to
+describe a channel once as a template and create 16 "instances" using the <Group> tag.
+If each channel contains let's say 20 parameters, which appear continuously in the flat parameter list,
+they can be addressed using an offset value instead of absolute indices
+(see Relative Parameter Addressing for details).
+
+
+
Attributes:
+
+
+
+
+
+ name
+
+
+ internal template name, referred to by groups.
+
+
+
+
+
+
+
+
+
ValueType
+
+
+
+
+
+ <ValueTypename="..." label="..."/>
+
+
+
+
+
+
+Defines an internal value type by a list of <Entry> tags.
+
+
+
Attributes:
+
+
+
+
+
+ name
+
+
+ internal value type name, referred to by parameters.
+
+
+
+
+ label
+
+
+ value label (e.g. "dB")
+
+
+
+
+
+
Remarks:
+
+
+The label attribute is used as parameter label if the label field of a <Param>
+tag using this value type is empty.
+
+
+
+
+
+
Entry
+
+
+
+
+
+ <Entryname="..." value="..."/>
+
+
+
+
+
+
+Each entry in a <ValueType> list provides a string representation for
+a certain parameter state. A simple example would be a toggle parameter with two
+states named "On" and "Off". The string "Off" should be displayed if the normalized parameter value is between
+0.0 and 0.5 (exclusively), and "On" if it is >= 0.5 and <= 1.0.
+
+
+
Attributes:
+
+
+
+
+
+ name
+
+
+ name of parameter state, displayed to the user (e.g. "On", "Off", "Sine", "Square",...)
+
+
+
+
+ value
+
+
+ optional: describes the parameter range this state corresponds to,
+ using the mathematical range definition [a, b].
+
+ Exclusive range:
+ e.g. "[0.0,0.5[" -> if value >= 0.0 and < 0.5
+
+ Inclusive range:
+ e.g. "[0.5,1.0]" -> if value >= 0.5 and <= 1.0
+
+
+
+
+
+
Remarks:
+
+
+The value range is optional. If not specified, the limits of a state are calculated based on the total number of entries
+in the value type:
+
+a = index / total
+b = (index + 1) / total;
+
+
+
+
+
+
Relative Parameter Addressing
+
+
+Relative parameter addressing is used to describe parameter IDs inside templates.
+Instead of assigning a parameter index directly, an expression - mostly consisting of a "base address" variable and
+a constant offset value - can be used. The variable is passed to the template each time it is "instanciated" as a
+group.
+
+With VST SDK 2.4 you can compile native VST Plug-Ins for 64 Bit Platforms (e.g. Windows XP x64 Edition). The formerly used 'long' data type has been replaced by VstInt32 and VstIntPtr:
+
VstInt32 is always 32 bits wide, regardless of the platform compiled for.
+
VstIntPtr is a generic type, with the same size as a pointer (4 Bytes on a 32 bit OS, 8 Bytes on x64 Systems).
+A new process function has been added to support 64 bit (double precision) floating-point audio samples. Please note that this function is optional, whereas the processReplacing function for 32 bit (single precision) floating-point samples is mandatory!
+New enum VstMidiEventFlags for VstMidiEvent::flags with value kVstMidiEventIsRealtime which indicates that an event is played live, not from a sequencer track. This allows the Plug-In to handle these flagged events with higher priority, especially when the Plug-In has a high latency (AEffect::initialDelay).
+
+ Two new methods (getNumMidiInputChannels and getNumMidiOutputChannels) allow the Plug-In to inform the host how many MIDI channels are actually used for input and/or output. In this case the host doesnt need to display all 16 MIDI channels to the user, if the Plug-In uses less than 16.
+The VST Parameters Structure XML definition provides an easy way to structure parameters of existing VST Plug-Ins hierarchically, without having to recompile the Plug-In binary. The VST SDK package contains a tool to test, extract and embed VSTXML resources.
+The VST Protocol is a historically grown technology. In Version 2.4 the API has undergone a general cleanup. Some rarely (or not at all) used features and inconsistent or redundant parts of the protocol have been declared as deprecated. Deprecated opcodes and data structures are still available in the SDK headers, but their names are modified if the VST_FORCE_DEPRECATED compile switch is active (1 by default) - this might cause errors when compiling existing code.
+What does it mean? Exisiting (already released) Hosts and Plug-Ins of course remain uninfluenced. If you create a new Plug with VST SDK 2.4 it should work in any existing host as well. However, there are some details that might cause compatibility problems:
+
+
MIDI Input: New Plugs should implement AudioEffectX::canDo "receiveVstMidiEvent" to indicate the presence of a MIDI Input, instead of wantEvents. The base class method AudioEffectX::resume can be called for compatibility with old VST hosts (< 2.4).
Idle Calls outside Editor: AudioEffectX::needIdle and AudioEffectX::fxIdle are not widely supported, thus Plugs can not rely on it. Please create your own timer/background thread if needed. On Windows SetTimer with a callback function could be used (look it up on MSDN), the MacOS X equivalent is InstallEventLoopTimer.
The exported 'main' function (aka 'main_macho' on Mac or 'main_plugin') should be named 'VSTPluginMain' on all platforms! For downwards compatibility, you can export both.
+
+To support VST Plug-Ins <= 2.4 in new Host Applications, you'll have to implement workarounds. In the long run, deprecated features shouldn't be used anymore. Future versions of VST SDK will not contain them at all.