Anukari 1.0 is out. Reflections on three years of full-time work, from leaving Google and a broken shoulder to first sound and full polyphony.
Evan Mezeske
Jun 2026
How 0.9.26 cuts Anukari's RAM use. A lock-free background allocator with epoch-based freeing replaces 154 MB of preallocated delay line buffers.
Mar 2026
I replaced the crackling JUCE limiter with a hard limit at +6 dBFS and re-leveled all 200+ factory presets to -15 LUFS for far more dynamic range.
Dec 2025
Looking back at the GPU years, where my 50,000-object goal led me astray, and why one SIMD backend beats maintaining CUDA, Metal, and OpenCL.
Nov 2025
Part 2 of the CPU rewrite, from spot-vectorizing float3 math with SSE and NEON intrinsics to restructuring loops for compiler auto-vectorization.
Anukari now runs on the CPU with hand-coded SIMD instead of the GPU. Part 1 explains the GPU origin story and the naive port that was only 5x slower.
With Apple's help I cut Metal kernel launch overhead under 50us using MTLSharedEvent and double-buffered encoding, then had to unbreak CUDA.
May 2025
Applying Apple's NDA guidance to the GPU spin loop, serializing its kernels with MTLEvent, and deduplicating it across processes via shared memory.
My Appeal to Apple post worked. I got a call with a Metal engineer, performance hints I can use now, and an open line to the right people at Apple.
macOS GPU clock heuristics don't recognize real-time audio work, and my spin loop workaround fails on Pro and Max chips. I need the Metal team's help.
An undocumented Metal error 14 with multiple plugin instances traced to kernels clearing 300 MB delay buffers that a low-watermark check made unnecessary.
Feb 2025
GarageBand silently stops calling ProcessBlock, so Anukari now detects the auto-bypass and hands the physics simulation to a background thread.
A minimax optimizer now packs Anukari's 11 entity types into 32 GPU warps to minimize branch divergence. Huge presets run up to 2x faster.
Nov 2024
The CUDA port is done with all goldens passing. Native 1024-thread blocks beat OpenCL's 256-thread cap, so big presets no longer double their latency.
MacOS won't up-clock the GPU for latency-sensitive audio, so Anukari now burns one warp on useless spin work. Latency dropped about 40 percent.
Metal profiling shows the simulation is ALU-bound, so I'm chasing half floats and signed indexes, plus a visual style doc for hiring 3D artists.
Async background asset loading plus a detachable cached renderer make reopening Anukari's VST GUI instant, even with 256 MB 2K skyboxes.
Oct 2024
On macOS the 3D graphics interfere with GPU audio even when nothing is drawn, so I'm starting the Filament port to rule out Apple's OpenGL.
Sep 2024
The OpenCL kernel now compiles and runs under Metal via macros and passes the golden tests, though the rough port still leaks memory everywhere.
The GPU copy optimization landed well, and NVIDIA on Windows runs big presets fine, but MacOS OpenCL stays mysteriously memory-bound. Metal port is next.
Aug 2024
Moving final microphone mixing onto the GPU should slash CPU-GPU copy bandwidth, my plan for the Mac performance problems pre-alpha testers uncovered.
Golden tests now compare audio via chunked FFTs and L2 distance, which surfaced an OpenCL bug on Mac where objects can legally live at address NULL.
Jun 2024
Two voice instances now run in parallel GPU work groups and pass the golden tests. Links stay shared in memory, so only mutable entities duplicate.
May 2024
Breaking ground on instanced voice mode, which turns any instrument polyphonic by using time dilation for tuning. Prototype first, design later.
Seeding the GPU PRNG from the current sample number made rendered audio depend on buffer size, so it now seeds once at startup and stays deterministic.
Mar 2024
Golden tests now render a preset and MIDI clip to audio and diff against a verified .flac, so optimizations and GPU ports can't silently break the sound.
Exhaustive PrecisionSlider unit tests caught a NaN-producing bug, prompting an audit of where the 36 kLOC codebase still needs test coverage.
Feb 2024
Master output level meters and a GPU meter are in. The GPU meter shows the share of the latency budget each block eats, like Ableton's CPU meter.
Fixed a bug where MIDI note off events were missed with the plugin GUI hidden, because GUI flow control froze the simulation timestamp.
Tracing a delay line bug to CL_WRITE_MAP_INVALIDATE_REGION skipping the DMA read on pinned memory, so stale data landed in the internal sample buffers.
Jan 2024
Found a cheap way to modulate rotation by restricting it to the Y axis for exciters and mics, and pushed panning modulation down to the GPU for free.
Dec 2023
Tens of thousands of random presets now get serialized to GPU format and simulated in a fuzz test, proving the new warp alignment code doesn't crash.
Padding GPU memory so each warp runs a single entity type cut kernel latency 25 to 50 percent and made performance far more stable.
Modulation values now reach the GUI, so a mic driven by two LFOs visibly circles in the 3D view. CPU-latched parameters like mallet hardness work too.
Modulators can now link to springs, with groundwork for modulating modulators. Fuzz testing caught bugs in the new code and old undo/redo paths.
Nov 2023
To let modulators drive spring stiffness the Link class itself becomes Linkable, kept safe by an invariant allowing one layer of recursion.
MIDI control modulators now render as spinning 3D knobs, and I applied an ADC trick using arch-specific pause instructions in the spin-loop sync code.
Modulation now covers sensors and exciters, and I'm weighing one flat layer of modulator recursion since GPUs can't do real recursion.
The Audio Units logo and the Audio Units symbol are trademarks of Apple Computer, Inc.
VST is a trademark of Steinberg Media Technologies GmbH, registered in Europe and other countries.