CrispyZebra is a lightweight, high-performance C++ synthesizer core engine designed to replicate the Phase Distortion (PD) synthesis of the 1980s CZ-series synthesizers.
https://hugelton.github.io/CrispyZebra/wasm
The interactive WebAssembly (WASM) implementation with a full GUI is available.
The engine is structured within the CrispyZebra namespace:
Oscillator: The core Phase Distortion engine utilizing a custom Sine Look-Up Table (LUT) to warp phases dynamically.
Envelope: High-precision Q16 internal state envelope generator supporting up to 8 stages with rate/level configurations.LFO: Low-frequency oscillator providing Triangle, Square, Saw Up, and Saw Down shapes for pitch modulation.
Voice: A polyphonic container that couples two parallel lines (Oscillators) with routing, detuning, and modulation options.Engine<MaxVoices>: The template-driven master class that handles MIDI inputs (midiNoteOn / midiNoteOff) and renders block buffers. The default WebAssembly build intentionally uses Engine<8> in all line-select modes; two-line patches are not reduced to four voices.CrispyZebra is a single-header engine. Include CrispyZebra.h into your project.
#include "CrispyZebra.h"
// Prepare your Sine Look-Up Table
const int16_t my_sine_lut[2048] = { /* pre-calculated sine values */ };
// Instantiate the engine with 8-voice polyphony
CrispyZebra::Engine<8> synthEngine;
void initAudio() {
uint32_t sampleRate = 44100;
synthEngine.setup(my_sine_lut, 2048, sampleRate);
}
void processAudio(float* buffer, uint32_t numSamples) {
// Render stereo float samples directly into your audio callback
synthEngine.processBlock<float, true>(buffer, numSamples);
}
void onMidiEvent(uint8_t status, uint8_t note, uint8_t velocity) {
if (status == 0x90 && velocity > 0) {
synthEngine.midiNoteOn(note);
} else if (status == 0x80 || (status == 0x90 && velocity == 0)) {
synthEngine.midiNoteOff(note);
}
}
The WebAssembly build defaults to 44.1 kHz, but the default engine rate and the browser AudioContext request can be selected at build time:
cd wasm
make SAMPLE_RATE=48000
Browsers may still choose the hardware output rate, so the engine is initialized with the actual AudioContext.sampleRate after startup.
This project is licensed under the GNU General Public License v3.0 (GPL-3.0) - see the LICENSE file for details. Copyright (C) 2026 Leo Kuroshita (@kurogedelic)
CrispyZebra is an independent open-source project developed by Leo Kuroshita. It is not affiliated with, endorsed by, or associated with CASIO Computer Co., Ltd. in any way. “CZ-101”, “CZ-series”, and “Phase Distortion” are referenced solely for historical and educational compatibility purposes.