text:
//------------------------------------------------------------------------
// Project     : VST SDK
// Version     : 3.6.7
//
// Category    : Interfaces
// Filename    : pluginterfaces/vst/ivstaudioprocessor.h
// Created by  : Steinberg, 10/2005
// Description : VST Audio Processing Interfaces
//
//-----------------------------------------------------------------------------
// This file is part of a Steinberg SDK. It is subject to the license terms
// in the LICENSE file found in the top-level directory of this distribution
// and at www.steinberg.net/sdklicenses.
// No part of the SDK, including this file, may be copied, modified, propagated,
// or distributed except according to the terms contained in the LICENSE file.
//-----------------------------------------------------------------------------

#pragma once

#include "ivstcomponent.h"

//------------------------------------------------------------------------
#include "pluginterfaces/base/falignpush.h"
//------------------------------------------------------------------------

//------------------------------------------------------------------------
/** Class Category Name for Audio Processor Component */
//------------------------------------------------------------------------
#ifndef kVstAudioEffectClass
#define kVstAudioEffectClass "Audio Module Class"
#endif

//------------------------------------------------------------------------
namespace Steinberg {
namespace Vst {
class IEventList;
class IParameterChanges;
struct ProcessContext;

//------------------------------------------------------------------------
/** Component Types used as subCategories in PClassInfo2 */
//------------------------------------------------------------------------
namespace PlugType
{
/**
\defgroup plugType Plug-in Type used for subCategories */
/*@{*/
//------------------------------------------------------------------------
const CString kFxAnalyzer			= "Fx|Analyzer";	///< Scope, FFT-Display, Loudness Processing...
const CString kFxDelay				= "Fx|Delay";		///< Delay, Multi-tap Delay, Ping-Pong Delay...
const CString kFxDistortion			= "Fx|Distortion";	///< Amp Simulator, Sub-Harmonic, SoftClipper...
const CString kFxDynamics			= "Fx|Dynamics";	///< Compressor, Expander, Gate, Limiter, Maximizer, Tape Simulator, EnvelopeShaper...
const CString kFxEQ					= "Fx|EQ";			///< Equalization, Graphical EQ...
const CString kFxFilter				= "Fx|Filter";		///< WahWah, ToneBooster, Specific Filter,...
const CString kFx					= "Fx";				///< others type (not categorized)
const CString kFxInstrument			= "Fx|Instrument";	///< Fx which could be loaded as Instrument too
const CString kFxInstrumentExternal	= "Fx|Instrument|External";	///< Fx which could be loaded as Instrument too and is external (wrapped Hardware)
const CString kFxSpatial			= "Fx|Spatial";		///< MonoToStereo, StereoEnhancer,...
const CString kFxGenerator			= "Fx|Generator";	///< Tone Generator, Noise Generator...
const CString kFxMastering			= "Fx|Mastering";	///< Dither, Noise Shaping,...
const CString kFxModulation			= "Fx|Modulation";	///< Phaser, Flanger, Chorus, Tremolo, Vibrato, AutoPan, Rotary, Cloner...
const CString kFxPitchShift			= "Fx|Pitch Shift";	///< Pitch Processing, Pitch Correction, Vocal Tuning...
const CString kFxRestoration		= "Fx|Restoration";	///< Denoiser, Declicker,...
const CString kFxReverb				= "Fx|Reverb";		///< Reverberation, Room Simulation, Convolution Reverb...
const CString kFxSurround			= "Fx|Surround";	///< dedicated to surround processing: LFE Splitter, Bass Manager...
const CString kFxTools				= "Fx|Tools";		///< Volume, Mixer, Tuner...
const CString kFxNetwork			= "Fx|Network";		///< using Network

const CString kInstrument			= "Instrument";			///< Effect used as instrument (sound generator), not as insert
const CString kInstrumentDrum		= "Instrument|Drum";	///< Instrument for Drum sounds
const CString kInstrumentSampler	= "Instrument|Sampler";	///< Instrument based on Samples
const CString kInstrumentSynth		= "Instrument|Synth";	///< Instrument based on Synthesis
const CString kInstrumentSynthSampler = "Instrument|Synth|Sampler";	///< Instrument based on Synthesis and Samples
const CString kInstrumentExternal	= "Instrument|External";///< External Instrument (wrapped Hardware)

const CString kSpatial				= "Spatial";		///< used for SurroundPanner
const CString kSpatialFx			= "Spatial|Fx";		///< used for SurroundPanner and as insert effect
const CString kOnlyRealTime			= "OnlyRT";			///< indicates that it supports only realtime process call, no processing faster than realtime
const CString kOnlyOfflineProcess	= "OnlyOfflineProcess";	///< used for Plug-in offline processing  (will not work as normal insert Plug-in)
const CString kNoOfflineProcess		= "NoOfflineProcess";	///< will be NOT used for Plug-in offline processing (will work as normal insert Plug-in)
const CString kUpDownMix			= "Up-Downmix";		///< used for Mixconverter/Up-Mixer/Down-Mixer
const CString kAnalyzer			    = "Analyzer";	    ///< Meter, Scope, FFT-Display, not selectable as insert plugin

const CString kMono					= "Mono";			///< used for Mono only Plug-in [optional]
const CString kStereo				= "Stereo";			///< used for Stereo only Plug-in [optional]
const CString kSurround				= "Surround";		///< used for Surround only Plug-in [optional]

//------------------------------------------------------------------------
/*@}*/
}

//------------------------------------------------------------------------
/** Component Flags used as classFlags in PClassInfo2 */
//------------------------------------------------------------------------
enum ComponentFlags
{
//------------------------------------------------------------------------
	kDistributable			= 1 << 0,	///< Component can be run on remote computer
	kSimpleModeSupported	= 1 << 1	///< Component supports simple IO mode (or works in simple mode anyway) see \ref vst3IoMode
//------------------------------------------------------------------------
};

//------------------------------------------------------------------------
/** Symbolic sample size.
\see ProcessSetup, ProcessData */
//------------------------------------------------------------------------
enum SymbolicSampleSizes
{
	kSample32,		///< 32-bit precision
	kSample64		///< 64-bit precision
};

//------------------------------------------------------------------------
/** Processing mode informs the Plug-in about the context and at which frequency the process call is called.
VST3 defines 3 modes:
- kRealtime: each process call is called at a realtime frequency (defined by [numSamples of ProcessData] / samplerate).
             The Plug-in should always try to process as fast as possible in order to let enough time slice to other Plug-ins.
- kPrefetch: each process call could be called at a variable frequency (jitter, slower / faster than realtime),
             the Plug-in should process at the same quality level than realtime, Plug-in must not slow down to realtime
			 (e.g. disk streaming)!
			 The host should avoid to process in kPrefetch mode such sampler based Plug-in.
- kOffline:  each process call could be faster than realtime or slower, higher quality than realtime could be used.
             Plug-ins using disk streaming should be sure that they have enough time in the process call for streaming,
			 if needed by slowing down to realtime or slower.
.
Note about Process Modes switching:
	-Switching between kRealtime and kPrefetch process modes are done in realtime thread without need of calling
	 IAudioProcessor::setupProcessing, the Plug-in should check in process call the member processMode of ProcessData
	 in order to know in which mode it is processed.
	-Switching between kRealtime (or kPrefetch) and kOffline requires that the host calls IAudioProcessor::setupProcessing
	 in order to inform the Plug-in about this mode change.
.
\see ProcessSetup, ProcessData */
//------------------------------------------------------------------------
enum ProcessModes
{
	kRealtime,		///< realtime processing
	kPrefetch,		///< prefetch processing
	kOffline		///< offline processing
};

//------------------------------------------------------------------------
/** kNoTail
 *
 * to be returned by getTailSamples when no tail is wanted
 \see IAudioProcessor::getTailSamples */
//------------------------------------------------------------------------
static const uint32 kNoTail = 0;
//------------------------------------------------------------------------
/** kInfiniteTail
 *
 * to be returned by getTailSamples when infinite tail is wanted
 \see IAudioProcessor::getTailSamples */
//------------------------------------------------------------------------
static const uint32 kInfiniteTail = kMaxInt32u;

//------------------------------------------------------------------------
/** Audio processing setup.
\see IAudioProcessor::setupProcessing */
//------------------------------------------------------------------------
struct ProcessSetup
{
//------------------------------------------------------------------------
	int32 processMode;			///< \ref ProcessModes
	int32 symbolicSampleSize;	///< \ref SymbolicSampleSizes
	int32 maxSamplesPerBlock;	///< maximum number of samples per audio block
	SampleRate sampleRate;		///< sample rate
//------------------------------------------------------------------------
};

//------------------------------------------------------------------------
/** Processing buffers of an audio bus.
This structure contains the processing buffer for each channel of an audio bus.
- The number of channels (numChannels) must always match the current bus arrangement.
  It could be set to value '0' when the host wants to flush the parameters (when the Plug-in is not processed).
- The size of the channel buffer array must always match the number of channels. So the host
  must always supply an array for the channel buffers, regardless if the
  bus is active or not. However, if an audio bus is currently inactive, the actual sample
  buffer addresses are safe to be null.
- The silence flag is set when every sample of the according buffer has the value '0'. It is
  intended to be used as help for optimizations allowing a Plug-in to reduce processing activities.
  But even if this flag is set for a channel, the channel buffers must still point to valid memory!
  This flag is optional. A host is free to support it or not.
.
\see ProcessData */
//------------------------------------------------------------------------
struct AudioBusBuffers
{
	AudioBusBuffers () : numChannels (0), silenceFlags (0), channelBuffers64 (0) {}

//------------------------------------------------------------------------
	int32 numChannels;		///< number of audio channels in bus
	uint64 silenceFlags;	///< Bitset of silence state per channel
	union
	{
		Sample32** channelBuffers32;	///< sample buffers to process with 32-bit precision
		Sample64** channelBuffers64;	///< sample buffers to process with 64-bit precision
	};
//------------------------------------------------------------------------
};

//------------------------------------------------------------------------
/** Any data needed in audio processing.
	The host prepares AudioBusBuffers for each input/output bus,
	regardless of the bus activation state. Bus buffer indices always match
	with bus indices used in IComponent::getBusInfo of media type kAudio.
\see AudioBusBuffers, IParameterChanges, IEventList, ProcessContext */
//------------------------------------------------------------------------
struct ProcessData
{
	ProcessData ()
	: processMode (0), symbolicSampleSize (kSample32), numSamples (0), numInputs (0)
	, numOutputs (0), inputs (0), outputs (0), inputParameterChanges (0), outputParameterChanges (0)
	, inputEvents (0), outputEvents (0), processContext (0) {}

//------------------------------------------------------------------------
	int32 processMode;			///< processing mode - value of \ref ProcessModes
	int32 symbolicSampleSize;   ///< sample size - value of \ref SymbolicSampleSizes
	int32 numSamples;			///< number of samples to process
	int32 numInputs;			///< number of audio input buses
	int32 numOutputs;			///< number of audio output buses
	AudioBusBuffers* inputs;	///< buffers of input buses
	AudioBusBuffers* outputs;	///< buffers of output buses

