DaisySP Developer Guide & DSP Runbook¶
This skill provides an operational runbook, architectural rules, and quick-lookup cheatsheet for developing real-time audio synthesis and signal processing applications using DaisySP.
1. Core Architectural Tenets¶
All code using DaisySP must strictly adhere to the following real-time audio constraints:
| Tenet | Rule | Engineering Contract |
|---|---|---|
| Static Memory | No runtime allocation. | Never call malloc, new, or standard dynamic containers in audio callbacks. Pre-allocate in BSS, template parameters, or SDRAM (DSY_SDRAM_BSS). |
| Evaluation Pattern | Single-sample Process() standard. |
Evaluate sample-by-sample for feedback stability. Use block processing (ProcessBlock) only where hardware SIMD-accelerated (FIR, Limiter, LadderFilter). |
| Signal Ranges | Normalized floats. | Audio signals: nominal \([-1.0\text{f}, +1.0\text{f}]\) (\(0\text{ dBFS}\)). Control voltages: \([0.0\text{f}, 1.0\text{f}]\). |
| Rate Separation | Decouple control from audio rate. | Evaluate envelopes (Adsr), LFOs, and UI parameter mappings once per audio block (or with blockSize parameter) rather than per-sample to save MCU cycles. |
| Lifecycle | Instantiation \(\to\) Init(sr) \(\to\) Process(). |
Default constructors initialize safe state; .Init(sample_rate) configures sample-rate-dependent filter coefficients and clears delay lines. |
2. Licensing & Submodule Inclusions¶
| Tier | Include Header | Build Flag | Notes |
|---|---|---|---|
| MIT Core | #include "daisysp.h" |
Default | Electro-Smith core, Andrew Simper SVF, Mutable Instruments ports (Plaits, Rings, stmlib). Safe for proprietary commercial firmware. |
| LGPL Submodule | #include "daisysp-lgpl.h" |
USE_DAISYSP_LGPL = 1 |
Csound, Soundpipe, Faust ports (ReverbSc, Compressor, MoogLadder, BlOsc, Pluck). Commercial distribution requires relinking capability (gather_lgpl.sh). |
3. Fast Module Selection Index¶
For detailed class methods and parameter limits, see Module Catalog Reference.
flowchart TD
DSP[DaisySP Catalog] --> Syn[Synthesis]
DSP --> Flt[Filters]
DSP --> FX[Effects]
DSP --> Drm[Drums]
DSP --> Phys[Physical Modeling]
DSP --> Dyn[Dynamics & Utilities]
Syn --> Osc[Oscillator / Fm2 / VariableShapeOscillator]
Flt --> Svf[Svf / LadderFilter / FIR / OnePole]
FX --> Cho[Chorus / Flanger / Phaser / ReverbSc]
Drm --> Kick[AnalogBassDrum / Snare / HiHat]
Phys --> Str[StringVoice / ModalVoice / Drip]
Dyn --> Lim[Limiter / Compressor / DelayLine / Looper]
| Functional Domain | Recommended Modules | Master Header Path |
|---|---|---|
| Subtractive Synthesis | Oscillator (PolyBLEP), VariableShapeOscillator, OscillatorBank |
Synthesis/ |
| FM & Complex Osc | Fm2 (2-Op FM), FormantOscillator, ZOscillator, BlOsc [LGPL] |
Synthesis/ |
| Filters | Svf (Simper stable SVF), LadderFilter (Moog 4-pole), FIR (ARM CMSIS accelerated), OnePole |
Filters/ |
| Time & Modulation FX | Chorus, Flanger, Phaser, Tremolo, PitchShifter |
Effects/ |
| Distortion & Lo-Fi | Overdrive, Wavefolder, Decimator, SampleRateReducer |
Effects/ |
| Reverberation | ReverbSc (Costello 8-delay matrix algorithmic reverb) [LGPL] |
DaisySP-LGPL/Source/Effects/ |
| Drum Synthesis | AnalogBassDrum (808 kick), AnalogSnareDrum, HiHat (6-osc cluster), SyntheticBassDrum, SyntheticSnareDrum |
Drums/ |
| Physical Modeling | StringVoice (Rings/Plaits string), ModalVoice (bell/plate), Resonator, Drip |
PhysicalModeling/ |
| Sampling & Loops | GranularPlayer (time-stretch & pitch shift), Looper (Frippertronics tape loops, overdub) |
Sampling/, Utility/ |
| Dynamics | Limiter (peak block limiter), CrossFade, Compressor (sidechain capable) [LGPL] |
Dynamics/ |
| Noise Generators | WhiteNoise, ClockedNoise, Dust (vinyl crackle), FractalRandomGenerator (1/f) |
Noise/ |
| Control & Envelopes | Adsr (curve shaping, block-update support), AdEnv, Phasor (0.0–1.0 ramp) |
Control/ |
| Utilities & Buffers | DelayLine (Hermite cubic interpolation), DcBlock, Metro, Maytrig, SampleHold |
Utility/ |
4. Memory Layout Rules for Embedded Targets (Daisy Seed / STM32H750)¶
flowchart TD
subgraph RAM["MCU Data RAM Domains"]
DTCM["DTCM (128 KB)\nFast DSP State\nNo DMA, No ReverbSc"]
AXI["AXI SRAM (512 KB)\nGeneral Heap/BSS & Code"]
SDRAM["External SDRAM (64 MB)\nDSY_SDRAM_BSS\nReverbs, Delays, Granular Buffers"]
end
- Large Footprint Danger:
ReverbScallocates98,936floats (~395 KB).PitchShifterallocates two 16K float delay lines (~128 KB).DelayLine<float, 48000>allocates 192 KB.- Storage Directive: Never allocate these classes locally on the function stack or in DTCM. Place them in static external SDRAM:
5. Master Math Cheatsheet (Utility/dsp.h)¶
Utility/dsp.h contains high-performance audio math approximations:
#include "Utility/dsp.h"
using namespace daisysp;
float hz = mtof(midi_note); // MIDI note to Hz (69 -> 440 Hz)
float gain = pow10f(db / 20.0f); // Fast 10^x (90% faster than powf)
float val = fclamp(raw_input, -1.0f, 1.0f); // Single-instruction ARM clamp
float freq = fmap(norm_pot, 20.f, 20000.f, Mapping::EXP); // Exponential mapping
float soft = SoftClip(sample); // Polynomial soft-clipping
float hard = SoftLimit(sample); // Cubic limiter
float blep = ThisBlepSample(t); // PolyBLEP anti-aliasing step
6. Common Pitfalls & Diagnostics¶
| Problem | Probable Cause | Verification & Corrective Action |
|---|---|---|
| Instant HardFault on boot | Large module on function stack or DTCM | Check .bss section size with arm-none-eabi-size. Decorate ReverbSc, PitchShifter, or large DelayLine with DSY_SDRAM_BSS. |
| Audio crackle / stutter | Denormal floating-point underflow stalls FPU | Enable Flush-to-Zero (FTZ) on Cortex-M7: __set_FPSCR(__get_FPSCR() \| (1 << 24));. |
| Filter outputs silence | Svf::Process(in) returns void |
Multi-output filters require querying getter methods: float out = flt.Low();. |
Linker error: undefined reference to ReverbSc |
Missing LGPL submodule build configuration | Add USE_DAISYSP_LGPL = 1 to project Makefile, or pass -DUSE_DAISYSP_LGPL. |
| Wrong pitch or modulation rate | Passing hardcoded sample rate (e.g. 48000) |
Always query the running hardware sample rate: module.Init(hw.AudioSampleRate());. |
| Synth freezes / controls drop out after drum hit | AnalogBassDrum runaway resonance starving control ISRs |
AnalogBassDrum scales SVF resonance by frequency (\(\text{res} = 0.4 \times q \times f\)). Above \(\approx 90\text{ Hz}\), resonance clamps to \(1.0\) (damping \(= 0.0\)), causing perpetual self-oscillation. Coupled with per-sample powf/sinf calls, the audio ISR saturates the CPU, starving the 1 kHz timer/main loop. Keep AnalogBassDrum \(\le 90\text{ Hz}\) or use a pitch-swept sine + envelope for higher drums (toms). Always backstop voice activity gates with a maximum lifetime ceiling. |
| Digital noise / audio crackles when overlapping drum hits | AnalogSnareDrum undamped resonance & per-sample powf CPU overload (\(>100\%\)) |
AnalogSnareDrum sets SVF resonance via \(\text{res} = 0.2 \times f \times q\), which clamps to \(1.0\) (\(\text{damp} = 0.0\)) across normal tuning/decay settings, causing all 5 resonators to enter perpetual self-oscillation. Because the tail never drops below silence, activity gates never sleep. Furthermore, AnalogSnareDrum::Process() evaluates 14 powf() and 6 sinf() calls and retunes 6 SVF filters per sample (~70% CPU on STM32H7). When a second drum hit (e.g. kick) plays concurrently, total CPU exceeds 100%, causing hardware SAI DMA buffer underruns (audible as harsh digital static/noise). Replace with a dedicated dual-mode sine + shaped noise snare voice that precalculates decay and filter coefficients at control/block rate. |
7. Verification Workflows¶
7.1 Verify Build & Memory Footprint¶
Run from the firmware project directory:
Verify that .data and .bss allocated to DTCM (0x20000000) do not exceed 128 KB.
8. Detailed References¶
- Exhaustive Module Catalog: Class-by-class methods, parameters, and origins.
- Production Audio Recipes: Monophonic synth, guitar multi-FX, and drum sequencer callbacks.
- Comprehensive Architecture Guide: Full ecosystem deep dive.