Guitar pedal
Pair the chip with a pedal-grade audio frontend, wire footswitches to GPIO and an expression pedal to the ADC, and you have a programmable effect box. The same live-push workflow applies: edit a patch, stomp, the sound changes.
Cedar runs on a $10 ESP32. That puts nkido in range of guitar pedals, Eurorack modules, stompboxes, and custom instruments. Anywhere you want live-coded audio without a laptop in the loop.
The ESP32 port is about showing that the cedar VM (hot-swap, live-coded patches, all the pieces that make nkido feel the way it does) fits on a chip that's cheap and widely available. Once that's true, the interesting question shifts from "does it work?" to "what do you build with it?"
Pair the chip with a pedal-grade audio frontend, wire footswitches to GPIO and an expression pedal to the ADC, and you have a programmable effect box. The same live-push workflow applies: edit a patch, stomp, the sound changes.
Map CV inputs to patch parameters, gate inputs to envelope triggers, and fit the result into a few HP of front panel. Cedar's live-push means the module's voice can be redefined without a firmware flash.
Battery, a small screen, a handful of physical controls. No host required. The last-pushed patch persists across reboots, so the device boots straight into whatever sound it was making.
None of those are built yet. The port gets us to the starting line: running cedar on a cheap chip, with the nkido workflow intact.
The reference build targets the AI-Thinker ESP32-A1S Audio Kit 2.2, a classic ESP32 paired with an ES8388 stereo codec, a headphone amp, and six onboard tactile switches. It boots, plays a 440 Hz sine out the jack, accepts patch pushes over USB serial, and binds the six buttons to the running patch's parameters. Other ESP32 + ES8388 boards will probably work with little or no modification; different codecs or chips need a new driver and sensible config changes.
The full story of the port (what fought me, the decisions behind each phase, and what turned out easier than expected) is in the dev journal.
If you have an A1S Audio Kit and a USB cable, the fastest path is the Docker build. No toolchain install required.
git clone --recursive https://github.com/mlaass/cedar-esp32.git
cd cedar-esp32
./scripts/docker-build.sh
./scripts/docker-flash.sh /dev/ttyUSB0Once it's running, push a new patch over serial:
python3 -m cedar_push --port /dev/ttyUSB0 my-patch.cbcFor native ESP-IDF builds, pin maps, board-specific config, and the full reference, see the repo README and build-docker.md.
The host compiles an Akkado patch to bytecode with parameter metadata, wraps it in a
small .cbc container, and sends it over USB serial. Cedar's built-in
crossfade handles the transition at the next audio block, so patches swap without
dropping samples. End-to-end latency is under 50 ms. Wire format and frame types are
in docs/uart-protocol.md.
Patches declare parameters. The device binds the first six declarations to the six onboard buttons in order, and each new patch re-maps them. This is the key insight for embedded deployment: a pedal or module's front panel can be wired to patch parameters the same way, and the patch stays portable between hardware targets.
The cedar VM's working state (around 1.15 MB of buffer pools, state pools, and reverb buffers) lives in the ESP32's PSRAM, the chip's slower external memory. Internal SRAM is reserved for the audio-rate code path. That split is what makes the footprint budget work on a chip with only ~128 KB of fast memory.
The most recent pushed patch is stored in on-chip flash and loaded at boot. Send cedar-push --reset-program to revert to the built-in demo.
The Phase 3 firmware weighs in at about 306 KB, roughly 10% of the app partition. To make that budget work, several cedar features are compiled out of the embedded build: audio decoders, SoundFont support, FFT, generic file I/O, MinBLEP oscillators, and the debug probe ring. Most come back in Phase 4 once on-device sample playback is wired up.
Full size breakdown, per-opcode profiler output, and the regression rule are in docs/size-baseline.md.