	IParameterChanges* inputParameterChanges;	///< incoming parameter changes for this block
	IParameterChanges* outputParameterChanges;	///< outgoing parameter changes for this block (optional)
	IEventList* inputEvents;				///< incoming events for this block (optional)
	IEventList* outputEvents;				///< outgoing events for this block (optional)
	ProcessContext* processContext;			///< processing context (optional, but most welcome)
//------------------------------------------------------------------------
};

//------------------------------------------------------------------------
/** Audio Processing Interface.
\ingroup vstIPlug vst300
- [plug imp]
- [extends IComponent]
- [released: 3.0.0]
- [mandatory]

This interface must always be supported by audio processing Plug-ins. */
//------------------------------------------------------------------------
class IAudioProcessor: public FUnknown
{
public:
//------------------------------------------------------------------------
	/** Try to set (from host) a predefined arrangement for inputs and outputs.
	    The host should always deliver the same number of input and output buses than the Plug-in needs
		(see \ref IComponent::getBusCount).
		The Plug-in returns kResultFalse if wanted arrangements are not supported.
		If the Plug-in accepts these arrangements, it should modify its buses to match the new arrangements
		(asked by the host with IComponent::getInfo () or IAudioProcessor::getBusArrangement ()) and then return kResultTrue.
		If the Plug-in does not accept these arrangements, but can adapt its current arrangements (according to the wanted ones),
		it should modify its buses arrangements and return kResultFalse. */
	virtual tresult PLUGIN_API setBusArrangements (SpeakerArrangement* inputs, int32 numIns,
												   SpeakerArrangement* outputs, int32 numOuts) = 0;

	/** Gets the bus arrangement for a given direction (input/output) and index.
		Note: IComponent::getInfo () and IAudioProcessor::getBusArrangement () should be always return the same
		information about the buses arrangements. */
	virtual tresult PLUGIN_API getBusArrangement (BusDirection dir, int32 index, SpeakerArrangement& arr) = 0;

	/** Asks if a given sample size is supported see \ref SymbolicSampleSizes. */
	virtual tresult PLUGIN_API canProcessSampleSize (int32 symbolicSampleSize) = 0;

	/** Gets the current Latency in samples.
		The returned value defines the group delay or the latency of the Plug-in. For example, if the Plug-in internally needs
		to look in advance (like compressors) 512 samples then this Plug-in should report 512 as latency.
		If during the use of the Plug-in this latency change, the Plug-in has to inform the host by
		using IComponentHandler::restartComponent (kLatencyChanged), this could lead to audio playback interruption
		because the host has to recompute its internal mixer delay compensation.
		Note that for player live recording this latency should be zero or small. */
	virtual uint32 PLUGIN_API getLatencySamples () = 0;

	/** Called in disable state (not active) before processing will begin. */
	virtual tresult PLUGIN_API setupProcessing (ProcessSetup& setup) = 0;

	/** Informs the Plug-in about the processing state. This will be called before any process calls start with true and after with false.
		Note that setProcessing (false) may be called after setProcessing (true) without any process calls.
		In this call the Plug-in should do only light operation (no memory allocation or big setup reconfiguration),
		this could be used to reset some buffers (like Delay line or Reverb). */
	virtual tresult PLUGIN_API setProcessing (TBool state) = 0;

	/** The Process call, where all information (parameter changes, event, audio buffer) are passed. */
	virtual tresult PLUGIN_API process (ProcessData& data) = 0;

	/** Gets tail size in samples. For example, if the Plug-in is a Reverb Plug-in and it knows that
		the maximum length of the Reverb is 2sec, then it has to return in getTailSamples()
		(in VST2 it was getGetTailSize ()): 2*sampleRate.
		This information could be used by host for offline processing, process optimization and
		downmix (avoiding signal cut (clicks)).
		It should return:
		 - kNoTail when no tail
		 - x * sampleRate when x Sec tail.
		 - kInfiniteTail when infinite tail. */
	virtual uint32 PLUGIN_API getTailSamples () = 0;

//------------------------------------------------------------------------
	static const FUID iid;
};

DECLARE_CLASS_IID (IAudioProcessor, 0x42043F99, 0xB7DA453C, 0xA569E79D, 0x9AAEC33D)

//------------------------------------------------------------------------
/** Extended IAudioProcessor interface for a component.
\ingroup vstIPlug vst310
- [plug imp]
- [extends IAudioProcessor]
- [released: 3.1.0]

Inform the Plug-in about how long from the moment of generation/acquiring (from file or from Input)
it will take for its input to arrive, and how long it will take for its output to be presented (to output or to Speaker).

Note for Input Presentation Latency: when reading from file, the first Plug-in will have an input presentation latency set to zero.
When monitoring audio input from a Audio Device, then this initial input latency will be the input latency of the Audio Device itself.

Note for Output Presentation Latency: when writing to a file, the last Plug-in will have an output presentation latency set to zero.
When the output of this Plug-in is connected to a Audio Device then this initial output latency will be the output
latency of the Audio Device itself.

A value of zero means either no latency or an unknown latency.

Each Plug-in adding a latency (returning a none zero value for IAudioProcessor::getLatencySamples) will modify the input
presentation latency of the next Plug-ins in the mixer routing graph and will modify the output presentation latency
of the previous Plug-ins.
\see IAudioProcessor
\see IComponent*/
//------------------------------------------------------------------------
class IAudioPresentationLatency: public FUnknown
{
public:
	//------------------------------------------------------------------------
	/** Informs the Plug-in about the Audio Presentation Latency in samples for a given direction (kInput/kOutput) and bus index. */
	virtual tresult PLUGIN_API setAudioPresentationLatencySamples (BusDirection dir, int32 busIndex, uint32 latencyInSamples) = 0;

	//------------------------------------------------------------------------
	static const FUID iid;
};

DECLARE_CLASS_IID (IAudioPresentationLatency, 0x309ECE78, 0xEB7D4fae, 0x8B2225D9, 0x09FD08B6)

//------------------------------------------------------------------------
} // namespace Vst
} // namespace Steinberg

//------------------------------------------------------------------------
#include "pluginterfaces/base/falignpop.h"
//------------------------------------------------------------------------


text:
//------------------------------------------------------------------------
// Project     : VST SDK
// Version     : 3.6.7
//
// Category    : Interfaces
// Filename    : pluginterfaces/vst/ivstnoteexpression.h
// Created by  : Steinberg, 10/2010
// Description : VST Note Expression Interfaces
//
//-----------------------------------------------------------------------------
// This file is part of a Steinberg SDK. It is subject to the license terms
// in the LICENSE file found in the top-level directory of this distribution
// and at www.steinberg.net/sdklicenses.
// No part of the SDK, including this file, may be copied, modified, propagated,
// or distributed except according to the terms contained in the LICENSE file.
//-----------------------------------------------------------------------------

#pragma once

#include "pluginterfaces/base/funknown.h"
#include "vsttypes.h"

//------------------------------------------------------------------------
#include "pluginterfaces/base/falignpush.h"
//------------------------------------------------------------------------

namespace Steinberg {
namespace Vst {
typedef uint32 NoteExpressionTypeID;
typedef double NoteExpressionValue;

//------------------------------------------------------------------------
/** NoteExpressionTypeIDs describes the type of the note expression.
VST predefines some types like volume, pan, tuning by defining their ranges and curves.
Used by NoteExpressionEvent::typeId and NoteExpressionTypeID::typeId
\see NoteExpressionTypeInfo
*/
enum NoteExpressionTypeIDs
{
	kVolumeTypeID = 0,		///< Volume, plain range [0 = -oo , 0.25 = 0dB, 0.5 = +6dB, 1 = +12dB]: plain = 20 * log (4 * norm)
	kPanTypeID,				///< Panning (L-R), plain range [0 = left, 0.5 = center, 1 = right]
	kTuningTypeID,			///< Tuning, plain range [0 = -120.0 (ten octaves down), 0.5 none, 1 = +120.0 (ten octaves up)]
							///< plain = 240 * (norm - 0.5) and norm = plain / 240 + 0.5
							///< oneOctave is 12.0 / 240.0; oneHalfTune = 1.0 / 240.0;
	kVibratoTypeID,			///< Vibrato
	kExpressionTypeID,		///< Expression
	kBrightnessTypeID,		///< Brightness
	kTextTypeID,			///< TODO:
	kPhonemeTypeID,			///< TODO:

	kCustomStart = 100000	///< custom note change type ids must start from here
};

//------------------------------------------------------------------------
/** Description of a Note Expression Type
This structure is part of the NoteExpressionTypeInfo structure, it describes for given NoteExpressionTypeID its default value
(for example 0.5 for a kTuningTypeID (kIsBipolar: centered)), its minimum and maximum (for predefined NoteExpressionTypeID the full range is predefined too)
and a stepCount when the given NoteExpressionTypeID is limited to discrete values (like on/off state).
\see NoteExpressionTypeInfo
*/
//------------------------------------------------------------------------
struct NoteExpressionValueDescription
{
	NoteExpressionValue defaultValue;		///< default normalized value [0,1]
	NoteExpressionValue minimum;			///< minimum normalized value [0,1]
	NoteExpressionValue maximum;			///< maximum normalized value [0,1]
	int32 stepCount;						///< number of discrete steps (0: continuous, 1: toggle, discrete value otherwise - see \ref vst3parameterIntro)
};

#if WINDOWS && !PLATFORM_64
#include "pluginterfaces/vst/vstpshpack4.h"
#endif
//------------------------------------------------------------------------
/** Note Expression Value event. Used in \ref Event (union)
A note expression event affects one single playing note (referring its noteId).
This kind of event is send from host to the Plug-in like other events (NoteOnEvent, NoteOffEvent,...) in \ref ProcessData during the process call.
Note expression events for a specific noteId can only occur after a NoteOnEvent. The host must take care that the event list (\ref IEventList) is properly sorted.
Expression events are always absolute normalized values [0.0, 1.0].
The predefined types have a predefined mapping of the normalized values (see \ref NoteExpressionTypeIDs)
\sa INoteExpressionController
*/
//------------------------------------------------------------------------
struct NoteExpressionValueEvent
{
	NoteExpressionTypeID typeId;	///< see \ref NoteExpressionTypeID
	int32 noteId;					///< associated note identifier to apply the change

	NoteExpressionValue value;		///< normalized value [0.0, 1.0].
};

//------------------------------------------------------------------------
/** Note Expression Text event. Used in Event (union)
A Expression event affects one single playing note. \sa INoteExpressionController

\see NoteExpressionTypeInfo*/
//------------------------------------------------------------------------
struct NoteExpressionTextEvent
{
	NoteExpressionTypeID typeId;	///< see \ref NoteExpressionTypeID (kTextTypeID or kPhoneticTypeID)
	int32 noteId;					///< associated note identifier to apply the change

	uint32 textLen;					///< the number of characters (TChar) between the beginning of text and the terminating
									///< null character (without including the terminating null character itself)

