DSPark 1.6.1
Header-only audio DSP framework in pure C++20 β€” zero dependencies
Loading...
Searching...
No Matches
DSPark

DSPark - A header-only audio DSP framework in pure C++20

v1.6.1 β€” 90+ headers of professional audio DSP: filters, dynamics, reverbs, physically-modeled analog (tape, tube, transformer), pitch, spectral tools, EBU-verified metering. One #include, the same code on every target β€” desktop apps, WebAssembly, mobile, embedded, offline tools, and native VST3/CLAP/AU plugins (effects and MIDI instruments) with HTML/CSS/JS editors.

πŸ“– Full API documentation: cristianmoresi.github.io/DSPark

CI runs a 630-case test suite and the public conformance suite on every commit across Windows (MSVC, x64 and ARM64), Linux (GCC + Clang, x64 and ARM64), macOS (ARM64) and WebAssembly (Emscripten), plus AddressSanitizer/UBSan, an exceptions-free embedded profile and a single-header amalgamation. Loudness is validated against the official EBU R128 test vectors, and a per-processor quality metrics table (THD+N, noise floor, spurious/aliasing, latency) is generated from the measurements.

#include "DSPark/DSPark.h"
eq.prepare(spec);
comp.prepare(spec);
reverb.prepare(spec);
eq.setBand(0, 100.0f, 3.0f); // Boost bass
comp.setThreshold(-18.0f); // Compress
eq.processBlock(buffer);
comp.processBlock(buffer);
reverb.processBlock(buffer);
Single-include umbrella header for the DSPark framework.
16-line FDN reverb with Jot absorption and 6 presets.
void setType(Type type) noexcept
void processBlock(AudioBufferView< T > buffer) noexcept
Processes an audio block in-place with zero allocations.
void prepare(const AudioSpec &spec)
Prepares the reverberation engine and allocates required memory.
High-fidelity modular compressor designed for real-time applications.
Definition Compressor.h:88
void setThreshold(T dB) noexcept
Sets the compression threshold in dB.
Definition Compressor.h:494
void prepare(const AudioSpec &spec)
Allocates buffers and initializes internal DSP state.
Definition Compressor.h:190
void setCharacter(Character type) noexcept
Changes ballistics and envelope behavior character.
Definition Compressor.h:658
void processBlock(AudioBufferView< T > buffer) noexcept
Processes an audio buffer in-place using its own signal as the sidechain.
Definition Compressor.h:262
Parametric multi-band EQ using cascaded biquads or FFT overlap-save convolution.
Definition Equalizer.h:57
void setBand(int index, T frequency, T gainDb)
Configures a band with frequency and gain (Peak filter).
Definition Equalizer.h:276
void prepare(const AudioSpec &spec)
Prepares all bands and allocates necessary resources for processing.
Definition Equalizer.h:108
void processBlock(AudioBufferView< T > buffer) noexcept
Processes an audio buffer in-place.
Definition Equalizer.h:174

No build system. No linking. No configuration. Just include and go.


Why DSPark

Most audio DSP libraries fall into two categories: either they require a massive framework dependency, or they cover only a narrow slice of what you need. Nothing gives you everything in a single, portable, dependency-free package.

DSPark was built to change that. Whether you are:

  • A software developer adding audio features to an app (zero DSP knowledge required)
  • A mixing engineer or sound technician building custom plugins and tools
  • A DSP engineer designing professional audio processors or embedded systems

You get the same framework, the same headers, the same API. The difference is how deep you go.

Progressive Disclosure API

Every processor exposes three levels of complexity:

// Level 1 β€” Just works:
eq.setBand(0, 1000.0f, -3.0f);
// Level 2 β€” More control:
eq.setBand(0, 1000.0f, -3.0f, 1.5f); // Adds Q factor
// Level 3 β€” Full control:
eq.setBand(0, { .frequency = 1000, .gain = -3, .q = 1.5,
.type = BandType::LowShelf, .slope = 24 });

You never see complexity you don't need. But it's always there when you do.

Extensible by Design

