← Back to Portfolio LuvNote →

πŸŽ›οΈ SingleGrain

JUCE / C++ • Commercial Granular Synthesizer VST3/AU Plugin

Published on MuseHub — view the full product page and demo videos

View Product Page →

Quick Navigation

✨ Feature Demonstrations

Granular Synthesis Engine

The core of SingleGrain is a polyphonic grain-based playback engine. It supports up to 16 simultaneous voices with intelligent voice stealing, precise grain envelope control, forward and reverse playback, and a Lock Pos mode for rhythmic loop effects. Every grain transition is click-free by enforcing mandatory envelope crossfades.
C++ JUCE AudioProcessor Linear Interpolation Envelope DSP

Engine Capabilities

  1. MIDI note-on triggers a new grain voice; pitch ratio pre-computed on note-on to avoid per-sample std::pow
  2. Grain envelope applies attack β†’ sustain β†’ decay with 2ms minimum crossfade to prevent audio clicks
  3. Forward or reverse playback selectable per-instance; Lock Pos freezes the grain start position for repeating rhythmic loops
  4. Force Mono mode limits to one active voice with crossfade stealing β€” ideal for monophonic lead lines
  5. Sub-sample accuracy achieved via linear interpolation between adjacent sample frames
  6. 16-voice polyphony with LRU voice stealing when the voice pool is exhausted
Each grain tracks its own envelope state machine (Attack / Sustain / Decay / Idle) and grain position independently. All 16 grain buffers are summed in the audio thread processBlock call, keeping the hot path branchless and cache-friendly.

3-LFO System with Custom Wavetable Editor

Three fully independent LFOs each offer three operating modes, five built-in waveforms, BPM host sync with 24 divisions, and a 256-sample point-based curve editor for drawing completely custom waveforms β€” all visualized in real-time with phase and output indicators.
Wavetable Synthesis Atomic Double-Buffering JUCE AudioPlayHead C++ DSP

LFO Modes

  1. Off β€” Free-running continuous oscillation, ignores MIDI
  2. Env β€” MIDI-triggered one-shot envelope; retriggers on each new note
  3. Sync β€” MIDI-triggered looping oscillation synced to host BPM; supports triplet and dotted note divisions

Custom Wavetable Flow

  1. User places up to N control points on the LFO curve editor canvas
  2. Hermite spline interpolation fills the 256-sample lookup table from the control points
  3. New table written to the back buffer, then atomic pointer swap makes it live β€” zero audio-thread locks
  4. Real-time visualization shows current phase position and output value on the LFO display
LFO tables use an atomic double-buffer pattern: the UI thread writes to the inactive buffer, then swaps the active pointer atomically. The audio thread always reads from the current active pointer without ever acquiring a lock.

32-Slot Modulation Matrix

A sophisticated 32-slot modulation matrix routes any of 11 sources (3 LFOs + 8 macros) to any of 25+ destinations. Each slot supports bipolar modulation amounts, an auxiliary source for complex chained modulation, direction modes, and a scalar multiplier. Knobs display active mod sources as Serum 2-style arcs with drag-to-assign from the matrix panel.
JUCE APVTS C++ Custom Knob Components Per-Block Caching

Modulation Assignment Flow

  1. User drags from an LFO or macro source onto any knob on the UI
  2. A mod slot is automatically created and highlighted in the matrix panel
  3. Amount is adjusted via the slot's bipolar amount knob (βˆ’1.0 to +1.0)
  4. Optional auxiliary source added for multiplicative modulation chaining
  5. Direction mode set: Default/Bipolar, Split (separate + and βˆ’ ranges), Up, or Down
  6. Knob displays a colored arc overlay showing total modulation contribution
Mod slot parameters live in the AudioProcessorValueTreeState. At the start of each processBlock, all 32 slots are read once into a local cache array β€” avoiding per-sample tree lookups on the audio thread. LFO depth can itself be a modulation destination, enabling LFO-modulates-LFO-depth patch architectures.

SSB Frequency Shifting

SingleGrain implements Single-Sideband (SSB) frequency shifting using an IIR-based Hilbert transformer approximation β€” four cascaded all-pass stages per channel β€” producing artifact-free pitch shifting that preserves the harmonic relationships between partials rather than stretching them like a pitch shifter would.
IIR Hilbert Transformer SSB Modulation Complex DSP (C++) Hysteresis Gate

