Skip to content

Repository files navigation

DirektDSP Plugin Template

A production-ready JUCE audio plugin template with config-driven setup, modular architecture, comprehensive testing, and CI/CD infrastructure.

This repo plays two roles in the DirektDSP ecosystem:

  1. Shared SDK — sibling plugin repos (Churn, Polygraph, …) consume cmake/, cmake-local/, and modules/ via ../PluginTemplate (sibling checkout). CI here must stay green: every plugin build depends on these files.
  2. Scaffold source — new plugins are generated from scaffold/ (the tokenized copy-me tree) plus this repo's source/, tests/, benchmarks/.

Scaffold a new plugin

python3 scripts/new_plugin.py <Name> --plugin-code <Xxxx> \
    --description "..." --tagline "..."

Renders a complete sibling repo into ../<Name> — sibling-checkout CMake, house CI (lint → sanitizers → builds → pluginval/clapval → installers → Moonbase → GitHub release), Moonbase wiring, and the InstallerGenerator/plugins/<name>.toml manifest so the plugin is in the central installer factory + catalog from day one. See scaffold/README.md and the /new-plugin skill. CI runs scripts/new_plugin.py --check to keep the scaffold render-clean.

Quick Start (in-tree template build)

# Clone with submodules
git clone --recursive <your-repo-url>
cd PluginTemplate

# Or if already cloned:
./scripts/setup.sh

# Build
cmake --preset debug
cmake --build build/debug

# Test
ctest --preset debug

Configuration

Edit project.toml to configure your plugin:

[project]
name = "MyPlugin"
product_name = "My Plugin"
company_name = "MyCompany"
bundle_id = "com.mycompany.myplugin"
manufacturer_code = "Myco"
plugin_code = "MyPl"
version = "1.0.0"
formats = ["VST3", "AU", "CLAP", "Standalone"]

[modules]
melatonin = true
clap = true

[build]
cpp_standard = 20
copy_after_build = true

Project Structure

source/
  PluginProcessor.h/cpp   — Main audio processor with APVTS, state versioning
  PluginEditor.h/cpp      — Resizable GUI with level meters, parameter controls
  DSP/
    Core/ProcessorCore.h   — Template DSP scaffold (smoothing, wet/dry, bypass, metering)
    Utils/ParameterSmoother.h  — Exponential parameter smoothing
    Utils/DSPUtils.h       — dB↔gain, clipping, frequency clamping utilities
    Utils/MeteringFIFO.h   — Lock-free SPSC FIFO for audio→GUI metering
  Service/
    PresetManager.h/cpp    — Category-based presets, dirty detection, menu building
common/                    — Multi-plugin interfaces (IPluginProcessor, IPluginState, etc.)
tests/
  PluginBasics.cpp         — Smoke tests (name, buses, parameters, state)
  safety/AudioSafetyTests.cpp  — NaN, Inf, denormal, extreme input, buffer size tests
  daw/StatePersistenceTests.cpp — State roundtrip, DAW session simulation
  helpers/                 — DSPTestHelpers, TestSignalGenerators, test_helpers
benchmarks/
  Benchmarks.cpp           — processBlock benchmarks at various block sizes
cmake-local/
  Sanitizers.cmake         — ASan + UBSan + TSan toggles
  Packaging.cmake          — Cross-platform installer generation
  ModuleSystem.cmake       — Conditional module loading

CMake Presets

Preset Description
debug Debug build with compile_commands.json
release Optimized release build
relwithdebinfo Release with debug symbols
asan Debug + AddressSanitizer + UBSan
tsan Debug + ThreadSanitizer
cmake --preset asan
cmake --build build/asan
ctest --preset asan

Optional Modules

Toggle in project.toml or via CMake flags:

Module Flag Description
CLAP ENABLE_CLAP CLAP plugin format support
Melatonin Inspector ENABLE_MELATONIN Debug UI overlay
Moonbase ENABLE_MOONBASE DRM/licensing
DirektDSP GUI ENABLE_DIREKTDSP_GUI Config-driven GUI framework
Cycfi Q ENABLE_CYCFI_Q DSP library for pitch detection
Common Layer ENABLE_COMMON_LAYER Multi-plugin ecosystem interfaces

Architecture

DSP Pipeline

Input → [Input Gain Smoother] → [Your DSP Chain] → [Wet/Dry Mix] → [Output Gain] → [Bypass Crossfade] → Output
                                                                                          ↓
                                                                               [Lock-free Metering FIFO]
                                                                                          ↓
                                                                               [GUI Level Meters @ 30fps]
  • Parameter smoothing: Exponential smoothing with configurable time per parameter (1-5ms typical)
  • Update throttling: DSP components updated every 32 samples (not per-sample)
  • Bypass: Ramped crossfade (5ms) — no clicks, VST3 compliant
  • Denormals: ScopedNoDenormals in processBlock
  • Metering: Lock-free SPSC FIFO, no mutexes on audio thread

State Management

  • Schema versioning: stateSchemaVersion embedded in serialized state
  • Migration pattern: Check version on load, run migration functions for old states
  • Preset manager: Category-based file organization, dirty state detection

Testing Strategy

Category What it tests
[plugin] Instance creation, bus layouts, parameter existence
[state] State serialization, schema version, round-trip
[safety] NaN, Inf, denormals, extreme input, buffer sizes, sample rates
[daw] State persistence across instances, DAW session simulation
[benchmark] processBlock performance at various configurations

CI/CD

The GitHub Actions workflow runs:

  1. Build & Test on Linux, macOS, Windows
  2. Format Check via clang-format
  3. ASan + UBSan sanitizer build on Linux
  4. Artifact Upload of built plugin binaries

Adding Your DSP

  1. Subclass DSP::Core::ProcessorCore<float> or use it directly
  2. Override onPrepare(), onProcess(), onReset(), onUpdateDSPComponents()
  3. Add parameters to createParameterLayout() in PluginProcessor.cpp
  4. Read parameters in processBlock() and call updateParameters()
  5. Increment stateSchemaVersion when changing the parameter layout

License

See LICENSE file.

About

Extended Template for Plugin Development based on PampleJuce

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages

Generated from sudara/pamplejuce