Effect classes expose protected internals so you can subclass them directly to reach the delay lines, filters and early reflections inside. They are deliberately leaf classes with non-virtual destructors β€” honouring the zero-virtual-dispatch design β€” so you extend by direct inheritance and composition rather than polymorphic base-pointer deletion:

class MyReverb : public dspark::AlgorithmicReverb<float> {
// Access FDN delay lines, absorption filters, early reflections...
// Add custom processing stages, expose your own presets
};

What's Included

Effects (36 processors)

Class Description
Equalizer<T> Multi-band parametric EQ with linear-phase (FFT) and IIR modes
Compressor<T> Modular: 5 detectors (Peak, RMS, TruePeak, SplitPolarity, Hilbert), 2 topologies (FF/FB), 4 characters (Clean/Opto/FET/Varimu), upward/downward modes. Hold and range controls, adaptive auto-makeup gain, external sidechain.
Limiter<T> ISP true-peak brickwall limiter with adaptive release
NoiseGate<T> State machine with hysteresis, hold time, duck mode. External sidechain.
Expander<T> Downward expander with threshold, ratio, hold, range
DynamicEQ<T> Frequency-selective dynamics (above/below threshold, dual-action)
MultibandCompressor<T> Crossover + per-band Compressor, configurable up to 12 bands (compile-time MaxBands)
TransientDesigner<T> Attack/sustain shaping via envelope following
DeEsser<T> Frequency-targeted dynamic reduction for sibilance
AlgorithmicReverb<T> 16-line FDN with Jot (1991) frequency-dependent absorption, Householder feedback mixing, Lexicon-style smooth random + noise modulation, serial allpass per line (Infinity2-style), feedback IIR smoothing (Verbity), allpass-interpolated modulated reads, tanh soft saturation, parallel allpass input diffuser (256 echo paths), Dattorro multi-tap output, output diffusion, M/S stereo width control, progressive ER absorption. 6 presets: Room, Hall, Chamber, Plate, Spring, Cathedral. Full parameter API for custom reverb design.
Reverb<T> Convolution reverb with IR loading, pre-delay, auto-resample
Saturation<T> 10 algorithms (Tube, Tape, Transformer, SoftClip, HardClip, Exciter, Wavefolder, Bitcrusher, Downsample, MultiStage). Adaptive blend, slew-dependent saturation, oversampling.
Clipper<T> 4-mode clipper (Hard/Soft/Analog/GoldenRatio), multi-stage, slew limiter, up to 16x oversampling
FilterEngine<T> Cascaded biquads, 9 shapes, 6–48 dB/oct slopes
CrossoverFilter<T> Linkwitz-Riley crossover (LR12/24/48), IIR + linear-phase modes
Chorus<T> Multi-voice LFO delay, stereo spread, flanger mode
Phaser<T> Allpass chain with LFO modulation, configurable stages, stereo LFO spread
Tremolo<T> Amplitude modulation with configurable LFO
Vibrato<T> Pitch modulation via modulated delay
RingModulator<T> Ring modulation with carrier oscillator
FrequencyShifter<T> Single-sideband frequency shift via Hilbert transform
Delay<T> Interpolated delay with feedback (clean or analog tanh regeneration), ping-pong, filters
Panner<T> 6 algorithms: equal-power, binaural (ITD), mid-pan, side-pan, Haas, spectral
Gain<T> Smoothed gain with fade, mute, polarity inversion
AutoGain<T> Automatic gain compensation based on loudness measurement
Crossfade<T> Linear, equal-power, S-curve
StereoWidth<T> M/S width control with bass-mono option
MidSide<T> Stereo Mid/Side encoding and decoding
NoiseGenerator<T> White, pink, and brown noise generation
DCBlocker<T> DC offset removal (1-pole or Butterworth order 2–10)
TapeMachine<T> Physical tape model: Jiles-Atherton hysteresis at 2x oversampling, NAB/CCIR record/play EQ with exact digital inverses, speed-dependent head-gap/spacing/thickness loss, head bump, common-transport wow & flutter
TubePreamp<T> Koren triode stages (12AX7) solved per sample with Newton-Raphson, exact Fender FMV tone stack as a Wave Digital R-type network, power-supply sag
TransformerModel<T> Audio transformer coloration: flux-domain Jiles-Atherton core (distortion rises as frequency falls β€” the LF "bloom"), magnetizing-inductance corner, HF resonance bell
PitchShifter<T> Phase vocoder with identity phase locking (Laroche-Dolson), exact tuning, transient phase reset, formant preservation (cepstral lift), stereo-coherent
GranularProcessor<T> 64-grain clouds over live input: per-grain pitch/pan/jitter, freeze, equal-power spread
SpectralDenoiser<T> Learnable-noise-profile spectral gating with the standard musical-noise defenses