	const TChar* text;				///< UTF-16, null terminated
};

#if WINDOWS && !PLATFORM_64
#include "pluginterfaces/base/falignpop.h"
#endif

//------------------------------------------------------------------------
/** NoteExpressionTypeInfo is the structure describing a note expression supported by the Plug-in.
This structure is used by the method \ref INoteExpressionController::getNoteExpressionInfo.
\see INoteExpressionController
*/
//------------------------------------------------------------------------
struct NoteExpressionTypeInfo
{
	NoteExpressionTypeID typeId;			///< unique identifier of this note Expression type
	String128 title;						///< note Expression type title (e.g. "Volume")
	String128 shortTitle;					///< note Expression type short title (e.g. "Vol")
	String128 units;						///< note Expression type unit (e.g. "dB")
	int32 unitId;							///< id of unit this NoteExpression belongs to (see \ref vst3UnitsIntro), in order to sort the note expression, it is possible to use unitId like for parameters. -1 means no unit used.
	NoteExpressionValueDescription valueDesc;	///< value description see \ref NoteExpressionValueDescription
	ParamID associatedParameterId;			///< optional associated parameter ID (for mapping from note expression to global (using the parameter automation for example) and back). Only used when kAssociatedParameterIDValid is set in flags.

	int32 flags;							///< NoteExpressionTypeFlags (see below)
	enum NoteExpressionTypeFlags
	{
		kIsBipolar		= 1 << 0,			///< event is bipolar (centered), otherwise unipolar
		kIsOneShot		= 1 << 1,			///< event occurs only one time for its associated note (at begin of the noteOn)
		kIsAbsolute		= 1 << 2,			///< This note expression will apply an absolute change to the sound (not relative (offset))
		kAssociatedParameterIDValid	= 1 << 3,///< indicates that the associatedParameterID is valid and could be used
	};
};

//------------------------------------------------------------------------
/** Extended Plug-in interface IEditController for note expression event support
\ingroup vstIPlug vst350
- [plug imp]
- [extends IEditController]
- [released: 3.5.0]
- [optional]

With this Plug-in interface, the host can retrieve all necessary note expression information supported by the Plug-in.
Note expression information (\ref NoteExpressionTypeInfo) are specific for given channel and event bus.

Note that there is only one NoteExpressionTypeID per given channel of an event bus.

The method getNoteExpressionStringByValue allows conversion from a normalized value to a string representation
and the getNoteExpressionValueByString method from a string to a normalized value.

When the note expression state changes (per example when switching presets) the Plug-in needs
to inform the host about it via \ref IComponentHandler::restartComponent (kNoteExpressionChanged).
*/
//------------------------------------------------------------------------
class INoteExpressionController: public FUnknown
{
public:
	/** Returns number of supported note change types for event bus index and channel. */
	virtual int32 PLUGIN_API getNoteExpressionCount (int32 busIndex, int16 channel) = 0;

	/** Returns note change type info. */
	virtual tresult PLUGIN_API getNoteExpressionInfo (int32 busIndex, int16 channel, int32 noteExpressionIndex, NoteExpressionTypeInfo& info /*out*/) = 0;

	/** Gets a user readable representation of the normalized note change value. */
	virtual tresult PLUGIN_API getNoteExpressionStringByValue (int32 busIndex, int16 channel, NoteExpressionTypeID id, NoteExpressionValue valueNormalized /*in*/, String128 string /*out*/) = 0;

	/** Converts the user readable representation to the normalized note change value. */
	virtual tresult PLUGIN_API getNoteExpressionValueByString (int32 busIndex, int16 channel, NoteExpressionTypeID id, const TChar* string /*in*/, NoteExpressionValue& valueNormalized /*out*/) = 0;

	//------------------------------------------------------------------------
	static const FUID iid;
};

DECLARE_CLASS_IID (INoteExpressionController, 0xB7F8F859, 0x41234872, 0x91169581, 0x4F3721A3)

//------------------------------------------------------------------------
//------------------------------------------------------------------------
/** KeyswitchTypeIDs describes the type of a key switch
\see KeyswitchInfo
*/
enum KeyswitchTypeIDs
{
	kNoteOnKeyswitchTypeID = 0,				///< press before noteOn is played
	kOnTheFlyKeyswitchTypeID,				///< press while noteOn is played
	kOnReleaseKeyswitchTypeID,				///< press before entering release
	kKeyRangeTypeID							///< key should be maintained pressed for playing
};

typedef uint32 KeyswitchTypeID;

//------------------------------------------------------------------------
/** KeyswitchInfo is the structure describing a key switch
This structure is used by the method \ref IKeyswitchController::getKeyswitchInfo.
\see IKeyswitchController
*/
struct KeyswitchInfo
{
	KeyswitchTypeID typeId;					///< see KeyswitchTypeID
	String128 title;						///< name of key switch (e.g. "Accentuation")
	String128 shortTitle;					///< short title (e.g. "Acc")

	int32 keyswitchMin;						///< associated main key switch min (value between [0, 127])
	int32 keyswitchMax;						///< associated main key switch max (value between [0, 127])
	int32 keyRemapped;						/** optional remapped key switch (default -1), the Plug-in could provide one remapped
											key for a key switch (allowing better location on the keyboard of the key switches) */

	int32 unitId;							///< id of unit this key switch belongs to (see \ref vst3UnitsIntro), -1 means no unit used.

	int32 flags;							///< not yet used (set to 0)
};

//------------------------------------------------------------------------
/** Extended Plug-in interface IEditController for key switches support
\ingroup vstIPlug vst350
- [plug imp]
- [extends IEditController]
- [released: 3.5.0]
- [optional]

When a (instrument) Plug-in supports such interface, the host could get from the Plug-in the current set
of used key switches (megatrig/articulation) for a given channel of a event bus and then automatically use them (like in Cubase 6) to
create VST Expression Map (allowing to associated symbol to a given articulation / key switch).
*/
//------------------------------------------------------------------------
class IKeyswitchController: public FUnknown
{
public:
	/** Returns number of supported key switches for event bus index and channel. */
	virtual int32 PLUGIN_API getKeyswitchCount (int32 busIndex, int16 channel) = 0;

	/** Returns key switch info. */
	virtual tresult PLUGIN_API getKeyswitchInfo (int32 busIndex, int16 channel, int32 keySwitchIndex, KeyswitchInfo& info /*out*/) = 0;

	//------------------------------------------------------------------------
	static const FUID iid;
};

DECLARE_CLASS_IID (IKeyswitchController, 0x1F2F76D3, 0xBFFB4B96, 0xB99527A5, 0x5EBCCEF4)

//------------------------------------------------------------------------
} // namespace Vst
} // namespace Steinberg

//------------------------------------------------------------------------
#include "pluginterfaces/base/falignpop.h"
//------------------------------------------------------------------------

repo_name: fedden/RenderMan

mime_type: text/x-c++


text:
//------------------------------------------------------------------------
// Project     : VST SDK
// Version     : 3.6.7
//
// Category    : Interfaces
// Filename    : pluginterfaces/vst/ivstplugview.h
// Created by  : Steinberg, 01/2009
// Description : Plug-in User Interface Extension
//
//-----------------------------------------------------------------------------
// This file is part of a Steinberg SDK. It is subject to the license terms
// in the LICENSE file found in the top-level directory of this distribution
// and at www.steinberg.net/sdklicenses.
// No part of the SDK, including this file, may be copied, modified, propagated,
// or distributed except according to the terms contained in the LICENSE file.
//-----------------------------------------------------------------------------

#pragma once

#include "pluginterfaces/base/funknown.h"
#include "vsttypes.h"

//------------------------------------------------------------------------
#include "pluginterfaces/base/falignpush.h"
//------------------------------------------------------------------------

//------------------------------------------------------------------------
namespace Steinberg {
namespace Vst {
//------------------------------------------------------------------------
// IParameterFinder Interface
//------------------------------------------------------------------------
/** Extension for IPlugView to find view parameters (lookup value under mouse support)
\ingroup pluginGUI vst302
- [plug imp]
- [extends IPlugView]
- [released: 3.0.2]

It is highly recommended to implement this interface.
A host can implement important functionality when a plug-in supports this interface.

For example, all Steinberg hosts require this interface in order to support the "AI Knob".
*/
class IParameterFinder: public FUnknown
{
public:
	//------------------------------------------------------------------------
	/** Find out which parameter in Plug-in view is at given position (relative to Plug-in view). */
	virtual tresult PLUGIN_API findParameter (int32 xPos, int32 yPos, ParamID& resultTag /*out*/) = 0;
	//------------------------------------------------------------------------
	static const FUID iid;
};

DECLARE_CLASS_IID (IParameterFinder, 0x0F618302, 0x215D4587, 0xA512073C, 0x77B9D383)

//------------------------------------------------------------------------
} // namespace Vst
} // namespace Steinberg

//------------------------------------------------------------------------
#include "pluginterfaces/base/falignpop.h"
//------------------------------------------------------------------------


text:
//------------------------------------------------------------------------
// Project     : VST SDK
// Version     : 3.6.7
//
// Category    : Interfaces
// Filename    : pluginterfaces/vst/ivstrepresentation.h
// Created by  : Steinberg, 08/2010
// Description : VST Representation Interface
//
//-----------------------------------------------------------------------------
// This file is part of a Steinberg SDK. It is subject to the license terms
// in the LICENSE file found in the top-level directory of this distribution
// and at www.steinberg.net/sdklicenses.
// No part of the SDK, including this file, may be copied, modified, propagated,
// or distributed except according to the terms contained in the LICENSE file.
//-----------------------------------------------------------------------------

#pragma once

#include "pluginterfaces/base/funknown.h"
#include "pluginterfaces/vst/vsttypes.h"

//------------------------------------------------------------------------
#include "pluginterfaces/base/falignpush.h"
//------------------------------------------------------------------------

//------------------------------------------------------------------------
namespace Steinberg {
class IBStream;

namespace Vst {

//------------------------------------------------------------------------
/** RepresentationInfo is the structure describing a representation
This structure is used in the function \see IXmlRepresentationController::getXmlRepresentationStream.
\see IXmlRepresentationController
*/
struct RepresentationInfo
{
	RepresentationInfo ()
	{
		memset (vendor, 0, kNameSize);
		memset (name, 0, kNameSize);
		memset (version, 0, kNameSize);
		memset (host, 0, kNameSize);
	}

	RepresentationInfo (char8* _vendor, char8* _name = 0, char8* _version = 0, char8* _host = 0)
	{
		memset (vendor, 0, kNameSize);
		if (_vendor)
			strcpy (vendor,	_vendor);
		memset (name, 0, kNameSize);
		if (_name)
			strcpy (name, _name);
		memset (version, 0, kNameSize);
		if (_version)
			strcpy (version, _version);
		memset (host, 0, kNameSize);
		if (_host)
			strcpy (host, _host);
	}

	enum
	{
		kNameSize = 64
	};
	char8 vendor[kNameSize];	///< Vendor name of the associated representation (remote) (eg. "Yamaha").
	char8 name[kNameSize];		///< Representation (remote) Name (eg. "O2").
	char8 version[kNameSize];	///< Version of this "Remote" (eg. "1.0").
	char8 host[kNameSize];		///< Optional: used if the representation is for a given host only (eg. "Nuendo").
};

//------------------------------------------------------------------------
//------------------------------------------------------------------------
/** Extended Plug-in interface IEditController for a component.
\ingroup vstIPlug vst350
- [plug imp]
- [extends IEditController]
- [released: 3.5.0]
- [optional]

A Representation based on XML is a way to export and structure, group Plug-ins parameters for a specific remote (could be hardware or software rack (like quickcontrols)).
\n
It allows to describe more precisely each parameter (what is the best matching to a knob, different titles lengths matching limited remote display,...).\n See an \ref Example.
 \n\n
- A Representation is composed of Pages (this means that to see all exported parameters the user has to navigate through the pages).
- A Page is composed of Cells (for example 8 Cells per page).
- A Cell is composed of Layers (for example a cell could have a knob, a display and a button which are 3 Layers).
- A Layer is associated to a Plug-in parameter using the ParameterID as identifier:
	- it could be a knob with a display for Title and/or value, this display uses the same parameterId, but it could an another one.
	- Switch
	- link which allows to jump directly to a subpage (an another page)
	- more... See Vst::LayerType
.

\n
This Representation is implemented as XML text following the Document Type Definition (DTD): http://dtd.steinberg.net/VST-Remote-1.1.dtd

\section Example
Here an example of what should be passed in the stream of getXmlRepresentationStream:

\code
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE vstXML PUBLIC "-//Steinberg//DTD VST Remote 1.1//EN" "http://dtd.steinberg.net/VST-Remote-1.1.dtd">
<vstXML version="1.0">
	<plugin classID="341FC5898AAA46A7A506BC0799E882AE" name="Chorus" vendor="Steinberg Media Technologies" />
	<originator>My name</originator>
	<date>2010-12-31</date>
	<comment>This is an example for 4 Cells per Page for the Remote named ProductRemote
	         from company HardwareCompany.</comment>

	<!-- ===================================== -->
	<representation name="ProductRemote" vendor="HardwareCompany" version="1.0">
		<page name="Root">
			<cell>
				<layer type="knob" parameterID="0">
					<titleDisplay>
						<name>Mix dry/wet</name>
						<name>Mix</name>
					</titleDisplay>
				</layer>
			</cell>
			<cell>
				<layer type="display"></layer>
			</cell>
			<cell>
				<layer type="knob" parameterID="3">
					<titleDisplay>
						<name>Delay</name>
						<name>Dly</name>
					</titleDisplay>
				</layer>
			</cell>
			<cell>
				<layer type="knob" parameterID="15">
					<titleDisplay>
						<name>Spatial</name>
						<name>Spat</name>
					</titleDisplay>
				</layer>
			</cell>
		</page>
		<page name="Page 2">
			<cell>
				<layer type="LED" ledStyle="spread" parameterID="2">
					<titleDisplay>
						<name>Width +</name>
						<name>Widt</name>
					</titleDisplay>
				</layer>
				<!--this is the switch for shape A/B-->
				<layer type="switch" switchStyle="pushIncLooped" parameterID="4"></layer>
			</cell>
			<cell>
				<layer type="display"></layer>
			</cell>
			<cell>
				<layer type="LED" ledStyle="singleDot" parameterID="17">
					<titleDisplay>
						<name>Sync Note +</name>
						<name>Note</name>
					</titleDisplay>
				</layer>
				<!--this is the switch for sync to tempo on /off-->
				<layer type="switch" switchStyle="pushIncLooped" parameterID="16"></layer>
			</cell>
			<cell>
				<layer type="knob" parameterID="1">
					<titleDisplay>
						<name>Rate</name>
					</titleDisplay>
				</layer>
			</cell>
		</page>
	</representation>
</vstXML>
\endcode
*/
//------------------------------------------------------------------------
class IXmlRepresentationController: public FUnknown
{
public:
	/** Retrieves a stream containing a XmlRepresentation for a wanted representation info */
	virtual tresult PLUGIN_API getXmlRepresentationStream (RepresentationInfo& info /*in*/, IBStream* stream /*out*/) = 0;

	//------------------------------------------------------------------------
	static const FUID iid;
};

DECLARE_CLASS_IID (IXmlRepresentationController, 0xA81A0471, 0x48C34DC4, 0xAC30C9E1, 0x3C8393D5)

//------------------------------------------------------------------------
/** Defines for XML representation Tags and Attributes */

#define ROOTXML_TAG			"vstXML"

#define COMMENT_TAG			"comment"
#define CELL_TAG			"cell"
#define CELLGROUP_TAG		"cellGroup"
#define CELLGROUPTEMPLATE_TAG	"cellGroupTemplate"
#define CURVE_TAG			"curve"
#define CURVETEMPLATE_TAG	"curveTemplate"
#define DATE_TAG			"date"
#define LAYER_TAG			"layer"
#define NAME_TAG			"name"
#define ORIGINATOR_TAG		"originator"
#define PAGE_TAG			"page"
#define PAGETEMPLATE_TAG	"pageTemplate"
#define PLUGIN_TAG			"plugin"
#define VALUE_TAG			"value"
#define VALUEDISPLAY_TAG	"valueDisplay"
#define VALUELIST_TAG		"valueList"
#define REPRESENTATION_TAG	"representation"
#define SEGMENT_TAG			"segment"
#define SEGMENTLIST_TAG		"segmentList"
#define TITLEDISPLAY_TAG	"titleDisplay"

#define ATTR_CATEGORY		"category"
#define ATTR_CLASSID		"classID"
#define ATTR_ENDPOINT		"endPoint"
#define ATTR_INDEX			"index"
#define ATTR_FLAGS			"flags"
#define ATTR_FUNCTION		"function"
#define ATTR_HOST			"host"
#define ATTR_LEDSTYLE		"ledStyle"
#define ATTR_LENGTH			"length"
#define ATTR_LINKEDTO		"linkedTo"
#define ATTR_NAME			"name"
#define ATTR_ORDER			"order"
#define ATTR_PAGE			"page"
#define ATTR_PARAMID		"parameterID"
#define ATTR_STARTPOINT		"startPoint"
#define ATTR_STYLE			"style"
#define ATTR_SWITCHSTYLE	"switchStyle"
#define ATTR_TEMPLATE		"template"
#define ATTR_TURNSPERFULLRANGE	"turnsPerFullRange"
#define ATTR_TYPE			"type"
#define ATTR_UNITID			"unitID"
#define ATTR_VARIABLES		"variables"
#define ATTR_VENDOR			"vendor"
#define ATTR_VERSION		"version"

//------------------------------------------------------------------------
/** Defines some predefined Representation Remote Names */
#define GENERIC 				"Generic"
#define GENERIC_4_CELLS			"Generic 4 Cells"
#define GENERIC_8_CELLS			"Generic 8 Cells"
#define GENERIC_12_CELLS		"Generic 12 Cells"
#define GENERIC_24_CELLS		"Generic 24 Cells"
#define GENERIC_N_CELLS			"Generic %d Cells"
#define QUICK_CONTROL_8_CELLS	"Quick Controls 8 Cells"

//------------------------------------------------------------------------
/** Layer Types used in a VST XML Representation */
//------------------------------------------------------------------------
namespace LayerType
{
	enum
	{
		kKnob = 0, 		///< a knob (encoder or not)
		kPressedKnob,  	///< a knob which is used by pressing and turning
		kSwitchKnob,	///< knob could be pressed to simulate a switch
		kSwitch,		///< a "on/off" button
		kLED,			///< LED like VU-meter or display around a knob
		kLink,			///< indicates that this layer is a folder linked to an another INode (page)
		kDisplay,		///< only for text display (not really a control)
		kFader,			///< a fader
		kEndOfLayerType
	};

	/** FIDString variant of the LayerType */
	static const FIDString layerTypeFIDString[] = {
		"knob"
		,"pressedKnob"
		,"switchKnob"
		,"switch"
		,"LED"
		,"link"
		,"display"
		,"fader"
		,0
	};
};

//------------------------------------------------------------------------
/** Curve Types used in a VST XML Representation */
//------------------------------------------------------------------------
namespace CurveType
{
	const CString kSegment		= "segment";	///<
	const CString kValueList	= "valueList";	///<
};

//------------------------------------------------------------------------
/** Attributes used to defined a Layer in a VST XML Representation */
//------------------------------------------------------------------------
namespace Attributes
{
	const CString kStyle		= ATTR_STYLE;			///< string attribute : See AttributesStyle for available string value
	const CString kLEDStyle		= ATTR_LEDSTYLE;		///< string attribute : See AttributesStyle for available string value
	const CString kSwitchStyle	= ATTR_SWITCHSTYLE;		///< string attribute : See AttributesStyle for available string value
	const CString kKnobTurnsPerFullRange = ATTR_TURNSPERFULLRANGE;	///< float attribute
	const CString kFunction		= ATTR_FUNCTION;		///< string attribute : See AttributesFunction for available string value
	const CString kFlags		= ATTR_FLAGS;			///< string attribute : See AttributesFlags for available string value
};

//------------------------------------------------------------------------
/** Attributes Function used to defined the function of a Layer in a VST XML Representation */
//------------------------------------------------------------------------
namespace AttributesFunction
{
	/// Global Style
	const CString kPanPosCenterXFunc		= "PanPosCenterX";		///< Gravity point X-axis (L-R) (for stereo: middle between left and right)
	const CString kPanPosCenterYFunc		= "PanPosCenterY";		///< Gravity point Y-axis (Front-Rear)
	const CString kPanPosFrontLeftXFunc		= "PanPosFrontLeftX";	///< Left channel Position in X-axis
	const CString kPanPosFrontLeftYFunc		= "PanPosFrontLeftY";	///< Left channel Position in Y-axis
	const CString kPanPosFrontRightXFunc	= "PanPosFrontRightX";	///< Right channel Position in X-axis
	const CString kPanPosFrontRightYFunc	= "PanPosFrontRightY";	///< Right channel Position in Y-axis
	const CString kPanRotationFunc			= "PanRotation";		///< Rotation around the Center (gravity point)
	const CString kPanLawFunc				= "PanLaw";				///< Panning Law
	const CString kPanMirrorModeFunc		= "PanMirrorMode";		///< Panning Mirror Mode
	const CString kPanLfeGainFunc			= "PanLfeGain";			///< Panning LFE Gain
	const CString kGainReductionFunc		= "GainReduction";		///< Gain Reduction for compressor
	const CString kSoloFunc					= "Solo";				///< Solo
	const CString kMuteFunc					= "Mute";				///< Mute
	const CString kVolumeFunc				= "Volume";				///< Volume
};

//------------------------------------------------------------------------
/** Attributes Style associated a specific Layer Type in a VST XML Representation */
//------------------------------------------------------------------------
namespace AttributesStyle
{
	/// Global Style
	const CString kInverseStyle			= "inverse";	///< the associated layer should use the inverse value of parameter (1 - x).

	/// LED Style
	const CString kLEDWrapLeftStyle		= "wrapLeft";	///< |======>----- (the default one if not specified)
	const CString kLEDWrapRightStyle	= "wrapRight";	///< -------<====|
	const CString kLEDSpreadStyle		= "spread";		///< ---<==|==>---
	const CString kLEDBoostCutStyle		= "boostCut";	///< ------|===>--
	const CString kLEDSingleDotStyle	= "singleDot";	///< --------|----

