2026-09-11 16:49:43 +02:00
|
|
|
# SM-26
|
|
|
|
|
|
2026-09-12 21:53:16 +02:00
|
|
|
A self-contained **subtractive synthesizer** written in modern C++ on top of
|
|
|
|
|
[JUCE](https://juce.com). It ships as a **VST3** on macOS and Linux plus a
|
|
|
|
|
macOS **Audio Unit**, with a hand-rolled DSP core, 52 factory presets and an
|
|
|
|
|
embedded 4x80 HD44780-style LCD driven by a cascaded on-screen menu.
|
2026-09-11 16:49:43 +02:00
|
|
|
|
2026-09-12 21:53:16 +02:00
|
|
|
## Why this is pretty good
|
|
|
|
|
|
|
|
|
|
* **One real dependency, always fetchable.** JUCE is the only external thing
|
|
|
|
|
this project needs, and the build fetches it automatically into `./build/`
|
|
|
|
|
on the first `make`. Your source tree stays clean: no vendored JUCE, no
|
|
|
|
|
submodules to go stale, no manual setup.
|
|
|
|
|
* **A tiny, readable DSP core with real character.** Twelve voices, two
|
|
|
|
|
oscillators with gliding, a self-oscillating state-variable filter with
|
|
|
|
|
drive, an ADSR, and a tempo-synced delay — all in one focused
|
|
|
|
|
`SynthEngine` with no external DSP libraries. Easy to read, easy to hack.
|
|
|
|
|
* **A UI people actually look at.** A 4x80 pixel LCD renderer with a real
|
|
|
|
|
menu (PRESETS / OSCILLATORS / FILTER / ENVELOPE / DELAY / SYSTEM) navigated
|
|
|
|
|
with a diamond of arrow keys plus ENTER/ESC. A DAW-native plugin that wears
|
|
|
|
|
its own little OS.
|
|
|
|
|
* **Knobs that mean something.** Four front-panel knobs that change meaning
|
|
|
|
|
per preset (`KnobView`) — every preset ships with a curated mapping and a
|
|
|
|
|
sensible value range, not just raw MIDI CCs.
|
|
|
|
|
* **Reproducible from a single command.** `make` = fetch JUCE → configure →
|
|
|
|
|
build → you're done. `make install` even ad-hoc-signs and un-quarantines
|
|
|
|
|
the macOS bundles so your DAW and `auval` accept them immediately.
|
|
|
|
|
|
|
|
|
|
## Features
|
|
|
|
|
|
|
|
|
|
* 12-voice polyphonic engine with voice stealing and glide
|
|
|
|
|
* 52 factory presets across Bass / Lead / Pad / Keys / Pluck / FX / Stab / Arp
|
|
|
|
|
* Dual-waveform oscillator section (sine / tri / saw / square / noise …)
|
|
|
|
|
* SVF low-pass filter with resonance **and** drive
|
|
|
|
|
* ADSR with a per-voice envelope and cutoff modulation
|
|
|
|
|
* Tempo-synced delay with rhythmic subdivision, locked to host BPM
|
|
|
|
|
* 4x80 LCD with live knob values, active preset, voice count and transport
|
|
|
|
|
* Footer that shows the exact git revision and build time
|
|
|
|
|
|
|
|
|
|
## Requirements
|
|
|
|
|
|
|
|
|
|
* C++17 compiler (Apple Clang or GCC)
|
|
|
|
|
* CMake >= 3.22
|
|
|
|
|
* Git (to fetch JUCE on the first build)
|
|
|
|
|
* Linux: X11/ALSA development headers
|
2026-09-11 16:49:43 +02:00
|
|
|
|
|
|
|
|
## Build
|
|
|
|
|
|
|
|
|
|
```sh
|
2026-09-12 21:53:16 +02:00
|
|
|
make # fetches JUCE into build/ (once), configures and builds
|
|
|
|
|
make install # installs + ad-hoc signs + un-quarantines the plugin bundles
|
2026-09-11 16:49:43 +02:00
|
|
|
make uninstall # removes the installed plugins
|
2026-09-12 21:53:16 +02:00
|
|
|
make clean # removes compiled artefacts only
|
|
|
|
|
make distclean # wipes build/ entirely (including the fetched JUCE)
|
2026-09-11 16:49:43 +02:00
|
|
|
```
|
|
|
|
|
|
2026-09-12 21:53:16 +02:00
|
|
|
* macOS installs to `~/Library/Audio/Plug-Ins/` (AU + **VST3**).
|
2026-09-11 16:49:43 +02:00
|
|
|
* Linux installs to `~/.vst3/`.
|
|
|
|
|
|
2026-09-12 21:53:16 +02:00
|
|
|
> Jumping straight into CMake also works: `cmake -S . -B build` builds a
|
|
|
|
|
> Release plugin and grabs JUCE from the same `build/juce` location.
|
|
|
|
|
|
2026-09-11 16:49:43 +02:00
|
|
|
If a freshly installed AU is not visible to `auval` / your DAW:
|
|
|
|
|
|
|
|
|
|
```sh
|
|
|
|
|
sudo killall -HUP coreaudiod
|
|
|
|
|
```
|
|
|
|
|
|
2026-09-12 21:53:16 +02:00
|
|
|
(or just restart the host).
|
|
|
|
|
|
2026-09-11 16:49:43 +02:00
|
|
|
## Usage
|
|
|
|
|
|
2026-09-12 21:53:16 +02:00
|
|
|
* Feed the plugin MIDI; the four front-panel knobs drive whichever parameters
|
|
|
|
|
the current preset maps them to (cutoff, resonance, envelope, delay — and a
|
|
|
|
|
wide range of other routings).
|
|
|
|
|
* Navigate with the **arrow diamond + ENTER/ESC**:
|
|
|
|
|
* root → PRESETS / OSCILLATORS / FILTER / ENVELOPE / DELAY / SYSTEM
|
|
|
|
|
* up/down move, left/right adjust, ENTER opens/confirms, ESC goes back
|
|
|
|
|
* The LCD shows the active preset, knob mappings with live values, host BPM
|
|
|
|
|
and voice count. The delay's SYNC mode locks to the host tempo and lets you
|
|
|
|
|
pick rhythmic subdivisions.
|
2026-09-11 16:49:43 +02:00
|
|
|
|
|
|
|
|
## Layout
|
|
|
|
|
|
|
|
|
|
```
|
2026-09-12 21:53:16 +02:00
|
|
|
Build: Makefile -> CMake -> JUCE (fetched into build/juce, never committed)
|
2026-09-11 16:49:43 +02:00
|
|
|
Source/
|
2026-09-12 21:53:16 +02:00
|
|
|
PluginProcessor.* audio processor + DSP shell
|
|
|
|
|
SynthEngine.* osc/filter/ADSR/delay voice engine (12 voices)
|
|
|
|
|
Presets.* 52 preset definitions + per-preset knob routings
|
|
|
|
|
SynthParams.* parameter model + formatting
|
|
|
|
|
PluginEditor.* panel, knobs, nav diamond, status footer
|
|
|
|
|
LcdDisplay.* 4x80 HD44780-style display renderer
|
|
|
|
|
MenuSystem.* cascaded menu state machine
|
|
|
|
|
tools/gen_buildinfo.sh generates git-revision + build-time header
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
Everything the project needs at build time lives under `./build/`, which is
|
|
|
|
|
git-ignored — the only things committed are your sources, this README and
|
|
|
|
|
the build glue.
|