DEV Community

SUDIP MONDAL
SUDIP MONDAL

Posted on

I Built a Free, Open-Source Guitar Amp Simulator in C++17 — Here's How

I Built a Free, Open-Source Guitar Amp Simulator in C++17

If you've ever wanted to practice guitar silently through headphones or do quick home recordings without spending $20+/month on commercial amp sim software, this project might interest you.

I built Amplitron — a free, open-source guitar amp simulator that runs on Windows, macOS, and Linux. Here's the technical story behind it.

The Problem

Commercial guitar amp simulators (Bias FX, Guitar Rig, AmpliTube) are excellent but expensive. If you just want to:

  • Practice silently through headphones
  • Record a quick demo track
  • Experiment with guitar tones

...paying $20-40/month feels excessive.

So I built Amplitron. It's MIT licensed, completely free, and runs natively without any cloud or subscription.

Tech Stack

  • C++17 — for the core application and DSP engine
  • PortAudio — cross-platform audio I/O (WASAPI/ASIO on Windows, CoreAudio on macOS, ALSA/PipeWire/JACK on Linux)
  • Dear ImGui + SDL2 — for the visual pedalboard interface
  • CMake — build system with vcpkg support on Windows
  • GitHub Actions — CI/CD for all 3 platforms (builds + tests on every push)

The Audio Engine

The most important design consideration for real-time audio is latency. The default configuration runs at:

  • Buffer size: 64 samples
  • Sample rate: 48kHz
  • Processing latency: ~1.3ms

At 64 samples, you have roughly 1.3ms before the audio buffer underruns. The audio callback does all DSP work in that window.

Thread Safety

The trickiest part of building a real-time audio app with a GUI is thread safety. The audio callback runs on a high-priority thread, and the GUI thread modifies the effect chain (add/remove effects, change parameters).

My solution: the effect chain uses try_lock on a mutex:

// Audio callback — never blocks even if GUI is modifying effects
void AudioEngine::processBuffer(float* output, const float* input, size_t frames) {
    if (effectChainMutex.try_lock()) {
        for (auto& effect : effectChain) {
            if (effect->isEnabled()) {
                effect->process(output, frames);
            }
        }
        effectChainMutex.unlock();
    }
    // If lock fails, just pass audio through unprocessed this buffer
}
Enter fullscreen mode Exit fullscreen mode

This ensures glitch-free audio even during heavy UI interactions.

The DSP Effects

Here's the technical breakdown of each effect:

Overdrive (Tube-Style Soft Clipping)

Classic tube amp overdrive uses asymmetric soft clipping. My implementation:

float overdrive(float x, float drive) {
    x *= drive;
    // Asymmetric soft clipping — positive half clips harder
    if (x > 0) {
        return x / (1.0f + std::abs(x));  // soft clip positive
    } else {
        return x / (1.0f + 0.5f * std::abs(x));  // softer on negative
    }
}
Enter fullscreen mode Exit fullscreen mode

Distortion (Hard Clipping + Waveshaping)

Uses tanh() for smooth hard clipping with tonal character:

float distortion(float x, float gain) {
    return std::tanh(x * gain) / std::tanh(gain);
}
Enter fullscreen mode Exit fullscreen mode

EQ (Biquad Filters)

The 3-band parametric EQ uses biquad filters:

  • Bass: Low shelf filter
  • Mid: Peaking filter
  • Treble/Presence: High shelf filter

Biquad filters are the standard for audio DSP — they're computationally cheap (5 multiply-adds per sample) and numerically stable.

Reverb (Schroeder Algorithm)

Schroeder reverb simulates room acoustics using:

  • 4 parallel comb filters — create the initial reflections and sustain
  • 2 series allpass filters — add diffusion and "smear" the sound
Input → [Comb 1] ─┐
Input → [Comb 2] ─┤→ Mix → [Allpass 1] → [Allpass 2] → Output
Input → [Comb 3] ─┤
Input → [Comb 4] ─┘
Enter fullscreen mode Exit fullscreen mode

Cabinet Simulation

Speaker cabinet emulation uses a combination of:

  • Low-pass rolloff (speakers don't reproduce ultra-high frequencies)
  • High-pass rolloff (speakers have a low-frequency cutoff)
  • Resonance peak at the speaker's natural frequency

The Visual Pedalboard

The UI is built with Dear ImGui, which is a great fit for real-time audio apps because:

  • Immediate mode: redraw every frame, perfect for real-time meters
  • Lightweight: minimal overhead
  • Custom rendering: easy to make it look like a physical pedal

Each pedal is rendered with:

  • Color-coded body (different color per effect type)
  • Rotary knobs (drag vertically to adjust — just like physical knobs)
  • LED indicator (bypass state)
  • Footswitch button to toggle bypass

Cross-Platform CI/CD

Every push to main automatically:

  1. Builds on Windows (MSVC + vcpkg), macOS (Homebrew), and Linux (apt)
  2. Runs the full test suite (64+ tests covering all 9 effects)
  3. Creates a release with binaries for all platforms

This was surprisingly easy to set up with GitHub Actions.

What's Next

  • VST3 plugin version (so it works inside DAWs)
  • More amp models (currently just the pedal chain approach)
  • IR-based cabinet simulation (using impulse responses for more realistic cab sound)
  • MIDI control for footswitch bypass

Try It

It's MIT licensed and completely free. Contributions welcome!


What would you add to a guitar amp simulator? I'd love to hear what effects or features matter most to you.

Top comments (0)