mirror of
https://codeberg.org/armin/chromaflock.git
synced 2026-09-01 04:10:47 +02:00
209 lines
6.8 KiB
Markdown
209 lines
6.8 KiB
Markdown
|
|
# ChromaFlock
|
|||
|
|
|
|||
|
|
A subtractive synthesizer plugin built with [JUCE](https://juce.com). VST3, AU, and Standalone formats. macOS.
|
|||
|
|
|
|||
|
|
## Overview
|
|||
|
|
|
|||
|
|
ChromaFlock is a fully-featured subtractive synthesizer with dual oscillators, multi-mode filter, dual LFOs, two envelopes, and a complete effects chain. All DSP is custom - no external audio libraries. 55 automatable parameters, 16-voice polyphony, 27 built-in presets, and a real-time visual interface with waveform display, spectrum analyzer, VU meter, and interactive piano keyboard.
|
|||
|
|
|
|||
|
|
## Obligatory AI-slop disclaimer
|
|||
|
|
|
|||
|
|
Chromaflock is 99.5% vibe-coded (a.k.a. "ai slop"). If that's a problem for you, please
|
|||
|
|
kindly just use a different synthesizer. There is also absolutely *NO* guarantee this
|
|||
|
|
will work reliably, be useful in any way, or even make any sense whatsoever.
|
|||
|
|
|
|||
|
|
## Signal Flow
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
Osc1 + Osc2 → Amp Envelope × Velocity → Filter → Drive → Distortion → Compressor → Auto-Pan → Delay → Reverb → Output
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
## Oscillators
|
|||
|
|
|
|||
|
|
Two independent oscillators per voice, each with:
|
|||
|
|
|
|||
|
|
- **5 waveforms**: Sine, Saw, Square, Triangle, Noise
|
|||
|
|
- **Octave shift**: -3 to +3
|
|||
|
|
- **Semitone shift**: -12 to +12
|
|||
|
|
- **Fine tune**: ±100 cents
|
|||
|
|
- **Level**: 0.0 – 1.0
|
|||
|
|
- **Phase offset** (OSC 2): 0.0 – 1.0 for detuned/synced phase relationships
|
|||
|
|
- **Stereo panning**: Equal-power pan law per oscillator, summed additively
|
|||
|
|
|
|||
|
|
## Filter
|
|||
|
|
|
|||
|
|
TPT (Topology-Preserving Transform) SVF - stable, alias-free, modulation-friendly. Two independent filter instances per voice for proper L/R stereo processing.
|
|||
|
|
|
|||
|
|
- **5 types**: Low-Pass 12dB, Low-Pass 24dB, Band-Pass, High-Pass, Notch
|
|||
|
|
- **Cutoff**: 25 Hz – 20 kHz (logarithmic)
|
|||
|
|
- **Resonance**: 0.0 – 1.0
|
|||
|
|
- **Envelope amount**: Modulates cutoff via filter envelope (±4 octave range)
|
|||
|
|
- **Key tracking**: Cutoff follows pitch, 0% – 100%
|
|||
|
|
|
|||
|
|
## Envelopes
|
|||
|
|
|
|||
|
|
Two independent ADSR envelopes per voice - one for amplitude, one for filter modulation:
|
|||
|
|
|
|||
|
|
| Parameter | Range |
|
|||
|
|
|-----------|-------|
|
|||
|
|
| Attack | 0.001s – 5.0s (log) |
|
|||
|
|
| Decay | 0.001s – 5.0s (log) |
|
|||
|
|
| Sustain | 0.0 – 1.0 |
|
|||
|
|
| Release | 0.001s – 10.0s (log) |
|
|||
|
|
|
|||
|
|
Linear ramp shape. Both envelopes reset per-note.
|
|||
|
|
|
|||
|
|
## LFOs
|
|||
|
|
|
|||
|
|
Two independent LFOs per voice, each with:
|
|||
|
|
|
|||
|
|
- **4 shapes**: Sine, Triangle, Saw, Square
|
|||
|
|
- **Rate**: 0.05 Hz – 20 Hz (log)
|
|||
|
|
- **Depth**: 0.0 – 1.0
|
|||
|
|
- **4 destinations**: Filter Cutoff, OSC1 Pitch, OSC2 Pitch, Both OSCs
|
|||
|
|
- Phase resets on note-on
|
|||
|
|
- Pitch modulation range: ±12 semitones
|
|||
|
|
|
|||
|
|
## Effects Chain
|
|||
|
|
|
|||
|
|
All effects are stereo and processed in series after the synth voice.
|
|||
|
|
|
|||
|
|
### Distortion
|
|||
|
|
|
|||
|
|
- **4 types**: Soft Clip (tanh), Hard Clip, Foldback (wave-folding), Overdrive
|
|||
|
|
- **Amount**: 0.0 – 1.0 (drives input gain 1x – 10x)
|
|||
|
|
- **Mix** (dry/wet): 0.0 – 1.0
|
|||
|
|
- Bypassed when amount < 0.001
|
|||
|
|
|
|||
|
|
### Compressor
|
|||
|
|
|
|||
|
|
- **Threshold**: -60 dB – 0 dB
|
|||
|
|
- **Ratio**: 1:1 – 20:1
|
|||
|
|
- **Attack**: 0.1 ms – 100 ms
|
|||
|
|
- **Release**: 10 ms – 1000 ms
|
|||
|
|
- **Makeup gain**: 0 – 24 dB
|
|||
|
|
- **Mix** (dry/wet): 0.0 – 1.0
|
|||
|
|
- Feed-forward envelope detector with separate attack/release time constants
|
|||
|
|
|
|||
|
|
### Auto-Pan
|
|||
|
|
|
|||
|
|
- Sinusoidal LFO panning
|
|||
|
|
- **Rate**: 0.05 Hz – 20 Hz
|
|||
|
|
- **Depth**: 0.0 – 1.0
|
|||
|
|
- Bypassed when depth < 0.001
|
|||
|
|
|
|||
|
|
### Delay
|
|||
|
|
|
|||
|
|
- **Time**: 10 ms – 1000 ms
|
|||
|
|
- **Feedback**: 0.0 – 0.95
|
|||
|
|
- **Ping-pong mode**: Cross-channel feedback for bouncing stereo echoes
|
|||
|
|
- **Spread**: 0.25 – 0.75 (secondary tap time)
|
|||
|
|
- **Mix** (dry/wet): 0.0 – 1.0
|
|||
|
|
- Dual-tap mode when ping-pong is off (wider stereo image)
|
|||
|
|
|
|||
|
|
### Reverb
|
|||
|
|
|
|||
|
|
- **Room size**: 0.0 – 1.0
|
|||
|
|
- **Damping**: 0.0 – 1.0
|
|||
|
|
- **Mix** (wet/dry): 0.0 – 1.0
|
|||
|
|
- Fixed stereo width at 0.8
|
|||
|
|
|
|||
|
|
## Master
|
|||
|
|
|
|||
|
|
- **Pan**: Full left – Full right
|
|||
|
|
- **Drive**: 1x – 5x (tanh soft clipping per-voice, normalized)
|
|||
|
|
- **Master Level**: 0.0 – 1.0
|
|||
|
|
- **Pitch Bend Range**: 1 – 12 semitones
|
|||
|
|
|
|||
|
|
## Voices
|
|||
|
|
|
|||
|
|
- **16-voice polyphony**
|
|||
|
|
- Velocity-sensitive amplitude
|
|||
|
|
- Per-sample rendering for smooth modulation
|
|||
|
|
- Denormal protection (`ScopedNoDenormals`)
|
|||
|
|
- All 55 parameters pushed to all voices every block
|
|||
|
|
|
|||
|
|
## Presets
|
|||
|
|
|
|||
|
|
27 built-in presets across 7 categories:
|
|||
|
|
|
|||
|
|
| Category | Presets |
|
|||
|
|
|----------|---------|
|
|||
|
|
| Init | Init |
|
|||
|
|
| Bass | Sub Bass, Reese Bass, Acid Bass, Pluck Bass, Moog Bass, Gritty Bass, FM Bass |
|
|||
|
|
| Lead | Sync Lead, Square Lead, Soft Lead, Saw Lead |
|
|||
|
|
| Pad | Warm Pad, Glass Pad, Dark Pad, Shimmer Pad, Evolving Pad, Choir Pad |
|
|||
|
|
| Keys | Electric Piano, Organ, Clav, Rhodes, Bell Keys, Toy Piano |
|
|||
|
|
| FX1 | Wobble, Distorted Lead, Auto-Pan Spread, Filtered Noise |
|
|||
|
|
| FX2 | Dub Delay, Reverse Reverb, Laser Zap, Space Drone, Ring Mod, Glitch Stutter |
|
|||
|
|
|
|||
|
|
Preset menu accessible from the PRESET button (top-left). Each preset stores all 55 parameters.
|
|||
|
|
|
|||
|
|
## UI
|
|||
|
|
|
|||
|
|
Custom dark theme with gold accents. ~50 knobs across 9 sections.
|
|||
|
|
|
|||
|
|
### Sections
|
|||
|
|
|
|||
|
|
| Section | Controls |
|
|||
|
|
|---------|----------|
|
|||
|
|
| OSC 1 | Waveform selector, Octave, Semi, Fine, Level knobs |
|
|||
|
|
| OSC 2 | Waveform selector, Octave, Semi, Fine, Level, Phase knobs |
|
|||
|
|
| Filter | Type selector, Cutoff, Resonance, Env Amount, Key Tracking knobs |
|
|||
|
|
| AMP ENV | Attack, Decay, Sustain, Release knobs |
|
|||
|
|
| FILTER ENV | Attack, Decay, Sustain, Release knobs |
|
|||
|
|
| Master | Pan, Drive, Level, PB Range knobs |
|
|||
|
|
| Distortion | Type selector, Amount, Mix knobs |
|
|||
|
|
| Compressor | Threshold, Ratio, Attack, Release, Makeup, Mix knobs |
|
|||
|
|
| Auto-Pan | Rate, Depth knobs |
|
|||
|
|
| LFO 1/2 | Rate, Depth knobs, Shape and Destination selectors |
|
|||
|
|
| Delay | Time, Feedback, Mix knobs, Ping-Pong selector, Spread knob |
|
|||
|
|
| Reverb | Size, Damping, Mix knobs |
|
|||
|
|
|
|||
|
|
### Visualizers
|
|||
|
|
|
|||
|
|
- **VU meter**: RMS + peak level, green-to-red gradient, 30 fps
|
|||
|
|
- **Waveform display**: Real-time from 1024-sample ring buffer, green gradient, 30 fps
|
|||
|
|
- **Spectrum analyzer**: 2048-point FFT, 48-bar log frequency display, Hamming window, 30 fps
|
|||
|
|
- **Piano keyboard**: Interactive C3–C7 (49 keys), click/drag to play, gold highlight on press
|
|||
|
|
- **Pitch bend strip**: Vertical drag control on left side of keyboard, resets to center on release
|
|||
|
|
|
|||
|
|
### Scaling
|
|||
|
|
|
|||
|
|
UI scaling: 100%, 125%, 150%, 200% via dropdown (top-right). Window resizes proportionally.
|
|||
|
|
|
|||
|
|
## Parameters
|
|||
|
|
|
|||
|
|
55 total parameters, all DAW-automatable and saved with session state via APVTS XML serialization.
|
|||
|
|
|
|||
|
|
## Building
|
|||
|
|
|
|||
|
|
Requires JUCE (drop the framework into `./JUCE/`). Then:
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
make # Build Release (VST3/AU/Standalone)
|
|||
|
|
make debug # Build Debug
|
|||
|
|
make clean # Remove build directory
|
|||
|
|
make rebuild # Clean + build
|
|||
|
|
make run # Build and launch Standalone app
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
Or directly with CMake:
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
cmake -B build -DCMAKE_BUILD_TYPE=Release
|
|||
|
|
cmake --build build --config Release -j8
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
Output: `build/ChromaFlock_artefacts/Release/VST3/ChromaFlock.vst3`
|
|||
|
|
|
|||
|
|
Plugins auto-copy to system folders (`~/Library/Audio/Plug-Ins/`) after build.
|
|||
|
|
|
|||
|
|
## Tech
|
|||
|
|
|
|||
|
|
- **Language**: C++17
|
|||
|
|
- **Framework**: JUCE 8
|
|||
|
|
- **DSP**: All custom - no external audio libs
|
|||
|
|
- **Filter**: TPT SVF (Topology-Preserving Transform State Variable Filter)
|
|||
|
|
- **Build**: CMake + Makefile wrapper
|
|||
|
|
- **Platform**: macOS
|