AAX SDK  2.4.1
Avid Audio Extensions Development Kit
Documents
The Avid Component Framework (ACF)

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.

More details

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.

ACF interfaces in AAX

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.

ACF interfaces: AAX_IACFEffectParameters and AAX_IACFController

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.

Using ACF interfaces

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:

Host-provided interfaces

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.

void SomeFunction (IACFUnknown * inController)
{
// When object is created, a reference is acquired
AAX_VController theController (inController);
//
// ...
//
// When object goes out of scope, the reference is released
}
Version-managed concrete Controller class.
COM compatible IUnknown C++ interface.
Definition: AAX_ACFInterface.doxygen:248
Version-managed concrete Controller class.
Definition: AAX_VController.h:56

Plug-in interfaces

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.

#include "AAX_UIDs.h"
#include "AAX_Assert.h"
#include "acfunknown.h"
void SomeFunction (IACFUnknown * inController)
{
// When interface is queried, a reference is acquired
if ( inController )
{
AAX_IEffectParameters* myEffectParameters = NULL;
ACFRESULT acfErr = ACF_OK;
acfErr = inController->QueryInterface(
(void **)&myEffectParameters);
AAX_ASSERT(ACFSUCCEEDED(acfErr));
}
//
// ...
//
// The reference must be explicitly released when finished
if (myEffectParameters)
{
myEffectParameters->Release();
myEffectParameters = NULL;
}
}
Declarations for cross-platform AAX_ASSERT, AAX_TRACE and related facilities.
#define AAX_ASSERT(condition)
Asserts that a condition is true and logs an error if the condition is false.
Definition: AAX_Assert.h:268
The interface for an AAX Plug-in's data model.
Unique identifiers for AAX/ACF interfaces.
const acfIID IID_IAAXEffectParametersV1
ACF interface ID for AAX_IACFEffectParameters.
Definition: AAX_UIDs.h:158
virtual BEGIN_ACFINTERFACE ACFRESULT ACFMETHODCALLTYPE QueryInterface(const acfIID &iid, void **ppOut)=0
Returns pointers to supported interfaces.
The interface for an AAX Plug-in's data model.
Definition: AAX_IEffectParameters.h:83

Interface versioning in AAX

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 :

ACF interfaces: AAX_IACFEffectParameters and AAX_IACFController (with possible host design)

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.

Adding a new version to AAX_IACFEffectParameters and AAX_IACFController

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:

Complete design example with versioned ACF interfaces

Documents

 ACF Elements
 ACF classes that are used by common AAX interfaces.
 
Collaboration diagram for The Avid Component Framework (ACF):