name: aax description: Optional AAX support for Pulp, including developer-supplied Avid SDK setup, CMake enablement, DigiShell/AAX Validator workflows, and local AAX builds on macOS or Windows. requires: scripts: - tools/audit.py - tools/deps/audit.py
tools: []
AAX Skill
Use this when working on Pulp's optional AAX support or when guiding users who want to build and validate AAX plugins locally.
Scope
Supported hosts: macOS and Windows
Unsupported: Linux and Ubuntu
Current scope: AAX Native
Out of scope: bundling Avid assets, DSP/AudioSuite support, PACE release automation
Never commit the AAX SDK, DigiShell, validator binaries, or Avid example code.
Never unpack Avid downloads inside the Pulp repo.
Keep AAX developer-supplied, opt-in, and out-of-tree.
Run the repo audits after AAX-related changes:
python3 tools/deps/audit.py --strict
What Users Should Download
Tell users to sign in at:
https://developer.avid.com/aax/
Required downloads:
AAX SDKDigiShell and AAX Validator
Optional later:
AAX Plug-In Page Table Editor
Do not recommend these for normal Pulp AAX setup unless the task explicitly needs them:
AAX Developer Toolsbeta bundles- Pro Tools installers
- HD Driver
- Avid Cloud Client Services
Suggested Install Locations
Preferred user-local locations so Pulp can auto-discover them:
~/SDKs/avid/aax-sdk/current
~/SDKs/avid/aax-validator/current
%USERPROFILE%\SDKs\avid\aax-sdk\current
%USERPROFILE%\SDKs\avid\aax-validator\current
Environment variables override auto-discovery:
export PULP_AAX_SDK_DIR=~/SDKs/avid/aax-sdk/current
export PULP_AAX_VALIDATOR_DIR=~/SDKs/avid/aax-validator/current
Core Commands
Check current AAX availability:
pulp status
pulp doctor
Build with AAX enabled:
cmake -S . -B build \
-DCMAKE_BUILD_TYPE=Debug \
-DPULP_ENABLE_AAX=ON \
-DPULP_AAX_SDK_DIR="$PULP_AAX_SDK_DIR"
cmake --build build --target MyPlugin_AAX -j$(sysctl -n hw.ncpu 2>/dev/null || nproc)
Validate built plugins:
pulp validate
pulp validate --all
Notes:
pulp validateuses the faster AAX describe-validation path when the validator is installed.pulp validate --allruns the broader AAX validator suite.- Do not launch multiple full AAX validator runs in parallel; DigiShell can collide on local ports.
Expected UX
- If the AAX SDK is missing, point users to the Avid sign-in page and
PULP_AAX_SDK_DIR. - If DigiShell/AAX Validator is missing, point users to the Avid sign-in page and
PULP_AAX_VALIDATOR_DIR. - On Linux or Ubuntu, explain that AAX is unsupported and remove
AAXfromFORMATS. - If validation reports that a bundle exists but the plugin binary is missing, build the target before validating it.
Gotchas
MIDI sysex accumulator
AAX splits multi-byte sysex (F0 … F7) across sequential AAX_CMidiPacket
entries — the first packet carries the F0 status byte, continuation
packets can appear with no status byte, and the final packet carries F7.
Each packet's mData field is at most 4 bytes. A single-packet decoder
will silently drop everything after the first 4 sysex bytes, and the
host will never see the real message.
The correct shape is a per-node accumulator:
std::vector<uint8_t> sysex_buffer;
bool sysex_in_progress = false;
int32_t sysex_start_offset = 0;
// for each packet in the node's buffer:
// if byte == 0xF0 → start accumulator, capture start_offset from mTimestamp
// while sysex_in_progress → append every payload byte (no status-byte requirement)
// if byte == 0xF7 → flush accumulator as one MidiEvent, reset
This matches the shape used for CLAP/VST3/AU/CoreMIDI/ALSA sysex. See
core/format/src/aax_runtime.cpp::decode_midi_node for the canonical
implementation.
The AAX bypass MIDI-thru helper must copy sidecar payloads with
MidiBuffer::add_sysex_copy(); MidiBuffer::SysexPayload is deliberately
not a movable raw std::vector.
When clearing an AAX process block's MIDI buffers, clear both the short-event
storage and the sysex sidecars. MidiBuffer::clear() resets short events only;
call clear_sysex() on both input and output buffers before decoding the next
block, or stale sidecar payloads can be re-emitted by a later block.
When adding or changing any AAX MIDI input path, exercise this against a multi-packet sysex vector (at least one packet across the 4-byte boundary and one terminator-only packet) in a unit test. Adapter fixes should ship with the regression tests that prove the fixed behavior.
Review Checklist
After any AAX-related change:
- Build with AAX disabled and confirm the repo still works normally.
- Build with
PULP_ENABLE_AAX=ONagainst a developer-supplied SDK. - Run
pulp validateandpulp validate --allwhen the validator is installed. - Recheck the user-facing guidance in
docs/guides/aax.mdif behavior changed.