	/// Switch Style
	const CString kSwitchPushStyle		= "push";		///< Apply only when pressed, unpressed will reset the value to min.
	const CString kSwitchPushIncLoopedStyle	= "pushIncLooped";	///< Push will increment the value. When the max is reached it will restart with min.
																///< The default one if not specified (with 2 states values it is a OnOff switch).
	const CString kSwitchPushDecLoopedStyle	= "pushDecLooped";	///< Push will decrement the value. When the min is reached it will restart with max.
	const CString kSwitchPushIncStyle	= "pushInc";	///< Increment after each press (delta depends of the curve).
	const CString kSwitchPushDecStyle	= "pushDec";	///< Decrement after each press (delta depends of the curve).
	const CString kSwitchLatchStyle		= "latch";		///< Each push-release will change the value between min and max.
														///< A timeout between push and release could be used to simulate a push style (if timeout is reached).
};

//------------------------------------------------------------------------
/** Attributes Flags defining a Layer in a VST XML Representation */
//------------------------------------------------------------------------
namespace AttributesFlags
{
	const CString kHideableFlag			= "hideable";	///< the associated layer marked as hideable allows a remote to hide or make it not usable a parameter when the associated value is inactive
};

//------------------------------------------------------------------------
} // namespace Vst
} // namespace Steinberg

//------------------------------------------------------------------------
#include "pluginterfaces/base/falignpop.h"
//------------------------------------------------------------------------


text:
//------------------------------------------------------------------------
// Project     : VST SDK
// Version     : 3.6.7
//
// Category    : Interfaces
// Filename    : pluginterfaces/vst/ivstautomationstate.h
// Created by  : Steinberg, 02/2015
// Description : VST Automation State Interface
//
//-----------------------------------------------------------------------------
// This file is part of a Steinberg SDK. It is subject to the license terms
// in the LICENSE file found in the top-level directory of this distribution
// and at www.steinberg.net/sdklicenses.
// No part of the SDK, including this file, may be copied, modified, propagated,
// or distributed except according to the terms contained in the LICENSE file.
//-----------------------------------------------------------------------------

#pragma once

#include "pluginterfaces/vst/vsttypes.h"

//------------------------------------------------------------------------
#include "pluginterfaces/base/falignpush.h"
//------------------------------------------------------------------------

//------------------------------------------------------------------------
namespace Steinberg {
namespace Vst {

//------------------------------------------------------------------------
/** Extended IComponent interface for a component.
\ingroup vstIPlug vst365
- [plug imp]
- [extends IComponent]
- [released: 3.6.5]
- [optional]

Hosts could inform the Plug-in about its current automation state (Read/Write/Nothing).
*/
//------------------------------------------------------------------------
class IAutomationState : public FUnknown
{
public:
//------------------------------------------------------------------------
	enum AutomationStates
	{
		kNoAutomation = 0,		///< Not Read and not Write
		kReadState = 1 << 0,	///< Read state
		kWriteState = 1 << 1,	///< Write state

		kReadWriteState = kReadState | kWriteState, ///< Read and Write enable
	};

	/** Sets the current Automation state. */
	virtual tresult PLUGIN_API setAutomationState (int32 state) = 0;

//------------------------------------------------------------------------
	static const FUID iid;
};

DECLARE_CLASS_IID (IAutomationState, 0xB4E8287F, 0x1BB346AA, 0x83A46667, 0x68937BAB)

} // namespace Vst
} // namespace Steinberg

//------------------------------------------------------------------------
#include "pluginterfaces/base/falignpop.h"
//------------------------------------------------------------------------


text:
//------------------------------------------------------------------------
// Project     : VST SDK
// Version     : 3.6.7
//
// Category    : Interfaces
// Filename    : pluginterfaces/vst/vstpshpack4.h
// Created by  : Steinberg, 05/2010
// Description : This file turns 4 Bytes packing of structures on. The file
//               pluginterfaces/base/falignpop.h is the complement to this file.
//
//-----------------------------------------------------------------------------
// This file is part of a Steinberg SDK. It is subject to the license terms
// in the LICENSE file found in the top-level directory of this distribution
// and at www.steinberg.net/sdklicenses.
// No part of the SDK, including this file, may be copied, modified, propagated,
// or distributed except according to the terms contained in the LICENSE file.
//-----------------------------------------------------------------------------

#pragma once

//----------------------------------------------------------------------------------------------
#if defined __BORLANDC__
	#pragma -a4
#else
	#if (_MSC_VER >= 800 && !defined(_M_I86)) || defined(_PUSHPOP_SUPPORTED)
		#pragma warning(disable:4103)
	#endif

	#pragma pack(push)
	#pragma pack(4)
#endif


text:
//------------------------------------------------------------------------
// Project     : VST SDK
// Version     : 3.6.7
//
// Category    : Interfaces
// Filename    : pluginterfaces/vst/ivsteditcontroller.h
// Created by  : Steinberg, 09/2005
// Description : VST Edit Controller Interfaces
//
//-----------------------------------------------------------------------------
// This file is part of a Steinberg SDK. It is subject to the license terms
// in the LICENSE file found in the top-level directory of this distribution
// and at www.steinberg.net/sdklicenses.
// No part of the SDK, including this file, may be copied, modified, propagated,
// or distributed except according to the terms contained in the LICENSE file.
//-----------------------------------------------------------------------------

#pragma once

#include "pluginterfaces/base/ipluginbase.h"
#include "vsttypes.h"

//------------------------------------------------------------------------
#include "pluginterfaces/base/falignpush.h"
//------------------------------------------------------------------------

//------------------------------------------------------------------------
/** Class Category Name for Controller Component */
//------------------------------------------------------------------------
#ifndef kVstComponentControllerClass
#define kVstComponentControllerClass "Component Controller Class"
#endif

//------------------------------------------------------------------------
namespace Steinberg {
class IPlugView;
class IBStream;

//------------------------------------------------------------------------
namespace Vst {
//------------------------------------------------------------------------
/** Controller Parameter Info. */
//------------------------------------------------------------------------
struct ParameterInfo
{
//------------------------------------------------------------------------
	ParamID id;				///< unique identifier of this parameter (named tag too)
	String128 title;		///< parameter title (e.g. "Volume")
	String128 shortTitle;	///< parameter shortTitle (e.g. "Vol")
	String128 units;		///< parameter unit (e.g. "dB")
	int32 stepCount;		///< number of discrete steps (0: continuous, 1: toggle, discrete value otherwise
							///< (corresponding to max - min, for example: 127 for a min = 0 and a max = 127) - see \ref vst3parameterIntro)
	ParamValue defaultNormalizedValue;	///< default normalized value [0,1] (in case of discrete value: defaultNormalizedValue = defDiscreteValue / stepCount)
	UnitID unitId;			///< id of unit this parameter belongs to (see \ref vst3UnitsIntro)

	int32 flags;			///< ParameterFlags (see below)
	enum ParameterFlags
	{
		kCanAutomate	 = 1 << 0,	///< parameter can be automated
		kIsReadOnly		 = 1 << 1,	///< parameter cannot be changed from outside (implies that kCanAutomate is false)
		kIsWrapAround	 = 1 << 2,	///< attempts to set the parameter value out of the limits will result in a wrap around [SDK 3.0.2]
		kIsList			 = 1 << 3,	///< parameter should be displayed as list in generic editor or automation editing [SDK 3.1.0]

		kIsProgramChange = 1 << 15,	///< parameter is a program change (unitId gives info about associated unit
									///< - see \ref vst3UnitPrograms)
		kIsBypass		 = 1 << 16	///< special bypass parameter (only one allowed): Plug-in can handle bypass
									///< (highly recommended to export a bypass parameter for effect Plug-in)
	};
//------------------------------------------------------------------------
};

//------------------------------------------------------------------------
/** View Types used for IEditController::createView */
//------------------------------------------------------------------------
namespace ViewType {
const CString kEditor = "editor";
}

//------------------------------------------------------------------------
/** Flags used for IComponentHandler::restartComponent */
//------------------------------------------------------------------------
enum RestartFlags
{
	kReloadComponent			= 1 << 0,	///< The Component should be reloaded             [SDK 3.0.0]
	kIoChanged					= 1 << 1,	///< Input and/or Output Bus configuration has changed        [SDK 3.0.0]
	kParamValuesChanged			= 1 << 2,	///< Multiple parameter values have changed
											///< (as result of a program change for example)  [SDK 3.0.0]
	kLatencyChanged				= 1 << 3,	///< Latency has changed (IAudioProcessor.getLatencySamples)  [SDK 3.0.0]
	kParamTitlesChanged			= 1 << 4,	///< Parameter titles or default values or flags have changed [SDK 3.0.0]
	kMidiCCAssignmentChanged	= 1 << 5,	///< MIDI Controller Assignments have changed     [SDK 3.0.1]
	kNoteExpressionChanged		= 1 << 6,	///< Note Expression has changed (info, count...) [SDK 3.5.0]
	kIoTitlesChanged			= 1 << 7,	///< Input and/or Output bus titles have changed  [SDK 3.5.0]
	kPrefetchableSupportChanged = 1 << 8,	///< Prefetch support has changed (\see IPrefetchableSupport) [SDK 3.6.1]
	kRoutingInfoChanged			= 1 << 9	///< RoutingInfo has changed (\see IComponent)    [SDK 3.6.6]
};

//------------------------------------------------------------------------
/** Host callback interface for an edit controller.
\ingroup vstIHost vst300
- [host imp]
- [released: 3.0.0]

Allow transfer of parameter editing to component (processor) via host and support automation.
Cause the host to react on configuration changes (restartComponent)

\see IEditController */
//------------------------------------------------------------------------
class IComponentHandler: public FUnknown
{
public:
//------------------------------------------------------------------------
	/** To be called before calling a performEdit (e.g. on mouse-click-down event). */
	virtual tresult PLUGIN_API beginEdit (ParamID id) = 0;

	/** Called between beginEdit and endEdit to inform the handler that a given parameter has a new value. */
	virtual tresult PLUGIN_API performEdit (ParamID id, ParamValue valueNormalized) = 0;

	/** To be called after calling a performEdit (e.g. on mouse-click-up event). */
	virtual tresult PLUGIN_API endEdit (ParamID id) = 0;

