Manguebyte Audio Framework
A modern, real-time-safe audio framework for Rust.
The crates are called manguebyte; the project is the Manguebyte Audio Framework.
Our goal is to be for Rust what JUCE is for C++, and then go further.
See where it already does.
Website: manguebyte.org
The goal
C++ has JUCE: one framework that takes you from an empty folder to a shipping synthesizer, effect plugin or audio application on every major platform. Rust has excellent audio crates, but they are scattered pieces that each project has to glue together on its own.
Manguebyte intends to be the complete equivalent of JUCE for Rust: audio and MIDI device I/O, DSP, audio file formats, a parameter system, plugin formats (CLAP, VST3, AU, LV2, standalone), plugin hosting, and a GUI toolkit, all designed to work together and all under a permissive license.
We do not want a port. We want what a framework looks like when it is designed for Rust from the first line:
- Fearless real-time code. Ownership rules catch data races between the audio thread and the UI at compile time, instead of as a crackle in production.
- Zero-cost composition. A tuple of processors is a processor. The chain is resolved at compile time, with no virtual calls and no allocation.
- Small, independent crates. Use the whole framework or only the buffer
type.
manguebyte-corehas no dependencies at all. - Permissive licensing. MIT or Apache-2.0, your choice. No copyleft, no per-seat fees, no splash screen.
Where it already goes beyond JUCE
Matching JUCE is the baseline. These are the places where Manguebyte already does something JUCE 9 does not, each one backed by a test that runs on every commit. docs/BEYOND_JUCE.md explains every row, with sources for what is said about JUCE and the limits of each claim.
| JUCE 9 | Manguebyte | Proof | |
|---|---|---|---|
| Automation timing | A processor reads each parameter once per block | Every change arrives with its frame and is applied on the exact sample | test |
| Block size | Whether the sound depends on the host's buffer size is up to each plugin | The same song rendered with six block patterns must match bit for bit | test |
| Changes from a UI or a restored state | Found by polling, or by listeners that can run on the audio thread | Delivered as events in the same stream as automation; no listeners exist | test |
| Real-time safety | A rule in the documentation | A counting allocator fails CI if any processor, or the plugin wrapper, touches the heap while processing | test |
| Per-note control | Through MPE channels | Note expression and modulation events addressed to one note, which MPE and MIDI 2.0 arrive as too, identical bit for bit; modulation never alters the stored value | test |
| CLAP | Not supported natively | One line, export_clap!; the example plugin passes the CLAP project's validator in CI |
CI |
| Testing a plugin | Needs a host or a hand-built rig | Harness plays notes and automation into a plugin inside a unit test |
example |
| Parameters and state across threads | Each plugin synchronises state access itself | Parameters are atomics; saving and loading need no lock and cannot race | test |
| Hosting plugins | No CLAP hosting; a hosted plugin is one object called from every thread; parameter changes carry no frame | Hosts CLAP and VST 3 with the thread rules in the types, and every event on its frame: hosted output is identical bit for bit to the plugin run alone | test |
| Loudness and broadcast meters | None in the documented API | BS.1770 / EBU R 128 loudness, true peak, VU, PPM and correlation, checked against the EBU's own test signals | test |
| OSC timing | Listeners on the message or network thread | A time-tagged bundle lands on its exact frame in the audio thread | test |
| Pitch and band analysis | None in the documented API | YIN and McLeod pitch detection with the note named; octave to twenty-fourth-octave bands on IEC 61260-1's frequencies, with A and C weighting | test |
| Keyboard state | Listeners that may run on the audio thread | Keys, velocities and the sustain pedal in atomics an interface polls; no listener, no lock, no heap call | test |
| Slow-downs in silence | A guard against subnormal numbers that each plugin places in its own callback | Set by the framework around every plugin and every device callback | test |
| Instruments ready to play | Classes to build an instrument from, none ready to play | Synthesised and modelled instruments and drum kits whose tuning and spectra are measured in tests, two of them against recordings | test |
| Changing the audio device | The device stops, and the callback is prepared again for the next one | The engine is prepared once and plays on while the output changes under it: a crossfade where two devices can play at once, a short faded gap where they cannot, the engine's output the same bit for bit | test |
| Licence | AGPLv3 or commercial | MIT or Apache-2.0 | licence |
These checks find real problems. The block-size test failed the first time it ran and exposed a voice that kept running after it had finished. The allocation guard caught a mutex that allocates on macOS. The CLAP validator and Miri each found a defect that the project's own tests had missed. The VST 3 wrapper's tests found a synth that forgot where the pitch wheel was between notes, and Steinberg's validator showed a class id that a session moved between Windows and macOS would not have recognised. The CLAP validator's timing of the example effect led to the framework guarding every plugin against subnormal numbers. All of them are fixed, and the checks stay in CI.
Where JUCE is ahead. JUCE has more than twenty years of production use
behind it and more breadth: a full GUI toolkit, with plugin editors on
macOS and Linux as well as Windows; AUv3 and AAX; Audio Units proven in
real hosts; hosting of plugins' editors; SIMD wrappers
and lookup tables among its DSP utilities; and applications that run on
iOS and Android. Manguebyte's editors open on Windows only, its Audio Unit
(version 2) passes auval in CI but has not been loaded in a DAW, its
mobile builds are compiled in CI but not run on a device, and it has none
of the rest yet. docs/JUCE_PARITY.md tracks the gap
module by module.
Status
Manguebyte is young. What exists is tested and usable, and it is enough to build and ship an instrument or effect as CLAP and VST 3, and to build the same plugin as an Audio Unit (version 2), an LV2 plugin and a standalone application, but it covers a small part of the road ahead and the API will change before 1.0. See ROADMAP.md for what exists and what is planned.
| Crate | What it gives you today |
|---|---|
manguebyte |
The whole framework under one name, plus a prelude; the plugin formats, editors, hosting and the sampler behind features |
manguebyte-core |
AudioBuffer, the Sample trait, Smoothed values, atomic floats, a wait-free SPSC queue, a log the audio thread can write to, decibel maths, a guard against subnormal numbers, and the AudioSource trait that device callbacks, graphs and mixers pull audio through, with audio in memory as a source |
manguebyte-dsp |
The Processor trait and tuple chains, sample-accurate events and transport, a polyphonic Synth with per-note expression, one reader that turns MIDI 1.0, MPE and MIDI 2.0 into per-note events, audio sources made of sources (a mixer, a sample rate converter, a channel router, a source through a processor) and sources as processors, band-limited oscillator, biquad filters (8 shapes), high-order IIR design (Butterworth, Chebyshev, elliptic), state-variable, one-pole and ladder filters, Linkwitz-Riley crossovers, ADSR envelope, interpolated delay lines and echo, chorus and flanger, phaser, compressor, noise gate, look-ahead limiter, reverb, waveshaper, dry/wet mixing, panner, envelope follower, oversampling, resampling at any ratio, noise, LFO, smoothed gain, FFT of any length, window functions, FIR design and a FIR filter, convolution with zero latency, true stereo and responses swapped while playing, an expander, sidechain keying for the dynamics, a band-limited wavetable oscillator, and instruments ready to play: physically modelled guitars and basses, four-operator FM, a tonewheel organ with a rotary speaker, the drums and kick bass of the classic analogue drum machine, an acid bass with accent and slide, mallets (marimba, vibraphone, xylophone, glockenspiel, celesta, kalimba, steel pan, tubular bells) by modal synthesis, bowed strings (violin to double bass, a section, pizzicato) and winds (flute, clarinet, saxophone, trumpet, trombone) by digital waveguide, choirs and a solo voice by formant synthesis, and drum kits: acoustic drums and cymbals by modal synthesis, calibrated against recordings, the 909, 606 and CR-78, and kits for trap, techno, house, drum and bass and lo-fi; and a deep polyphonic synthesiser (three oscillators with sixteen-voice unison and wavetables, two filters of fifteen models, a modulation matrix) with 68 presets for electronic and pop music |
manguebyte-analysis |
Loudness to BS.1770 and EBU R 128, checked against the EBU's test signals; true peak, peak, RMS, VU and PPM meters; stereo correlation; a spectrum analyser with octave bands and weighting; pitch detection. All real-time safe, readable from any thread |
manguebyte-graph |
A processing graph that is rewired while it plays: edits reach the audio thread through a wait-free queue, nodes keep their state, removed nodes are freed off the audio thread, and paths of different latency are lined up automatically |
manguebyte-params |
Lock-free float, integer, switch and choice parameters; linear, skewed and logarithmic ranges; text conversion; smoothing; saved state that survives version changes; descriptions of every parameter (range, curve, steps, names, smoothing) as data and as JSON for a web editor |
manguebyte-state |
Application state for editors: a document tree with stable ids, undoable named transactions, gestures that are one undo step, history limits, change journals instead of listeners, a mirror of the parameters where host automation never enters the history, saved with the plugin's state; text and binary forms with migrations, a settings file, and snapshots handed to the audio thread without allocating |
manguebyte-plugin |
The Plugin trait every format wraps, with the MIDI controllers it listens to, how it reads MPE, the notes, expressions and MIDI it sends out and their translation to MIDI 2.0, MIDI 1.0 or MPE, plugin state, and a Harness that plays notes, automation and a sidechain into a plugin inside a unit test and keeps what it sends |
manguebyte-clap |
Exports a Plugin as a CLAP plugin with one line. Notes, expression, automation and modulation arrive on their exact frame, and a plugin's notes, expressions and MIDI go out through an output note port. Passes the CLAP project's validator |
manguebyte-vst3 |
Exports the same Plugin as a VST 3 plugin with one line. Every automation point lands on its frame; notes carry ids, tuning and per-note expression; the MIDI controllers the plugin declares arrive as MIDI again; a plugin's notes and expressions go out through an output event bus. Passes Steinberg's validator on Windows, Linux and macOS |
manguebyte-lv2 |
Exports the same Plugin as an LV2 plugin with one line, and generates its Turtle files; cargo mangue writes the .lv2 bundle. Tested through its C interface in process, and CI loads the example plugins' bundles with lilv; not yet checked by lv2lint or loaded in any host but the framework's own |
manguebyte-au |
Exports the same Plugin as an Audio Unit (version 2) for macOS with one line; cargo mangue writes and installs the .component. Tested through its C interface on every system, and both example plugins pass Apple's auval in a macOS CI job |
manguebyte-host |
Loads CLAP, VST 3, LV2 and Audio Unit (version 2) plugins made by anyone and runs them as processors, through one interface for all four formats, with every event on its frame and nothing allocated while processing; LV2 bundles read with its own Turtle reader, Audio Units found and made through AudioToolbox on macOS. Finds the plugins installed on a system and lists them in a process of their own, so one that crashes or hangs is reported and the host goes on, with a cache of what it found |
manguebyte-midi |
MIDI 1.0 channel and system messages, a byte-stream parser, standard MIDI files, sample-accurate MidiBuffer; MIDI 2.0 packets (UMP) and translation between the protocols; RPN and NRPN; MPE zones and note tracking; keyboard state; MIDI-CI: discovery, profiles, property exchange and process inquiry, and a device agent an application drives |
manguebyte-formats |
WAV (with RF64), AIFF, FLAC, Ogg Vorbis, Ogg Opus (CELT) and MP3, read and written, and MPEG layers I and II read, whole or block by block with exact seeking; codecs written from their specifications: FLAC checked against FFmpeg, the Vorbis, Opus and MPEG decoders tested on files libvorbis, libopus, LAME and FFmpeg wrote, the Vorbis and MP3 encoders' files decoded by FFmpeg and libvorbis to the same audio and length, and the Opus encoder's by this crate's decoder, to the exact length; tags, cue points, loops, Broadcast Wave fields and pictures in one metadata model, kept on a round trip; waveform thumbnails with a cache; AAC, ALAC and WMA through the system's codecs on Windows and macOS; wait-free bridges to play and record from an audio callback, and a transport source: play, pause, stop, seek and loop a streamed file from any thread, sample-exact |
manguebyte-osc |
Open Sound Control over UDP and TCP, with a real-time bridge that puts time-tagged bundles on their exact frame |
manguebyte-devices |
Audio hosts (WASAPI, ASIO, CoreAudio, ALSA, JACK, AAudio), device listing and selection, playback, recording and full-duplex streams that follow the drift between two devices' clocks, in any hardware sample format, with timing and latency in every callback; a device manager that saves its setup and restores it with fallbacks, follows devices as they are plugged in and out (by polling), and changes the devices under a running engine without stopping it or preparing it again, crossfading where two devices can play at once; a public AudioBackend seam for backends from other crates; MIDI input and output ports, virtual ones too, with arrival times mapped to frames so a player's timing survives the audio buffer, read into per-note events for MPE, system exclusive input for MIDI-CI, and packets sent from the audio thread when their frame is heard, unchanged to ports that speak MIDI 2.0 (macOS, iOS, Linux) and as MIDI 1.0 bytes to the others; a headless backend for tests |
manguebyte-ump-io |
The systems' own Universal MIDI Packet output for manguebyte-devices, which forbids unsafe: CoreMIDI's MIDISendEventList in the MIDI 2.0 protocol (macOS, iOS) and the ALSA sequencer's UMP events (Linux), opened at run time with dlopen so an older system falls back to MIDI 1.0 and says why; CoreMIDI's event list and the sequencer's UMP event laid out in Rust and tested on every system |
manguebyte-pro-io |
GPLv3, opt-in. ASIO drivers spoken to directly: listing from the registry, loading t |
