- C++ 95.2%
- Makefile 1.9%
- CMake 1.5%
- C 1.4%
- Split into CLI / CMake library / Cardputer ADV firmware sections - Wrap ASCII art in code block (Forgejo renders bare lines as single paragraph) - Add component overview table at the top Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> |
||
|---|---|---|
| esp32 | ||
| lib | ||
| .gitignore | ||
| audio_pipewire.cpp | ||
| audio_pipewire.h | ||
| bb8 | ||
| bb8_engine.cpp | ||
| bb8_engine.h | ||
| main.cpp | ||
| Makefile | ||
| README.md | ||
888888b. 888888b. .d8888b.
888 "88b 888 "88b d88P Y88b
888 .88P 888 .88P Y88b. d88P
8888888K. 8888888K. "Y88888"
888 "Y88b888 "Y88b.d8P""Y8b.
888 888888 888888 888
888 d88P888 d88PY88b d88P
8888888P" 8888888P" "Y8888P"
Bytebeat synthesizer — generate audio from arithmetic expressions over a time variable t.
Each sample is the low 8 bits of the expression evaluated at t = 0, 1, 2, …
This repository contains three components sharing the same engine:
| Component | Target | Directory |
|---|---|---|
| CLI | Linux / PipeWire | ./ |
| Static library | Any CMake project | lib/ |
| Firmware | M5Stack Cardputer ADV (ESP32-S3) | esp32/ |
Supported operators: + - * / % & | ^ ~ << >> < <= > >= == != ?: ( )
Linux CLI
Command-line tool that streams audio through PipeWire.
Dependencies
- C++17 compiler,
libpipewire-0.3,pkg-config
sudo pacman -S pipewire pkg-config # Arch Linux
Build
make
sudo make install # optional, installs to /usr/local/bin/bb8
Usage
bb8 -expr <expression> [options]
-expr <expr> Bytebeat expression (variable: t) [required]
-rate <hz> Sample rate in Hz (default: 8000)
-time <sec> Stop after N seconds (default: infinite)
-loop Run indefinitely (default behaviour)
Press Ctrl-C to stop.
bb8 -expr "t*(t>>8|t>>9)&46&t>>8"
bb8 -expr "t*(t>>5&t>>8)" -time 30
bb8 -expr "2*(t>>5&t)-(t>>5)+t*(t>>14&14)" -rate 44100
CMake Library
lib/ exposes a minimal C API for embedding bytebeat audio in CMake projects.
API
#include <bb8.h>
void bb8_play(const char *expr, int sampleRate, float duration); // duration <= 0 → infinite
void bb8_stop(void);
Integration
add_subdirectory(/path/to/bb8/lib bb8)
target_link_libraries(your_target PRIVATE bb8)
#include <bb8.h>
bb8_play("t*(t>>8|t>>9)&46&t>>8", 8000, -1); // start (background thread)
bb8_stop(); // stop + join
Cardputer ADV Firmware
esp32/ is a full port for the M5Stack Cardputer ADV (ESP32-S3 + ES8311 codec).
Features
- Real-time audio via ES8311 / I2S DMA
- Live expression editing on the Cardputer keyboard
- Waveform display (~10 Hz refresh)
- Instant hot-swap on Enter (lock-free, audio never glitches)
- BtnA toggles playback
Build & flash
Requires PlatformIO.
cd esp32
pio run # compile
pio run -t upload # flash
pio device monitor # serial output
How it works
The engine is re-implemented with ESP32 constraints: int32_t arithmetic (native 32-bit),
fixed-size bytecode array (no heap allocation), IRAM_ATTR evaluate() to avoid flash cache misses.
Two FreeRTOS tasks run in parallel:
- Core 0 — audio task (max priority): fills 256-sample chunks via
evaluate(), feedsSpeaker.playRaw() - Core 1 — UI task: keyboard input, display, expression compilation
Engine hot-swap uses std::atomic acquire/release so the audio path never takes a lock.
License
MIT