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
100 lines
3.1 KiB
Markdown
100 lines
3.1 KiB
Markdown
# 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)
|
|
```
|