Skip to content

sk-engines 0.5.1

Latest

Choose a tag to compare

@shakfu shakfu released this 25 Jun 06:52

Changes since the last Release

Added

  • Real ChucK MidiIn on the bare-metal build (prototype; build-verified, on-hardware wake test pending). libchuck.a is now compiled with ChucK's MidiIn/MidiOut device classes enabled (__DISABLE_MIDI__ dropped from all three ChucK define sites — scripts/fetch_chuck.sh, the firmware Makefile, and pod/Makefile.chuck, kept ABI-consistent), but with midiio_rtmidi's RtMidi backend stripped: there is no OS MIDI API or callback thread on bare metal, and rtmidi.cpp (166 KB) stays out. A new MidiInManager::inject() feeds bytes straight into ChucK's per-VM MIDI buffer + event-wake path, so a .ck patch can use the desktop-portable MidiIn min; min.recv(msg); idiom (examples/chuck/midi_in.ck) instead of host-specific globals. The full channel-voice MIDI stream is forwarded (real velocity, NoteOff, CC, pitch-bend, aftertouch, program change) plus system realtime (clock/start/continue/stop): a new IEngine::handle_midi_message(status, d1, d2) virtual (no-op for engines that only use handle_midi_note) is driven from the UI MIDI poll (core.ui.midi.cpp) for every representable event; ChuckEngine overrides it to enqueue raw bytes on a lock-free ring (chuck_midi_in.h), and ChuckEngine::process() drains it and injects into device 0 on the run() thread, right before ck->run(), so a shred blocked on min => now is woken that block. ChuckEngine::handle_midi_note is kept only to map channel→deck for the panel gate-in LED. The vendored-ChucK edits live in scripts/patches/midi_daisy.patch, applied idempotently by scripts/fetch_chuck.sh (because thirdparty/chuck is gitignored and regenerated). The firmware (make engine-chuck) links with matching ABI. Ported from the daisy-apps sibling project; replication guide in docs/dev/chuck-midi-in-porting.md, and the user-facing capabilities + remaining incompatibilities (no MidiOut, single virtual device / no enumeration, 3-byte messages only) are documented in docs/engines/chuck.md. (SysEx / system-common aren't representable in a 3-byte MidiMsg and are not forwarded; on-hardware wake test still pending.)

  • mosc engine (ENGINE=mosc) — a dual macro-oscillator on the Mutable Instruments Plaits DSP, hardware-verified. make engine-mosc gives each deck a complete plaits::Voice — the full 24-engine Plaits synthesis voice (virtual analog, waveshaping, FM, wavetable, grain, additive, chord, speech, swarm, noise, particle, string, modal, drums, plus the newer "engine2" models: VA-VCF, phase distortion, 6-op FM, wave terrain, string machine, chiptune) — so the two decks are two independent oscillators. Knobs map Plaits' whole panel: PITCH = note, Alt+PITCH = engine select (24 models), SIZE = harmonics, POS = timbre, ENV = morph, MOD_AMT = LPG decay, MODFREQ = LPG colour, MIX = level. The per-deck Mode switch picks Gate (each trigger strikes the LPG/decay envelope — Play pad / gate-in / MIDI / Seq) vs Drone (LPG bypassed, engine runs open), and the global Routing switch combines the two voices three ways: Stereo (A→L, B→R), DoubleMono (mono sum), and GenerativeStereo (an out/aux spread that uses Plaits' otherwise-discarded auxiliary output for width). The three per-deck CV jacks are wired: V/Oct → note, CV_SIZE_POS → harmonics, CV_MIX → timbre. Like csound/chuck it is a BOOT_QSPI build (the 24-engine voice is ~292 KB of code, too big for the 186 KB SRAM_EXEC, so it executes from QSPI flash) — but unlike them it still synthesises from the platform SDRAM arena (a normal arena engine that merely executes from QSPI), so no SD card or external library is needed; the Plaits DSP is vendored in-tree (src/engine/mosc/thirdparty/plaits). Cloned from the reso engine (same author, same stmlib, same PIMPL + arena-placement pattern). User doc: docs/engines/mosc.md; internals, the QSPI build, and the 24-engine order in docs/dev/mosc-impl.md.

  • Shared stmlib for the Mutable Instruments engines (reso + mosc). Both engines depend on Émilie Gillet's stmlib support library; the two vendored copies were byte-for-byte identical (same upstream, unchanged for years), so they are now a single trimmed copy at src/engine/common/thirdparty/stmlib (the union of the Rings and Plaits closures, 19 files), shared via the STMLIB_TP/STMLIB_INC make vars. reso's former src/engine/reso/thirdparty/stmlib was removed (its tree is now rings only); this is a dedup with no functional change.

Flashing an sk-engines firmware (0.5.1)

Each .bin here is a complete firmware for one engine. Flash exactly one at a time.

Prerequisite

These app binaries are not standalone: they run under the spotykach bootloader, which must
already be installed on the device. Installing the bootloader is a separate, device-level
procedure not covered here.

Step 1: enter bootloader mode

Both methods below need the device in its bootloader (DFU) mode first: hold Reset ~3s until
the bottom pad LEDs breathe white.

Step 2, option A: Daisy Web Programmer (easiest)

Needs a WebUSB browser - Chrome or Edge (Firefox and Safari will not work).

  1. With the device in bootloader mode, open https://flash.daisy.audio/
  2. On the "File Upload" tab, choose your engine binary (sk--0.5.1.bin).
  3. Click FLASH.

Step 2, option B: dfu-util (command line)

dfu-util -a 0 -s 0x90040000:leave -D sk-<engine>-0.5.1.bin -d ,0483:df11

Verify

  • Confirm the download is intact: shasum -a 256 -c SHA256SUMS
  • Confirm what a binary is: arm-none-eabi-strings <file>.bin | grep '^spotykach '
    (prints e.g. spotykach 0.5.1 engine=reverb)

Note for the csound and chuck and mosc engines

sk-csound-*.bin and sk-chuck-*.bin and sk-mosc-*.bin are QSPI apps: unlike the other engines they execute in place from QSPI flash
(their language runtimes are too big for SRAM), so they are also larger downloads and take longer to
flash. Same address and steps as above, with two caveats:

  • They need a bootloader that runs QSPI apps (the spotykach bootloader does); a SRAM-only
    bootloader cannot run them.
  • With dfu-util, the :leave step may print a harmless Error 74 / "get_status" message at the
    end - the write has already succeeded. Ignore it (the Web Programmer does not show this).