Skip to main content

tono_core/
lib.rs

1//! Tono core — the pure, headless audio engine.
2//!
3//! This crate is the deterministic heart of tono with **no I/O and no
4//! transport**. Rendering is a pure function of `(graph, seed, sample_rate)`
5//! → byte-identical audio, so a sound is data you can test, diff, and cache:
6//!
7//! ```
8//! use tono_core::dsl::SoundDoc;
9//! use tono_core::render;
10//!
11//! let doc: SoundDoc = serde_json::from_str(r#"{
12//!     "name": "blip", "duration": 0.3, "engine": 4,
13//!     "root": { "type": "mul", "inputs": [
14//!         { "type": "sine", "freq": 880 },
15//!         { "type": "env", "a": 0.002, "d": 0.08, "s": 0.0, "r": 0.05 } ] }
16//! }"#).unwrap();
17//!
18//! let a = render::render(&doc);
19//! let b = render::render(&doc);
20//! assert_eq!(a, b); // byte-identical every run
21//! ```
22//!
23//! # The map
24//!
25//! Authoring: [`dsl`] (the `SoundDoc` graph + validation) · [`patch`]
26//! (templates with named parameters) · [`edit`] (path-addressed edits) ·
27//! [`vary`] (deterministic variations).
28//!
29//! Rendering: [`render`] (the offline bounce) · [`streaming`] (real-time,
30//! byte-identical to the bounce) · [`dsp`] (RNG, loudness, limiting) ·
31//! [`player`] (buffer playback).
32//!
33//! Playing live: [`runtime`] (the [`runtime::AudioSource`] seam, `Engine`,
34//! `Mixer`, the wait-free split) · [`instrument`] (polyphonic playable
35//! voices) · [`drumkit`] · [`adaptive`] (intensity stems, quantized
36//! transitions, stingers).
37//!
38//! Composing: [`song`] (tracks/patterns/arrangement, compiles to a plain
39//! `SoundDoc`) · [`catalog`] + [`presets`] (ready-made voices).
40//!
41//! Feedback: [`analysis`] (stats + spectrogram/waveform images) · [`review`]
42//! (grade a sound against its archetype).
43//!
44//! # Features and the shell
45//!
46//! The lean build is pure compute (serde only); the heavy deps are optional,
47//! behind features (both on by default): `analysis` pulls in rustfft + image for
48//! [`analysis`]/[`review`], and `sampler` pulls in rustysynth for the SoundFont
49//! sampler instrument. So the same core compiles to a native binary, a WASM
50//! playground, or a lean in-engine runtime. The `tono render` CLI, audio-file
51//! encoders, and MIDI export live in the `tono` shell crate that depends on this one.
52//!
53//! Longer-form guides: the [cookbook] (the node vocabulary + recipes) and the
54//! [architecture guide] (how the pieces compose, bottom-up).
55//!
56//! [cookbook]: https://github.com/marmikshah/tono/blob/master/docs/cookbook.md
57//! [architecture guide]: https://marmikshah.github.io/tono/architecture.html
58
59#![warn(missing_docs)]
60
61pub mod adaptive;
62#[cfg(feature = "analysis")]
63pub mod analysis;
64pub mod catalog;
65pub mod drumkit;
66pub mod dsl;
67pub mod dsp;
68pub mod edit;
69pub mod instrument;
70pub mod patch;
71pub mod player;
72pub mod presets;
73pub mod render;
74#[cfg(feature = "analysis")]
75pub mod review;
76pub mod runtime;
77pub mod song;
78pub mod streaming;
79pub mod vary;
80
81/// The workhorse names in one import: `use tono_core::prelude::*;` covers the
82/// primary flow (author a doc or a [`song::Song`], render it, analyze it, play
83/// it) without hunting across the crate's nineteen modules.
84pub mod prelude {
85    pub use crate::adaptive::{AdaptiveMusic, LoopBuffer, Quantize};
86    #[cfg(feature = "analysis")]
87    pub use crate::analysis::{Analysis, stats, stats_stereo};
88    pub use crate::catalog::{
89        Bass, Drums, ElectricPiano, GrandPiano, Guitar, Organ, Strings, Voice,
90    };
91    pub use crate::dsl::{Adsr, ENGINE_VERSION, Node, SeqNote, SeqWave, SoundDoc, Value};
92    pub use crate::instrument::{Instrument, InstrumentDesign, Note};
93    pub use crate::patch::Patch;
94    pub use crate::render::{RenderProduct, render, render_product};
95    pub use crate::runtime::{
96        AudioSource, Engine, InstanceHandle, Mixer, PatchId, Priority, StreamSource, Tween,
97    };
98    pub use crate::song::{Song, note, note_vel};
99}