![]() |
AAX SDK
2.4.1
Avid Audio Extensions Development Kit
|
How the AAX C++ interfaces work.
The objects and interfaces in AAX are based on the Avid Component Framework (ACF). The ACF is Avid’s implementation of COM, and is the framework that AAX, as well as AVX (Avid Video Externsions) plug-ins are built on.
ACF can be considered an implementation detail of the AAX SDK; the SDK is written to protect plug-in developers from the intricacies of ACF, and it is not necessary to understand ACF or COM in order to use the SDK.
As in COM, ACF draws a distinction between the concept of an object and the concept of an interface. An object is treated as a "black box" of code, whereas an interface is a class of pure virtual methods that allows one to access the functionality inside the object. An object in ACF is represented by the IACFUnknown interface, which is binary compatible with the COM class IUnknown. (Likewise, IACFUnknown follows the same reference counting rules as IUnknown objects.) This interface allows a client to get pointers to other interfaces on a given object using the QueryInterface() method.
Reference counting is an important aspect of both COM and ACF. Simply put, reference counting is the practice of tracking all references to an object, so that a program can determine when the object can safely be deleted. The AAX SDK library handles this reference counting behind the scenes, so plug-ins that call into the SDK library to manage their component interfaces will not leak references.
Many additional resources can be found both online and print that cover COM and reference counting in greater detail.
The binary interface between an AAX plug-in and host is defined by a series of ACF interfaces. Each of these interfaces inherits from IACFUnknown. The implementation of each ACF interface typically uses CACFUnknown
, a utility class that provides basic reference counting and additional fundamental ACF details to satisfy IACFUnknown.
These ACF interfaces may be implemented by either the AAX plug-in or the host. The host retains a reference to each interface that is implemented by the plug-in in order to call methods on the plug-in's implementation. Correspondingly, the plug-in retains references to various interfaces that are implemented by the host, and may call host methods via these interfaces.
The figure above demonstrates this design: the plug-in implements AAX_IACFEffectParameters directly, and retains a reference to an AAX_IACFController that is implemented by the host.
In order to implement AAX_IACFEffectParameters, AAX_IEffectParameters inherits from CACFUnknown
and implements QueryInterface() to ensure that the IACFUnknown interface is implemented. The rest of the implementation of AAX_IACFEffectParameters is contained in AAX_CEffectParameters and the plug-in's custom data model class.
The reference to AAX_IACFController is managed by a versioned implementation class. For more information about this design, see below.
Depending on where an interface is implemented, there are two specific ways to acquire a reference to the underlying AAX object from an IACFUnknown pointer:
Interfaces that are managed by the host must be carefully version-controlled in order to maintain compatibility with many different host versions. The AAX SDK includes "AAX_V" classes to handle this versioning. AAX_V classes are concrete classes that query the host for the correct version of the requested interface. These classes can also handle re-routing deprecated calls and other complicated versioning logic.
To create an AAX_V object, pass an IACFUnknown pointer to the underlying host-managed interface in to the AAX_V class' constructor. ACF reference counting is handled automatically by the object's construction and destruction routines, so no additional calls are necessary to acquire and release the reference.
Interfaces to objects that are owned by the plug-in always have a known version and therefore do not require AAX_V object management. Instead, these interfaces must be acquired and released directly using ACF.
The ACF-based interface used by AAX is designed to allow additional features to be added to the architecture. This can be achieved via the addition of new kinds of interfaces (e.g. AAX_IEffectDirectData) or by extending the existing interfaces. In this section, we will describe an approach for interface extension.
First, here is a more complete picture of "version 1" of the AAX_IACFEffectParameters and AAX_IACFController interfaces, including a possible host implementation of AAX_IACFController :
To extend these interfaces, new "version 2" interfaces are created that inherit from the original interface classes. Although any version 1 method could be called on the new version 2 class, references to each interface are retained by the client in order to clarify the specific version in which each method was introduced.
In this example, if the plug-in is loaded by an older host, the reference to AAX_IACFControllerV2
will return as NULL
, and calls to the V2 methods in AAX_IController will return an "unimplemented" error code. Similarly, if a plug-in that only implements AAX_IACFEffectParameters is loaded into a host that supports AAX_IACFEffectParametersV2
, that host will receive a NULL
reference to the newer interface version and will only be able to call methods on the plug-in's implementation of the original interface.
As a final example, here is a possible design involving new versions of both AAX_IACFEffectParameters and AAX_IACFController, with an example design for the host's implementation as well as the plug-in's:
Documents | |
ACF Elements | |
ACF classes that are used by common AAX interfaces. | |