Core (40 building blocks)

Class Description
StateVariableFilter<T> TPT SVF: 8 modes (LP/HP/BP/Notch/AP/Bell/LowShelf/HighShelf), simultaneous multi-output
LadderFilter<T> Moog-style 4-pole TPT filter, 6 modes, drive, self-oscillation
Biquad<T> TDF-II biquad with 9 coefficient types and lock-free auto-promote of staged coefficients; the filter core is double whatever T is, so a corner far below the sample rate keeps its poles where they were designed
BiquadCoeffs Standalone factory for biquad coefficients (LP, HP, BP, Peak, Shelf, Notch, AP, Tilt), always double
FFTComplex<T> / FFTReal<T> Radix-2 FFT with SIMD (SSE3/NEON), real-optimised
Convolver<T> Partitioned overlap-save FFT convolution
ZeroLatencyConvolver<T> Gardner non-uniform partitioning: zero-latency convolution with time-distributed tail FFTs (flat CPU even for second-long IRs)
wdf::* (WDF.h) Wave Digital Filter circuit toolkit: R/L/C leaves, series/parallel adaptors, Newton-Raphson diode roots with analytic seeds, and an R-type adaptor (MNA-derived scattering) for non-adaptable topologies
Hysteresis<T> Jiles-Atherton magnetic hysteresis with implicit trapezoidal Newton-Raphson solver (tape, transformers)
ModulationRouter<T> Block-rate modulation routing: any source callable to any parameter setter, with depth and smoothing
StateWriter/StateReader Versioned key/value preset blobs + JSON helpers β€” every effect implements getState()/setState()
FIRFilter<T> FIR engine with windowed-sinc design
Oversampling<T> 2x–16x polyphase half-band Kaiser filters (-80 dB+ rejection), transparent up/down round-trip, exact reported latency
Oscillator<T> PolyBLEP (sine, saw, square, triangle)
WavetableOscillator<T> Mipmapped wavetable with bandlimited harmonics
Resampler<T> Polyphase windowed-sinc sample-rate conversion
EnvelopeGenerator<T> (ADSREnvelope) ADSR with exponential curves
RingBuffer<T> Power-of-two circular buffer with interpolated read
SmoothedValue<T> Parameter smoother (exponential, linear, chase, or disabled)
Smoothers 9 smoothing algorithms (linear, exponential, one-pole, asymmetric, slew, SVF, Butterworth…)
ProcessorChain<T,...> Zero-overhead compile-time processor chain with per-slot bypass
SpectralProcessor<T> STFT-based analysis-modification-synthesis framework
Dither<T> TPDF dithering with noise shaping
DenormalGuard RAII FTZ/DAZ (x86 SSE, ARM, WebAssembly)
Interpolation 5 methods (linear, cubic, Hermite, Lagrange, allpass)
Hilbert<T> FIR (windowed-sinc) Hilbert transform for analytic signals β€” flat magnitude across the audible band
WindowFunctions<T> 8 windows (Hann, Hamming, Blackman, Kaiser…)
DryWetMixer<T> Parallel dry/wet mixing for effects
TruePeakDetector<T> Shared ITU-R BS.1770-4 inter-sample peak detector (used by Compressor, Limiter, LoudnessMeter)
SpinLock RT-safe spinlock for thread-safe parameters
SpscQueue<T> Lock-free single-producer / single-consumer queue
AudioSpec Audio environment descriptor (sample rate, block size, channels)
AudioBuffer<T> 32-byte aligned owning buffer (SIMD-ready)
AudioBufferView<T> Non-owning view (what processors receive)
SimdOps SIMD-accelerated buffer operations (SSE2/AVX/NEON with scalar fallback)
DspMath Constants, dB ⇄ gain, fast tanh / tan / sin / cos / exp / log / pow10, range mapping
Phasor<T> Phase accumulator for LFO and oscillator construction
SampleAndHold<T> Sample-and-hold with configurable hold time
WaveshapeTable<T> LUT-based waveshaping with linear / cubic interpolation
AnalogRandom Analog-flavoured random generators (smooth, noise, jitter)
AnalogConstants Reference constants from analog-hardware research (zero runtime cost)
ProcessorTraits C++20 concepts: AudioProcessor, SampleProcessor, GeneratorProcessor

