Building my first audio plugin with JUCE
After years of tweaking knobs on other people's plugins, I finally decided to build my own. The idea had been bouncing around in my head for a while: a simple tube saturation plugin that actually sounded warm without being muddy.
Why JUCE?
If you're getting into audio plugin development, JUCE is basically the industry standard. It handles the cross-platform plumbing (VST3, AU, and AAX with Avid's SDK) so you can focus on the actual DSP. The learning curve is real, but the documentation is solid and there's a great community.
void WarmTubeProcessor::processBlock(juce::AudioBuffer<float>& buffer, juce::MidiBuffer&)
{
juce::ScopedNoDenormals noDenormals;
for (int channel = 0; channel < buffer.getNumChannels(); ++channel)
{
auto* channelData = buffer.getWritePointer(channel);
for (int sample = 0; sample < buffer.getNumSamples(); ++sample)
{
// Soft clipping with tube-style saturation
float x = channelData[sample] * driveAmount;
channelData[sample] = std::tanh(x) * outputGain;
}
}
}
The basic idea behind tube saturation is soft clipping. When you push a tube amp, it doesn't cut the signal off harshly. It rounds it off smoothly, adding harmonics that our ears hear as "warmth."
There's a catch, though. tanh() is symmetric, so it only adds odd harmonics, which lean toward grit more than warmth. Real tubes are asymmetric, and that asymmetry is where the even harmonics come from. Adding a small DC bias before the curve (and removing it afterward) gets you a lot closer.
The DSP rabbit hole
What started as a simple tanh() waveshaper quickly became an obsession with modeling how vacuum tubes actually behave. There's a reason good saturation plugins cost what they do: the math gets complicated fast.
Key things I learned:
- Oversampling is essential. Any nonlinearity creates new harmonics, and the ones above Nyquist fold back down as aliasing. JUCE's
dsp::Oversamplingclass makes this easy. - Smooth your parameters. Jumping straight to a new drive value mid-buffer causes zipper noise.
SmoothedValuefixes it. - Filters matter. Pre- and post-filtering shape the character dramatically.
- UI is half the battle. A good-looking plugin makes you want to use it.
What's next
I'm currently working on a proper EQ section and a bias control, so you can dial in how asymmetric (and how "warm") the curve gets. The goal is to release it as a free plugin once it's polished enough.
If you're thinking about building your own plugins, I'd say go for it. The combination of music and code is incredibly satisfying, and there's nothing quite like hearing your own DSP in a mix.