1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
//! runtime — the embeddable real-time control surface over the deterministic engine.
//!
//! The idiomatic library API a game (or any host) drives: [`Engine::load`] a
//! [`SoundDoc`](crate::dsl::SoundDoc) (or [`Engine::load_patch`] a [`Patch`](crate::patch::Patch) with named parameters) as
//! a reusable **resource**, [`Engine::play`] as many independent **instances** as
//! you like, and control each by its [`InstanceHandle`] with [`Tween`]-smoothed
//! setters. Host output adapters (cpal, an AudioWorklet, a Bevy source) target
//! the [`AudioSource`] trait, so they never depend on a concrete engine type.
//!
//! Backed today by the deterministic buffer renderer ([`crate::player::Player`]),
//! which keeps the mix **byte-identical to an offline bounce**. Instance master
//! controls (gain / pan / stop) apply live per block; parameter and layer-gain
//! changes ([`Engine::set_param`] / [`Engine::set_layer_gain`]) re-render the
//! instance and **crossfade** for a click-free swap — control-rate today, and
//! sample-accurate once the stateful streaming renderer lands behind this same
//! seam. Multi-threaded real-time use goes through [`Engine::split`].
//!
//! # Adapters
//!
//! A host output is a thin shim over [`AudioSource`] + [`Engine::split`]. cpal:
//!
//! ```ignore
//! let (mut control, mut audio) = Engine::new(sr).split(2048);
//! let stream = device.build_output_stream(
//! &config,
//! move |out: &mut [f32], _| { audio.fill(out); }, // audio thread drains the ring
//! err_fn, None,
//! )?;
//! stream.play()?;
//! // On a control thread: loop { control.pump(1024); std::thread::sleep(dt); }
//! ```
//!
//! A Bevy `Decodable` / rodio `Source` wraps the same [`Renderer`]; an
//! AudioWorklet calls [`AudioSource::fill`] on each 128-frame quantum.
/// Pre-allocated scratch depth (frames) shared by the runtime's `fill` paths
/// ([`Engine`], [`Mixer`], [`StreamSource`]): covers any host block up to this
/// size without allocating in the audio callback; a larger block grows the
/// scratch once, on the first such call.
pub const SCRATCH_FRAMES: usize = 8192;
pub use ;
pub use ;
pub use ;
pub use ;