Analysis (9 analyzers)

Class Description
LevelFollower<T> Peak and RMS envelope follower
EnvelopeFollower<T> Public attack/release detector (Peak or RMS law) for sidechains, modulation and metering
SpectrumAnalyzer<T> Real-time FFT spectrum with peak hold
LoudnessMeter<T> EBU R128: momentary, short-term, integrated, LRA, true peak β€” passes the official EBU test vectors (Tech 3341/3342, BS.1770-5 K-weighting and true-peak interpolator)
Goertzel<T> Single-frequency O(N) magnitude detection
PitchDetector<T> YIN pitch detection with FFT-accelerated difference function (O(N log N))
PitchFollower<T> Musical pitch tracking source: confidence gating, octave-jump correction, constant-rate semitone glide
PhaseCorrelation<T> Stereo correlation/balance meter with a goniometer (vectorscope) point feed
OnsetDetector<T> Causal SuperFlux onset detection (log-filtered spectral flux, vibrato-suppressing max filter, Boeck-2012 adaptive peak picker); shared front-end for beat tracking

I/O (3 file handlers)

Class Description
WavFile Read/write WAV (PCM 8/16/24/32-bit, float 32/64-bit)
Mp3File MPEG-1 Layer III codec β€” read (CBR/VBR) + write (CBR encoder, 32–320 kbps)
AudioFile Abstract base class for custom format implementations

Music (2 modules)

Class Description
HarmonyConstants Constexpr musical harmony toolkit: 61 scales (bitmask representation), 15 chord recipes with inversions, MIDI/note conversion, key-aware naming (sharp/flat), diatonic chord generation. Fully constexpr/consteval β€” generates static tables at compile time.
ChordDetector<T> Real-time chord recognition: per-note Goertzel chroma, template matching over ten chord families, bass-note root disambiguation, confidence-gated hold

Quick Start

Installation

Copy the DSPark/ folder into your project. Done.

#include "DSPark/DSPark.h"

Requires a C++20 compiler. Tested with MSVC 19.50+, and compatible with GCC 12+, Clang 15+, Emscripten 3+.

Build with optimizations. DSPark is header-only: all DSP code compiles inside your translation units and inherits your build flags. A debug build runs the processors 3-7x slower than release, which matters more here than with libraries that ship precompiled binaries. If an effect seems too slow, check your flags first: -O2/-O3 and -DNDEBUG on GCC/Clang, /O2 and /DNDEBUG on MSVC.

Process a WAV File