	/** Instructs host to restart the component. This should be called in the UI-Thread context!
	\param flags is a combination of RestartFlags */
	virtual tresult PLUGIN_API restartComponent (int32 flags) = 0;

//------------------------------------------------------------------------
	static const FUID iid;
};

DECLARE_CLASS_IID (IComponentHandler, 0x93A0BEA3, 0x0BD045DB, 0x8E890B0C, 0xC1E46AC6)

//------------------------------------------------------------------------
/** Extended Host callback interface IComponentHandler2 for an edit controller
\ingroup vstIHost vst310
- [host imp]
- [extends IComponentHandler]
- [released: 3.1.0]

One part handles:
- Setting dirty state of Plug-in
- requesting the host to open the editor

The other part handles parameter group editing from Plug-in UI. It wraps a set of \ref IComponentHandler::beginEdit /
\ref IComponentHandler::performEdit / \ref IComponentHandler::endEdit functions (see \ref IComponentHandler)
which should use the same timestamp in the host when writing automation.
This allows for better synchronizing multiple parameter changes at once.

\section IComponentHandler2Example Examples of different use cases
\code
	//--------------------------------------
	// in case of multiple switch buttons (with associated ParamID 1 and 3)
	// on mouse down :
	hostHandler2->startGroupEdit ();
	hostHandler->beginEdit (1);
	hostHandler->beginEdit (3);
	hostHandler->performEdit (1, 1.0);
	hostHandler->performEdit (3, 0.0); // the opposite of paramID 1 for example
	....
	// on mouse up :
	hostHandler->endEdit (1);
	hostHandler->endEdit (3);
	hostHandler2->finishGroupEdit ();
	....
	....
	//--------------------------------------
	// in case of multiple faders (with associated ParamID 1 and 3)
	// on mouse down :
	hostHandler2->startGroupEdit ();
	hostHandler->beginEdit (1);
	hostHandler->beginEdit (3);
	hostHandler2->finishGroupEdit ();
	....
	// on mouse move :
	hostHandler2->startGroupEdit ();
	hostHandler->performEdit (1, x); // x the wanted value
	hostHandler->performEdit (3, x);
	hostHandler2->finishGroupEdit ();
	....
	// on mouse up :
	hostHandler2->startGroupEdit ();
	hostHandler->endEdit (1);
	hostHandler->endEdit (3);
	hostHandler2->finishGroupEdit ();
\endcode
\see IComponentHandler
\see IEditController*/
//------------------------------------------------------------------------
class IComponentHandler2: public FUnknown
{
public:
	//------------------------------------------------------------------------
	/** Tells host that the Plug-in is dirty (something besides parameters has changed since last save),
	if true the host should apply a save before quitting. */
	virtual tresult PLUGIN_API setDirty (TBool state) = 0;

	/** Tells host that it should open the Plug-in editor the next time it's possible.
	You should use this instead of showing an alert and blocking the program flow (especially on loading projects). */
	virtual tresult PLUGIN_API requestOpenEditor (FIDString name = ViewType::kEditor) = 0;

	//------------------------------------------------------------------------
	/** Starts the group editing (call before a \ref IComponentHandler::beginEdit),
	the host will keep the current timestamp at this call and will use it for all \ref IComponentHandler::beginEdit
	/ \ref IComponentHandler::performEdit / \ref IComponentHandler::endEdit calls until a \ref finishGroupEdit (). */
	virtual tresult PLUGIN_API startGroupEdit () = 0;

	/** Finishes the group editing started by a \ref startGroupEdit (call after a \ref IComponentHandler::endEdit). */
	virtual tresult PLUGIN_API finishGroupEdit () = 0;

	//------------------------------------------------------------------------
	static const FUID iid;
};

DECLARE_CLASS_IID (IComponentHandler2, 0xF040B4B3, 0xA36045EC, 0xABCDC045, 0xB4D5A2CC)

//------------------------------------------------------------------------
/** Edit controller component interface.
\ingroup vstIPlug vst300
- [plug imp]
- [released: 3.0.0]

The Controller part of an effect or instrument with parameter handling (export, definition, conversion...).
\see IComponent::getControllerClassId, IMidiMapping */
//------------------------------------------------------------------------
class IEditController: public IPluginBase
{
public:
//------------------------------------------------------------------------
	/** Receives the component state. */
	virtual tresult PLUGIN_API setComponentState (IBStream* state) = 0;

	/** Sets the controller state. */
	virtual tresult PLUGIN_API setState (IBStream* state) = 0;

	/** Gets the controller state. */
	virtual tresult PLUGIN_API getState (IBStream* state) = 0;

	// parameters -------------------------
	/** Returns the number of parameters exported. */
	virtual int32 PLUGIN_API getParameterCount () = 0;
	/** Gets for a given index the parameter information. */
	virtual tresult PLUGIN_API getParameterInfo (int32 paramIndex, ParameterInfo& info /*out*/) = 0;

	/** Gets for a given paramID and normalized value its associated string representation. */
	virtual tresult PLUGIN_API getParamStringByValue (ParamID id, ParamValue valueNormalized /*in*/, String128 string /*out*/) = 0;
	/** Gets for a given paramID and string its normalized value. */
	virtual tresult PLUGIN_API getParamValueByString (ParamID id, TChar* string /*in*/, ParamValue& valueNormalized /*out*/) = 0;

	/** Returns for a given paramID and a normalized value its plain representation
		(for example 90 for 90db - see \ref vst3AutomationIntro). */
	virtual ParamValue PLUGIN_API normalizedParamToPlain (ParamID id, ParamValue valueNormalized) = 0;
	/** Returns for a given paramID and a plain value its normalized value. (see \ref vst3AutomationIntro) */
	virtual ParamValue PLUGIN_API plainParamToNormalized (ParamID id, ParamValue plainValue) = 0;

	/** Returns the normalized value of the parameter associated to the paramID. */
	virtual ParamValue PLUGIN_API getParamNormalized (ParamID id) = 0;
	/** Sets the normalized value to the parameter associated to the paramID. The controller must never
	    pass this value-change back to the host via the IComponentHandler. It should update the according
		GUI element(s) only!*/
	virtual tresult PLUGIN_API setParamNormalized (ParamID id, ParamValue value) = 0;

	// handler ----------------------------
	/** Gets from host a handler. */
	virtual tresult PLUGIN_API setComponentHandler (IComponentHandler* handler) = 0;

	// view -------------------------------
	/** Creates the editor view of the Plug-in, currently only "editor" is supported, see \ref ViewType.
		The life time of the editor view will never exceed the life time of this controller instance. */
	virtual IPlugView* PLUGIN_API createView (FIDString name) = 0;

//------------------------------------------------------------------------
	static const FUID iid;
};

DECLARE_CLASS_IID (IEditController, 0xDCD7BBE3, 0x7742448D, 0xA874AACC, 0x979C759E)

//------------------------------------------------------------------------
/** Knob Mode */
//------------------------------------------------------------------------
enum KnobModes
{
	kCircularMode = 0,		///< Circular with jump to clicked position
	kRelativCircularMode,	///< Circular without jump to clicked position
	kLinearMode				///< Linear: depending on vertical movement
};

typedef int32 KnobMode;		///< Knob Mode

//------------------------------------------------------------------------
/** Edit controller component interface extension.
\ingroup vstIPlug vst310
- [plug imp]
- [extends IEditController]
- [released: 3.1.0]

Extension to inform the Plug-in about the host Knob Mode,
and to open the Plug-in about box or help documentation.

\see IEditController*/
//------------------------------------------------------------------------
class IEditController2: public FUnknown
{
public:
	/** Host could set the Knob Mode for the Plug-in. Return kResultFalse means not supported mode. \see KnobModes. */
	virtual tresult PLUGIN_API setKnobMode (KnobMode mode) = 0;

	/** Host could ask to open the Plug-in help (could be: opening a PDF document or link to a web page).
	    The host could call it with onlyCheck set to true for testing support of open Help.
		Return kResultFalse means not supported function. */
	virtual tresult PLUGIN_API openHelp (TBool onlyCheck) = 0;

	/** Host could ask to open the Plug-in about box.
	    The host could call it with onlyCheck set to true for testing support of open AboutBox.
		Return kResultFalse means not supported function. */
	virtual tresult PLUGIN_API openAboutBox (TBool onlyCheck) = 0;

	//------------------------------------------------------------------------
	static const FUID iid;
};

DECLARE_CLASS_IID (IEditController2, 0x7F4EFE59, 0xF3204967, 0xAC27A3AE, 0xAFB63038)

//------------------------------------------------------------------------
/** MIDI Mapping Interface.
\ingroup vstIPlug vst301
- [plug imp]
- [extends IEditController]
- [released: 3.0.1]

MIDI controllers are not transmitted directly to a VST component. MIDI as hardware protocol has
restrictions that can be avoided in software. Controller data in particular come along with unclear
and often ignored semantics. On top of this they can interfere with regular parameter automation and
the host is unaware of what happens in the Plug-in when passing MIDI controllers directly.

So any functionality that is to be controlled by MIDI controllers must be exported as regular parameter.
The host will transform incoming MIDI controller data using this interface and transmit them as normal
parameter change. This allows the host to automate them in the same way as other parameters.
CtrlNumber could be typical MIDI controller value extended to some others values like pitch bend or
after touch (see \ref ControllerNumbers).
If the mapping has changed, the Plug-in should call IComponentHandler::restartComponent (kMidiCCAssignmentChanged)
to inform the host about this change. */
//------------------------------------------------------------------------
class IMidiMapping: public FUnknown
{
public:

	/** Gets an (preferred) associated ParamID for a given Input Event Bus index, channel and MIDI Controller.
	*	@param[in] busIndex - index of Input Event Bus
	*	@param[in] channel - channel of the bus
	*   @param[in] midiControllerNumber - see \ref ControllerNumbers for expected values (could be bigger than 127)
	*	@param[in] id - return the associated ParamID to the given midiControllerNumber
	*/
	virtual tresult PLUGIN_API getMidiControllerAssignment (int32 busIndex, int16 channel,
															CtrlNumber midiControllerNumber, ParamID& id/*out*/) = 0;

	//------------------------------------------------------------------------
	static const FUID iid;
};

DECLARE_CLASS_IID (IMidiMapping, 0xDF0FF9F7, 0x49B74669, 0xB63AB732, 0x7ADBF5E5)

//------------------------------------------------------------------------
/** Parameter Editing from Host.
\ingroup vstIPlug vst350
- [plug imp]
- [extends IEditController]
- [released: 3.5.0]
- [optional]

If this interface is implemented by the edit controller and when performing edits from outside
the Plug-in (host / remote) of a not automatable and not read only flagged parameter (kind of helper parameter),
the host will start with a beginEditFromHost before calling setParamNormalized and end with an endEditFromHost.
Here the sequencing, the host will call:
- beginEditFromHost ()
- setParamNormalized ()
- setParamNormalized ()
- ...
- endEditFromHost ()
\see IEditController */
//------------------------------------------------------------------------
class IEditControllerHostEditing : public FUnknown
{
public:
	/** Called before a setParamNormalized sequence, a endEditFromHost will be call at the end of the editing action. */
	virtual tresult PLUGIN_API beginEditFromHost (ParamID paramID) = 0;

	/** Called after a beginEditFromHost and a sequence of setParamNormalized. */
	virtual tresult PLUGIN_API endEditFromHost (ParamID paramID) = 0;

	//------------------------------------------------------------------------
	static const FUID iid;
};

DECLARE_CLASS_IID (IEditControllerHostEditing, 0xC1271208, 0x70594098, 0xB9DD34B3, 0x6BB0195E)

//------------------------------------------------------------------------
} // namespace Vst
} // namespace Steinberg

//------------------------------------------------------------------------
#include "pluginterfaces/base/falignpop.h"
//------------------------------------------------------------------------


text:
set(sdk_sources
	source/common/pluginview.cpp
	source/main/pluginfactoryvst3.cpp
	source/vst/vstaudioeffect.cpp
	source/vst/vstbus.cpp
	source/vst/vstbypassprocessor.cpp
	source/vst/vstcomponent.cpp
	source/vst/vstcomponentbase.cpp
	source/vst/vsteditcontroller.cpp
	source/vst/vstinitiids.cpp
	source/vst/vstnoteexpressiontypes.cpp
	source/vst/vstparameters.cpp
	source/vst/vstpresetfile.cpp
	source/vst/vstrepresentation.cpp
)

