The Beautiful Mess
What We Learned Building Plugins That Don't Suck
Or: How I learned to stop worrying and love the segfault
Look, I'm not going to sugarcoat this: Building audio plugins that actual professionals want to use is like trying to juggle chainsaws while riding a unicycle. On fire. In the dark.
But here's the thing: it's also one of the most rewarding things you can do as a, you know, founder/designer/developer type person. And our community? You folks are simultaneously the best and worst thing about this job.
The Thread Safety Rabbit Hole
Remember when we thought "just slap a mutex on it" was a valid threading strategy? Yeah, good times. Turns out, locking in an audio callback is like bringing a kazoo to a symphony orchestra—technically music, but everyone's going to hate you.
We learned this the hard way with AlterOne's pitch shifter. Version 0.1 had this beautiful, elegant design where the UI thread could update DSP parameters whenever it felt like it. Worked great... until it didn't. Users started reporting random clicks and pops that we couldn't reproduce. Classic heisenbug territory.
Turns out, when you're processing audio at 48kHz with a 512-sample buffer, you've got about 10 milliseconds to do your thing. That's it. Any lock contention, any memory allocation, any "I'll just quickly check this one thing" moment—and boom, you're staring at an XRUN. The DAW glitches. The engineer screams. The cat jumps off the desk.
The Fix: Atomic Operations
// Before: "It'll be fine"
void processBlock(AudioBuffer& buffer) {
mutex.lock(); // <- narrator: it was not fine
float gain = parameters.gain;
mutex.unlock();
// ... process ...
}// After: Actually fine
void processBlock(AudioBuffer& buffer) {
ScopedNoDenormals noDenormals;
float gain = gainParam->load(); // atomic read, no locks
// ... process ...
}Everything between threads happens through std::atomic parameters. The audio thread reads, never writes to shared state (except meters). The UI thread writes, never blocks. Zero locks. Zero blocking. Zero drama.
Zero locks. Zero blocking. Zero drama.
The Aliasing Wars
You know what nobody tells you about DSP? That beautiful, mathematically pure std::tanh() saturation you're so proud of? It's spewing aliasing artifacts all over your frequency spectrum like a sprinkler at a fancy garden party.
We discovered this during LihisSplattener development. The plugin sounded "okay" on 808 kicks and vocal stems, but run it on high-frequency content like hi-hats or cymbals, and it was like listening through a cheese grater.
The Oversampling Trap
Our first instinct? "Let's just oversample everything!" 4x oversampling, problem solved, ship it.
Except now the CPU usage was through the roof. Turns out, oversampling the entire signal chain—including linear processes like input gain and EQ—is like hiring a Formula 1 pit crew to change the batteries in your TV remote. Technically effective, hilariously wasteful.
Enter ADAA
The real breakthrough came when we discovered Antiderivative Anti-Aliasing (ADAA). Instead of brute-force oversampling, you analytically solve for the antiderivative of your nonlinear function and use calculus to get alias-free output.
ADAA in Action
// F(x) is the antiderivative of your nonlinearity
// For tanh(x), F(x) = log(cosh(x))
float process(float x) {
if (abs(x - x1) < tolerance) {
return tanh(0.5f * (x + x1));
}
// ADAA: (F(x) - F(x1)) / (x - x1)
float y = (logCosh(x) - logCosh(x1)) / (x - x1);
x1 = x;
return y;
}The result? Clean saturation at any sample rate, with CPU usage lower than oversampling. Our plugins now sound great at 44.1kHz and sublime at 192kHz, without requiring a NASA supercomputer.
Smart Oversampling Architecture
Oversample only what needs it. Save CPU. Sound better.
The "It Works On My Machine" Syndrome
Here's a fun game: build a plugin on your Mac, test it in Logic Pro, think you're golden. Then watch it crash three different ways in Ableton Live, behave weirdly in Reaper, and refuse to load in FL Studio.
Welcome to plugin development, where every DAW is its own special snowflake with its own interpretations of the VST3 spec.
The pluginval Savior
The turning point was when we started treating pluginval not as an optional suggestion but as a gate that must be passed. Level 10. No exceptions.
This tool stress-tests your plugin in ways you'd never think of:
- Loads and unloads it 100 times in a row
- Randomizes parameters at audio rate
- Changes sample rates and buffer sizes mid-stream
- Tests state save/restore with every permutation
The first time we ran it on AlterOne, it found 14 issues. Things we'd never have caught in manual testing.
Quality Gates Pipeline
No shortcuts. No exceptions. No regressions.
The Performance Obsession
"Your plugin uses 1.2% CPU at 48kHz."
That sentence might sound meaningless to a web developer, but in audio plugin land, it's the difference between a tool that ships and one that collects dust.
Why? Because professional producers don't use one instance of your plugin. They use ten. Fifteen. Thirty-seven. If each one used even 3% CPU, that project would be unplayable.
Our Target
< 1% CPU per instance at 48kHz on an M1 MacBook Air
Not Pro. Not Max. The Air—because if it runs well there, it'll run anywhere.
• No allocations in the audio thread. Period. Everything pre-allocated in prepareToPlay().
• SIMD where it matters. Not everywhere, just the hot paths that actually show up in profiling.
• Smart oversampling. Only the nonlinear stages, not the whole chain.
• Efficient algorithms. Sometimes the mathematically elegant solution isn't the performant one.
Performance Optimization Strategy
Profile. Optimize. Benchmark. Repeat.
Why We Do This (The Mushy Bit)
So why put ourselves through this? Why spend months chasing down sub-1% CPU targets and hunting denormal numbers at 3am?
Because when it works—when a user loads your plugin and immediately gets the sound they heard in their head—there's nothing quite like it.
We get messages like:
"AlterOne saved my vocal stem. I was about to scrap the whole track."
"LihisSplattener made my 808s hit harder than they ever have."
"Your plugins just... work. I don't think about them. They're invisible tools that do exactly what I need."
That last one might be the highest compliment. When your plugin becomes invisible—when it's not the thing the user thinks about, but the tool that lets them think about their music—you've won.
What's Next
We're not done. Not even close.
There are aliasing artifacts still lurking in corner cases. Performance optimizations waiting to be discovered. UI improvements that'll make workflows faster. New DSP algorithms we're dying to implement.
And honestly? That's the fun part. Each plugin is a puzzle. Each optimization is a challenge. Each user request is a hint at what's possible.
So yeah, building industry-leading plugins is hard. It's frustrating. It's occasionally soul-crushing.
But when you nail it? When you ship something that just works, that sounds beautiful, that becomes an invisible tool in someone's creative process?
Worth every segfault.
Related Articles
Written by The KnobSmith Audio Team · January 5, 2026