Initial commit of a toy analogue audio generator

Key components:
- no_std core so it can be used bare metal on embedded systems
- default implementation for RPi 2350, with midi input and I2s output using PIO
- Visualiser for the web to play with on a dev system
This commit is contained in:
2026-03-23 15:06:31 +00:00
commit 496b6bdc71
34 changed files with 3662 additions and 0 deletions

99
README.md Normal file
View File

@@ -0,0 +1,99 @@
# Sound — Analogue Synthesiser
A modular analogue synthesiser written in Rust.
- **`synth-core`** — `no_std` DSP library (oscillators, filters, envelopes, LFO, MIDI). Runs on microcontrollers and WASM.
- **`synth-visualiser`** — browser-based visualiser (oscilloscope, spectrum analyser, patch bay) compiled to WebAssembly.
## Prerequisites
```sh
# Rust toolchain (stable)
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
# WASM target
rustup target add wasm32-unknown-unknown
# wasm-pack (builds and packages the WASM module)
cargo install wasm-pack
```
## Build
### synth-core (native — tests and development)
```sh
cargo build -p synth-core
cargo test -p synth-core
```
### synth-core (WASM — verify it cross-compiles)
```sh
cargo build -p synth-core --target wasm32-unknown-unknown
```
### synth-visualiser (browser)
Run from the workspace root:
```sh
wasm-pack build crates/synth-visualiser --target web --out-dir ../../www/pkg
```
This generates `www/pkg/` containing the compiled `.wasm` binary and the JS glue module.
## Run
Serve the `www/` directory with any static HTTP server. A browser is required (the Web Audio API is not available over `file://`).
```sh
# Python (no install needed)
python3 -m http.server --directory www 8080
# Or with npx serve
npx serve www
```
Then open [http://localhost:8080](http://localhost:8080).
## Microcontroller deployment
`synth-core` targets bare-metal Cortex-M out of the box. Add the relevant target and uncomment the linker flags in [`.cargo/config.toml`](.cargo/config.toml).
```sh
# Example: Daisy Seed / STM32H750 (Cortex-M7)
rustup target add thumbv7em-none-eabihf
cargo build -p synth-core --target thumbv7em-none-eabihf
```
A microcontroller runner crate (I²S output, UART MIDI) can be added as a new workspace member when needed.
## Project structure
```
sound/
├── crates/
│ ├── synth-core/ # no_std DSP library
│ │ └── src/
│ │ ├── oscillator.rs VCO — Sine, Saw, Square, Triangle, Pulse
│ │ ├── filter.rs SVF — LP / HP / BP / Notch
│ │ ├── envelope.rs ADSR envelope generator
│ │ ├── vca.rs Voltage-controlled amplifier
│ │ ├── lfo.rs Low-frequency oscillator
│ │ ├── midi.rs Byte-stream MIDI parser
│ │ ├── patch.rs Cable routing graph
│ │ ├── math.rs DSP utilities (lerp, dB, MIDI→Hz)
│ │ └── config.rs SampleRate type
│ └── synth-visualiser/ # WASM browser front-end
│ └── src/
│ ├── engine.rs AudioContext + AnalyserNode
│ ├── oscilloscope.rs Time-domain canvas view
│ ├── spectrum.rs FFT canvas view
│ ├── patchbay.rs Drag-and-drop patch cables
│ └── params.rs SynthParams (JSON serialisable)
└── www/
├── index.html Browser UI
├── bootstrap.js WASM loader (ES module)
└── pkg/ Generated by wasm-pack (git-ignored)
```