vpr.h
#if !defined(vpr_h)
#define vpr_h
// Design goals of VPR (VST Plugin Replacement API):
//
// Cross-platform (Windows, MacOS X, Linux, Embedded).
// Cross-architecture (32-bit, 64-bit, Endian-ness is host native).
// Host and plug-in behaviors fully specified.
// Capabilities are found by getting procedure pointers by name (like OpenGL).
// UNICODE labels for all text (wchar_t).
// Version levels, where version X.Y means that capabilities Z,W are guaranteed.
// Well-defined threading model.
// C API
// Should be possible to make high-quality VST 2.4 <-> VPR mappings
/** Real-time functions include suspend, resume, process and events.
Real-time functions cannot call malloc()/new, and cannot call any system
functions that may cause a thread to block (file I/O, VM, etc).
Some functions are said to "interlock" with real-time functions; this means
that those functions may call blocking/memory functions, but that process()
will not be called until those functions return, so there may be a glitch
in sound if those functions take a long time. However, this guarantee makes
it easier on the plug to avoid having to do thread interlock on itself.
It's also important to note that interlocks (and real-time functions) on the
instance level only are valid on a per-instance basis. Thus, two different
instances may be in the same (or different) real-time or interlocking
functions at the same time.
Plug-ins may not call the host back except in response to a host call or a
window message received in the thread for the host GUI window.
Specifically, a plug-in may not call back the host from a thread it spawns
itself, or an OS callback other than a window message from the GUI window
thread initiated by the host.
The host may not turn around and call the plug from a vprHost callback. The
host must set a flag of some sort and call the plug back sometime after the
function making the vprHost call has returned to the host. This reduces
reentrancy risks between different host/plug combinations significantly.
*/
/** The VPR_MAJOR_VERSION macro defines the current major version of the API.
A major version is updated when significant new functionality is added or
changed, and different major versions may not be cross-compatible.
*/
#define VPR_MAJOR_VERSION 0
/** The VPR_MINOR_VERSION macro defines the current minor release of the API.
Minor versions start over at 0 when the major version is updated. Different
minor versions of the same version are still basically compatible, although
newer features may not be understood by older plug-ins.
*/
#define VPR_MINOR_VERSION 1
/** The VPR_API_VERSION macro defines a single size_t that defines compatibility
levels. The APIFLAGS define different variations within a current version.
See VPR_API_FLAG_XXX for possible values.
*/
#define VPR_API_VERSION(APIMAJOR,APIMINOR,APIFLAGS) \
((size_t)((((APIMAJOR) & 0xff) << 24)|(((APIMINOR) & 0xff) << 16)|((APIFLAGS) & 0xff)))
/** Use VPR_API_GETMAJOR to retrieve the major version from a composite version
value created by VPR_API_VERSION.
*/
#define VPR_API_GETMAJOR(API) \
(((size_t)(API) >> 24) & 0xff)
/** Use VPR_API_GETMINOR to retrieve the minor version from a composite version
value created by VPR_API_VERSION.
*/
#define VPR_API_GETMINOR(API) \
(((size_t)(API) >> 16) & 0xff)
/** Use VPR_API_GETFLAGS to retrieve the flags from a composite version value
created by VPR_API_VERSION.
*/
#define VPR_API_GETFLAGS(API) \
((size_t)(API) & 0xffff)
/** vpr_count is used wherever counts of things (patches, inputs, etc) are used. It is
32 bits on all platforms, and unsigned. size_t is used for memory sizes and the
version number, and is 32 or 64 bits depending on platform.
*/
typedef unsigned int vpr_count;
/** vpr_bool is used wherever a yes/no answer is needed. 0 means false, non-0 means true,
with a preferred value of 1 for true.
*/
typedef unsigned char vpr_bool;
enum {
vpr_false = 0,
vpr_true = 1
/* vpr_file_not_found :-) */
};
/** @defgroup basics Plug-in basics. */
/**@{*/
/** struct VPRHost represents the top-level interface to the host from the plug.
The host gives a pointer to an instance of this struct to the plug-in when it
calls VPRInit.
*/
struct VPRHost {
size_t size_VPRHost; ///< sizeof(VPRHost)
size_t host_version; ///< VPR_API_VERSION(...)
void * pCookie; ///< Always pass this back to calls to GetFunc or GetString
void (__stdcall * GetFunc)( ///< Retrieve a function pointer from the host (for host functions).
///< Note that the actual type of the function is not varargs; instead
///< it will be a function with typesafe parameters, as defined by the
///< function name specification. You will have to cast to the right type.
void const * pCookie, ///< Identifies the plug making the request to the host (from VPRHost::pCookie)
wchar_t const * iName, ///< The name of the function to get
void (__stdcall ** oFunc)( ///< Host will set this to NULL or to the function pointer.
void * pCookie, ///< Identifies the plug-in to the host. Other arguments vary by function.
...));
void (__stdcall * GetString)( ///< Get a string from the host, based on the given name.
void const * pCookie, ///< Identifies the plug to the host. See VPRHost::pCookie.
wchar_t const * iName, ///< Which string is requested from the host.
wchar_t const ** oString); ///< The host returns a pointer to the string here, or NULL.
};
enum {
/** The name of fixed-length names, used as labels in various structs.
Any name that is treated as a wchar_t * can be any reasonable length.
@note: The name is counted in characters, and includes a terminating nul character.
*/
VPRNameLen = 32
};
/** A VPRConfig is a different configuration of basically the same effect/instrument.
Examples may include a sampler that can support a single mono out, or up to 32 separate
output channels. That can be exposed as a single config that allows different numbers
of channels, or as a number of pre-set configs (stereo out, 5.1 out, 7.1 out, say).
*/
struct VPRConfig {
size_t size_VPRConfig;
wchar_t name[VPRNameLen];
float sampleRateMin;
float sampleRateMax;
vpr_count flags;
vpr_count numInputsMin;
vpr_count numInputsMax;
vpr_count numOutputsMin;
vpr_count numOutputsMax;
};
/** @defgroup flags values for VPRConfig::flags */
/**@{*/
#define VPR_CONFIG_FORMAT_MASK 0xf
#define VPR_CONFIG_FORMAT_FLOAT 0x0
#define VPR_CONFIG_FORMAT_DOUBLE 0x1
#define VPR_CONFIG_LAYOUT_MASK 0xf0
#define VPR_CONFIG_LAYOUT_CHANNELS 0x00
#define VPR_CONFIG_LAYOUT_STEREO 0x10
#define VPR_CONFIG_LAYOUT_NDOTM 0x20
#define VPR_CONFIG_LAYOUT_MATRIX 0x30
/**@}*/
/** The plug-in provides a pointer to a struct VPRPlug to the host from VPRInit. This
allows the host to get hold of additional functionality from the plug.
*/
struct VPRPlug {
size_t size_VPRPlug; ///< sizeof(VPRPlug)
size_t plug_version; ///< VPR_API_VERSION(...)
size_t flags;
void (__stdcall * GetFunc)( ///< The host gets a function from the plug.
wchar_t const * iName, ///< The name of the function to get.
void (__stdcall ** oFunc)( ///< The function is returned here by the plug, or it's set to NULL.
...));
void (__stdcall * GetString)( ///< Return a string from the plug-in.
wchar_t const * iName, ///< The name of the string to return.
wchar_t const ** oString); ///< The string is returned here, or it's set to NULL by the plug.
VPRConfig const ** configs; ///< The different configurations available for this plug.
size_t numConfigs; ///< The number of configurations.
};
/** @defgroup plugflags Flag values for VPRPlug::flags */
/**@{*/
#define VPR_PLUG_FLAG_GENERATES_CONTROL 0x1
#define VPR_PLUG_FLAG_GENERATES_AUTOMATION 0x2
#define VPR_PLUG_FLAG_USES_TRANSPORT 0x4
#define VPR_PLUG_FLAG_USES_NOTES 0x8
/**@}*/
/** @defgroup strings Well-known strings for plug or host GetString calls. */
/**@{*/
#define VPR_GETSTRING_MANUFACTURER L"manufacturer" ///< My Company
#define VPR_GETSTRING_PRODUCTLINE L"productline" ///< My Plug
#define VPR_GETSTRING_MODEL L"model" ///< Pro Lite XL
#define VPR_GETSTRING_RELEASE L"version" ///< 2.1 2008-01-22
#define VPR_GETSTRING_CATEGORY L"category" ///< Morph/Vocoder
#define VPR_GETSTRING_LONGNAME L"longname" ///< My Plug by My Company
#define VPR_GETSTRING_SHORTNAME L"shortname" ///< MyPlug
#define VPR_GETSTRING_COPYRIGHT L"copyright" ///< (c) 2008 My Company; Crackers Are Lame!
#define VPR_GETSTRING_SUPPORTURL L"supporturl" ///< http://whatever.com/wherever.html
#define VPR_GETSTRING_EXTENSIONS L"extensions" ///< vpr_offline_processing vpr_time_warp ext_mind_control
/**@}*/
#if !defined(DLLEXPORT)
#if defined(_MSC_VER)
#define DLLEXPORT __declspec(dllexport)
#else
#define DLLEXPORT
#define __stdcall
#endif
#endif
/** Define VPR_PLUGFUNCTIONS_AS_POINTERS to forward declare the VPR plug functions as
function pointers (as used by a host). Else they will be declared as functions
(as defined by a plug-in).
*/
#if defined(VPR_PLUGFUNCTIONS_AS_POINTERS)
#define VPR_PLUGFUNC(x) typedef void (__stdcall * x ## Ptr)
#else
#define VPR_PLUGFUNC(x) void __stdcall x
#endif
/** Define VPR_HOSTFUNCTIONS_AS_POINTERS to forward declare the VPR host functions as
function pointers (as used by a plug). Else they will be declared as functions
(as defined by a host).
*/
#if defined(VPR_HOSTFUNCTIONS_AS_POINTERS)
#define VPR_HOSTFUNC(x) typedef void (__stdcall * x ## Ptr)
#else
#define VPR_HOSTFUNC(x) void __stdcall x
#endif
/** The plug must implement a function called VPRInit with the following signature.
The host loads the DLL/.so that contains the plug-in, prepares a VPRHost structure
with a unique pCookie value, and passes it to VPRInit for the plug-in. The plug-in
prepares a VPRPlug structure, and passes it to the host by assigning the pointer
to *oPlug. If something goes wrong, return vpr_false, else return vpr_true.
@note The host may call this function more than once. However, any such call is
interlocked with any other call.
@todo Should there be one "init," and then getting a number of plugs, and then
initing/instantiating each of the plugs? That would be a little more elegant.
@param index Which one of possibly many separate plug-ins to initialize. This
largely useful for wrapping a number of VST or DXi instruments into a single VPR
wrapper -- most plugs will be able to provide their different configurations as
config indices, rather than as totally separate plugs. Another useful case might
be a "channel strip" DLL which provides one plug for EQ, one for dynamics, etc.
@param iHost The host provides information about itself to the plug here. This
pointer must be valid for the lifetime of the plug.
@param oPlug the plug stores a pointer to information about itself here. That
pointer must be valid for the lifetime of the plug, and will be used by the host
to identify the specific plug instance in some cases.
@return true if successful (and index in range); false if unsuccessful.
*/
DLLEXPORT vpr_bool VPRInit(
vpr_count index,
VPRHost const * iHost,
VPRPlug const ** oPlug);
/** A convenient typedef to use for a host loading plugs. */
typedef vpr_bool (__stdcall * VPRInit_Func)(
VPRHost const *,
VPRPlug const **);
/**@}*/
/** @defgroup plugs Management of plug-ins at the container level. */
/**@{*/
/** Plug returns the list of patches that this plug currently has stored. The pointers
returned from the plug must be valid until the next non-realtime call into the plug.
@param oNames Plugin stores a pointer to wchar_t string pointers here. At least
one patch needs to exist. Each string is the name of a patch.
@param oCount Plugin stores the number of patches (patch names) here.
@note Patches are managed separately from instances. This function is mostly used
for bootstrapping data to use for instances.
@todo Should patches be per-config?
*/
VPR_PLUGFUNC(vprPlugGetPatchList)(
VPRPlug const *plug,
wchar_t const * const ** oNames,
vpr_count * oCount);
/** Plug returns the data needed to restore the patch in question to its current
state. If not possible, plug returns NULL. The returned pointer must be valid
until the next non-realtime call into the plug.
@param patch The patch index to get data for.
@param oData A pointer to patch data in a serialized format.
@param oSize The amount of data pointed at by oData.
@note This function is used mainly to bootstrap getting settings to apply to
instances.
*/
VPR_PLUGFUNC(vprPlugGetPatchData)(
VPRPlug const *plug,
vpr_count patch,
void const ** oData,
size_t * oSize);
/** Do regular housekeeping tasks within the plug-in, which may include memory
allocation, updating knobs in GUI, etc. This function is NOT interlocked, but
may still be called between resume and suspend. This function is not called
very often, except it's guaranteed to be called at least once after start-up,
and at least periodically while the host is not doing real-time processing.
Hosts are also guranteed to call this idle at least once after each global supend
and before each global resume, as well as when it detects that the host window
has been switched in/out of focus.
*/
VPR_PLUGFUNC(vprPlugIdle)(VPRPlug const *plug);
/** vprPlugCreateInstance is called by the host to create a new plug-in instance.
@param hInstance An identifier to use when calling the host back regarding this
particular instance.
@param oInstance The plug returns the instance handle to the host here. Or
NULL on failure.
@param config Which configuration (among the ones in VPRPlugInfo) to use to create the instance.
@param patch The patch to initialize the plug instance with.
*/
VPR_PLUGFUNC(vprPlugCreateInstance)(
VPRPlug const *plug,
void * hInstance,
void ** oInstance,
vpr_count config,
void const *patchData,
size_t patchSize);
/**@}*/
/** @defgroup instance Management of each plug instance (instrument or effect). */
/**@{*/
/** For a plug-in to request that the host call idle at non-real-time as soon as possible.
@note This function is safe to call from a real-time function.
*/
VPR_HOSTFUNC(vprHostRequestInstanceIdle)(
void * hInstance);
/** Idle an instance, similar to idling a plug, but instance specific.
@note This call is NOT interlocked, but may still get called between resume and suspend.
*/
VPR_PLUGFUNC(vprInstanceIdle)(
void * iInstance);
/** vprInstanceDestroy is called by the host to destroy a specific plug-in instance.
This should destroy any allocated buffers, close any plugin managed windows, etc.
@param iInstance The previously allocated instance to destroy.
@note This function may only be called when the instance is suspended.
*/
VPR_PLUGFUNC(vprInstanceDestroy)(
void * iInstance);
/** Apply the data of a patch to a plug instance.
@param iInstance The instance to apply the patch to.
@param iVersion The version of the plug that wrote the patch data in iData.
@param iData The patch data to apply. May have come from a previous version of the plug!
@param iSize The size of the patch data.
@note This function will interlock with process() on an instance.
*/
VPR_PLUGFUNC(vprInstanceApplyPatch)(
void * iInstance,
size_t iVersion,
void const *iData,
size_t iSize);
/** Get the patch data for the current instance, in the same format as vprPlugGetPatchData().
@param iInstance the instance to get patch data for.
@param oData Store a pointer to patch data here. This pointer needs to be valid until
the next non-realtime call to the plug.
@param oSize Store the size of the data in oData here.
@note This function will interlock with process() on an instance.
*/
VPR_PLUGFUNC(vprInstanceGetPatchData)(
void * iInstance,
void const ** oData,
size_t * oSize);
/** Request that the plug re-configures its inputs/outputs to a new configuration.
@param iInstance the plug instance to re-configure.
@param config the config index to use (see VPRPlug).
@note Host will re-call GetInputs and GetOutputs after this call.
@note This function may only be called when the instance is suspended.
*/
VPR_PLUGFUNC(vprInstanceSetConfig)(
void * iInstance,
vpr_count config);
/**@}*/
/** @defgroup inputs Management of inputs of data to process to instances. */
/**@{*/
/** VPRInstanceInput describes each individual input of the plug.
*/
struct VPRInstanceInput {
size_t size_VPRInstanceInput; ///< sizeof(VPRInstanceInput)
wchar_t name[VPRNameLen]; ///< Name/label of this input.
vpr_count latency; ///< Additional latency added by this input.
vpr_count flags; ///< Flags related to this input.
vpr_count group; ///< The group of the input (for display grouping).
vpr_count groupIndex; ///< Index within the group. L,R for stereo. L,R,C,S,LS,RS,LR,RR for surround
};
/** The host calls vprInstanceGetInputs to get a list of the inputs the plug has in
the current configuration.
@param iInstance The instance to get inputs for.
@param oInputs Plug returns an array of pointers to VPRInstanceInput structs. The pointers need
to be valid until the next non-realtime call into the plug.
@param oCount Plug returns the number of inputs (and this of VPRInstanceInput structs) here.
*/
VPR_PLUGFUNC(vprInstanceGetInputs)(
void * iInstance,
VPRInstanceInput const * const** oInputs,
vpr_count * oCount);
/** The host requests that a plug adds inputs to its current config. The host will then re-call
GetInputs to see whether it worked. If it worked, the inputs are added after the existing.
@param iInstance The instance to add inputs to.
@param count The number of additional inputs requested.
@note This function may only be called when the instance is suspended.
*/
VPR_PLUGFUNC(vprInstanceAddInputs)(
void * iInstance,
vpr_count count);
/** The host notifies the plug that a given input is connected or not. A disconnected plug will
not receive any input signal, although it still has a buffer in process.
@param iInstance The instance owning the connection.
@param input The input index to be connected/disconnected.
@param connected Whether the input is to be considered connected or not.
@note This function may only be called when the instance is suspended.
*/
VPR_PLUGFUNC(vprInstanceConnectInput)(
void * iInstance,
vpr_count input,
vpr_bool connected);
/** The plug can request that the host call back with GetInputs, to discover whether something
has changed in the layout. It is safe to call this function from the plug at real-time.
However, the host will suspend processing before it calls GetInputs(), so the plug may receive
additional calls to process before GetInputs is actually called, and the current inputs cannot
become invalid until GetInputs (or at least Suspend) is called.
@note This function is safe to call from real-time functions.
*/
VPR_HOSTFUNC(vprHostRequestInputChange)(
void * hInstance);
/**@}*/
/** @defgroup outputs Management of data outputs from plugs. */
/**@{*/
/** The instance declares information about its outputs in VPRInstanceOutput structs. */
struct VPRInstanceOutput {
size_t size_VPRInstanceOutput; ///< sizeof(VPRInstanceOutput)
wchar_t name[VPRNameLen]; ///< Name/label of this output
vpr_count latency; ///< Additional latency added by this output
vpr_count tail; ///< The maximum length of the processing tail after input goes to 0
vpr_count flags; ///< Flags related to the input
vpr_count group; ///< The group of the output (multiple inputs of different groups
///< may be presented separately)
vpr_count groupIndex; ///< The index within the group. L,R for stereo, L,R,C,S,LS,RS,LR,RR for surround
};
/** The Host calls the plug to get a list of all outputs.
@param iInstance The instance for which to list outputs.
@param oOutputs The plug stores a pointer to an array of pointers to output information
here. The pointers need to be valid until the next non-real-time call.
@param oCount The plug stores the number of outputs here.
@note This function may only be called when the instance is suspended.
*/
VPR_PLUGFUNC(vprInstanceGetOutputs)(
void * iInstance,
VPRInstanceOutput const * const** oOutputs,
vpr_count * oCount);
/** The host informs the plug that the output is connected or not. An unconnected output does
not need to produce any output, although it still gets a buffer in process.
@param iInstance The plug instance that owns the output.
@param output The index of the output within the instance that is being reconnected.
@param connected Whether the output is becoming connected or disconnected.
@note This function may only be called when the instance is suspended.
*/
VPR_PLUGFUNC(vprInstanceConnectOutput)(
void * iInstance,
vpr_count output,
vpr_bool connected);
/** The plug can call the host, requesting that the host re-discover available outputs. This is
safe to call during real-time. However, the host will not call GetOutputs until after suspending
the processing, so one or more calls to process may still happen. The plug cannot assume that
the number of outputs has changed until the call to GetOutputs (or at least Suspend).
@param hInstance The host handle for the plug instance being re-configured.
@note This function is safe to call from real-time functions.
*/
VPR_HOSTFUNC(vprHostRequestOutputChange)(
void * hInstance);
/**@}*/
/** @defgroup control Messages and control information */
/**@{*/
/** MIDI controllers are mapped to parameters. For parameters, see VPRParameter in the GUI section.
*/
struct VPRControllerMap {
size_t size_VPRControllerMap; ///< sizeof(VPRControllerMap)
vpr_count parameter; ///< The instance-specific parameter index
unsigned char midiControllerHi; ///< The MIDI controller index, hi part (or 0 for single-byte)
unsigned char midiControllerLo; ///< The MIDI controller index, lo part
vpr_bool positive; ///< Whether the controller maps to -x..x or to 0..x
vpr_bool normalized; ///< Whether x is 1, or 127/16383
};
/** The host can ask an instance for a map of controllers to parameters. This is
useful to turn MIDI CC messages to parameters.
@param iInstance the plug instance being asked for mappings
@param oMap The plug stores a pointer to an array of VPRControllerMap structs here.
@param oCount The plug stores the number of mappings here.
@note This function may only be called when the instance is suspended.
*/
VPR_PLUGFUNC(vprInstanceGetControllerMap)(
void * iInstance,
VPRControllerMap const * const** oMap,
vpr_count * oCount);
/** All values go through this variant struct. That allows implementations to be type safe.
However, hosts must provide parameters of the right type as per declarations by the instance.
The plug instance is not required to do type conversion on its own.
*/
struct VPRParameterValue {
union {
float f;
int i;
vpr_bool b;
wchar_t const *s;
char _whatever[12]; ///< sizeof(VPRParameterValue) is 16 bytes
};
vpr_count type;
};
/** Parameters can be continuous, discrete, triggered or text values.
*/
enum {
vpr_param_float,
vpr_param_int,
vpr_param_bool,
vpr_param_string
};
/** Used for user-controlled parameters. Part of VPRControlMessage.
*/
struct VPRControlParameter {
VPRParameterValue inValue; ///< starting value of the parameter at the initial delay point.
VPRParameterValue outValue; ///< final value of the parameter
vpr_count channel; ///< sub-channel (typically, MIDI channel)
vpr_count parameter; ///< what parameter is being controlled.
vpr_count rampDelay; ///< ramp over how many samples. If 0, use only outValue.
};
/** Used for note-on and note-off messages.
Note that note-on with velocity 0 means note-off (running status).
Part of VPRControlMessage.
*/
struct VPRControlNote {
float midiNote; ///< MIDI note number, including detuning
float velocity; ///< MIDI velocity, 127.0 is hardest, 0.0 is softest
vpr_count channel; ///< MIDI channel
vpr_bool onOff; ///< 0 for off, 1 for on
};
/** Data dumps are a wrapper for MIDI SysEx dumps, generally.
Part of VPRControlMessage.
*/
struct VPRControlData {
vpr_count channel; ///< SysEx has no channel, but this message might
vpr_count _reserved; ///< write as 0, don't read
void const * data; ///< Pointer to actual data, live until after the next process call
size_t size; ///< size of data pointed at
};
/** Transport commands. Part of VPRControlMessage.
*/
struct VPRControlTransport {
unsigned char section; ///< section/day/whatever
unsigned char hour; ///< hours since start of section
unsigned char minute; ///< minutes since last hour
unsigned char second; ///< seconds since last minute
vpr_count frame; ///< frame within the second; range depends on mode
vpr_count subframe; ///< 0 for even field, 1 for odd field, for TV modes
vpr_count mode; ///< transport mode (playing, stopped, etc) and timecode type
};
/** @defgroup mode values for VPRControlTransport::mode */
/**@{*/
#define VPR_TRANSPORT_MODE_MASK 0xf
#define VPR_TRANSPORT_MODE_STOP 0 ///< Stopped
#define VPR_TRANSPORT_MODE_PLAY 1 ///< Playing back
#define VPR_TRANSPORT_MODE_RECORD 2 ///< Recording
#define VPR_TRANSPORT_MODE_PAUSE 3 ///< Pending re-start
#define VPR_TRANSPORT_MODE_FF 4 ///< Fast Forward with monitor
#define VPR_TRANSPORT_MODE_REW 5 ///< Rewind with monitor
#define VPR_TRANSPORT_MODE_JUMP 6 ///< Instant jump
#define VPR_TRANSPORT_TIMECODE_MASK 0xff00
#define VPR_TRANSPORT_TIMECODE_24 (24<<8)
#define VPR_TRANSPORT_TIMECODE_25 (25<<8)
#define VPR_TRANSPORT_TIMECODE_2997 (29<<8)
#define VPR_TRANSPORT_TIMECODE_30 (30<<8)
#define VPR_TRANSPORT_TIMECODE_50 (50<<8)
#define VPR_TRANSPORT_TIMECODE_5994 (59<<8)
#define VPR_TRANSPORT_TIMECODE_60 (60<<8)
#define VPR_TRANSPORT_TIMECODE_FIELDMASK 0xf0
#define VPR_TRANSPORT_TIMECODE_EVENODD 0x10 ///< When set, "subframe" is even/odd
#define VPR_TRANSPORT_TIMECODE_SCANLINE 0x20 ///< When set, "subframe" is scanline #
#define VPR_TRANSPORT_TIMECODE_SAMPLE 0x30 ///< When set, "subframe" is samples-since-frame
/**@}*/
/** VPRControlMessage is how all kinds of control events go into the plug instance.
*/
struct VPRControlMessage {
size_t size_VPRControlMessage; ///< sizeof(VPRControlMessage)
size_t delay; ///< Delay in samples from the start of the next buffer processed
vpr_count what; ///< vpr_control_parameter, vpr_control_note, vpr_control_data, vpr_control_transport
vpr_count _reserved; ///< ignore on read; write as 0
union {
VPRControlParameter parameter; ///< for parameter/controller change
VPRControlNote note; ///< for note on / off
VPRControlData data; ///< for sysex
VPRControlTransport transport; ///< for timecode/transport information
};
};
enum {
vpr_control_parameter,
vpr_control_note,
vpr_control_data,
vpr_control_transport,
};
/** The host calls vprInstanceControl to send control information that pertains to the
next process call. If the plug is currently suspended, the messages must take
immediate effect.
@param iInstance The plug instance to receive the messages.
@param iMessages A pointer to the messages to process. These messages must be valid
until the next process call has returned if the plug is resumed, or until the next
idle call if the plug is suspended.
@param numMessages the number of message pointers in the iMessages array.
@note This function is interlocked, and should be real-time.
@note The host should only send at most one vprInstanceControl for each process call.
*/
VPR_PLUGFUNC(vprInstanceControl)(
void * iInstance,
VPRControlMessage const * const * iMessages,
vpr_count numMessages);
/** Each parameter is described with a number of properties, allowing a host to
create a reasonable display of different parameters.
*/
struct VPRParameter {
size_t size_VPRParameter; ///< sizeof(VPRParameter)
wchar_t const *name; ///< the name of this parameter
vpr_count channel; ///< Which MIDI channel it's active on.
vpr_count grouping; ///< all parameters with the same grouping value are displayed together
vpr_count parent; ///< some other parameter may be "master" of this parameter (in layout)
vpr_count flags; ///< VPR_PARAM_FLAG values.
VPRParameterValue standard; ///< The "standard" value for the parameter
VPRParameterValue minimum; ///< The minimum legal value for the parameter
VPRParameterValue maximum; ///< The maximum legal value for the parameter
wchar_t const * const * valueNames; ///< If non-NULL, contains a NULL terminated array of value names for int/bool
};
/** @defgroup paramflags Values for VPRParameter::flags */
/**@{*/
#define VPR_PARAM_LOGARITHMIC 0x1 ///< The parameter is best manipulated in logarithmic fashion
#define VPR_PARAM_NOTENUMBER 0x2 ///< The parameter is a note number
#define VPR_PARAM_HERZ 0x4 ///< The parameter measures frequency
#define VPR_PARAM_DB 0x8 ///< The parameter measures dB
#define VPR_PARAM_GAIN 0x10 ///< The parameter measures gain change (linear if not dB)
#define VPR_PARAM_FILENAME 0x10000 ///< The parameter is a file name.
#define VPR_PARAM_INACTIVE 0x1000000 ///< The value of this parameter is currently being ignored.
#define VPR_PARAM_DERIVED 0x4000000 ///< This parameter is derived from other sources, and setting
///< it probably won't have much effect (if any).
/**@}*/
/** The instance can declare parameters that are tweakable by the host. The host
can ask the instance for a list of these parameters. The pointers returned by
this function must be valid until the next non-realtime call into the instance.
Order (index) is important.
@param iInstance The instance to return parameters for.
@param oParams The instance returns a pointer to an array of VPRParameter pointers here.
@param count The instance returns the number of parameters here.
@note This function is interlocked.
*/
VPR_PLUGFUNC(vprInstanceGetParameters)(
void * iInstance,
VPRParameter const * const ** oParams,
vpr_count * count);
/** The host can read the current parameter values.
@param iInstance The instance that parameters are gotten from.
@param firstIndex The index of the first parameter being gotten.
@param count The number of parameters, starting at firstIndex, being gotten.
@oValues The instance returns a pointer to an array of parameter value pointers here.
@note This function is interlocked.
*/
VPR_PLUGFUNC(vprInstanceGetParameterValues)(
void * iInstance,
vpr_count firstIndex,
vpr_count count,
VPRParameterValue *oValues);
/** The host can write/set the current parameter values. This is somewhat redundant
to the automation/control messages, but perhaps convenient for bulk dumps.
@param iInstance The instance that parameters are set on.
@param firstIndex The index of the first parameter being set.
@param count The number of parameters, starting at firstIndex, being set.
@iValues An array of pointers to parameter values.
@note This function is interlocked.
*/
VPR_PLUGFUNC(vprInstanceSetParameterValues)(
void * iInstance,
vpr_count firstIndex,
vpr_count count,
VPRParameterValue const *iValues);
/**@}*/
/** @defgroup automation Automation and routing support */
/**@{*/
/** vprHostControl allows a plug to send control information intended for some other plug.
Remember to set the appropriate plug-in flag for the host to know to pay attention.
@note This function is safe to call at real time, assuming the plug has pre-allocated
the message storage space.
@param hInstance The host handle for the plug-in sending the control information.
@param iMessages A pointer to an array of VPRControlMessage struct pointers.
@param numMessages Number of message structs.
@note this function is safe to call from real-time functions. The messages must be
valid/readable until the plug-in is suspended, or the next call to process.
*/
VPR_HOSTFUNC(vprHostControl)(
void * hInstance,
VPRControlMessage const * const * iMessages,
vpr_count numMessages);
/** vprHostAutomate allows a plug instance to send control information related to the plug instance itself,
for later play-back to the plug.
Remember to set the appropriate plug-in flag for the host to know to pay attention.
@note This function is safe to call at real time, assuming the plug has pre-allocated
the message storage space.
@param hInstance The host handle for the plug-in sending the control information.
@param iMessages A pointer to an array of VPRControlMessage struct pointers.
@param numMessages Number of message structs.
@note This function is safe to call from a real-time function. The messages must
be valid/readable until the plug-in is suspended, or the next call to process, or
the next call to instance idle (if the plug is currently suspended).
*/
VPR_HOSTFUNC(vprHostAutomate)(
void * hInstance,
VPRControlData const ** iMessages,
vpr_count numMessages);
/**@}*/
/** @defgroup processing Data processing support */
/**@{*/
/** struct VPRProcessFloat contains information to use when processing float data.
It is filled in by the host before calling process, and is read by the plug instance.
*/
struct VPRProcessFloat {
size_t size_VPRProcessFloat; ///< sizeof(VPRProcessFloat)
size_t numSamples; ///< Number of samples to process in this invocation.
float const * const * input; ///< Array of pointers to input channel data.
float * const * output; ///< Array of pointers to output channel storage.
VPRControlTransport timecode; ///< The approximate timecode for the start of the buffer.
///< The value is "approximate" in the case where the timecode
///< is not inherently sample accurate. For sample accurate
///< timecode, request VPR_PLUG_FLAG_USES_TRANSPORT.
///< The timecode value is for when the sample actually gets
///< played (and thus may include compensation for latency
///< further down the line).
};
/** Struct VPRProcessDouble contains parameters for processing double precision data.
@see VPRProcessFloat.
*/
struct VPRProcessDouble {
size_t size_VPRProcessDouble;
size_t numSamples;
double const * const * input;
double * const * output;
VPRControlTransport timecode;
};
/** The host calls the plug instance to reconfigure for a new host format.
Typically this is because sample rate or overall processing latence has changed.
@param iInstance The instance being re-configured.
@param sampleRate The new sample rate in samples per second.
@param totalLatency The end-to-end latency of the processing chain from the plug to the output.
@note This call only happens when the plug is suspended.
*/
VPR_PLUGFUNC(vprInstanceSetFormat)(
void * iInstance,
float sampleRate,
vpr_count totalLatency);
/** The host tells the plug instance that it will start calling process, and that control changes after
resume (before suspend) should take affect at scheduled sample times rather than immediately.
@param iInstance The instance being resumed.
*/
VPR_PLUGFUNC(vprInstanceResume)(
void * iInstance);
/** The host tells the plug instance that it's done calling process for now, and that future control
changes (until resume) should take effect immediately.
@param iInstance The instance being suspended.
*/
VPR_PLUGFUNC(vprInstanceSuspend)(
void * iInstance);
/** The host tells the instance to process a group of samples out of the stream.
This version is the default version of processing.
@param iInstance The instance that processes data.
@param data The data to process.
@todo Should I only support ProcessDouble?
*/
VPR_PLUGFUNC(vprInstanceProcessFloat)(
void * iInstance,
VPRProcessFloat const * data);
/** The host tells the instance to process a group of samples out of the stream.
This version can be requested by setting the _DOUBLE flag in the configuration.
@param iInstance The instance that processes data.
@param data The data to process.
@todo Should this be required in addition to processFloat? If so, remove the flag from config.
*/
VPR_PLUGFUNC(vprInstanceProcessDouble)(
void * iInstance,
VPRProcessDouble const * data);
/**@}*/
/** @defgroup gui Support for settings windows */
/**@{*/
/** The host asks the instance for its current desired window size.
@param iInstance What instance to get a window for.
@param outWidth The instance sets its desired width here.
@param outHeight The instance sets its desired height here.
@note This function is interlocked.
*/
VPR_PLUGFUNC(vprInstanceGetWindowSize)(
void * iInstance,
vpr_count * outWidth,
vpr_count * outHeight);
/** The host asks the instance to create the settings window for itself.
@param iInstance The instance to create a window for.
@param width The width of window to create.
@param height The height of window to create.
@param hostWindow The hosting window that "owns" the child window.
@note The value of "hostWindow" depends on the host OS. On Windows,
it will be a HWND.
@note This function is interlocked.
*/
VPR_PLUGFUNC(vprInstanceCreateWindow)(
void * iInstance,
vpr_count width,
vpr_count height,
void * hostWindow);
/** The host tells the instance that the window is about to be destroyed.
Depending on the host OS, the plug may not need to do much in here, as
child windows may be automatically destroyed when a host window is destroyed.
@param iInstance The instance for which the window is being destroyed.
@note This function is interlocked.
*/
VPR_PLUGFUNC(vprInstanceDestroyWindow)(
void * iInstance);
/** The plug-in instance can ask the host to make the window for the instance
distinctive (flash the title bar, etc) and display a message related to the
plug-in. This message might be an alert, or go in a log, or be displayed as
an overlay of the plug-in in some arrangement window.
@param pCookie The plug-in handle. Can be NULL if hInstance isn't NULL.
@param hInstance The instance handle. Can be NULL if pCookie isn't NULL.
@param message The message to display from the plug. Can be NULL.
@note This function is NOT safe to call from a real-time function.
*/
VPR_HOSTFUNC(vprHostAttention)(
void * pCookie,
void * hInstance,
wchar_t const * message);
/** The instance can request that the host close its window. The host may not
close the window immediately.
@param hInstance The instance that wishes to have its window closed.
@note This function is safe to call from a real-time function.
*/
VPR_HOSTFUNC(vprHostCloseWindow)(
void * hInstance);
/** The instance can request that the host resize its window within certain limits.
This resizing may happen immediately, or may just mean that the user is allowed
to resize the window.
@param hInstance The instance handle to allow re-sizing for.
@param minWidth The minimum width allowed for the window.
@param minHeight The minimum height allowed for the window.
@param maxWidth The maximum width allowed for the window.
@param maxHeight The maximum height allowed for the window.
@preferBig TRUE if the host should attempt to make the window as big as possible.
@note This is not a real-time safe function.
*/
VPR_HOSTFUNC(vprHostRequestWindowSize)(
void * hInstance,
vpr_count minWidth,
vpr_count minHeight,
vpr_count maxWidth,
vpr_count maxHeight,
vpr_bool preferBig);
/** The instance can notify the host that its set of parameters changed.
@param hInstance The instance handle whose parameter set changed.
@note This function is safe to call from a real-time function.
*/
VPR_HOSTFUNC(vprHostParameterListChanged)(
void * hInstance);
/**@}*/
#endif // vpr_h