Reviews AudioUnit v2/v3 plugin implementations for spec compliance, thread safety, and correctness. Use when the user asks to review an AudioUnit plugin, check an AUv3 app extension, audit property or parameter handling, or asks "is my AUComponent thread-safe?" or "why does my AU crash in Logic?". Trigger on phrases like "review my AudioUnit", "check my AUv3", "is my render block safe?", or when you see AURenderCallback, internalRenderBlock, kAudioUnitProperty_*, or AUAudioUnit in the code.
Scanned 5/27/2026
Install via CLI
openskills install kunitoki/sonic-skills---
name: au-review
description: >
Reviews AudioUnit v2/v3 plugin implementations for spec compliance, thread safety, and
correctness. Use when the user asks to review an AudioUnit plugin, check an AUv3 app
extension, audit property or parameter handling, or asks "is my AUComponent thread-safe?"
or "why does my AU crash in Logic?". Trigger on phrases like "review my AudioUnit",
"check my AUv3", "is my render block safe?", or when you see AURenderCallback,
internalRenderBlock, kAudioUnitProperty_*, or AUAudioUnit in the code.
---
# AudioUnit (AUv2 / AUv3) Review
AUv2 runs in-process inside the host; AUv3 runs in a sandboxed XPC extension. Both share
the same realtime-callback constraints, but AUv3 adds ObjC/Swift runtime exposure and
app-extension lifecycle rules that introduce a distinct class of violations.
## Step 0 — Run universal checks first
Invoke `audio-dsp-review` and `audio-numerics-review` before this skill. This skill adds
AU-specific checks on top; it does not replace realtime-safety or numerics reviews.
## Step 1 — Identify AU version and structure
Determine which AU variant is under review:
| Variant | Entry point | Render surface |
|---------|------------|---------------|
| AUv2 (Component Manager) | `AudioComponentRegister` / `AUMIDIEffectFactory` | `AURenderCallback` |
| AUv3 (App Extension) | `AUAudioUnit` subclass, `NSExtensionPrincipalClass` | `internalRenderBlock` |
Locate: the render callback / render block, `allocateRenderResourcesAndReturnError:`,
`deallocateRenderResources`, `supportedViewConfigurations`, and all
`kAudioUnitProperty_*` / `AUParameter` access sites.
## Step 2 — Scan for AU-specific violations
| Violation | Where to look | Risk |
|-----------|--------------|------|
| ObjC message send (`[obj msg]` / `.property`) in render callback | `AURenderCallback` body, `internalRenderBlock` capture body | ObjC runtime uses locks and may allocate; not realtime-safe |
| Render block calls through `self`, weak references, Swift closures, or ObjC properties | AUv3 render block | Runtime calls and weak-reference loads are not realtime-safe |
| `kAudioUnitProperty_*` read/written from render thread | Any render-path property access | `AudioUnitGetProperty` / `SetProperty` are not thread-safe |
| Parameter ramps not applied sample-accurately | `AUParameterEvent` handling, `AUv2 renderProc` | Parameter jumps produce zipper noise on DAW automation |
| Tail time not reported via `kAudioUnitProperty_TailTime` | Reverb, delay, convolution AUs | Host silences the AU before tail has decayed |
| AUv3 extension missing `com.apple.security.app-sandbox` entitlement | Xcode target entitlements | App Store / Notarisation rejection; Logic refuses to load |
| `NSFileManager`, `NSUserDefaults`, or `UserDefaults` accessed from render block | AUv3 internalRenderBlock | Main-thread-only / file-I/O APIs; realtime violation and potential deadlock |
| `AUAudioUnit` subclass not calling `super` in `allocateRenderResources` | `allocateRenderResourcesAndReturnError:` override | Resources for format negotiation never initialised; silent misrender |
| Format negotiation not honouring `outputBusses[n].format` before allocating | `allocateRenderResources` | Mismatch between agreed and actual format; distortion or crash |
| `auval` failures not addressed | Overall AU implementation | Plugin rejected or silently disabled by Logic, GarageBand, and MainStage |
## Step 3 — Write the review
Same format as `audio-dsp-review` / `audio-numerics-review`:
`Verdict` · `Critical Violations` (category, file:line, Why, Fix) · `Warnings` · `What's Done Well` · `Recommended Fixes (priority order)`
Prefix the header with `AudioUnit Review: [file / class]`.
## auval checklist
Run `auval -a` to list registered AUs; validate with type/subtype/manufacturer codes:
`auval -v aufx MYFX MFGR` (effect) · `auval -v aumu MYSY MFGR` (instrument)
| Common auval failure | Cause | Fix |
|----------------------|-------|-----|
| `AU does not support kAudioUnitProperty_CocoaUI` | Missing `NSView`-based UI factory | Implement `AUCocoaViewInfo` + property handler |
| `Render returned error` | Non-zero `OSStatus` from render callback | Validate stream format; guard every render call |
| `TailTime not set` | Reverb/delay returns 0 tail time | Return duration from `kAudioUnitProperty_TailTime` |
| `Latency reported as 0` | Plugin adds latency but reports none | Return correct samples from `kAudioUnitProperty_Latency` |
| `Parameter not in range` | Default value outside `AUParameterInfo` min/max | Clamp default inside declared range |
## Quick fix table
| Violation | Fix |
|-----------|-----|
| ObjC call in render block | Cache plain C/C++ DSP objects, buffers, and atomics before returning the block; call ObjC only outside callback |
| `self` / weak-self use in render block | Capture raw C++ kernel pointers or `__unsafe_unretained` ivars once; do not load weak refs or call properties per render |
| Property access from render thread | Use `std::atomic<>` or lock-free FIFO; read/write properties only from main/audio-graph thread |
| No sample-accurate parameter ramps | Process `AUParameterEvent` list per-sample; use a one-pole smoother for missing events |
| Missing tail time | AUv2: implement `kAudioUnitProperty_TailTime`; AUv3: override `tailTime` in seconds |
| Sandbox entitlement missing | Enable the AUv3 app-extension sandbox; add file/network entitlements only when the extension actually needs them |
| `NSUserDefaults` in render block | Store params via `AUParameter` tree; load defaults only in `init` / `allocateRenderResources` |
No comments yet. Be the first to comment!