set(pluginterfaces_sources
	${SDK_ROOT}/pluginterfaces/base/falignpop.h
	${SDK_ROOT}/pluginterfaces/base/falignpush.h
	${SDK_ROOT}/pluginterfaces/base/fplatform.h
	${SDK_ROOT}/pluginterfaces/base/fstrdefs.h
	${SDK_ROOT}/pluginterfaces/base/ftypes.h
	${SDK_ROOT}/pluginterfaces/base/funknown.h
	${SDK_ROOT}/pluginterfaces/base/futils.h
	${SDK_ROOT}/pluginterfaces/base/fvariant.h
	${SDK_ROOT}/pluginterfaces/base/geoconstants.h
	${SDK_ROOT}/pluginterfaces/base/ibstream.h
	${SDK_ROOT}/pluginterfaces/base/icloneable.h
	${SDK_ROOT}/pluginterfaces/base/ierrorcontext.h
	${SDK_ROOT}/pluginterfaces/base/ipersistent.h
	${SDK_ROOT}/pluginterfaces/base/ipluginbase.h
	${SDK_ROOT}/pluginterfaces/base/istringresult.h
	${SDK_ROOT}/pluginterfaces/base/iupdatehandler.h
	${SDK_ROOT}/pluginterfaces/base/keycodes.h
	${SDK_ROOT}/pluginterfaces/base/pluginbasefwd.h
	${SDK_ROOT}/pluginterfaces/base/smartpointer.h
	${SDK_ROOT}/pluginterfaces/base/ucolorspec.h
	${SDK_ROOT}/pluginterfaces/base/conststringtable.cpp
	${SDK_ROOT}/pluginterfaces/base/conststringtable.h
	${SDK_ROOT}/pluginterfaces/base/funknown.cpp
	${SDK_ROOT}/pluginterfaces/base/ustring.cpp
	${SDK_ROOT}/pluginterfaces/base/ustring.h
)

set(vst_includes
	${SDK_ROOT}/pluginterfaces/gui/iplugview.h
	${SDK_ROOT}/pluginterfaces/gui/iplugviewcontentscalesupport.h
	${SDK_ROOT}/pluginterfaces/vst/ivstattributes.h
	${SDK_ROOT}/pluginterfaces/vst/ivstaudioprocessor.h
	${SDK_ROOT}/pluginterfaces/vst/ivstautomationstate.h
	${SDK_ROOT}/pluginterfaces/vst/ivstchannelcontextinfo.h
	${SDK_ROOT}/pluginterfaces/vst/ivstcomponent.h
	${SDK_ROOT}/pluginterfaces/vst/ivstcontextmenu.h
	${SDK_ROOT}/pluginterfaces/vst/ivsteditcontroller.h
	${SDK_ROOT}/pluginterfaces/vst/ivstevents.h
	${SDK_ROOT}/pluginterfaces/vst/ivsthostapplication.h
	${SDK_ROOT}/pluginterfaces/vst/ivstinterappaudio.h
	${SDK_ROOT}/pluginterfaces/vst/ivstmessage.h
	${SDK_ROOT}/pluginterfaces/vst/ivstmidicontrollers.h
	${SDK_ROOT}/pluginterfaces/vst/ivstnoteexpression.h
	${SDK_ROOT}/pluginterfaces/vst/ivstparameterchanges.h
	${SDK_ROOT}/pluginterfaces/vst/ivstplugview.h
	${SDK_ROOT}/pluginterfaces/vst/ivstprefetchablesupport.h
	${SDK_ROOT}/pluginterfaces/vst/ivstprocesscontext.h
	${SDK_ROOT}/pluginterfaces/vst/ivstrepresentation.h
	${SDK_ROOT}/pluginterfaces/vst/ivstunits.h
	${SDK_ROOT}/pluginterfaces/vst/vstpresetkeys.h
	${SDK_ROOT}/pluginterfaces/vst/vstpshpack4.h
	${SDK_ROOT}/pluginterfaces/vst/vsttypes.h
)

add_library(sdk STATIC ${sdk_sources} ${pluginterfaces_sources} ${vst_includes})
target_link_libraries(sdk PRIVATE base)

# iOS target
if(MAC AND XCODE AND IOS_DEVELOPMENT_TEAM)
	add_library(sdk_ios STATIC ${sdk_sources} ${pluginterfaces_sources} ${vst_includes})
	smtg_set_platform_ios(sdk_ios)
	target_link_libraries(sdk_ios PRIVATE base_ios)
endif()

source_group("public.sdk"	FILES ${sdk_sources})
source_group("vst"			FILES ${vst_includes})
source_group("base"			FILES ${pluginterfaces_sources})


text:
//------------------------------------------------------------------------
// Project     : VST SDK
//
// Category    : Helpers
// Filename    : public.sdk/source/vst3stdsdk.cpp
// Created by  : Steinberg, 09/2008
// Description : include basic helpers cpp files
//
//-----------------------------------------------------------------------------
// LICENSE
// (c) 2017, Steinberg Media Technologies GmbH, All Rights Reserved
//-----------------------------------------------------------------------------
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
//   * Redistributions of source code must retain the above copyright notice,
//     this list of conditions and the following disclaimer.
//   * Redistributions in binary form must reproduce the above copyright notice,
//     this list of conditions and the following disclaimer in the documentation
//     and/or other materials provided with the distribution.
//   * Neither the name of the Steinberg Media Technologies nor the names of its
//     contributors may be used to endorse or promote products derived from this
//     software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
// IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
// OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE  OF THIS SOFTWARE, EVEN IF ADVISED
// OF THE POSSIBILITY OF SUCH DAMAGE.
//-----------------------------------------------------------------------------

#include "public.sdk/source/vst/vstaudioeffect.cpp"
#include "public.sdk/source/vst/vstcomponent.cpp"
#include "public.sdk/source/vst/vstcomponentbase.cpp"
#include "public.sdk/source/vst/vsteditcontroller.cpp"
#include "public.sdk/source/vst/vstbus.cpp"
#include "public.sdk/source/vst/vstparameters.cpp"


text:
//-----------------------------------------------------------------------------
// Project     : SDK Core
// Version     : 1.0
//
// Category    : Common Base Classes
// Filename    : public.sdk/source/main/linuxmain.cpp
// Created by  : Steinberg, 01/2004
// Description : Linux Component Entry
//
//-----------------------------------------------------------------------------
// LICENSE
// (c) 2017, Steinberg Media Technologies GmbH, All Rights Reserved
//-----------------------------------------------------------------------------
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
//   * Redistributions of source code must retain the above copyright notice,
//     this list of conditions and the following disclaimer.
//   * Redistributions in binary form must reproduce the above copyright notice,
//     this list of conditions and the following disclaimer in the documentation
//     and/or other materials provided with the distribution.
//   * Neither the name of the Steinberg Media Technologies nor the names of its
//     contributors may be used to endorse or promote products derived from this
//     software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
// IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
// OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE  OF THIS SOFTWARE, EVEN IF ADVISED
// OF THE POSSIBILITY OF SUCH DAMAGE.
//-----------------------------------------------------------------------------

#if defined(__GNUC__) && ((__GNUC__ >= 4) || ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 1)))
#define EXPORT	__attribute__ ((visibility ("default")))
#else
#define EXPORT
#endif

//------------------------------------------------------------------------
void* moduleHandle = 0;

//------------------------------------------------------------------------
bool InitModule ();		///< must be provided by Plug-in: called when the library is loaded
bool DeinitModule ();	///< must be provided by Plug-in: called when the library is unloaded

//------------------------------------------------------------------------
extern "C"
{
	EXPORT bool ModuleEntry (void*);
	EXPORT bool ModuleExit (void);
}

static int counter {0};

//------------------------------------------------------------------------
bool ModuleEntry (void* sharedLibraryHandle)
{
	if (++counter == 1)
	{
		moduleHandle = sharedLibraryHandle;
		return InitModule ();
	}
	return true;
}

//------------------------------------------------------------------------
bool ModuleExit (void)
{
	if (--counter == 0)
	{
		moduleHandle = nullptr;
		return DeinitModule ();
	}
	return true;
}


text:
//------------------------------------------------------------------------
// Project     : VST SDK
//
// Category    : Common Base Classes
// Filename    : public.sdk/source/main/pluginfactoryvst3.cpp
// Created by  : Steinberg, 01/2004
// Description : Standard Plug-in Factory
//
//-----------------------------------------------------------------------------
// LICENSE
// (c) 2017, Steinberg Media Technologies GmbH, All Rights Reserved
//-----------------------------------------------------------------------------
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
//   * Redistributions of source code must retain the above copyright notice,
//     this list of conditions and the following disclaimer.
//   * Redistributions in binary form must reproduce the above copyright notice,
//     this list of conditions and the following disclaimer in the documentation
//     and/or other materials provided with the distribution.
//   * Neither the name of the Steinberg Media Technologies nor the names of its
//     contributors may be used to endorse or promote products derived from this
//     software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
// IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
// OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE  OF THIS SOFTWARE, EVEN IF ADVISED
// OF THE POSSIBILITY OF SUCH DAMAGE.
//-----------------------------------------------------------------------------

#include "pluginfactoryvst3.h"
#include "pluginterfaces/gui/iplugview.h"
#include "pluginterfaces/base/ibstream.h"

#include <stdlib.h>

