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:
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:
The counter increments by 1.0 each sample. When it exceeds \(r\), a new sample is captured and the counter wraps:
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:
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:
5. Dry/Wet Mix
Where \(m = \text{mix} / 100\).
Core Equations
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