Search guides and the APICtrl K
  1. API reference
  2. Formats and wrappers

auv3_wrapper.h

The Audio Unit v3 format wrapper (AUAudioUnit), for macOS and iOS.

#include <sonore/auv3_wrapper.h>
On this page

Design notes

What AUv3 is, next to the AUv2 this SDK already builds

An AUv2 (au_wrapper.h) is a bundle of C functions a host dlopens into its own process. An AUv3 is an Objective-C OBJECT -- a subclass of Apple's AUAudioUnit -- that lives in an app EXTENSION (.appex), shipped inside an ordinary application, and usually runs in a process of its own that the host talks to across the system's audio-unit bridge. It is the only kind of plugin iOS and iPadOS load (GarageBand, AUM, Cubasis, Logic Pro for iPad), and the only kind the Mac App Store accepts. Logic and every other Mac host load both, and auval validates both.

Written against the runtime, as every Apple file here is

The SDK stays plain C++, so there is no .mm file: the AUAudioUnit subclass is REGISTERED at runtime (objc_allocateClassPair), each method a C function with the selector's signature, and every call into a framework class is objc_msgSend through a correctly typed pointer -- exactly what the compiler emits for Objective-C. The blocks AUv3 trades in (the render block, the parameter tree's observers) are built by hand to clang's block ABI (apple_block.h); the blocks a HOST hands over (pull input, musical context, transport, MIDI out) are called through their invoke pointers.

The C structs AUv3 declares only in Objective-C headers -- the render events, the MIDI event list -- are mirrored below with the layout asserted, as window_cocoa.h mirrors CGRect.

What it shares, and what it adds

Include it AFTER clap_wrapper.h (formats.h does, for SONORE_BUILD_AUV3): the DSP instance, parameters, the state blob, presets, the bypass crossfade, the output guard and both editors are the shared Instance's, so an AUv3 saves the same bytes and sounds the same as every other format. The state dictionary is AUv2's ClassInfo layout (type, subtype, manufacturer, version, name, SonoreState), so a preset file reads the same in either.

AUv3 adds what AUv2 never had: parameter changes as timed render events (sample-accurate here when the descriptor asks, PluginDescriptor:: automationGranularity, by the same block splitting CLAP and VST3 use), a begin/end GESTURE for every edit an editor makes, MIDI 2.0 event lists, and the track's name (contextName).

Status

Compiled on Windows against tests/au_shim on every build (the shim's README says what that proves and what it does not). On macOS CI it is built as an .appex inside a container app, registered with pluginkit and validated by auval, and tests/auv3_selftest.cpp drives the class in-process the way a host does. On iOS CI it is built for the simulator and the same self-test runs there. Opened in a real host's window and played from a real keyboard: not yet, by nobody in this loop.

Types 10

AURenderEventHeader: what every render event starts with.

AUParameterEvent, for kEventParameter and kEventParameterRamp.

AUMIDIEvent, for kEventMIDI and kEventMIDISysEx. data is declared three bytes long and runs on for length bytes when the event is a SysEx.

MIDIEventPacket (CoreMIDI, macOS 11 / iOS 14): Universal MIDI Packet words.

MIDIEventList: the packets, back to back.

AUMIDIEventList, for kEventMIDIEventList.

The fields every block starts with (apple_block.h builds whole ones; this is for calling a block somebody else made).

objc_super's layout: the receiver, then the class the method search STARTS at -- the framework class our runtime class extends, named outright. Never object_getClass(self)'s superclass: a key-value observer subclasses the object at runtime, and that superclass is then our own class.

Everything one AUAudioUnit object holds: the shared Instance every format drives, the framework objects the unit publishes (buses, parameter tree, presets), the render block, and the host's blocks for the timeline and MIDI output, copied when render resources are allocated.

Owned by the Objective-C object (an instance variable), created in its initialiser and deleted in its dealloc. Render reads only what allocateRenderResources sized.

Both classes, before NSExtensionMain asks for the principal one.

Functions 104

Aliases 11

Constants 18

Macros 1

  • macro#define SONORE_AUV3_FACTORY_CLASS "SonoreAUv3Factory"
    The class name the extension's Info.plist names as NSExtensionPrincipalClass. It has to be known when the plist is written, so it cannot be made unique per image the way every other runtime class here is: sonore_add_auv3 derives it from the target and passes it in. A build without the helper (a syntax check, a self-test) gets this fallback.
    auv3_wrapper.h:97
↑↓ to move↵ to openEvery public name in the headers, and every guide