# RMX-19 - Super Sound Module (VST3 / AU) RMX-19 is a virtual synthesizer sound module, implemented as an audio plugin in C++ with JUCE. The plugin is a self-contained subtractive synth: two oscillators, a state-variable filter, dual envelopes, an LFO, a built-in FX unit (chorus / delay / space), and a factory patch bank - all edited and browsed through the on-screen LCD instead of a conventional panel of knobs. ## Screenshot ![RMX-19 screenshot](shot.png) --- ## Blueprint ![RMX-19 blueprint](blueprint.png) --- ## What it is at a glance | | | |---|---| | **Format** | VST3 and Audio Unit (AU) plugin | | **Transport** | Host JUCE-based AU / VST3 on macOS arm64 | | **Architecture** | Subtractive / virtual-analog synthesizer | | **UI model** | Simulated 19" rack module with a 160×64 dot-matrix LCD | | **Voice count** | 16-voice polyphonic engine (1–16 selectable) | | **Audio** | 24-bit/96 kHz capable; optional 2× HQ oversampling | | **MIDI** | Note on/off, aftertouch-style CCs, pitch wheel, sustain pedal | --- ## Feature overview ### Sound engine - **Two oscillators** per voice, each with five waveforms: sine, triangle, sawtooth, pulse, and noise. - **Oscillator mix** (blend between OSC1 and OSC2) and **detune** (in cents) for rich, thick unison-style stacking. - **State-variable filter** in the Chamberlin style with three modes: low-pass, band-pass, and high-pass, plus **cutoff**, **resonance**, **filter envelope amount**, and **key tracking**. - **Two ADSR envelopes**: one for the amplifier and one for the filter, each with independent attack / decay / sustain / release. - **One LFO** with rate, depth, and four selectable shapes (sine, triangle, square, sample-and-hold), routable to three targets: filter cutoff, pitch, or amplitude (tremolo). - **Portamento / glide** per patch, **master tune** (±12 semitones). - **Voice panning**: user pan plus a small per-voice random offset to spread the stereo image. ### Effects The FX unit is stacked **chorus** and **delay**, selectable via **FX TYPE**: - **OFF** - bypass. - **CHORUS** - modulated short delay (uses the FX time as a base). - **DELAY** - ping-pong-style feedback delay with a cross-feedback network. - **SPACE** - a combination of chorus + delay (widened stereo ambience). **FX DEPTH** sets the wet/dry mix; **FX TIME** sets the delay time in seconds when running free. Crucially, the delay can also be **quantized to the host tempo** (see below). #### Delay tempo sync The delay can be locked to your DAW's transport tempo. On the **FX** screen there is a fourth row labeled **SYNC** that chooses from these rhythmic divisions (values are multiplied against `60 / BPM` to derive the delay in seconds): | SYNC value | Music-notation equivalent | |------------|---------------------------| | `OFF` | free (use FX TIME in seconds) | | `1/16` | sixteenth note | | `1/8` | eighth note | | `1/8T` | eighth-note triplet | | `1/8D` | dotted eighth | | `1/4` | quarter note | | `1/4T` | quarter-note triplet | | `1/4D` | dotted quarter | | `1/2` | half note | | `3/4` | dotted half | | `1/1` | whole note | When a SYNC value other than `OFF` is selected, the FX TIME knob is ignored for the delay and the delay time follows the host tempo in real time. ### Factory patches RMX-19 ships with a hand-tuned bank of factory presets organized by category (POLY PAD, KEY, BASS, LEAD, and more). Patches are stored as parameter settings and can be recalled either from the LCD patch browser or from the DAW's own program list. --- ## The rack front panel (UI) The plugin looks like a 19" rack unit sitting in your DAW. The main elements: - **LCD display** - the green-on-black dot-matrix screen where all editing happens. - **Nav diamond** (`▲ ▼ ◀ ▶`) - move the cursor / change values. - **ENTER** and **BACK** - confirm a selection or return to the previous screen. - **UI scale** dropdown (bottom-right) - resize the whole rack anywhere from 50% to 300%. - A **power LED** and cosmetic backplate graphics round out the hardware illusion. You can also drive the whole interface with the keyboard: **arrow keys** for navigation, **Return / Space** for ENTER, and **Escape** for BACK. ### Using the LCD The interface is a small nested menu system: 1. **SPLASH** - the boot-up screen; press ENTER to continue. 2. **HOME** - shows the current patch number, name, category, and a live voice-activity bar. Use ◀/▶ (or ▲/▼) to step through patches. 3. **MENU** - eight destinations: `PATCH`, `VOICE`, `FILTER`, `ENVELOPE`, `LFO`, `FX`, `MASTER`, `ABOUT`. 4. **PATCH** - scroll through the factory bank; press ENTER to load the highlighted patch. 5. **VOICE / FILTER / ENVELOPE / LFO / FX / MASTER** - parameter screens. Highlight a row and use ◀/▶ to adjust it (defaults to fine steps). #### The parameter screens | Screen | Parameters | |--------|------------| | **VOICE** | OSC1 WAVE, OSC2 WAVE, COARSE TUNE 1, COARSE TUNE 2, DETUNE 1, DETUNE 2, OSC BAL | | **FILTER** | FILTER TYPE, CUTOFF, RESONANCE, FILT ENV, KEY TRACK | | **ENVELOPE** | AMP ATTACK, AMP DECAY, AMP SUSTAIN, AMP RELEASE, FENV ATTACK, FENV DECAY, FENV SUSTAIN, FENV RELEASE | | **LFO** | LFO RATE, LFO SHAPE, LFO DEPTH, LFO TARGET | | **FX** | FX TYPE, FX DEPTH, FX TIME, **SYNC** (delay tempo sync) | | **MASTER** | MASTER VOL, STEREO PAN, POLYPHONY, PORTAMENTO, MASTER TUNE, HQ MODE | > **Finding the delay sync.** On the **FX** screen the rows are FX TYPE, > FX DEPTH, FX TIME, and then a fourth row labeled **SYNC**. Press **DOWN** > three times from the top of the FX screen to reach it, then use **◀/▶** to > pick a rhythmic division (see the table above). ### About screen Shows the RMX-19 build: git branch / SHA / dirty marker, the build date/time, the JUCE version, and the target platform. The LCD **footer** also shows the git branch@commit and build timestamp on every screen. --- ## MIDI RMX-19 accepts MIDI input and maps the following messages: | MIDI | Action | |------|--------| | Note on / off | Play / release voices | | Pitch wheel | ±2 semitones, smoothed | | CC 64 | Sustain pedal (sustains held notes) | | CC 1 / 74 | Filter cutoff | | CC 2 / 71 | Filter resonance | | CC 3 / 76 | LFO rate | | CC 4 / 91 | FX depth | | CC 7 | Master volume | | CC 10 | Stereo pan | | CC 72 | Amp release | | CC 73 | Amp attack | | CC 77 | LFO depth | The plugin also exposes each patch as a DAW program, so preset changes from the host map onto the factory bank. --- ## DSP notes - **Voice engine** - each voice is a classic two-osc → mix → SVF filter → amp-envelope chain. The oscillator mix is a crossfade between OSC1 and OSC2, and each oscillator has its own tuning: a coarse tune in semitones (`2^(ctune/12)`) plus a fine detune in cents (`2^(detuneN/1200)`, DETUNE 1 → OSC1, DETUNE 2 → OSC2). - **Filter** - a stable Chamberlin state-variable filter; cutoff is modulated by the filter envelope, key tracking, the LFO, and the mod wheel, with a smoothed control signal to suppress zipper noise. - **Envelopes** - exponential ADSRs (attack/decay/release are time-domain tau-based approximations, sustain is a level). - **HQ mode** - a MASTER-screen toggle that renders the engine at **2× the host sample rate** internally, then downsamples, reducing alias artifacts at high cutoff / bright oscillators. - **Output stage** - per-sample `tanh` soft-clipping plus a DC-blocking filter, and a master volume gain. - **FX** - a modulated short delay (chorus) and a cross-feedback delay line (delay). The feedback delay supports host-tempo sync via the SYNC setting. Tail length is sized to fit the longest possible sync delay. --- ## Building from source ### Prerequisites macOS on Apple Silicon (arm64), macOS 12.0 or later: - CMake ≥ 3.22 - A C++17 compiler (Apple Clang via Xcode / Command Line Tools) - `git` (to fetch the JUCE framework) Linux: - CMake ≥ 3.22, a C++17 compiler (GCC or Clang), `git`, `pkg-config` - Development packages used by JUCE (Debian/Ubuntu): `libasound2-dev libx11-dev libxext-dev libxinerama-dev libxrandr-dev` `libxcursor-dev libxcomposite-dev libfreetype6-dev libfontconfig1-dev` `libgl1-mesa-dev` - No GTK/WebKit or libcurl packages are needed: the plug-in does not use the web browser, native file-chooser dialogs, ``, or networking (`JUCE_WEB_BROWSER=0`, `JUCE_USE_CURL=0`). The build fetches **JUCE 8.0.4** automatically into `build/JUCE` on first configure - no manual JUCE setup is required. ### Commands ```sh make # configure + build VST3 (and AU on macOS) make install # build + install (~/Library/Audio/Plug-Ins on macOS, ~/.vst3 on Linux) make uninstall # remove installed bundles make clean # delete the CMake build tree make info # print build paths ``` On Linux the AU format is skipped automatically; only the VST3 is produced, and `make install` copies it to `~/.vst3` (JUCE's default Linux VST3 scan path). A plain `cmake -S . -B build -DJUCE_ROOT= && cmake --build build --parallel` works on Linux as well. Both `make` and that command compile with all logical cores by default; override with `make JOBS=8`. `make` (configure) is designed to be cheap when nothing changed and refreshes the git branch/hash and timestamp embedded in the LCD footer on every configure, so the About screen always reflects the current source state. ### Notes - After `make install`, **restart (or cold-start) your DAW** so macOS rescans AudioComponents. A freshly-installed AU may not appear until the host is relaunched. - Installed bundles are ad-hoc code-signed; if your DAW refuses to load the AU, run `codesign --force --deep --sign - ` again or re-install. --- ## Project layout ``` CMakeLists.txt Build configuration (JUCE plugin target, git build info) Makefile Building / installing convenience wrapper b3.png Rack faceplate background image (embedded as binary data) Source/ PluginProcessor.cpp/.h Audio processor: MIDI, FX engine, patch I/O, state save/load PluginEditor.cpp/.h Rack front panel: buttons, scale dropdown, rendering LcdPanel.cpp/.h Dot-matrix LCD: all screens, navigation, glyph rendering SynthEngine.cpp/.h The voice / oscillator / filter / envelope DSP core Params.cpp/.h Parameter table, formatting, UI value stepping, delay sync names PresetBank.cpp/.h Factory patch definitions and bank lookup Probe.cpp Offline dev probe (scripted MIDI, no GUI/DAW) BuildInfo.h.in Compile-time git/timestamp template ``` ### Development probe `Source/Probe.cpp` is an offline executable (`rmx_probe`) used during development to drive the processor with scripted MIDI events without a DAW or GUI. It is defined in `CMakeLists.txt` for convenience and is not part of the shipped plugin. --- ## License / attribution RMX-19 is a personal / hobby project. It is built on the [JUCE](https://juce.com) audio framework under its own license. The rack hardware aesthetic pays tribute to classic 90s synthesizer rack gear; the plugin is an original implementation and is not affiliated with or endorsed by any hardware manufacturer.