OverdriveBlock

Asymmetric soft-clipping distortion with tone control.

Overview

OverdriveBlock applies warm, tube-like distortion using hyperbolic tangent saturation with different curves for positive and negative signal halves. This asymmetric approach creates a more organic sound than symmetric clipping.

Mathematical Foundation

What is Distortion?

Distortion occurs when a system's output is a nonlinear function of its input. In audio, this nonlinearity creates new frequencies (harmonics) that weren't present in the original signal.

For a pure sine wave input at frequency $f$:

  • Linear system: Output is still just frequency $f$
  • Nonlinear system: Output contains $f$, $2f$, $3f$, $4f$... (harmonics)

Soft vs Hard Clipping

Hard clipping simply limits the signal: $$ y = \begin{cases} 1 & \text{if } x > 1 \ x & \text{if } |x| \leq 1 \ -1 & \text{if } x < -1 \end{cases} $$

This creates harsh distortion with many high-frequency harmonics.

Soft clipping uses a smooth saturation curve: $$ y = \tanh(x) $$

The hyperbolic tangent smoothly approaches $\pm 1$ as $|x| \to \infty$, creating a warmer, more musical distortion.

The Hyperbolic Tangent

The tanh function is ideal for soft clipping:

$$ \tanh(x) = \frac{e^x - e^{-x}}{e^x + e^{-x}} $$

Properties:

  • Output range: $(-1, 1)$
  • Passes through origin: $\tanh(0) = 0$
  • Odd function: $\tanh(-x) = -\tanh(x)$
  • Smooth everywhere
  • Approaches $\pm 1$ asymptotically

Saturation Curve with Adjustable Knee

This implementation uses a scaled tanh to control the "knee" (how abruptly clipping begins):

$$ y = \frac{\tanh(k \cdot x)}{k} $$

where $k$ is the knee factor (this block uses $k = 1.5$).

  • Larger $k$: Sharper knee, more aggressive clipping
  • Smaller $k$: Softer knee, more gradual compression

Asymmetric Saturation

Real tube amplifiers and analog circuits often clip asymmetrically—the positive and negative halves of the waveform are processed differently. This creates even harmonics (2nd, 4th, 6th...) in addition to odd harmonics.

This block applies different scaling to positive and negative signals:

$$ y = \begin{cases} 1.4 \cdot \text{softclip}(0.7x) & \text{if } x > 0 \quad \text{(softer, more headroom)} \ 0.8 \cdot \text{softclip}(1.2x) & \text{if } x < 0 \quad \text{(harder, more compression)} \end{cases} $$

where: $$ \text{softclip}(x) = \frac{\tanh(1.5x)}{1.5} $$

Harmonic Content

Clipping TypeHarmonics GeneratedCharacter
Symmetric softOdd only (3rd, 5th, 7th...)Clean, tube-like
Asymmetric softOdd + Even (2nd, 3rd, 4th...)Warm, organic
Hard clipMany high-orderHarsh, buzzy

The 2nd harmonic is an octave above the fundamental and adds "warmth." The 3rd harmonic is an octave + fifth, adding "body."

Tone Control Filter

After clipping, a one-pole low-pass filter controls brightness:

$$ y[n] = y[n-1] + \alpha \cdot (x[n] - y[n-1]) $$

where: $$ \alpha = 1 - e^{-2\pi f_c / f_s} $$

The cutoff frequency $f_c$ is mapped from the tone parameter:

  • Tone 0.0: $f_c \approx 300$ Hz (dark)
  • Tone 1.0: $f_c \approx 3000$ Hz (bright)

Creating an Overdrive

#![allow(unused)]
fn main() {
use bbx_dsp::{blocks::OverdriveBlock, graph::GraphBuilder};

let mut builder = GraphBuilder::<f32>::new(44100.0, 512, 2);

// Parameters: drive, level, tone, sample_rate
let od = builder.add(OverdriveBlock::new(2.0, 0.8, 0.5, 44100.0));
}

Port Layout

PortDirectionDescription
0InputAudio input
0OutputDistorted audio

Parameters

ParameterTypeRangeDefaultDescription
drivef641.0 - 10.0+1.0Input gain before clipping
levelf640.0 - 1.01.0Output level
tonef640.0 - 1.00.5Brightness (0=dark, 1=bright)

Drive Values

DriveCharacter
1.0Subtle warmth
3.0Moderate saturation
5.0Heavy overdrive
10.0+Aggressive distortion

Usage Examples

Basic Overdrive

#![allow(unused)]
fn main() {
use bbx_dsp::{blocks::{OscillatorBlock, OverdriveBlock}, graph::GraphBuilder, waveform::Waveform};

let mut builder = GraphBuilder::<f32>::new(44100.0, 512, 2);

let osc = builder.add(OscillatorBlock::new(440.0, Waveform::Sine, None));
let od = builder.add(OverdriveBlock::new(3.0, 0.7, 0.5, 44100.0));

builder.connect(osc, 0, od, 0);
}

Aggressive Distortion

#![allow(unused)]
fn main() {
use bbx_dsp::{blocks::{OscillatorBlock, OverdriveBlock}, graph::GraphBuilder, waveform::Waveform};

let mut builder = GraphBuilder::<f32>::new(44100.0, 512, 2);

let osc = builder.add(OscillatorBlock::new(110.0, Waveform::Saw, None));
let od = builder.add(OverdriveBlock::new(8.0, 0.5, 0.6, 44100.0));  // High drive, lower output

builder.connect(osc, 0, od, 0);
}

With DC Blocker

Distortion can introduce DC offset:

#![allow(unused)]
fn main() {
use bbx_dsp::{blocks::{DcBlockerBlock, OscillatorBlock, OverdriveBlock}, graph::GraphBuilder, waveform::Waveform};

let mut builder = GraphBuilder::<f32>::new(44100.0, 512, 2);

let osc = builder.add(OscillatorBlock::new(440.0, Waveform::Sine, None));
let od = builder.add(OverdriveBlock::new(5.0, 0.7, 0.5, 44100.0));
let dc = builder.add(DcBlockerBlock::new(true));

builder.connect(osc, 0, od, 0);
builder.connect(od, 0, dc, 0);
}

Warm Bass Distortion

#![allow(unused)]
fn main() {
use bbx_dsp::{blocks::{OscillatorBlock, OverdriveBlock}, graph::GraphBuilder, waveform::Waveform};

let mut builder = GraphBuilder::<f32>::new(44100.0, 512, 2);

let osc = builder.add(OscillatorBlock::new(80.0, Waveform::Saw, None));
let od = builder.add(OverdriveBlock::new(2.0, 0.8, 0.3, 44100.0));  // Low tone for warmth

builder.connect(osc, 0, od, 0);
}

Implementation Notes

  • Asymmetric soft clipping using scaled tanh
  • One-pole low-pass filter for tone control
  • Click-free parameter changes via smoothing
  • Denormal flushing in filter state
  • Multi-channel with independent filter states

Further Reading

  • Pirkle, W. (2019). Designing Audio Effect Plugins in C++, Chapter 19: Distortion Effects. Focal Press.
  • Smith, J.O. (2010). Physical Audio Signal Processing, Appendix I: Nonlinear Distortion. online
  • Schimmel, J. (2008). "Nonlinear Filtering in Computer Music." Proceedings of DAFx.
  • Pakarinen, J. & Yeh, D. (2009). "A Review of Digital Techniques for Modeling Vacuum-Tube Guitar Amplifiers." Computer Music Journal, 33(2).