SSB Shift Signal Path

  1. Input audio split into in-phase (xI) and quadrature (xQ) paths via 4-stage IIR all-pass filters
  2. Complex exponential oscillator generates cos(Ο‰t) and sin(Ο‰t) at the shift frequency
  3. SSB output: xIΒ·cos(Ο‰t) βˆ’ xQΒ·sin(Ο‰t) β†’ shifts all partials by a fixed Hz offset
  4. Hysteresis gate engages shifting when |Hz| > 1.5, disengages when |Hz| < 0.5 β€” prevents click artifacts when modulation crosses 0 Hz
Unlike pitch shifting (which multiplies all frequencies by a ratio), SSB shifting adds a constant Hz offset to every partial. This produces inharmonic textures when applied heavily β€” a distinctive sound useful for metallic pads and evolving atmospheres. Three shift ranges are offered: Β±500 Hz, Β±2000 Hz, and Β±5000 Hz.

BPM-Synced Grain Scheduling

Grains can be synchronized precisely to the host DAW's BPM using 24 selectable note divisions from 1/32 to 4/1, including triplet and dotted variants. An equal knob-travel spacing algorithm ensures consistent feel across all tempo ranges, and grain handoff logic prevents audible cuts when the division parameter changes mid-grain.
JUCE AudioPlayHead C++ BPM Sync Logic Division Retrigger

Sync Flow

  1. Host BPM read each processBlock via AudioPlayHead::getCurrentPosition
  2. Selected division (e.g. 1/8T) converted to samples: (60 / BPM) Γ— divisionRatio Γ— sampleRate
  3. Grain retrigger counter counts down in samples; at zero a new grain begins
  4. On division change mid-grain: smooth decay applied to current grain, new grain starts at next zero crossing
  5. BPM alert banner appears in the plugin UI when loaded preset BPM differs from host by more than a threshold
The 24 division values are mapped to equal knob-travel positions using a non-linear index β†’ value mapping. This means the user gets consistent resolution across musical time divisions rather than the divisions being crowded at one end of the knob range. Wall-clock retrigger is used for synced grains; independent grain index retrigger for unsynced mode.

Professional Plugin Infrastructure

Beyond DSP, SingleGrain ships as a polished commercial product: a full preset system with embedded or external sample references, serial-based license activation via MuseDRM, an interactive tutorial overlay system, in-app sample recording and normalization, drag-and-drop file loading, and undo/redo support throughout.
JUCE APVTS MuseDRM / MuseHub JUCE BinaryData Custom Tutorial System

Commercial Features

  1. Preset save/load via XML serialization of the full ValueTree state β€” samples embedded as base64 or referenced by path
  2. Serial activation checked on plugin load; MuseDRM wrapping for MuseHub distribution
  3. Tutorial overlay highlights UI elements step-by-step with animated callouts
  4. Sample recorder: arm β†’ record β†’ auto-trim silence β†’ normalize β†’ save to samples folder
  5. Drag-and-drop loading of arbitrary audio files from the OS file system
  6. Full undo/redo stack via JUCE UndoManager for all parameter changes
Factory samples and SVG assets are embedded directly into the plugin binary at compile time via a PowerShell pre-build script that generates FactoryContentData.cpp/h. This eliminates external file dependencies and makes the VST3 truly self-contained on install.

πŸ“‹ Professional Summary

Commercial Granular Synthesizer β€” JUCE / C++ / VST3 / AU SingleGrain is a commercially released granular synthesizer VST3/AU plugin built entirely in C++ using the JUCE framework. It is distributed on MuseHub under the LuvNote LLC brand and targets professional music producers, sound designers, and composers working in any major DAW on Windows and macOS.

The plugin's DSP core implements from-scratch granular synthesis (16-voice polyphonic), an IIR Hilbert transformer-based SSB frequency shifter, a three-LFO system with atomic double-buffered custom wavetables, and a 32-slot modulation matrix with per-block parameter caching. All audio-thread code is lock-free β€” LFO table swaps use atomic pointer exchange, and UI updates flow through JUCE's thread-safe message queue.

