Gin
Loading...
Searching...
No Matches
Public Member Functions | List of all members
BitCrusher Class Reference

Anti-aliased bitcrusher with independent bit depth and sample rate reduction. More...

#include <gin_bitcrusher.h>

Public Member Functions

 BitCrusher (int maxChannels_=2, int maxBlockSize_=4096)
 
void setSampleRate (double sr)
 Sets the sample rate.
 
void setParams (float bitDepth, float rateHz, bool dirtyMode)
 Sets the parameters.
 
void reset ()
 Resets all internal state.
 
int getLatencySamples () const
 Latency in samples for the current mode.
 
void process (juce::AudioSampleBuffer &buffer)
 Processes a buffer of audio.
 

Detailed Description

Anti-aliased bitcrusher with independent bit depth and sample rate reduction.

BitCrusher combines two classic lo-fi effects with optional anti-aliasing:

Bit depth reduction quantizes the amplitude of the signal to a reduced number of bits (1 to 16). Quantization is a static nonlinearity that generates harmonics which alias back into the audible range, so the quantizer runs inside a 4x juce::dsp::Oversampling stage - the signal is upsampled, quantized at the oversampled rate, then filtered and decimated back down.

Sample rate reduction resamples the signal to a lower rate (e.g. 500Hz to 48kHz) with a sample & hold driven by a phase accumulator, like a sync'd oscillator. Each hold transition is a step discontinuity which would normally cause fold-back aliasing. Instead of naively holding values, a polyBLEP correction is injected around each discontinuity (across the samples before and after the step, via a one sample delay line), giving a band-limited step that keeps the audible stepped character without the harsh fold-back. The held value is sampled at the exact step instant by linear interpolation of the input.

Signal chain: oversample -> quantize -> decimate -> BLEP sample & hold. The sample & hold runs last, at the project rate, since the BLEP correction band-limits the steps relative to the output Nyquist, and holding after quantization keeps the steps exactly on the bit grid.

Dirty mode bypasses all anti-aliasing (naive quantization and naive hold, zero latency) for the raw aliased sound of a classic bitcrusher.

Key Features:

Usage:

crusher.setSampleRate (44100.0);
// 8 bits, hold at 6kHz, anti-aliased
crusher.setParams (8.0f, 6000.0f, false);
crusher.process (buffer);
// raw lo-fi: naive quantization and hold
crusher.setParams (8.0f, 6000.0f, true);
crusher.process (buffer);
// report crusher.getLatencySamples() to the host
Anti-aliased bitcrusher with independent bit depth and sample rate reduction.
Definition gin_bitcrusher.h:75
A lightweight 2D point class for projects that don't use juce_graphics.
Definition gin_point.h:25
See also
ValueSmoother, AirWindowsDistortion

Constructor & Destructor Documentation

◆ BitCrusher()

BitCrusher::BitCrusher ( int  maxChannels_ = 2,
int  maxBlockSize_ = 4096 
)

Member Function Documentation

◆ setSampleRate()

void BitCrusher::setSampleRate ( double  sr)

Sets the sample rate.

Resets the effect.

References reset(), setParams(), and ValueSmoother< T >::setSampleRate().

Referenced by BitCrusher().

◆ setParams()

void BitCrusher::setParams ( float  bitDepth,
float  rateHz,
bool  dirtyMode 
)

Sets the parameters.

Parameters
bitDepthBits of amplitude resolution (1 to 16)
rateHzTarget sample & hold rate in Hz. At or above the project rate the signal passes through unheld.
dirtyModetrue bypasses all anti-aliasing for the classic raw aliased sound

References ValueSmoother< T >::setValue().

Referenced by setSampleRate().

◆ reset()

void BitCrusher::reset ( )

Resets all internal state.

References ValueSmoother< T >::snapToValue().

Referenced by setSampleRate().

◆ getLatencySamples()

int BitCrusher::getLatencySamples ( ) const

Latency in samples for the current mode.

Zero in dirty mode, otherwise the oversampling filter latency plus one sample for the BLEP delay. Changes when dirty mode is toggled.

◆ process()

void BitCrusher::process ( juce::AudioSampleBuffer &  buffer)

Processes a buffer of audio.

Channels beyond maxChannels are left untouched. Buffers larger than maxBlockSize are processed in chunks.


The documentation for this class was generated from the following file: