//------------------------------------------------------------------------
// Project     : VST SDK
// Version     : 2.4
//
// Category    : VST 2.x Classes
// Filename    : public.sdk/source/vst2.x/audioeffect.h
// Created by  : Steinberg, 01/2004
// Description : Class AudioEffect (VST 1.0).
// 
//-----------------------------------------------------------------------------
// LICENSE
// (c) 2017, Steinberg Media Technologies GmbH, All Rights Reserved
//-----------------------------------------------------------------------------
// This Software Development Kit may not be distributed in parts or its entirety  
// without prior written agreement by Steinberg Media Technologies GmbH. 
// This SDK must not be used to re-engineer or manipulate any technology used  
// in any Steinberg or Third-party application or software module, 
// unless permitted by law.
// 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 SDK IS PROVIDED BY STEINBERG MEDIA TECHNOLOGIES GMBH "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 STEINBERG MEDIA TECHNOLOGIES GMBH 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.
//----------------------------------------------------------------------------------

#pragma once

#include "pluginterfaces/vst2.x/aeffect.h"	// "c" interface

class AEffEditor;

//-------------------------------------------------------------------------------------------------------
/** VST Effect Base Class (VST 1.0). */
//-------------------------------------------------------------------------------------------------------
class AudioEffect
{
public:
//-------------------------------------------------------------------------------------------------------
	AudioEffect (audioMasterCallback audioMaster, VstInt32 numPrograms, VstInt32 numParams); ///< Create an \e AudioEffect object
	virtual ~AudioEffect (); ///< Destroy an \e AudioEffect object

	virtual VstIntPtr dispatcher (VstInt32 opcode, VstInt32 index, VstIntPtr value, void* ptr, float opt);	///< Opcodes dispatcher

//-------------------------------------------------------------------------------------------------------
/// \name State Transitions
//-------------------------------------------------------------------------------------------------------
//@{
	virtual void open () {}		///< Called when plug-in is initialized
	virtual void close () {}	///< Called when plug-in will be released
	virtual void suspend () {}	///< Called when plug-in is switched to off
	virtual void resume () {}	///< Called when plug-in is switched to on
//@}

//-------------------------------------------------------------------------------------------------------
/// \name Processing
//-------------------------------------------------------------------------------------------------------
//@{
	virtual void setSampleRate (float sampleRate)  { this->sampleRate = sampleRate; }	///< Called when the sample rate changes (always in a suspend state)
	virtual void setBlockSize (VstInt32 blockSize) { this->blockSize = blockSize; }		///< Called when the Maximun block size changes (always in a suspend state). Note that the sampleFrames in Process Calls could be smaller than this block size, but NOT bigger.

	virtual void processReplacing (float** inputs, float** outputs, VstInt32 sampleFrames) = 0; ///< Process 32 bit (single precision) floats (always in a resume state)

#if VST_2_4_EXTENSIONS
	virtual void processDoubleReplacing (double** inputs, double** outputs, VstInt32 sampleFrames) {} ///< Process 64 bit (double precision) floats (always in a resume state) \sa processReplacing
#endif // VST_2_4_EXTENSIONS
//@}

//-------------------------------------------------------------------------------------------------------
/// \name Parameters
//-------------------------------------------------------------------------------------------------------
//@{
	virtual void setParameter (VstInt32 index, float value) {}	///< Called when a parameter changed
	virtual float getParameter (VstInt32 index) { return 0; }	///< Return the value of the parameter with \e index
	virtual void setParameterAutomated (VstInt32 index, float value);///< Called after a control has changed in the editor and when the associated parameter should be automated
//@}

//-------------------------------------------------------------------------------------------------------
/// \name Programs and Persistence
//-------------------------------------------------------------------------------------------------------
//@{
	virtual VstInt32 getProgram () { return curProgram; }					///< Return the index to the current program
	virtual void setProgram (VstInt32 program) { curProgram = program; }	///< Set the current program to \e program
	
	virtual void setProgramName (char* name) {}				///< Stuff the name field of the current program with \e name. Limited to #kVstMaxProgNameLen.
	virtual void getProgramName (char* name) { *name = 0; }	///< Stuff \e name with the name of the current program. Limited to #kVstMaxProgNameLen.
	
	virtual void getParameterLabel (VstInt32 index, char* label)  { *label = 0; }	///< Stuff \e label with the units in which parameter \e index is displayed (i.e. "sec", "dB", "type", etc...). Limited to #kVstMaxParamStrLen.
	virtual void getParameterDisplay (VstInt32 index, char* text) { *text = 0; }	///< Stuff \e text with a string representation ("0.5", "-3", "PLATE", etc...) of the value of parameter \e index. Limited to #kVstMaxParamStrLen.
	virtual void getParameterName (VstInt32 index, char* text)    { *text = 0; }    ///< Stuff \e text with the name ("Time", "Gain", "RoomType", etc...) of parameter \e index. Limited to #kVstMaxParamStrLen.
	
	virtual VstInt32 getChunk (void** data, bool isPreset = false) { return 0; } ///< Host stores plug-in state. Returns the size in bytes of the chunk (plug-in allocates the data array)
	virtual VstInt32 setChunk (void* data, VstInt32 byteSize, bool isPreset = false) { return 0; }	///< Host restores plug-in state
//@}
	
//-------------------------------------------------------------------------------------------------------
/// \name Internal Setup
//-------------------------------------------------------------------------------------------------------
//@{
	virtual void setUniqueID (VstInt32 iD)        { cEffect.uniqueID = iD; }		///< Must be called to set the plug-ins unique ID!
	virtual void setNumInputs (VstInt32 inputs)   { cEffect.numInputs = inputs; }	///< Set the number of inputs the plug-in will handle. For a plug-in which could change its IO configuration, this number is the maximun available inputs.
	virtual void setNumOutputs (VstInt32 outputs) { cEffect.numOutputs = outputs; }	///< Set the number of outputs the plug-in will handle. For a plug-in which could change its IO configuration, this number is the maximun available ouputs.

