Skip to main content

audiobox/
lib.rs

1//! Audio decoding, editing, analysis and encoding in safe Rust, with zero dependencies,
2//! and the audio side of a game: a real-time mixer, an 8-bit synthesizer and
3//! parametric sound effects.
4//!
5//! The crate uses only the standard library: no C libraries, FFmpeg, build scripts or
6//! `unsafe`. It compiles to WebAssembly, and its synthesizer, effects and mixer give
7//! the same samples on every platform.
8//!
9//! ```
10//! use audiobox::{AudioFormat, NormalizeOptions, decode, encode};
11//!
12//! fn prepare(bytes: &[u8]) -> audiobox::Result<Vec<u8>> {
13//!     let clip = decode(bytes)?
14//!         .cut(1.5, 30.0)?
15//!         .to_mono()
16//!         .resample(16_000)?
17//!         .normalize(NormalizeOptions::default())?;
18//!     encode(&clip, AudioFormat::Flac)
19//! }
20//! # let wav = encode(&audiobox::Audio::new(vec![vec![0.1; 48_000 * 2]], 48_000)?, AudioFormat::Wav)?;
21//! # prepare(&wav)?;
22//! # Ok::<(), audiobox::Error>(())
23//! ```
24//!
25//! # What is included
26//!
27//! | Area | Items | Feature |
28//! | --- | --- | --- |
29//! | Decoding and encoding | [`decode`], [`encode`], [`read_audio_file`], [`write_audio_file`] for WAV, AIFF, CAF, AU, FLAC and MP3 | always |
30//! | Editing and DSP | [`Audio`]: cut, concat, mix, fades, filters, resampling, limiter, tempo and pitch | always |
31//! | Analysis | [`Audio::loudness`], peaks, RMS, [`analyze::spectrum`], waveforms | always |
32//! | Streaming | [`stream::Decoder`] for WAV, FLAC and MP3 a chunk at a time with seeking; raw PCM and resampling across chunks | always |
33//! | Disk streaming | `stream::FileStream`: a native reader thread and bounded PCM/encoded buffers | `file-stream` |
34//! | Synthesizer | [`synth`]: text scores rendered in an 8-bit style | `synth` |
35//! | Sound effects | [`sfx`]: parameters, text form and seeded presets | `sfx` |
36//! | Game mixer | [`mixer`]: voices, buses, fades, loops and an allocation-free `render` | `mixer` |
37//! | Sound assets | [`assets`]: background loading and a budgeted decoded-audio cache | `assets` |
38//! | Adaptive music | [`music`]: beat/bar transitions, crossfades, cues and intensity layers | `music` |
39//! | Sound events | [`events`]: named text events with seeded choices, variation and limits | `events` |
40//!
41//! Enable the optional modules you use:
42//!
43//! ```toml
44//! [dependencies]
45//! audiobox = { version = "0.5", features = ["mixer", "synth", "sfx"] }
46//! ```
47//!
48//! # Determinism
49//!
50//! These give the same samples on every platform, including WebAssembly: the
51//! synthesizer, the sound effects and the mixer, and the offline transforms that render
52//! audio — [`Audio::pan`], [`Audio::gain`] and [`Audio::gain_db`], [`Audio::fade`],
53//! [`Audio::crossfade_to`], [`Audio::filter`], [`Audio::limit`], [`Audio::limit_true_peak`],
54//! [`Audio::resample`],
55//! [`Audio::tempo`], [`Audio::pitch`], [`Audio::trim_silence`],
56//! [`Audio::normalize`], and [`analyze::from_db`]. They compute with the crate's own
57//! sine and `2^x` series instead of the platform's `sin`, `cos`, `exp` and `powf`, whose
58//! last bits can differ between systems; CI pins their output with checksums on Linux,
59//! macOS, Windows and WebAssembly. Analysis that only reports numbers, such as
60//! loudness, true peak and spectra, use the platform's math. Normalization in every
61//! unit uses a separate deterministic measurement path and reports its values
62//! through [`Audio::normalize_with_report`]. [`Audio::measure_deterministic`] exposes
63//! that path for non-mutating final validation. Both LUFS paths require >= 4000 Hz.
64//!
65//! Integer PCM export supports optional seeded [`Dither::Tpdf`] noise through
66//! [`EncodeOptions::dither`]. Its quantization is deterministic, including FLAC and
67//! [`stream::PcmEncoder::with_dither`] across chunk boundaries. Dither is disabled
68//! by default; float, G.711 and MP3 output reject enabled dither.
69//!
70//! Errors are [`Error`] values with a stable [`ErrorCode`]. Decoding is bounded by
71//! [`Limits`], checked before allocating. The [website](https://jmsansan.github.io/audiobox-rs/)
72//! has a browser sandbox and a sound-effect and chiptune playground that run this crate
73//! through WebAssembly.
74#![forbid(unsafe_code)]
75#![cfg_attr(docsrs, feature(doc_cfg))]
76pub mod analyze;
77#[cfg(feature = "assets")]
78#[cfg_attr(docsrs, doc(cfg(feature = "assets")))]
79pub mod assets;
80mod audio;
81mod codec;
82mod decoder;
83mod dsp;
84mod error;
85mod flac;
86mod formats;
87#[cfg(feature = "mixer")]
88mod identity;
89mod io;
90mod math;
91pub mod metadata;
92#[cfg(feature = "mixer")]
93#[cfg_attr(docsrs, doc(cfg(feature = "mixer")))]
94pub mod mixer;
95mod ogg;
96#[cfg(feature = "events")]
97#[cfg_attr(docsrs, doc(cfg(feature = "events")))]
98pub use mixer::events;
99#[cfg(feature = "music")]
100#[cfg_attr(docsrs, doc(cfg(feature = "music")))]
101pub use mixer::music;
102pub mod mp3;
103pub mod pcm;
104#[cfg(feature = "sfx")]
105#[cfg_attr(docsrs, doc(cfg(feature = "sfx")))]
106pub mod sfx;
107pub mod stream;
108#[cfg(feature = "synth")]
109#[cfg_attr(docsrs, doc(cfg(feature = "synth")))]
110pub mod synth;
111#[cfg(any(feature = "synth", feature = "music"))]
112mod timing;
113mod true_peak;
114mod types;
115pub use audio::Audio;
116pub use codec::{
117    ReadAudioOptions, decode, decode_with_options, encode, encode_with_options, read_audio_file,
118    read_audio_file_with_options, sniff, write_audio_file,
119};
120pub use dsp::*;
121pub use error::{Error, ErrorCode, Result};
122pub use metadata::{CoverArt, Tags};
123pub use true_peak::TruePeakLimiterOptions;
124pub use types::*;