Skip to content

BitCrush

Tier: Color | ComponentType: 19 | Params: 5

Bit depth reduction and sample rate decimation with optional TPDF dither and anti-aliasing pre-filter.

Overview

BitCrush simulates the quantization artifacts of early digital audio hardware by reducing the effective bit depth and sample rate of the signal. Bit depth reduction snaps continuous amplitude values to a coarser grid, introducing quantization noise that ranges from subtle grit at 12--16 bits down to harsh, metallic distortion at 1--4 bits. Sample rate reduction uses a zero-order hold to decimate the signal, producing the characteristic aliasing and staircase waveforms of low-sample-rate converters.

The two effects are independent and can be used separately or combined. Reducing only sample rate with full bit depth creates the lo-fi character of vintage samplers. Reducing only bit depth creates the harsh quantization noise of early digital effects. Together they recreate the full character of vintage digital audio hardware.

Two optional features improve the quality of the effect. TPDF dither adds triangular probability density function noise before quantization, which converts harmonic quantization distortion into a flat noise floor -- the same technique used in professional audio mastering. Pre-filter applies a one-pole lowpass at half the decimation rate (Nyquist frequency of the reduced sample rate), acting as an anti-aliasing filter that reduces harsh aliasing artifacts from the sample rate reduction.

File Locations

Path
Header Sources/FolioDSP/include/FolioDSP/Color/BitCrush.h
Implementation Sources/FolioDSP/src/Color/BitCrush.cpp
Tests Tests/FolioDSPTests/BitCrushTests.swift
Bridge Sources/FolioDSPBridge/src/FolioDSPBridge.mm (BitCrushBridge)

Parameters

Index Name Description Min Max Default Min Default Max Default Unit
0 Bit Depth Number of quantization bits -- lower values = coarser quantization 1 24 4 16 16 bits
1 Sample Rate Effective output sample rate -- lower values = more aliasing 100 96000 1000 44100 44100 Hz
2 Dither Enable TPDF dither before quantization (0=off, 1=on) 0 1 0 1 0
3 Pre-Filter Enable anti-aliasing lowpass at half decimation rate (0=off, 1=on) 0 1 0 1 0
4 Mix Dry/wet blend 0 100 0 100 100 %

Processing Algorithm

The process() function executes these steps for each input sample:

1. Pre-Filter (Optional)

When enabled, a one-pole lowpass filter at half the decimation rate removes high-frequency content that would alias during sample rate reduction:

\[f_c = \frac{f_{\text{decimate}}}{2}\]
\[\alpha = 1 - e^{-2\pi \cdot f_c / f_s}\]
\[s_n = s_{n-1} + \alpha \cdot (x - s_{n-1})\]

2. Sample Rate Decimation

A zero-order hold reduces the effective sample rate. A counter tracks the hold interval based on the ratio of host sample rate to target sample rate:

\[r = \frac{f_s}{f_{\text{decimate}}}\]

The counter increments by 1.0 each sample. When it exceeds \(r\), a new sample is captured and the counter wraps:

\[\text{if } c \geq r: \quad h = x, \quad c \mathrel{-}= r\]

The held sample \(h\) is output for all samples until the next capture.

3. TPDF Dither (Optional)

When enabled, two uniform random values from an xorshift32 PRNG are summed and scaled to one quantization level, producing triangular probability density function noise:

\[x_d = x + \frac{r_1 + r_2}{L}\]

Where \(L = 2^{\text{bits}}\) is the number of quantization levels, and \(r_1, r_2 \in [-1, 1]\) are uniform random values.

4. Quantization

The signal is quantized to the specified bit depth:

\[L = 2^{\text{bits}}\]
\[y_q = \frac{\text{round}(x \cdot L)}{L}\]

5. Dry/Wet Mix

\[y = x_{\text{dry}} \cdot (1 - m) + y_q \cdot m\]

Where \(m = \text{mix} / 100\).

Core Equations

\[L = 2^{\text{bits}}\]
\[y = \frac{\text{round}(x \cdot L)}{L}\]
\[\text{hold}(x, r) = x_{\text{captured}} \text{ every } \lfloor f_s / f_{\text{dec}} \rfloor \text{ samples}\]

Snapshot Fields

Field Type Range Unit Description
Bit Depth Float 1--24 bits Current bit depth setting
Sample Rate Float 100--96000 Hz Current decimation sample rate
Input Level Float 0--1 Smoothed absolute input level
Output Level Float 0--1 Smoothed absolute output level
Quant Error Float 0--1 Instantaneous quantization error magnitude
Dither Uint8 0--1 Whether TPDF dither is enabled
Pre-Filter Uint8 0--1 Whether anti-aliasing pre-filter is enabled

Implementation Notes

  • Zero-order hold: The decimation uses a floating-point counter rather than an integer divider, allowing non-integer sample rate ratios. The counter subtracts the ratio (rather than resetting to zero) to preserve fractional accumulation.
  • TPDF dither PRNG: Uses xorshift32 for real-time-safe random number generation. Two random values are summed to produce triangular distribution. The PRNG state persists across calls, seeded with 0xABCDEF01.
  • Quantization error: Computed as \(|y_q - x|\) and reported in the snapshot for visualization (used by the StaircaseView in the TestHarness).
  • Level tracking uses exponential smoothing with coefficient 0.01 for display-rate visualization.
  • No parameters are marked as smoothed -- all changes take effect immediately, which is appropriate for the inherently discontinuous nature of bit crushing.
  • Snapshot emission is decimated to ~60 fps (every 735 samples at 44.1 kHz).

Equation Summary

y = round(x·2^bits) / 2^bits; decimate