	virtual void canProcessReplacing (bool state = true);	///< Tells that processReplacing() could be used. Mandatory in VST 2.4!

#if VST_2_4_EXTENSIONS
	virtual void canDoubleReplacing (bool state = true);	///< Tells that processDoubleReplacing() is implemented.
#endif // VST_2_4_EXTENSIONS

	virtual void programsAreChunks (bool state = true);	///< Program data is handled in formatless chunks (using getChunk-setChunks)
	virtual void setInitialDelay (VstInt32 delay);		///< Use to report the plug-in's latency (Group Delay)
//@}

//-------------------------------------------------------------------------------------------------------
/// \name Editor
//-------------------------------------------------------------------------------------------------------
//@{
	void setEditor (AEffEditor* editor);				///< Should be called if you want to define your own editor
	virtual AEffEditor* getEditor () { return editor; }	///< Returns the attached editor
//@}

//-------------------------------------------------------------------------------------------------------
/// \name Inquiry
//-------------------------------------------------------------------------------------------------------
//@{
	virtual AEffect* getAeffect ()   { return &cEffect; }		///< Returns the #AEffect structure
	virtual float getSampleRate ()   { return sampleRate; }		///< Returns the current sample rate
	virtual VstInt32 getBlockSize () { return blockSize; }		///< Returns the current Maximum block size
//@}

//-------------------------------------------------------------------------------------------------------
/// \name Host Communication
//-------------------------------------------------------------------------------------------------------
//@{
	virtual VstInt32 getMasterVersion ();		///< Returns the Host's version (for example 2400 for VST 2.4)
	virtual VstInt32 getCurrentUniqueId ();		///< Returns current unique identifier when loading shell plug-ins
	virtual void masterIdle ();					///< Give idle time to Host application
//@}

//-------------------------------------------------------------------------------------------------------
/// \name Tools (helpers)
//-------------------------------------------------------------------------------------------------------
//@{
	virtual void dB2string (float value, char* text, VstInt32 maxLen);		///< Stuffs \e text with an amplitude on the [0.0, 1.0] scale converted to its value in decibels.
	virtual void Hz2string (float samples, char* text, VstInt32 maxLen);	///< Stuffs \e text with the frequency in Hertz that has a period of \e samples.
	virtual void ms2string (float samples, char* text, VstInt32 maxLen);	///< Stuffs \e text with the duration in milliseconds of \e samples frames.
	virtual void float2string (float value, char* text, VstInt32 maxLen);	///< Stuffs \e text with a string representation on the floating point \e value.
	virtual void int2string (VstInt32 value, char* text, VstInt32 maxLen);	///< Stuffs \e text with a string representation on the integer \e value.
//@}

//-------------------------------------------------------------------------------------------------------
// Deprecated methods
//-------------------------------------------------------------------------------------------------------
/// @cond ignore
	virtual void DECLARE_VST_DEPRECATED (process) (float** inputs, float** outputs, VstInt32 sampleFrames) {}
	virtual float DECLARE_VST_DEPRECATED (getVu) () { return 0; }
	virtual void DECLARE_VST_DEPRECATED (hasVu) (bool state = true);
	virtual void DECLARE_VST_DEPRECATED (hasClip) (bool state = true);
	virtual void DECLARE_VST_DEPRECATED (canMono) (bool state = true);
	virtual void DECLARE_VST_DEPRECATED (setRealtimeQualities) (VstInt32 qualities);
	virtual void DECLARE_VST_DEPRECATED (setOfflineQualities) (VstInt32 qualities);
	virtual bool DECLARE_VST_DEPRECATED (isInputConnected) (VstInt32 input);
	virtual bool DECLARE_VST_DEPRECATED (isOutputConnected) (VstInt32 output);
/// @endcond

//-------------------------------------------------------------------------------------------------------
protected:	
	audioMasterCallback audioMaster;	///< Host callback
	AEffEditor* editor;					///< Pointer to the plug-in's editor
	float sampleRate;					///< Current sample rate
	VstInt32 blockSize;					///< Maximum block size
	VstInt32 numPrograms;				///< Number of programs
	VstInt32 numParams;					///< Number of parameters
	VstInt32 curProgram;				///< Current program
	AEffect  cEffect;					///< #AEffect object

/// @cond ignore
	static VstIntPtr dispatchEffectClass (AEffect* e, VstInt32 opcode, VstInt32 index, VstIntPtr value, void* ptr, float opt);
	static float getParameterClass (AEffect* e, VstInt32 index);
	static void setParameterClass (AEffect* e, VstInt32 index, float value);
	static void DECLARE_VST_DEPRECATED (processClass) (AEffect* e, float** inputs, float** outputs, VstInt32 sampleFrames);
	static void processClassReplacing (AEffect* e, float** inputs, float** outputs, VstInt32 sampleFrames);

#if VST_2_4_EXTENSIONS
	static void processClassDoubleReplacing (AEffect* e, double** inputs, double** outputs, VstInt32 sampleFrames);
#endif // VST_2_4_EXTENSIONS
/// @endcond
};
