AAX SDK  2.1.1
Avid Audio Extensions Development Kit
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages

How to route and process MIDI in AAX plug-ins.

Midi Overview

DirectMidi is Avid's protocol for communication of MIDI and other timing-critical plug-in information. It is a cross-platform solution to tightly integrate the host application, audio engine, and plug-ins.

MIDI node types

There are four kinds of nodes an AAX plug-in can create. See AAX_EMIDINodeType for additional details about these node types:

Adding MIDI functionality to a plug-in

Whether a plug-in will use MIDI in its algorithm or its data model, MIDI data is accessed via ports in the algorithm's context structure. To add a MIDI node to the algorithm context, call AAX_IComponentDescriptor::AddMIDINode() with the appropriate node type.

//==============================================================================
// Algorithm context definitions
//==============================================================================
// Context structure
struct SMy_Alg_Context
{
[...]
AAX_IMIDINode * mMIDIInNodeP; // Local input MIDI node pointer
AAX_IMIDINode * mMIDINodeOutP; // Local output MIDI node pointer
AAX_IMIDINode * mMIDINodeTransportP; // Transport node
[...]
};
enum EDemoMIDI_Alg_PortID
{
[...]
//
// Add the MIDI node as a physical address within the context field
,eAlgPortID_MIDINodeIn = AAX_FIELD_INDEX (SDemoMIDI_Alg_Context, mMIDINodeP)
,eAlgPortID_MIDINodeOut = AAX_FIELD_INDEX (SDemoMIDI_Alg_Context, mMIDINodeOutP)
,eAlgPortID_MIDINodeTransport = AAX_FIELD_INDEX (SDemoMIDI_Alg_Context, mMIDINodeTransportP)
[...]
};
// ***************************************************************************
// ROUTINE: DescribeAlgorithmComponent
// Algorithm component description
// ***************************************************************************
static void DescribeAlgorithmComponent( AAX_IComponentDescriptor * outDesc )
{
[...]
// Register MIDI nodes
err = outDesc->AddMIDINode(eAlgPortID_MIDINodeA, AAX_eMIDINodeType_LocalInput, "DemoMIDI", 0xffff); AAX_ASSERT (err == 0);
err = outDesc->AddMIDINode(eAlgPortID_MIDINodeOut, AAX_eMIDINodeType_LocalOutput, "DemoMIDIOut", 0xffff); AAX_ASSERT (err == 0);
err = outDesc->AddMIDINode(eAlgPortID_MIDINodeTransport, AAX_eMIDINodeType_Transport, "DemoMIDITrnsprt", 0xffff); AAX_ASSERT (err == 0);
[...]
}

Using MIDI in a plug-in algorithm

Like with other algorithm context ports, data in MIDI nodes is directly available in the plug-in's algorithm process function. Here is an example from the DemoMIDI_NoteOn sample plug-in:

template<int kNumChannelsIn, int kNumChannelsOut>
void
DemoMIDI_AlgorithmProcessFunction (
SDemoMIDI_Alg_Context * const inInstancesBegin [],
const void * inInstancesEnd)
{
[...]
// Setup MIDI In node pointers
AAX_IMIDINode* midiNodeIn = instance->mMIDINodeP;
AAX_CMidiStream* midiBufferIn = midiNodeIn->GetNodeBuffer();
AAX_CMidiPacket* midiBufferInPtr = midiBufferIn->mBuffer;
uint32_t packets_count_in = midiBufferIn->mBufferSize;
// Setup MIDI Out node pointers
AAX_IMIDINode* midiNodeOut = instance->mMIDINodeOutP;
AAX_CMidiStream* midiBufferOut = midiNodeOut->GetNodeBuffer();
AAX_CMidiPacket* midiBufferOutPtr = midiBufferOut->mBuffer;
uint32_t packets_count_out = midiBufferOut->mBufferSize;
// Setup MIDI Transport node pointers
AAX_IMIDINode* midiTransport = instance->mMIDINodeTransportP;
AAX_ITransport * transport = midiTransport->GetTransport();
bool transport_is_playing = false;
if (transport)
transport->IsTransportPlaying(&transport_is_playing);
if(transport_is_playing)
{
//
// While there are packets in the node
while (packets_count_in > 0)
{
midiBufferOutPtr = midiBufferInPtr; // Copy the packet from the input MIDI node
// to the output MIDI node
midiBufferOutPtr->mTimestamp = timeStamp; // Set the MIDI time stamp
midiNodeOut->PostMIDIPacket(midiBufferOutPtr); // Post the MIDI packet
midiBufferOut->mBufferSize = packets_count_in; //
midiBufferInPtr++;
packets_count_in--;
}
}
[...]
}

Accessing MIDI in the plug-in data model

A plug-in may access MIDI data in its data model via the UpdateMIDINodes method. This method provides an AAX_CMidiPacket. Because the MIDI packet structure does not identify the associated MIDI stream's type (input, output, global, or transport) this method also provides an index into the plug-in's algorithm context structure which can be used to identify the semantics of the MIDI packet.

Collaboration diagram for MIDI: