Sound Byte Libs f27ea30
C++ firmware library for audio applications on 32-bit ARM Cortex-M processors
Loading...
Searching...
No Matches
Sound Byte Libs

C++ firmware library for embedded audio on ARM Cortex-M

What is Sound Byte Libs?

Sound Byte Libs is a library for building musical instruments and audio applications on 32-bit ARM microcontrollers.

Write once, run on multiple targets. SBL provides useful building blocks without imposing structure on your application. Through compile-time template polymorphism, you get hardware portability with zero-overhead abstractions.

Key features:

  • Cross-platform: Same code compiles for RP2040, RP2350, STM32H7
  • Bare-metal: No vendor HALs - SVD-generated register definitions
  • Tiny binaries: 1KB blinker, 13KB synth voice, 24KB polyphonic instrument
  • Complete DSP toolkit: Oscillators, filters, envelopes, delay lines, lookup tables
  • MIDI support: Stream parser with running status, channel filtering, hardware input
  • Audio-focused: DMA-driven I2S output, real-time safe, static allocation only
  • 471 unit tests + DSP golden reference suite

Quick Start

Prerequisites: ARM GCC toolchain (arm-none-eabi-gcc)

# Clone the ecosystem
git clone https://github.com/soundbytelabs/sound-byte-libs.git
git clone https://github.com/soundbytelabs/sound-byte-libs-examples.git
git clone https://github.com/soundbytelabs/sbl-hardware.git
# Set environment
export SBL_PATH=/path/to/sound-byte-libs
export SBL_HW_PATH=/path/to/sbl-hardware
# Build for Daisy Seed (STM32H750)
cd sound-byte-libs-examples/hello-blinker
cmake --preset daisy
cmake --build build/daisy
# Flash with dfu-util (hold BOOT, press RESET, release BOOT)
dfu-util -a 0 -s 0x08000000:leave -D build/daisy/hello_blinker.bin

What Can You Build?

SBL scales from trivial to complex, and every byte is accounted for:

  • hello-blinker (1KB) – LED blinking on any supported board. Proves the architecture: manifest-driven GPIO, zero-overhead HAL, multi-platform from one source file.
  • hello-synth (13KB) – A complete subtractive synthesizer voice. Band-limited PolyBLEP oscillator through a state variable filter and VCA, driven by an ADSR envelope, with MIDI input over UART. Runs on Daisy Pod.
  • hello-instrument (24KB) – A polyphonic chord pad instrument with up to 6 SuperSaw voices, stereo SVF filtering, LFO modulation, beat-quantized chord changes, circle-of-fifths navigation, and multi-mode knob mapping with pickup. Also Daisy Pod.

The jump from 1KB to 24KB tells the story: SBL's layered architecture means you only pay for what you use.

Code Example

#include <sbl/hw/hw.hpp> // Single include: drivers + generated config
int main() {
sbl::driver::init();
// LED handle resolved at build time from hardware manifest
constexpr auto led = sbl::hw::gpio::status_led;
sbl::driver::Gpio::set_mode(led, sbl::gpio::PinMode::Output);
while (true) {
sbl::driver::Gpio::toggle(led);
sbl::driver::Timer::delay_ms(500);
}
}
Uber-umbrella header for all target-specific code.

Build System

SBL provides optional CMake hooks that simplify build setup. Our examples use them, but you can wire up builds however you prefer.

include($ENV{SBL_PATH}/tools/cmake/SblHooks.cmake)
sbl_pre_project() # Resolves hardware, configures toolchain
project(my_app C CXX ASM)
sbl_post_project() # Finalizes platform setup, creates sbl::driver
add_executable(my_app src/main.cpp)
target_link_libraries(my_app PRIVATE sbl::driver)
sbl_finalize(my_app) # Generates .bin, .hex as needed

When using hooks, they read your target manifest and configure the build accordingly — setting up the ARM toolchain, generating binary outputs (BIN/HEX), and wiring in platform-specific startup code. Override hooks or skip them entirely for custom setups.

Platform Support

Platform MCU Core Status
Daisy Seed STM32H750 Cortex-M7 Primary — full peripheral support
Raspberry Pi Pico RP2040 Cortex-M0+ GPIO, Timer, UART, USB CDC
Raspberry Pi Pico 2 RP2350 Cortex-M33 GPIO, Timer, UART, USB CDC

The STM32H7 is the primary development target with full audio support: ADC (polling + DMA scan), DMA, SAI/I2S, and all DSP/widget layers verified on hardware.

Tools

SBL provides four Python tools that work together:

Tool Purpose When Run
cecrops SVD → C++ register headers Rare (new MCU/peripheral)
sloth Hardware resolution → config headers Every build (via CMake)
lute Lookup table generation (waveforms, pitch) When adding/changing tables
sbl Project configuration and utilities Project setup, queries

sloth - Hardware Resolution

sloth (Sound Byte Labs Open Tool for Hardware) resolves hardware manifests and generates type-safe C++ headers.

# Resolve and show hardware graph
python -m sloth graph targets/daisy.json
# Generate config headers
python -m sloth generate targets/daisy.json -o build/generated
# Query MCU info (used by CMake hooks)
python -m sloth resolve targets/daisy.json --print-mcu-name

cecrops - Register Generation

cecrops generates C++ register definitions from CMSIS-SVD files with manifest-driven configuration and integrated patching for SVD errata.

# Generate register headers from SVD
python -m cecrops generate sbl-hardware/mcu/arm/stm32h750
# Show SVD file info
python -m cecrops info path/to/file.svd

Each MCU using cecrops has a cecrops.json manifest defining SVD source, output peripherals, and patches. See FDP-009 for design details.

sbl - Project CLI

sbl provides project configuration and utility commands.

# Initialize a new SBL project
python -m sbl_cli init my-project --target daisy
# Show project info
python -m sbl_cli info

Repository Structure

sound-byte-libs/
├── src/sbl/ # Library source
│ ├── hal/ # Layer 1: Hardware abstraction + convenience
│ ├── primitives/ # Layer 2: Buffers, containers, math, IO
│ ├── dsp/ # Layer 3: DSP atoms (phase, filters, LUTs)
│ ├── patterns/ # Layer 3: Timing, synchronization
│ ├── components/ # Layer 4: CV, controls, display
│ ├── midi/ # Layer 4: MIDI parser + input
│ ├── usb/ # Layer 4: USB CDC
│ ├── widgets/ # Layer 5: Sources, processors, modulators
│ ├── log/ # Logging system
│ ├── validation/ # SFINAE contract validation
│ └── common/ # Shared constants
├── tools/ # sloth, lute, cmake hooks, sbl-cli
├── sbl-schema/ # Pydantic models → JSON schemas
├── test/ # 471 C++ tests, 53 Python tests
└── docs/ # Architecture, hardware system, guides

Examples (separate repository)

sound-byte-libs-examples/
├── hello-blinker/ # LED blinking (multi-platform)
├── hello-uart/ # Debug serial output
├── hello-adc/ # ADC DMA scan + CvInput smoothing
├── hello-dma/ # DMA memory transfer
├── hello-audio/ # SAI/I2S audio + knob-controlled pitch
├── hello-usb-cdc/ # USB virtual serial port
├── hello-controls/ # Buttons, encoder, LEDs, pots (Daisy Pod)
├── hello-synth/ # Subtractive synth voice with MIDI (Daisy Pod)
├── hello-instrument/ # Polyphonic SuperSaw chord instrument (Daisy Pod)
├── hello-i2c/ # I2C bus scanner (Daisy Seed)
└── hello-pwm/ # SoftPwm BCM LED driver (Daisy Pod)

Documentation

Document Description
Architecture System design and layer model
Hardware System sloth, manifests, code generation
Namespaces Namespace structure and includes
Style Guide Coding conventions
Roadmap Development milestones

Design Philosophy

  • Bare metal first - No vendor HALs, SVD-generated registers
  • Every byte matters - We celebrate small binaries
  • Audio timing - Designed for real-time constraints
  • Cross-vendor - Avoid platform lock-in
  • Templates for performance - Clean APIs, zero runtime overhead

License

Copyright (c) 2025 Michael Skiles. See LICENSE file.