On the product side, SingleGrain ships with a serial-based license activation system (MuseDRM), factory content embedded directly in the binary at build time, a full preset manager, interactive tutorial overlay, and in-app sample recording. The result is a production-grade plugin that demonstrates deep expertise in real-time audio DSP, lock-free concurrent systems, plugin UX design, and C++ performance engineering.

🎯 Most Marketable Skills

Audio DSP

  • Granular synthesis (16-voice polyphonic)
  • SSB frequency shifting (IIR Hilbert)
  • Wavetable LFO synthesis (256-sample)
  • Envelope DSP with click-free crossfades
  • Linear interpolation (sub-sample precision)

JUCE / C++ Architecture

  • JUCE AudioProcessorValueTreeState
  • Lock-free atomics (double-buffer LFO tables)
  • Per-block parameter caching (mod matrix)
  • AudioPlayHead BPM sync
  • BinaryData pre-build asset embedding

Plugin UX Engineering

  • 32-slot modulation matrix UI
  • Serum 2-style drag-to-assign mod arcs
  • Custom 256-point wavetable curve editor
  • Real-time LFO phase visualization
  • Interactive tutorial overlay system

Commercial Release

  • MuseHub / MuseDRM license integration
  • Serial activation system
  • Self-contained binary (embedded assets)
  • Preset manager (XML / ValueTree)
  • Cross-platform: VST3 (Win/Mac) + AU (Mac)

πŸ—οΈ Architecture

DSP Engine

  • PluginProcessor.cpp
  • 16-voice grain pool
  • SSB frequency shifter
  • Grain envelope state machines
  • Linear interpolation playback

Modulation System

  • 3Γ— wavetable LFOs
  • 32-slot mod matrix
  • 8 macro controllers
  • Atomic double-buffer tables
  • Per-block slot cache

UI Framework

  • PluginEditor.cpp (JUCE)
  • Custom mod-arc knobs
  • Wavetable curve editor
  • LFO phase visualizer
  • Tutorial overlay system

Parameter Architecture

  • AudioProcessorValueTreeState
  • UndoManager (full undo/redo)
  • XML preset serialization
  • Atomic visualization data
  • Raw pointer param caching

Build & Distribution

  • JUCE 8.x + CMakeLists.txt
  • VS2022 + macOS CI builds
  • PowerShell asset pre-build
  • MuseDRM wrapping
  • VST3 + AU targets

πŸ† Key Achievements

🎡

Commercial MuseHub Release

Shipped a fully licensed, commercially distributed VST3/AU plugin on MuseHub with serial activation, MuseDRM wrapping, and a royalty-free perpetual license model.

πŸ”¬

SSB Frequency Shifting

Implemented Single-Sideband shifting from scratch: IIR Hilbert transformer, complex exponential oscillator, and hysteresis gate for artifact-free frequency offsetting.

🎚️

32-Slot Modulation Matrix

Full modulation routing with 3 LFOs + 8 macros, 25+ destinations, drag-to-assign UI arcs, aux chaining, and direction modes β€” with zero audio-thread lock contention.

⚑

Lock-Free Audio Thread

LFO wavetable updates via atomic pointer swap, mod matrix parameters cached per-block, and visualization data passed to UI via atomic reads β€” no mutexes on the audio thread.

✏️

Custom Wavetable Editor

256-sample per-LFO wavetable drawn with a point-based curve editor, filled via Hermite spline interpolation, and swapped live into the audio engine without a gap in sound.

🎸

BPM-Synced Scheduling

24 host-sync divisions with triplet/dotted variants, equal knob-travel spacing, and smooth grain handoff on division changes β€” no audible cuts mid-grain.

βš™οΈ Full Tech Stack

C++ JUCE 8.x VST3 Audio Units (AU) Granular Synthesis SSB Frequency Shifting IIR Hilbert Transformer Wavetable LFO Modulation Matrix JUCE APVTS Lock-Free Atomics AudioPlayHead MuseDRM / MuseHub CMakeLists.txt Visual Studio 2022 PowerShell Build Scripts BinaryData Embedding UndoManager
← Back to Portfolio