/*===================================================================================================
AAX_CommonInterface_Algorithm.doxygen

Copyright 2011-2017, 2023 Avid Technology, Inc. 
All rights reserved.

CONFIDENTIAL: this document contains confidential information of Avid. Do
not disclose to any third party. Use of the information contained in this
document is subject to an Avid SDK license.

===================================================================================================*/

/**	@defgroup CommonInterface_Algorithm Real-time algorithm callback
	@ingroup MainInterface
	
	@brief A plug-in's audio processing core
	
	\section algpagecontents On this page
		\li \ref alg_def
		\li \ref alg_memmgmt
		\li \ref alg_comm
		\li	\ref alg_initialization
		\li \ref alg_processing
		\li \ref alg_pd
		\li \ref alg_examp
		\li \ref alg_porttypes
		\li \ref alg_seealso

<DIV CLASS="section">	
	\section alg_def Algorithm definition
	
		Algorithm processing in %AAX plug-ins is handled via a C-style algorithm processing callback
		(see code below.) Each Effect variation in a plug-in must register an algorithm entrypoint
		in the plug-in \ref CommonInterface_Describe "description", and the host will call this
		entrypoint to render a buffer of audio samples.
		
		\code
		void AAX_CALLBACK MyPlugIn_AlgorithmProcessFunction(
			SMyPlugIn_Alg_Context * const	inInstancesBegin [],
			const void *					inInstancesEnd)
			{
				//
				// Processing code...
				//
			}
		\endcode
</DIV>


<DIV CLASS="section">		
	\section alg_memmgmt Algorithm memory management
		
		This callback pattern is designed such that plug-in algorithms may be easily loaded in remote
		memory spaces on a variety of devices and quickly re-compiled for different operating
		environments without significant changes to the code, and this design goal informs the
		algorithm's memory management techniques.
		
		\dotfile aax_alg_context.dot
		
		When the %AAX host calls a plug-in's algorithm callback, it provides a block of memory
		describing the state of the plug-in.  This block of memory, known as the algorithm's
		\em context, can be thought of as the algorithm's interface to the outside world: when
		another part of the plug-in interacts with the algorithm, it does so by posting information
		to the algorithm's context.

		\code
		//==============================================================================
		// Component context definitions
		//==============================================================================

		// Context structure
		struct SDemoDist_Alg_Context
		{
			int32_t					* mCtrlBypassP;					// Coefficient message destination
			float					* mCtrlMixP;					// Coefficient message destination
			float					* mCtrlInpGP;					// Coefficient message destination
			float					* mCtrlOutGP;					// Coefficient message destination
			SDemoDist_DistCoefs		* mCoefsDistP;					// Coefficient message destination
			SDemoDist_FiltCoefs		* mCoefsFiltP;					// Coefficient message destination
	
			CSimpleBiquad			* mBiquads;						// Private data
	
			float*					* mInputPP;						// Audio signal input
			float*					* mOutputPP;					// Audio signal output
			float*					* mMeterTapsPP;					// Meter signal output
		};
		\endcode
		
		It is important to note that, in most circumstances, algorithm callbacks do not own their
		own memory.  The algorithm and its memory is managed entirely by the host or shell environment,
		and relies on the host-provided context structure for all state information.
		
		If persistent memory is required, algorithms can register for block(s) of persistent state date via the
		\ref AAX_IComponentDescriptor::AddPrivateData() API (as in SDemoDist_Alg_Context::mBiquads above.)
		A plug-in may store state data in the resulting \em "private data" context fields and this data will be
		restored by the host when the algorithm is next called. See the \ref alg_pd section below for more
		information.
</DIV>


<DIV CLASS="section">
	\section alg_comm Communicating with the algorithm
		
		Plug-ins communicate with their algorithms via a buffered, host-managed message system. The host
		guarantees that messages posted to this system will be delivered to the applicable context field
		and that the algorithm's context is up to date every time the component is entered.
		
		This system utilizes a static data routing scheme that is defined in the plug-in's describe
		method.  Once the routing scheme has been defined, the plug-in may post packets of data to its
		algorithm using \ref AAX_IController::PostPacket().
		
		In order to reference the fields in its algorithm's context, the plug-in's host-side code uses
		unique identifiers generated with the \ref AAX_FIELD_INDEX macro:
				
		\code
		enum EDemoDist_Alg_PortID
		{
			 eAlgPortID_BypassIn					= AAX_FIELD_INDEX (SDemoDist_Alg_Context, mCtrlBypassP)
			,eAlgPortID_MixIn						= AAX_FIELD_INDEX (SDemoDist_Alg_Context, mCtrlMixP)
			,eAlgPortID_InpGIn						= AAX_FIELD_INDEX (SDemoDist_Alg_Context, mCtrlInpGP)
			,eAlgPortID_OutGIn						= AAX_FIELD_INDEX (SDemoDist_Alg_Context, mCtrlOutGP)
			,eAlgPortID_CoefsDistIn					= AAX_FIELD_INDEX (SDemoDist_Alg_Context, mCoefsDistP)
			,eAlgPortID_CoefsFilterIn				= AAX_FIELD_INDEX (SDemoDist_Alg_Context, mCoefsFiltP)
	
			,eAlgFieldID_Biquads					= AAX_FIELD_INDEX (SDemoDist_Alg_Context, mBiquads)

			,eDemoDist_AlgFieldID_AudioIn			= AAX_FIELD_INDEX (SDemoDist_Alg_Context, mInputPP)
			,eDemoDist_AlgFieldID_AudioOut			= AAX_FIELD_INDEX (SDemoDist_Alg_Context, mOutputPP)
			,eAlgFieldID_MeterTaps					= AAX_FIELD_INDEX (SDemoDist_Alg_Context, mMeterTapsPP)
		};
		\endcode
		
		See \ref CommonInterface_Describe for more information about registering context fields and
		defining a plug-in's message routing scheme.
</DIV>


<DIV CLASS="section">	
	\section alg_initialization Algorithm initialization
	
		The following events occur before the %AAX host begins calling a plug-in's algorithm:
		
		\li The Effect's \ref CommonInterface_DataModel "data model" is initialized
		\li An initial call to \ref AAX_IEffectParameters::ResetFieldData() is made for each private
		    data block in the algorithm.
		\li An initial call to \ref AAX_IEffectParameters::GenerateCoefficients() is made and coefficient
		    packets are dispatched to each of the algorithm's data ports based on the default model
		    state.
		\li All packets are delivered and initial algorithm context state is set
		\li If one has been registered, the algorithm's optional initialization callback is called
		    with the default context
		\li (Algorithmic processing begins)
	
		\subsection alg_initialization_private_data Private data initialization
	
			To initialize an algorithm's private data blocks,
			\ref AAX_IEffectParameters::ResetFieldData() is called on the host for each block in the
			algorithm.  The host uses this method to acquire a default initialized memory block for
			each private data port, which is then copied into the algorithm's memory pool and
			provided to its context.
			
			The default implementation of this method in
			\ref AAX_CEffectParameters::ResetFieldData() "AAX_CEffectParameters" will initialize
			the data to zero.
			
			\sa \ref alg_pd
			
		\subsection alg_initialization_optional_callback Optional initialization callback
		
			If any additional initialization or de-initialization steps are required for proper
			operation of the algorithm, an optional initialization routine may be registered and
			associated with the algorithm's processing callback.  This initialization routine will
			be called in the same device / memory space as the algorithm's processing context.
			The initialization callback is provided with the algorithm's default context and is
			called both before every new instance of the Effect begins its algorithm render
			callbacks and before every instance is destroyed.
		
			This initialization routine is provided in \ref CommonInterface_Describe "Describe" as
			an argument to the platform's \c AddProcessProc registration method:
			
			\ifnot docs_for_cpexam
				\li \ref AAX_IComponentDescriptor::AddProcessProc_Native()
				\li \ref AAX_IComponentDescriptor::AddProcessProc_TI()
			
				\compatibility As of Pro Tools 10.2.1 an algorithm's
				initialization calllback routine will have up to 5 seconds to execute.
			
				\sa \ref AAX_CInstanceInitProc
			\endif
				
</DIV>


<DIV CLASS="section">
	\section alg_processing Algorithm processing

		Once the algorithm has been initialized and processing begins, the algorithm function is
		called regularly by the host audio engine. The algorithm may read the context data provided
		by the host and is responsible for writing data to all of the samples in its output buffers
		each time it is executed.

		\note The data in an algorithm's output buffers is not initialized before the algorithm
		is called, thus the algorithm must always write data into all output samples. This is to
		ensure equivalent behavior between all platforms, some of which do not have the resource
		budget to pre-initialize output data buffers.

</DIV>


<DIV CLASS="section">
	\section alg_pd Persistent algorithm memory

		An %AAX plug-in algorithm may contain one or more <EM>private data</EM> ports in its context.
		These are the only context fields in which an algorithm may store persistant state data.
			
		\subsection alg_pd_characteristics Private memory characteristics

			Each private data port is a pointer to a preallocated block of memory.  The size of each port
			is defined during Describe when the port is registered.  On DSP systems, the plug-in may
			request that the data block be placed in the chip's external memory.

			Once private data is allocated by the plug-in host or DSP shell, it will not be relocated or
			re-allocated until the algorithm is destroyed (see \ref alg_initialization_optional_callback)

		\subsection alg_pd_registration Private data port registration

			Private data ports are registered during Describe via \ref
			AAX_IComponentDescriptor::AddPrivateData().  This method defines the size of the data block
			that will be allocated as well as an initialization callback with format \ref
			AAX_CInitPrivateDataProc.

		\subsection alg_pd_init Private data initialization

			\ref AAX_IEffectParameters::ResetFieldData() is called on the host for both Native and DSP
			plug-ins.  For DSP plug-ins, the initialized data block is copied to the DSP by the %AAX host
			following the initialization callback.  The initialization callbacks for a plug-in's private
			data blocks are called after all host modules have been initialized and before the algorithm's
			optional initialization callback.

			\sa \ref alg_initialization

		\subsection alg_pd_comm Private data communication

			It is possible to transfer data to and from the algorithm's private data blocks using the \ref
			AAX_IPrivateDataAccess interface, which is available in a TimerWakeup context through the \ref
			AAX_IEffectDirectData interface.
\ifnot docs_for_cpexam
            For more information about this API, see auxinterface_directdata_privatedataaccess.
\endif

</DIV>


<DIV CLASS="section">
	\section alg_examp Example algorithm callback
	
		As a final example, the code below describes a simple audio processing component. The
		component's context contains one message pointer to receive incoming "gain" parameter
		values, as well as one audio data input, "pdI", and one audio data output, "pdO".
		Additionally there is a message pointer to receive "bypass" on/off values. The host
		calls the component each time a new input sample buffer must be processed, and each
		time the component is called the host ensures that all context fields are up-to-date.
		
		\code
		void AAX_CALLBACK MyPlugIn_AlgorithmProcessFunction(
			SMyPlugIn_Alg_Context * const	inInstancesBegin [],
			const void *					inInstancesEnd)
			{

				// Get a pointer to the beginning of the memory block table
				SMyPlugIn_Alg_Context* AAX_RESTRICT instance = inInstancesBegin [0];

				//--------- Iterate over plug-in instances ---------//
				for (SMyPlugIn_Alg_Context * const * walk = inInstancesBegin; walk < inInstancesEnd; ++walk)
				{
					instance = *walk;
	
					//--------- Retrieve instance-specific information ---------//
					//
					const SMyPlugIn_CoefsGain* const AAX_RESTRICT	coefsGainP =	instance->mCoefsGainP;	// Input (const)
					const int32_t	bypass		= *instance->mCtrlBypassP; 
					const float		gain		= coefsGainP->mGain;

					//--------- Run processing loop over each input channel ---------//
					//
					for (int ch = 0; ch < kNumChannelsIn; ch++) // Iterate over all input channels
					{

						//--------- Run processing loop over each sample ---------//
						//
						for (int t = 0; t < kAudioWindowSize; t++)
						{
							float* const AAX_RESTRICT pdI = instance->mInputPP [ch];
							float* const AAX_RESTRICT pdO = instance->mOutputPP [ch];
	
							if ( pdI && pdO )
							{
								pdO [t] = gain * pdI [t];
								if (bypass) { pdO [t] = pdI [t]; } 
							}
						} // Go to the next sample
					} // Go to next channel
				} // End instance-iteration loop
			}
		\endcode

</DIV>


<DIV CLASS="section">
	@section alg_porttypes Port Types and Behavior
In this section, we will examine the various kinds of ports that can be used by the algorithm component in an %AAX plug-in:
		<OL>
			<LI CLASS="List">
			Standard message input </LI>
			<LI CLASS="List">
			Internal state storage </LI>
			<LI CLASS="List">
			Metering output </LI>
			<LI CLASS="List">
			Environment variable retrieval </LI>
			<LI CLASS="List">
			Other functionality enhancement </LI>
		</OL>

		@subsection subsection__standard_message_input Standard message input
Most ports will function as pointers to incoming data. This data can have any type. For example, an algorithm's context may include a port of type float* to receive incoming float data and another port of type <TT>SMyCustomStructure</TT>* to receive incoming <TT>SMyCustomStructure</TT> data.

Like all registered context fields, input ports are managed by the hosting environment such that they always point to the most recently received data at the time that the algorithm callback is entered. The algorithm may not store or alter data in a standard message input port: this data is available as read-only input. If data is stored in the space allocated for the port's data then the result will be undefined behavior.

To define a standard message input port, a plug-in should call \ref AAX_IComponentDescriptor::AddDataInPort().

		@subsection subsection__internal_state_storage Internal state storage
Most plug-ins require local data to be accessible to their algorithms. These may be static data, such as lookup tables, or dynamic data, such as coefficient smoothing history or delay lines. In the DemoDist sample plug-in, <TT>SDemoDist_Alg_Context::mBiquads</TT> is an example of this type of port: it is not modified by any other component and <TT>DemoDist_AlgorithmProcessFunction()</TT> relies on the <TT>mBiquads</TT> data persisting between processing calls.

A component that has registered a private data field is given access to a block of private data. Although the memory in this block will be allocated by the host, its data is fully owned by the component. Because this data is considered private to its parent component, other components cannot overwrite or target this data. Plug-ins that need to transmit data directly between their algorithms' private data ports and their other modules may use the \ref AAX_IEffectDirectData interface, which provides an API for reading from or writing to this data from outside of the algorithm callback.

The plug-in's data model includes an initialization function that is called by the %AAX host at the time of plug-in instantiation and "reset" events. This initialization method is called on the host for both Native and DSP plug-ins. Since this method is part of the plug-in's data model, it has direct access to plug-in state information.

		@subsection subsection__metering_output Metering output
Plug-in metering ports are populated with an array of float values, or 'taps'. One tap is provided per plug-in meter. The algorithm writes per-buffer peak values to this port and the %AAX host applies standardized ballistics to these values. Both raw and processed meter values are available to the plug-in's GUI.

		@subsection subsection__environment_variable_retrieval Environment variable retrieval
Another use of ports is to receive data from the %AAX host describing the execution environment. For example, an algorithm may include a port to receive the number of samples in its processing window or the sample rate. These services are provided automatically by the host once the component registers ports for them.

		@subsection subsection__other_functionality_enhancement Other functionality enhancement
An algorithm component may use ports to gain additional functionality that is provided by the host. For example, an algorithm that will be compiled for accelerated environments may take advantage of the TI chip's Direct Memory Access functionality by registering a DMA port. The host will then allow this port to access memory directly using AAX's DMA APIs.

</DIV>


<DIV CLASS="section">
\ifnot docs_for_cpexam
	\section alg_seealso Additional Information
	
		For information about optional features for the algorithm processing callback, see
		the following \ref AdditionalFeatures documentation:
		
			\li \ref additionalFeatures_DMA
			\li \ref additionalFeatures_BackgroundProc
\endif

</DIV>

 */
 
