01 // EFFECT PLUGIN
MASKERAD-8 BITCRUSHER
A simple lo-fi downsampler + bitcrusher with an 8-bit GUI. Crush bits (16→1), hold samples (x1→x32), add drive, filter the top off. Runs 100% in your browser — no upload.
- BIT DEPTH 1–16
- DOWNSAMPLE x1–x32
- 8 PRESET CARTRIDGES
- VST3 CODE INCLUDED
MASKERAD-8 // BITCRUSHER V1.0
48KHZ INSIDE
○ STANDBY○ BYPASS
LVL
BIT 16DS x1~48000 HZMIX 0%
* press POWER or PLAY DEMO to boot the audio engine. sound stays on your device.
01 BIT DEPTH8
02 DOWNSAMPLE4x
03 DRIVE2
04 MIX100%
05 TONE (LP)12000HZ
06 VOLUME80%
▼ PRESET CARTRIDGE — TAP TO LOAD
IN: NONE (IDLE)DSP: Tanh(DRV) → HOLD xN → Q(BIT) → LP → OUT
01 — Play
Hit PLAY DEMO for a chiptune loop, LOAD FILE for your own sample, or USE MIC for live crush.
02 — Crush
Lower BIT for grit, raise DOWNSAMPLE for aliasing, push DRIVE for saturation, roll TONE to dull.
03 — Use it
POWER = true bypass. Below is the same DSP as JUCE C++ — paste into a JUCE project to build a real .vst3.
▸ Real VST3? Copy the JUCE C++ DSP
// MASKERAD-8 — minimal JUCE bitcrusher (drop into a JUCE AudioProcessor)
// Params: bitDepth (1..16), downsample (1..32), drive (1..10), mix (0..1)
class Maskerad8DSP {
public:
void prepare(double sr) { sampleRate = sr; reset(); }
void reset() { holdL = holdR = 0.0f; counter = 0; }
void process(juce::AudioBuffer<float>& buf,
float bits, int ds, float drive, float mix) {
const int N = std::max(1, ds);
const float levels = std::pow(2.0f, juce::jlimit(1.0f, 16.0f, bits) - 1.0f);
auto crush = [&](float x) {
float d = std::tanh(x * drive); // drive / saturation
if (bits >= 16.0f) return d;
return juce::jlimit(-1.0f, 1.0f,
std::round(d * levels) / levels); // bit quantize
};
for (int ch = 0; ch < buf.getNumChannels(); ++ch) {
auto* data = buf.getWritePointer(ch);
for (int i = 0; i < buf.getNumSamples(); ++i) {
float dry = data[i];
if (ch == 0 ? (counter % N == 0) : false) holdL = crush(dry);
if (ch == 1 ? (counter % N == 0) : false) holdR = crush(dry);
if (buf.getNumChannels() == 1 && counter % N == 0) holdL = crush(dry);
float wet = (ch == 0 ? holdL : holdR);
data[i] = dry * (1.0f - mix) + wet * mix; // downsample via hold
if (ch == 0) counter++;
}
}
}
private:
double sampleRate = 48000.0;
float holdL = 0, holdR = 0;
int counter = 0;
};