An Arduino library that runs Pure Data (Pd) patches on ESP32 microcontrollers with I2S audio output.
Build audio synthesisers, effects, and interactive sound installations by designing patches in Pd on your computer, then running them on an ESP32 with real-time parameter control from GPIO, sensors, or serial.
Adapted for the Arduino IDE from ESPd by Miller Puckette.
- Load and hot-swap
.pdpatches stored on LittleFS flash - Send/receive floats, bangs, and symbols between Arduino code and Pd patches
- Stereo I2S audio output (16-bit, configurable sample rate)
- Internal DAC output on ESP32/ESP32-S2 (8-bit, no external hardware needed)
- Dedicated FreeRTOS audio task for glitch-free playback
- Thread-safe message queue for control from
loop() - PSRAM support for large tables, delay lines, and samplers
- Works on all ESP32 variants (ESP32, S2, S3, C3, C6)
#include <ESPdLib.h>
void setup() {
ESPdLib::Config config;
config.sampleRate = 48000;
config.bclkPin = 38;
config.wsPin = 39;
config.doutPin = 40;
Pd.begin(config);
Pd.openPatch("my-patch.pd");
Pd.sendFloat("freq", 440.0);
}
void loop() {
float freq = analogRead(1) / 4095.0 * 2000.0;
Pd.sendFloat("freq", freq);
delay(20);
}-
LittleFS Upload Tool (recommended) -- Place
.pdfiles in your sketch'sdata/folder, then useCmd+Shift+P> "Upload LittleFS to Pico/ESP8266/ESP32". Requires the arduino-littlefs-upload plugin. -
Serial Upload -- Send patches at runtime without recompiling:
python3 scripts/upload_patch.py /dev/cu.usbmodem* my-patch.pd -
Embedded Fallback -- A default sinewave patch is compiled into the EmbeddedExample sketch and auto-written to LittleFS if no patches are found.
Patches must use [receive] objects (not GUI elements) to accept values from Arduino code:
[r freq] --> [osc~] --> [*~] --> [dac~]
[r amp] --^
No FFT, networking, external libraries, or GUI objects -- headless audio only. Sub patches and abstractions are supported.
- Any ESP32 board (ESP32, S2, S3, C3, C6)
- I2S DAC module (MAX98357A, PCM5102, UDA1334A, etc.)
- Configurable I2S pins via
config.bclkPin,config.wsPin,config.doutPin
- ESP32 (GPIO25 = left, GPIO26 = right) or ESP32-S2 (GPIO17 = left, GPIO18 = right)
- Set
config.useInternalDAC = true— I2S pin settings are ignored - 8-bit output resolution (lower quality than external I2S DAC)
- Not available on ESP32-S3, C3, C6, or other chips without a built-in DAC
ESPdLib::Config config;
config.useInternalDAC = true;
Pd.begin(config);- Arduino IDE 2.x
- Arduino-ESP32 core v3.x (ESP-IDF 5.x based)
- LittleFS partition in flash (default partition schemes include one)
See ESPdLib-Documentation.md for the full API reference, architecture details, PSRAM configuration, Pd engine update instructions, and troubleshooting guide.
Based on Pure Data by Miller Puckette. Pd is released under the BSD license.