Boutique Audio DSP: Porting Windows VST3 to macOS Universal Audio Units (AU) in JUCE 8
Cross-compiling Universal Binary 2 (arm64 & x86_64), passing Apple's strict auval validation tests for Logic Pro, and navigating macOS Gatekeeper security for indie plugin developers.
In independent audio software engineering, porting an established Windows VST3 catalog to macOS—specifically Apple’s Audio Unit (AU / .component) format for Logic Pro and GarageBand—presents unique technical challenges.
Between Apple Silicon (arm64) and Intel (x86_64) hardware divergence, strict memory alignment constraints, and Apple’s rigorous auval (Audio Unit Validation Tool) pipeline, achieving 100% crash-free cross-platform compatibility requires rigorous architectural discipline.
This technical retrospective outlines the lessons learned while transitioning the Lo-bit record catalog to macOS Universal Audio Units using JUCE 8.
1. Universal Binary 2: Fat Binaries for arm64 & x86_64
Modern macOS systems span both Apple Silicon M-series chips and legacy Intel workstations. A release build must package both architectures into a single fat binary:
lipo -info MyPlugin.component/Contents/MacOS/MyPlugin
# Output: Architectures in the fat file: MyPlugin are: x86_64 arm64
SIMD Instruction Portability
Directly hardcoded Intel SSE intrinsics (_mm_load_ps, etc.) fail compilation on ARM NEON. Utilizing juce::dsp::SIMDRegister or macro branching to NEON vector instructions is mandatory for maintaining real-time DSP performance across architectures.
2. Passing the auval Validation Gauntlet
Logic Pro subjects newly discovered AU plugins to automated validation via the terminal command auval. A single assertion failure or unhandled exception permanently blacklists the plugin.
The Top 3 Validation Failure Points
- Unsafe Initialization Lifecycle: Never dereference audio buffers in
processBlockbeforeprepareToPlayhas concluded. Always implement thread-safe atomic initialization checks. - Channel Bus Configuration: Logic Pro tests mono-to-stereo and pure mono channel configurations extensively. AudioProcessor configurations must explicitly declare support for discrete channel sets via
BusesProperties. - Locking the Real-Time Audio Thread: Direct GUI repaints or mutex acquisition inside
processBlockviolates real-time deadlines. Always decouple parameter communication via lock-free FIFOs orstd::atomicfloats.
3. Managing Gatekeeper Quarantine for Indie Builds
For un-notarized indie plugins distributed outside the Mac App Store, macOS automatically tags downloaded files with the com.apple.quarantine extended attribute, preventing execution.
Users can clear this quarantine attribute safely using the terminal:
sudo xattr -rd com.apple.quarantine /Library/Audio/Plug-Ins/Components/MyPlugin.component
Following this command and resetting the Logic Pro Plugin Manager, the AU component initializes seamlessly with full native DSP performance.
*Tracks created using the environments, gear, and techniques featured on this site are available for preview and free download in the Lo-bit LAB Free BGM Library. Continuously updated.*