#include "DSPark/DSPark.h"
int main()
{
dspark::WavFile input, output;
input.openRead("input.wav");
auto info = input.getInfo();
dspark::AudioSpec spec { info.sampleRate, 512, info.numChannels };
dspark::AudioBuffer<float> buffer(info.numChannels, 512);
comp.prepare(spec);
lim.prepare(spec);
comp.setThreshold(-18.0f);
lim.setCeiling(-1.0f);
output.openWrite("output.wav", info);
while (input.readSamples(buffer.toView()))
{
comp.processBlock(buffer.toView());
lim.processBlock(buffer.toView());
output.writeSamples(buffer.toView());
}
output.close();
}
Owning audio buffer with contiguous, 32-byte aligned storage.
High-performance brickwall lookahead limiter.
Definition Limiter.h:71
void prepare(double sampleRate, int numChannels=2, double initialLookaheadMs=-1.0)
Allocates memory and prepares the limiter for processing.
Definition Limiter.h:93
void processBlock(AudioBufferView< T > buffer) noexcept
Processes an AudioBufferView in-place.
Definition Limiter.h:167
void setCeiling(T dB) noexcept
Sets the absolute output ceiling.
Definition Limiter.h:340
Complete WAV file reader and writer in pure C++20.
Definition WavFile.h:67
AudioFileInfo getInfo() const override
Retrieves metadata of the currently opened file.
Definition WavFile.h:145
bool readSamples(AudioBufferView< float > dest) override
Reads samples from the start of the file into the destination view.
Definition WavFile.h:147
bool writeSamples(AudioBufferView< const float > src) override
Writes samples from the view to the file.
Definition WavFile.h:191
bool openRead(const std::filesystem::path &path) override
Opens a WAV file for reading.
Definition WavFile.h:78
bool openWrite(const std::filesystem::path &path, const AudioFileInfo &info) override
Opens a WAV file for writing, overwriting if it exists.
Definition WavFile.h:106
void close() override
Finalizes file headers and releases system handles.
Definition WavFile.h:226
Describes the audio environment for a DSP processor.
Definition AudioSpec.h:35
double sampleRate
Sample rate in Hz.
Definition AudioSpec.h:43

Build a Channel Strip

using namespace dspark;
> channelStrip;
channelStrip.prepare(spec);
channelStrip.processBlock(buffer);
Compile-time chain of audio processors.
Main namespace for the DSPark framework.

Per-Sample Processing

svf.prepare(spec);
svf.setCutoff(2000.0f);
svf.setResonance(0.7f);
for (int i = 0; i < numSamples; ++i)
{
svf.setCutoff(lfo.getNextSample() * 2000 + 500); // Modulate per sample
auto [lp, hp, bp] = svf.processMultiOutput(input[i], 0);
output[i] = lp; // Or hp, bp, or any combination
}
TPT State Variable Filter with simultaneous multi-output.
void setResonance(T resonance) noexcept
Sets the resonance amount.
void setCutoff(T hz) noexcept
Sets the cutoff/center frequency.
MultiOutput processMultiOutput(T input, int channel) noexcept
Processes a single sample returning LP, HP, BP simultaneously.
void prepare(const AudioSpec &spec) noexcept
Prepares the filter.

Draw an EQ Curve (Plugin GUI)

eq.prepare(spec);
eq.setBand(0, 80.0f, 4.0f);
eq.setBand(1, 3000.0f, -2.0f, 2.0f);
// Get magnitude response for drawing
std::vector<float> freqs(512), mags(512);
for (int i = 0; i < 512; ++i)
freqs[i] = 20.0f * std::pow(1000.0f, static_cast<float>(i) / 511.0f);
eq.getMagnitudeForFrequencyArray(freqs.data(), mags.data(), 512);
// mags[] now contains the combined EQ curve β€” plot it in your GUI
void getMagnitudeForFrequencyArray(const T *frequencies, T *magnitudes, int numPoints) const noexcept
Computes the combined magnitude response of all enabled bands.
Definition Equalizer.h:476

Build VST3 / CLAP / AU plugins