namespace Steinberg {

CPluginFactory* gPluginFactory = 0;

DEF_CLASS_IID (IPluginBase)
DEF_CLASS_IID (IPlugView)
DEF_CLASS_IID (IPlugViewIdleHandler)
DEF_CLASS_IID (IPlugFrame)
DEF_CLASS_IID (IPlugFrameIdle)
DEF_CLASS_IID (IBStream)
DEF_CLASS_IID (IPluginFactory)
DEF_CLASS_IID (IPluginFactory2)
DEF_CLASS_IID (IPluginFactory3)

//------------------------------------------------------------------------
//  CPluginFactory implementation
//------------------------------------------------------------------------
CPluginFactory::CPluginFactory (const PFactoryInfo& info)
: classes (0)
, classCount (0)
, maxClassCount (0)
{
	FUNKNOWN_CTOR

	factoryInfo = info;
}

//------------------------------------------------------------------------
CPluginFactory::~CPluginFactory ()
{
	if (gPluginFactory == this)
		gPluginFactory = 0;

	if (classes)
		free (classes);

	FUNKNOWN_DTOR
}

//------------------------------------------------------------------------
IMPLEMENT_REFCOUNT (CPluginFactory)

//------------------------------------------------------------------------
tresult PLUGIN_API CPluginFactory::queryInterface (FIDString _iid, void** obj)
{
	QUERY_INTERFACE (_iid, obj, IPluginFactory::iid, IPluginFactory)
	QUERY_INTERFACE (_iid, obj, IPluginFactory2::iid, IPluginFactory2)
	QUERY_INTERFACE (_iid, obj, IPluginFactory3::iid, IPluginFactory3)
	QUERY_INTERFACE (_iid, obj, FUnknown::iid, IPluginFactory)
	*obj = 0;
	return kNoInterface;
}

//------------------------------------------------------------------------
bool CPluginFactory::registerClass (const PClassInfo* info,
									FUnknown* (*createFunc)(void*), void* context)
{
	if (!info || !createFunc)
		return false;

	PClassInfo2 info2;
	memcpy (&info2, info, sizeof (PClassInfo));
	return registerClass (&info2, createFunc, context);
}

//------------------------------------------------------------------------
bool CPluginFactory::registerClass (const PClassInfo2* info,
									FUnknown* (*createFunc)(void*), void* context)
{
	if (!info || !createFunc)
		return false;

	if (classCount >= maxClassCount)
	{
		if (!growClasses ())
			return false;
	}

	PClassEntry& entry = classes[classCount];
	entry.info8 = *info;
	entry.info16.fromAscii (*info);
	entry.createFunc = createFunc;
	entry.context = context;
	entry.isUnicode = false;

	classCount++;
	return true;
}

//------------------------------------------------------------------------
bool CPluginFactory::registerClass (const PClassInfoW* info,
								    FUnknown* (*createFunc)(void*), void* context)
{
	if (!info || !createFunc)
		return false;

	if (classCount >= maxClassCount)
	{
		if (!growClasses ())
			return false;
	}

	PClassEntry& entry = classes[classCount];
	entry.info16 = *info;
	entry.createFunc = createFunc;
	entry.context = context;
	entry.isUnicode = true;

	classCount++;
	return true;
}

//------------------------------------------------------------------------
bool CPluginFactory::growClasses ()
{
	static const int32 delta = 10;

	size_t size = (maxClassCount + delta) * sizeof (PClassEntry);
	void* memory = classes;

	if (!memory)
		memory = malloc (size);
	else
		memory = realloc (memory, size);

	if (!memory)
		return false;

	classes = (PClassEntry*)memory;
	maxClassCount += delta;
	return true;
}

//------------------------------------------------------------------------
bool CPluginFactory::isClassRegistered (const FUID& cid)
{
	for (int32 i = 0; i < classCount; i++)
	{
		if (cid == classes[i].info16.cid)
			return true;
	}
	return false;
}

//------------------------------------------------------------------------
tresult PLUGIN_API CPluginFactory::getFactoryInfo (PFactoryInfo* info)
{
	if (info)
		memcpy (info, &factoryInfo, sizeof (PFactoryInfo));
	return kResultOk;
}

//------------------------------------------------------------------------
int32 PLUGIN_API CPluginFactory::countClasses ()
{
	return classCount;
}

//------------------------------------------------------------------------
tresult PLUGIN_API CPluginFactory::getClassInfo (int32 index, PClassInfo* info)
{
	if (info && (index >= 0 && index < classCount))
	{
		if (classes[index].isUnicode)
		{
			memset (info, 0, sizeof (PClassInfo));
			return kResultFalse;
		}

		memcpy (info, &classes[index].info8, sizeof (PClassInfo));
		return kResultOk;
	}
	return kInvalidArgument;
}

//------------------------------------------------------------------------
tresult PLUGIN_API CPluginFactory::getClassInfo2 (int32 index, PClassInfo2* info)
{
	if (info && (index >= 0 && index < classCount))
	{
		if (classes[index].isUnicode)
		{
			memset (info, 0, sizeof (PClassInfo2));
			return kResultFalse;
		}

		memcpy (info, &classes[index].info8, sizeof (PClassInfo2));
		return kResultOk;
	}
	return kInvalidArgument;
}

//------------------------------------------------------------------------
tresult PLUGIN_API CPluginFactory::getClassInfoUnicode (int32 index, PClassInfoW* info)
{
	if (info && (index >= 0 && index < classCount))
	{
		memcpy (info, &classes[index].info16, sizeof (PClassInfoW));
		return kResultOk;
	}
	return kInvalidArgument;
}

//------------------------------------------------------------------------
tresult PLUGIN_API CPluginFactory::createInstance (FIDString cid, FIDString _iid, void** obj)
{
	for (int32 i = 0; i < classCount; i++)
	{
		if (memcmp (classes[i].info16.cid, cid, sizeof (TUID)) == 0)
		{
			FUnknown* instance = classes[i].createFunc (classes[i].context);
			if (instance)
			{
				if (instance->queryInterface (_iid, obj) == kResultOk)
				{
					instance->release ();
					return kResultOk;
				}
				else
					instance->release ();
			}
			break;
		}
	}

	*obj = 0;
	return kNoInterface;
}

//------------------------------------------------------------------------
tresult PLUGIN_API CPluginFactory::setHostContext (FUnknown* /*context*/)
{
	return kNotImplemented;
}

} // namespace Steinberg


text:
EXPORTS
	GetPluginFactory
	InitDll
	ExitDll


text:
//-----------------------------------------------------------------------------
// Project     : SDK Core
// Version     : 1.0
//
// Category    : Common Base Classes
// Filename    : public.sdk/source/main/macmain.cpp
// Created by  : Steinberg, 01/2004
// Description : Mac OS X Bundle Entry
//
//-----------------------------------------------------------------------------
// LICENSE
// (c) 2017, Steinberg Media Technologies GmbH, All Rights Reserved
//-----------------------------------------------------------------------------
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
//   * Redistributions of source code must retain the above copyright notice,
//     this list of conditions and the following disclaimer.
//   * Redistributions in binary form must reproduce the above copyright notice,
//     this list of conditions and the following disclaimer in the documentation
//     and/or other materials provided with the distribution.
//   * Neither the name of the Steinberg Media Technologies nor the names of its
//     contributors may be used to endorse or promote products derived from this
//     software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
// IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
// OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE  OF THIS SOFTWARE, EVEN IF ADVISED
// OF THE POSSIBILITY OF SUCH DAMAGE.
//-----------------------------------------------------------------------------

#ifndef __CF_USE_FRAMEWORK_INCLUDES__
#define __CF_USE_FRAMEWORK_INCLUDES__ 1
#endif

#include <CoreFoundation/CoreFoundation.h>

#if defined(__GNUC__) && ((__GNUC__ >= 4) || ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 1)))
#define EXPORT	__attribute__ ((visibility ("default")))
#else
#define EXPORT
#endif

//------------------------------------------------------------------------
CFBundleRef ghInst = 0;
unsigned int bundleRefCounter = 0;	// counting for bundleEntry/bundleExit pairs
void* moduleHandle = 0;
#define MAX_PATH 2048
char gPath[MAX_PATH] = {0};

//------------------------------------------------------------------------
bool InitModule ();		///< must be provided by Plug-in: called when the library is loaded
bool DeinitModule ();	///< must be provided by Plug-in: called when the library is unloaded

//------------------------------------------------------------------------
extern "C"
{
	EXPORT bool bundleEntry (CFBundleRef);
	EXPORT bool bundleExit (void);
}

#include <vector>

std::vector< CFBundleRef > gBundleRefs;

//------------------------------------------------------------------------
bool bundleEntry (CFBundleRef ref)
{
	if (ref)
	{
		bundleRefCounter++;
		CFRetain (ref);

		// hold all bundle refs until plug-in is fully uninitialized
		gBundleRefs.push_back (ref);

		if (!moduleHandle)
		{
			ghInst = ref;
			moduleHandle = ref;

			// optain the bundle path
			CFURLRef tempURL = CFBundleCopyBundleURL (ref);
			CFURLGetFileSystemRepresentation (tempURL, true, (UInt8*)gPath, MAX_PATH);
			CFRelease (tempURL);
		}
	}
	return InitModule ();
}

//------------------------------------------------------------------------
bool bundleExit (void)
{
	if (DeinitModule ())
	{
		if (--bundleRefCounter == 0)
		{	// release the CFBundleRef's once all bundleExit clients called in
			// there is no way to identify the proper CFBundleRef of the bundleExit call
			for (size_t i = 0; i < gBundleRefs.size(); i++)
				CFRelease (gBundleRefs[i]);
			gBundleRefs.clear();
		}
		return true;
	}

	return false;
}


text:
_GetPluginFactory
_bundleEntry
_bundleExit


text:
//-----------------------------------------------------------------------------
// Project     : SDK Core
// Version     : 1.0
//
// Category    : Common Base Classes
// Filename    : public.sdk/source/main/dllmain.cpp
// Created by  : Steinberg, 01/2004
// Description : Windows DLL Entry
//
//-----------------------------------------------------------------------------
// LICENSE
// (c) 2017, Steinberg Media Technologies GmbH, All Rights Reserved
//-----------------------------------------------------------------------------
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
//   * Redistributions of source code must retain the above copyright notice,
//     this list of conditions and the following disclaimer.
//   * Redistributions in binary form must reproduce the above copyright notice,
//     this list of conditions and the following disclaimer in the documentation
//     and/or other materials provided with the distribution.
//   * Neither the name of the Steinberg Media Technologies nor the names of its
//     contributors may be used to endorse or promote products derived from this
//     software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
// IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
// OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE  OF THIS SOFTWARE, EVEN IF ADVISED
// OF THE POSSIBILITY OF SUCH DAMAGE.
//-----------------------------------------------------------------------------

#include "pluginterfaces/base/ftypes.h"

#include <windows.h>

#if defined (_MSC_VER) && defined (DEVELOPMENT)
	#include <crtdbg.h>
#endif

#ifdef UNICODE
#define tstrrchr wcsrchr
#else
#define tstrrchr strrchr
#endif

//------------------------------------------------------------------------
HINSTANCE ghInst = 0;
void* moduleHandle = 0;
Steinberg::tchar gPath[MAX_PATH] = {0};

//------------------------------------------------------------------------
#define DllExport __declspec( dllexport )

//------------------------------------------------------------------------
extern bool InitModule ();		///< must be provided by Plug-in: called when the library is loaded
extern bool DeinitModule ();	///< must be provided by Plug-in: called when the library is unloaded

//------------------------------------------------------------------------
#ifdef __cplusplus
extern "C" {
#endif
	bool DllExport InitDll () ///< must be called from host right after loading dll
	{
		return InitModule ();
	}
	bool DllExport ExitDll ()  ///< must be called from host right before unloading dll
	{
		return DeinitModule ();
	}
#ifdef __cplusplus
} // extern "C"
#endif

//------------------------------------------------------------------------
BOOL WINAPI DllMain (HINSTANCE hInst, DWORD dwReason, LPVOID /*lpvReserved*/)
{
	if (dwReason == DLL_PROCESS_ATTACH)
	{
	#if defined (_MSC_VER) && defined (DEVELOPMENT)
		_CrtSetReportMode ( _CRT_WARN, _CRTDBG_MODE_DEBUG );
		_CrtSetReportMode ( _CRT_ERROR, _CRTDBG_MODE_DEBUG );
		_CrtSetReportMode ( _CRT_ASSERT, _CRTDBG_MODE_DEBUG );
		int flag = _CrtSetDbgFlag (_CRTDBG_REPORT_FLAG);
		_CrtSetDbgFlag (flag | _CRTDBG_LEAK_CHECK_DF);
	#endif

		moduleHandle = ghInst = hInst;

		// gets the path of the component
		if (GetModuleFileName (ghInst, gPath, MAX_PATH) > 0)
		{
			Steinberg::tchar* bkslash = tstrrchr (gPath, TEXT ('\\'));
			if (bkslash)
				gPath[bkslash - gPath + 1] = 0;
		}
	}

	return TRUE;
}