Releases: rainybit-code/spore
Releases · rainybit-code/spore
Release list
v0.5.0
- Patch dump/load + preset management over USB MIDI (
docs/MIDI_PROTOCOL.md§3-4).
New SysEx commands let Propagator drive the on-device presets it previously couldn't see:
0x10/0x50dump the full live patch (device → editor, so a hardware tweak or a recall
syncs the UI),0x11loads a patch, and0x20/0x21/0x22save / recall / list the three
QSPI slots of the active mode, with0x52reporting slot occupancy + the active slot. A
Program Change is an alias for recall. The slots are the same ones the Footswitch-2 gesture
uses; the commands reuse the existing capture/apply glue. Patch values are 7-bit to stay
under libDaisy's 128-byte inbound SysEx buffer. - Fix: intermittent crackle in Synth mode under load. The crackle was a per-block CPU
spike, not sustained load (so the watchdog, which only sheds after ~150 ms, never caught
it): a moving filter envelope changed the cutoff every sample, forcing a per-sample
SetFreq(Svfsinf+powf/ Moog polynomial) on every voice — and a chord put all 6
voices on that path at once, tipping a block past its deadline. The voice filter now
recomputes its coefficients at control rate (every 8 samples, ~6 kHz — inaudible for
sweeps) while keeping the existing "skip when unchanged" fast path for static patches.
The audio block size also goes 48 → 64 (~1.3 ms @ 48 kHz) for more headroom against
transient spikes.
v0.4.0
- Presets (
io/presets.h): three per mode, stored in QSPI. Hold Footswitch 2 to enter
preset mode, flip Toggle 2 to recall slot 1/2/3 (the slot is the variant position), or tap
Footswitch 1 (while holding FS2) to save the current sound. Recalled knob values use the
existing soft-takeover, so physical pots don't jump. LEDs show the active preset
(right = 1, left = 2, both = 3). - Run from SRAM via the Daisy bootloader (
APP_TYPE=BOOT_SRAM). The firmware outgrew the
128 KB internal flash, so it now loads from QSPI into SRAM — hundreds of KB of headroom. Uses
the fast 10 ms bootloader (near-instant boot). Flashing changed: install the bootloader
once withscripts/install-bootloader.{sh,ps1}, then flash the app with
scripts/flash.{sh,ps1}— or let Propagator do it. The wavetables moved to SDRAM to fit the
SRAM build's smaller default.bss. - Automated/remote flashing. CC 118 ≥ 64 reboots into the Daisy bootloader with an
infinite DFU window, so Propagator can reflash the app over WebUSB without any button timing.
(CC 119 still reboots to the STM ROM DFU, now used to update the bootloader itself.) Releases
also publishspore-vX.Y.Z-bootloader.binso the editor can install the bootloader too. - Removed the "hold both footswitches → DFU" gesture. Enter DFU over MIDI (CC 118 for the
app, CC 119 for the bootloader) or with the Daisy Seed's BOOT+RESET buttons. Frees the
footswitch combinations for presets. - Lower audio-CPU on the voice path (no audible change): the per-voice filter only
recomputes its coefficients when cutoff / resonance / filter-type actually change, so
static-filter patches skip asinf+powf(Svf) or coefficient polynomial (Moog) every
sample; unison detune offsets are precomputed per block instead of dividing per sample;
and the final hard clamp is folded into the master limiter (one less buffer pass). - Link-time optimization (
-flto) trims ~1.5 KB of internal flash (98.2% → 97.1%);
usb_identity.cis kept out of LTO so its USB-descriptor override stays deterministic. - CI checks a CHANGELOG entry on every PR (skippable via a
skip-changelog/
dependencieslabel), and the PR template now lists only the manual items CI can't
verify (formatting, build, and changelog are enforced automatically). - Contributor tooling. Added
CONTRIBUTING.md, GitHub issue/PR templates, a
.clang-format(Google C++, 4-space, 100-col) +.editorconfig, and a CI job that
enforces formatting. Newscripts/setup.{sh,ps1}one-shot bootstrap (submodules + libs). - Internal cleanup (no behaviour change):
PumpMiditakes aMidiContextstruct
instead of 11 positional args; per-mode parameter defaults are assigned by enum name so
reordering can't silently shift them; CPU-watchdog and LED thresholds moved into
params::watchdog/params::ui.
v0.3.4
- New Granular engine controls (
config/gran_params.h, CC 94-97) for the Propagator
GRANULAR pod, beyond the 6 physical knobs: Reverse (backwards-grain probability, was a
fixed 30%), Width (per-grain stereo pan spread — granular is now stereo), Shape
(grain window soft Hann -> hard flat-top gate), and Scale-lock (snap grain pitches to
off / major / minor / pentatonic). Defaults reproduce the previous sound.
v0.3.3
- Cleaner master output: a DC blocker (one-pole ~20 Hz high-pass per channel) strips any
offset built up by resonant filters / wavefolding / drive before it eats headroom, and the
master volume / cutoff / resonance are now smoothed (~15 ms) so stepped MIDI CC and fast knob
moves no longer zipper (worst on resonant cutoff). - Reverse grains in Granular: ~30% of grains now play backwards for a shimmering, less
directional texture. - Granular octaves stay in tune. The octave-quantize (VAR position 2) used
powf(2, k)for
the rate, which isn't bit-exact (worse under-ffast-math) so octaves beat against the dry
signal. Now the octave shift is an exactldexpfx2^n, and it's taken relative to the dialed
Pitch (so the Pitch knob works in octave mode instead of being snapped away).
v0.3.2
- Granular pitch is now in tune. The pitch knob quantizes to whole semitones (it used to
sweep +/-24 semitones continuously, so it detuned against anything you played unless dialed
exactly), with a small center detent that snaps to unison. - Smoother short grains. The grain spawn interval is now randomized (+/-40%) so small grains
form a cloud instead of a periodic buzz at the spawn rate. (Overlap still depends on Density vs
Size: very short grains at low density are sparse by nature -- raise Density for a denser wash.) - Master limiter instead of a hard clip. The output stage now rides the gain down when a
peak would exceed the ceiling (fast ~0.5 ms attack, slow ~150 ms release) and lets it recover
smoothly, so a resonant filter / stacked grains / runaway feedback get turned down rather
than crushed. A hard clamp to [-1, 1] stays only as an inaudible backstop for the attack slip. - Generative no longer locks up on re-seed. The Brightness/Texture roll could land on a
timbre too heavy for the budget (Moog 4-pole + unison + FM + fold across all 5 voices), and
since Generative skips the global FX the CPU watchdog had nothing to shed -> it overran,
starved MIDI, and needed a reboot. Now: the roll caps its worst case (no unison, Moog rare),
and the watchdog sheds voices in the active mode and auto-recovers when load drops
(~400 ms cool-down) instead of latching until a mode change. - Lower CPU across the board via
-ffast-math -fno-finite-math-onlyon the DSP build
(reassociation / reciprocals / fast fp-contract; NaN+Inf handling kept for the chaos guard
and CPU meter), plus a cheaper Granular hot loop -- Hann window from a LUT (was a per-grain
cosfevery sample) and branch-wrap instead of%on the buffer indices.
v0.3.1
- Generative steering (
config/gen_params.h, CC 32-37): the timbre still rolls
randomly on re-seed, but the roll is now biased by Brightness + Texture, and
behaviour is steerable via Chord (stacking), Swell (note length) and Motion
(walk step), plus a Wander morph-depth. Synth params stay synth-only (no reuse).
v0.3.0
- Control echo (device -> editor): the firmware now transmits a CC when a hardware
control changes -- mode/FX/VAR toggles (CC 16/17/93), the 12 shift-layer knobs (CC 20-31),
and bypass (CC 91) -- so Propagator mirrors the physical surface. Change-detected, sent
from the main loop (not the audio ISR). First half of live 2-way sync. - Master output stage: a switchable LP/BP/HP filter (cutoff + resonance) and a
master volume, applied after the global FX and before the limiter (fx/master.h).
Filter type 0 = off (volume only). CC 7 (vol), 88 (type), 89 (cutoff), 90 (res). - MIDI control of the footswitches + VAR switch: CC 91 = bypass, CC 92 = mode action
(freeze / re-seed), CC 93 = TOGGLE 2 variant. Modes now read an overridablectx.variant
instead of reading Toggle 2 directly, so the whole control surface is drivable over MIDI. - Fix Generative-mode CPU overload / MIDI lockup. Generative ran its own
ReverbSc
and the global FX reverb (double reverb) → the audio callback overran and starved MIDI.
The global FX path is now skipped in Generative (it has its own reverb). - Clear processing on mode change. New
GlobalFx::Reset()clears the FX delay/reverb
tail, and each mode now implementsOnEnter()to silence its voices/grains/reverb, so
nothing from the previous mode lingers (or keeps costing CPU) into the next. - CPU watchdog. If the callback stays overloaded (~150 ms),
g_overloadlatches: the
global FX is shed and the onboard LED fast-blinks (~5 Hz). Cleared by a mode/FX change —
i.e. change something to regain control.
v0.2.1
- Steps mod-matrix source (#8): the logistic-map (stepped) chaos
ChaosStepis now a
routable Synth matrix source (was computed but unused). Source encoding widened*7→*8
(synth_mode.h); Propagator gains the jack with a v2→v3 patch migration. - Live Chaos controls + telemetry: Lorenz speed is now tunable over CC 18
(ModEngine::SetChaosSpeed, range inparams::mod). New SysEx chaos-state query
(F0 7D 03 F7→0x43 <x> <z>) reports the attractor's X/Z so Propagator can draw it
live — reports the already-computed value, so no extra audio-CPU cost.
v0.2.0
- Chaos modulation sources: a Lorenz attractor (smooth) + logistic map (stepped)
added to the sharedModEngine(mod/modulation.h) — deterministic-but-never-repeating
movement. Wired into Generative (chaotic filter sway + wavetable-scan drift) and
Granular (density drift). Params inparams::mod. Seedocs/MODULATION.md. - Chaos as a Synth mod-matrix source (#7): route the Lorenz chaos to any destination
via the patchbay. Source encoding widened from*6→*7(synth_mode.h); Propagator
gains the matching jack (with a v1→v2 patch migration so old routings keep their meaning).
v0.1.2
- Fix reverb crackle: enable the FPU's flush-to-zero (
FPSCR.FZ) at boot. The
Cortex-M7 handles denormal floats on a slow path and libDaisy only enables FPU
access, so a decayingReverbSctail (no denormal guard of its own) stalled the
FPU as it rang out. FZ also protects the delay/filter feedback paths. - CPU-load metering: instrument the audio callback with
CpuLoadMeterand report
avg/peak load over SysEx (queryF0 7D 02 F7→ replyF0 7D 42 <avg%> <max%> F7).
Propagator shows it live. Seedocs/MIDI_PROTOCOL.md.