DSPark is a DSP framework first, but it ships a complete native plugin layer: the same class that processes your audio becomes a loadable plugin with nothing but this repository β€” no external SDK to download (Steinberg's official C API header is vendored under its permissive 2025 license).

struct MySaturator
{
static constexpr auto descriptor = dspark::plugin::Descriptor {
.name = "My Saturator", .vendor = "Me",
.productId = "com.me.mysaturator", .version = "1.0.0",
};
static constexpr auto parameters = dspark::plugin::params(
dspark::plugin::param("drive", "Drive", -12.0f, 36.0f, 0.0f, "dB"));
void prepare(const dspark::AudioSpec& spec) { sat_.prepare(spec); }
void setParameter(int, float v) noexcept { sat_.setDrive(v); }
void processBlock(dspark::AudioBufferView<float> io) noexcept { sat_.processBlock(io); }
};
DSPARK_VST3_PLUGIN(MySaturator)
Native VST3 backend: a complete plugin from one DSPark plugin class.
#define DSPARK_VST3_PLUGIN(PluginClass)
Declares the VST3 module entry points for one plugin class. Place once in exactly one translation uni...
Non-owning view over audio channel data.
Definition AudioBuffer.h:50
Professional multi-algorithm saturation processor with analog simulation.
Definition Saturation.h:612
constexpr std::array< Param, sizeof...(Ps)> params(Ps... ps) noexcept
Builds the parameter table (use inside static constexpr auto).
constexpr Param param(const char *id, const char *name, float minValue, float maxValue, float defValue, const char *unit) noexcept
Continuous parameter helper.
Static identity of a plugin. All fields are plain literals so the whole descriptor can live in a stat...
cl /std:c++20 /O2 /LD /EHsc /I . mysaturator.cpp /Fe:MySaturator.vst3

Sample-accurate parameter automation, state save/restore, soft bypass, latency reporting (including runtime changes), mono/stereo bus negotiation and denormal protection are handled by the layer. The same binary is also a CLAP plugin (DSPARK_CLAP_PLUGIN) and an Audio Unit for Logic Pro (DSPARK_AU_PLUGIN, validated by Apple's auval in CI); presets are byte-portable across all three formats by construction. The optional contract grows with one method each: a host-routable sidechain bus (two-buffer processBlock, examples/plugin_ducker/), MIDI input and instruments (handleMidiEvent + Category::Instrument, examples/plugin_synth/ β€” an 8-voice synth validated as an aumu music device), host transport for tempo-synced DSP (setTransport), offline render quality switching (setOfflineRendering) and factory presets published to every host's preset browser (factoryPresets). Each capability is proven functionally in CI by dedicated smoke hosts β€” measured ducking, measured note pitch, measured automation step positions β€” not just compiled.

For a custom GUI, write it in plain HTML/CSS/JS: the WebView editor layer embeds it in the host window on every format and platform β€” WebView2 on Windows, WKWebView on macOS, WebKitGTK on Linux/X11 β€” with a tiny dspark JS bridge for parameters and automation gestures, and a dspark_add_plugin(... EDITOR_HTML ui/editor.html) build step that inlines ordinary separate web files. Every example plugin passes Tracktion's pluginval and clap-validator in CI, and dedicated editor smoke hosts exercise a real web view per platform on every commit.

Start here: the plugin guide documents the complete contract (required and optional methods, what each maps to per format, the threading model, the editor layer per platform, shipping checklists). Inherit dspark::plugin::PluginBase<T> to see every overridable method with safe defaults in one place (examples/plugin_template/), or write a free-standing struct (examples/plugin_saturator/); the WebView editor examples are examples/plugin_webview_editor/ (single file) and examples/plugin_webview_files/ (separate web files).


DSParkLab β€” Interactive Testing App

DSParkLab is an interactive, plugin-style GUI application for real-time testing of every DSPark processor. Load any audio file, enable effects, shape them on an interactive analyzer or with parameter controls, and hear the results instantly.

# Build (requires MSVC with C++20 support + Windows SDK for D3D11)
DSParkLab\build.bat
DSParkLab\DSParkLab.exe

Features:

  • Asynchronous WAV/MP3 loading with format auto-detection (audio thread never blocks on I/O)
  • 34 effects organised by category (Filters, Dynamics, Distortion, Analog, Modulation, Pitch, Spatial, Utility) β€” including the physical tape/tube/transformer models, pitch shifter with formant preservation, granular engine and denoiser
  • Interactive analyzer: log-frequency spectrum behind a live response curve, with draggable nodes for the EQ / Filter / Dynamic EQ (drag X = frequency, Y = gain, mouse-wheel = Q)
  • Dynamic EQ draws its live per-band reaction in real time; multiband compressor shows crossover bands with per-band gain reduction
  • Auto-generated parameter panels with mouse-wheel-adjustable sliders and combo boxes
  • Live oversampling selection (up to 16x) on Saturation and Clipper for audible anti-alias comparison
  • Convolution Reverb loads real impulse responses (WAV) or builds a synthetic one
  • Per-channel level meters, waveform view, and gain-reduction metering
  • A/B bypass for instant comparison, and transport controls (play, pause, stop, seek, loop)

Built with Dear ImGui (MIT) and miniaudio (public domain). These dependencies are bundled in DSParkLab/vendor/ and are only used by the testing app β€” the DSPark framework itself remains 100% dependency-free.


Platform Support

Platform Status Notes
Windows (MSVC) Tested in CI x64 and ARM64, C++20, /W4 (only benign C4324 alignas padding notices)
Linux (GCC / Clang) Tested in CI x64 and ARM64, C++20, -Wall -Wextra
macOS (Clang) Tested in CI ARM64, C++20, -Wall -Wextra
WebAssembly (Emscripten) Tested in CI Zero syscalls in audio path; scalar and SIMD128
iOS / Android Compatible ARM NEON denormal flush supported
Plugins (VST3 / CLAP / AU) Native Built-in plugin layer with WebView editors (guide)

Technical Highlights

  • C++20: Concepts (AudioProcessor, SampleProcessor, GeneratorProcessor), designated initializers, std::numbers
  • Zero allocation in audio thread: All memory pre-allocated in prepare()
  • SIMD inner loops: SSE2/SSE3/AVX/NEON-accelerated buffer operations and FFT, with automatic scalar fallback
  • Cache-friendly: Contiguous memory, 32-byte aligned buffers
  • Thread-safe parameters: All setters use std::atomic with memory_order_relaxed β€” safe to call from any thread (UI, automation, audio) with zero contention
  • Lock-free coefficient updates: Biquad::setCoeffs() is consumed automatically by processBlock() and processSample() via a relaxed-load fast path. No external sequencing required.
  • No virtual dispatch in hot path: Templates and compile-time polymorphism
  • Physically-modeled algorithms: Tape (Chowdhury 2019 hysteresis with Langevin function, head bump pre-filter, gap-loss HF rolloff), FDN reverb (Jot 1991 absorption, Householder mixing, Dattorro 1997 multi-tap output, Lexicon-style modulation, serial allpass density, allpass interpolation, tanh soft saturation), TPT state-variable and ladder filters
  • Full Doxygen documentation: Every public class and method documented β€” browse it at cristianmoresi.github.io/DSPark

Architecture

DSPark/
β”œβ”€β”€ DSPark.h # Single umbrella include + full documentation
β”œβ”€β”€ Core/ (41) # Building blocks: filters, FFT, WDF, oscillators, SIMD
β”œβ”€β”€ Effects/ (36) # Ready-to-use processors: EQ, compressor, reverb, tape...
β”œβ”€β”€ Analysis/ (9) # Metering: LUFS (EBU-verified), spectrum, pitch, correlation, onset
β”œβ”€β”€ IO/ (3) # File I/O: WAV read/write, MP3 read/write
β”œβ”€β”€ Music/ (2) # Harmony constants + real-time chord detection
β”œβ”€β”€ plugin/ # Native plugin layer: VST3, CLAP, AU + WebView editor
β”œβ”€β”€ tests/ # Test suite: 630+ cases, zero dependencies
β”œβ”€β”€ conformance/ # Public conformance suite (runs in CI)
β”œβ”€β”€ docs/ # Cookbook, plugin guide, metrics table
β”œβ”€β”€ examples/ # WAV processing, channel strip, plugins, templates
β”œβ”€β”€ tools/ # VST3/CLAP/AU-editor smoke hosts, editor host, amalgamator
└── DSParkLab/ # Interactive testing app (Win32 + ImGui + miniaudio)

What's New in v1.6.1

Reverb performance: an Eco engine for constrained targets and direct control over convolution IRs, both prompted by real-world feedback from a synthesizer firmware project (issue #2).

  • Eco quality mode: AlgorithmicReverb::setQuality(Quality::Eco) runs a reduced engine (8 FDN lines, control-rate modulation, linear allpass interpolation, leaner output stage) measuring about 3.3x cheaper per block, with the same control set and the same decay calibration. The default Full engine is bit-identical to v1.6.0.
  • IR shaping on the convolution reverb: setDecayScale() rescales the impulse response's own T60 (estimated from its Schroeder decay curve) and trims the now-silent tail, so shorter decays also cut convolution cost roughly in proportion; setStretch() resamples the IR tape-speed style for larger or smaller spaces. Both always reshape the IR as loaded and republish atomically, exactly like loadIR().
  • DSParkLab: a Quality selector on the Reverb and Decay Scale / Stretch sliders on the Convolution Reverb, for instant A/B.

What's New in v1.6.0

The host contract: the plugin layer now covers everything a host can offer an effect or an instrument β€” each capability one declarative member, each one proven functionally in CI (measured, not just compiled).

  • Instruments & MIDI: handleMidiEvent(MidiEvent) adds a note input to every format (VST3 event bus + IMidiMapping for pitch bend / mod / sustain / pressure, CLAP note ports speaking both CLAP and raw-MIDI dialects, AU MusicDevice selectors), and Category::Instrument builds a true generator: no audio inputs, an aumu Audio Unit, cleared buffers that voices add into. examples/plugin_synth/ β€” 8 voices, voice stealing, pitch bend, sample-accurate note starts β€” passes auval and plays a measured 440 Hz in CI.
  • Host transport: setTransport(TransportInfo) delivers tempo, musical position, time signature, loop points and play state per block, from the VST3 ProcessContext, the CLAP transport event and the AU host callbacks β€” the basis for tempo-synced delays, LFOs and gates.
  • Mono everywhere: every plugin now negotiates mono and stereo by default (ChannelSupport restricts it when the DSP is inherently stereo); the sidechain mirrors the main width.
  • Sample-accurate automation by default: parameter, bypass and note events ride one time-ordered stream and processing splits at 32-frame boundaries, so fast curves land where the host drew them (declarative opt-out for FFT-heavy plugins).
  • The professional details: runtime latency changes notify the host natively in all three formats; setOfflineRendering(bool) switches quality for bounces; factoryPresets publishes to every host's preset browser (VST3 program list, CLAP preset-load + preset-discovery, AU factory presets); host bypass and the active program now persist in the state container; process() runs under DSPark's denormal guard.
  • Proven by instrumentation: the new tools/plugin_probe.cpp encodes what the wrapper delivers into its output, and the smoke hosts measure it β€” transport DC, the offline sign flip, an automation step landing on its exact sample, note pitch by zero crossings, the latency-changed notification β€” on every platform, on every commit. pluginval and clap-validator caught two real state-persistence bugs along the way; both fixed and now regression-covered.

License

MIT License. See [LICENSE](LICENSE).

Free to use in commercial and open-source projects. Attribution appreciated.


Author

Cristian Moresi β€” Software developer and music producer with professional experience in mixing engineering and sound design.

DSPark was created to provide a truly free, professional-grade DSP toolkit accessible to developers at every level of expertise β€” from desktop app builders to DSP engineers designing embedded audio systems. It is a genuine open-source alternative to commercial audio frameworks, built from the ground up with no dependencies and no compromises.


Contributing

Contributions are welcome. Please open an issue to discuss proposed changes before submitting a pull request.

Building and testing the framework needs only a C++20 compiler and CMake:

cmake -S . -B build -DCMAKE_BUILD_TYPE=Release
cmake --build build --parallel
ctest --test-dir build --output-on-failure

See CONTRIBUTING.md for the full development workflow, the conventions the codebase follows, and what CI checks on every commit.

For bug reports, include: compiler version, platform, minimal reproduction code.