Skip to main content

audio_automation/
lib.rs

1//! # audio-automation
2//!
3//! Generic automation system for audio parameters - framework-agnostic.
4//!
5//! This crate provides:
6//! - **Automation curves** - 20+ curve types including linear, exponential, bezier, and advanced easing
7//! - **Automation envelopes** - Time-based parameter control with multiple points
8//! - **Automation states** - DAW-style states (Off/Play/Write/Touch/Latch)
9//! - **Generic target system** - Works with any parameter type via generics
10//! - **Serialization support** - Save/load automation with serde
11//! - **`#![no_std]`** - Works on embedded and WASM targets (requires `alloc`)
12//!
13//! ## Quick Start
14//!
15//! ```rust
16//! use audio_automation::{AutomationEnvelope, AutomationPoint, CurveType};
17//!
18//! #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
19//! enum Param { Volume, Cutoff }
20//!
21//! let env = AutomationEnvelope::new(Param::Volume)
22//!     .with_point(AutomationPoint::new(0.0, 0.0))
23//!     .with_point(AutomationPoint::with_curve(4.0, 1.0, CurveType::Exponential))
24//!     .with_range(0.0, 1.0);
25//!
26//! let value = env.get_value_at(2.0).unwrap();
27//! ```
28//!
29//! ## Curve Types
30//!
31//! - **Linear** - Straight line interpolation
32//! - **Exponential** - Accelerating (ease-in)
33//! - **Logarithmic** - Decelerating (ease-out)
34//! - **SCurve** - S-shaped (ease in-out)
35//! - **Stepped** - No interpolation (staircase)
36//! - **Bezier** - Custom curve with control points
37//! - **Advanced Easing** - Elastic, Bounce, Back, Circular, and polynomial variants
38//!
39//! ## Example: Transformations
40//!
41//! ```rust
42//! use audio_automation::*;
43//!
44//! # #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
45//! # enum Param { Volume }
46//!
47//! let mut automation = AutomationEnvelope::new(Param::Volume)
48//!     .with_point(AutomationPoint::new(0.0, 0.0))
49//!     .with_point(AutomationPoint::with_curve(4.0, 1.0, CurveType::SCurve))
50//!     .with_point(AutomationPoint::new(8.0, 0.5));
51//!
52//! automation
53//!     .shift_points(2.0)
54//!     .scale_time(1.5)
55//!     .clamp_values(0.0, 1.0);
56//!
57//! assert!(automation.get_value_at(3.0).unwrap() < 0.1);
58//! ```
59//!
60//! ## Example: Iterating and Indexing
61//!
62//! ```rust
63//! use audio_automation::*;
64//!
65//! # #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
66//! # enum Param { Volume, Cutoff }
67//!
68//! let env = AutomationEnvelope::new(Param::Volume)
69//!     .with_point(AutomationPoint::new(0.0, 0.0))
70//!     .with_point(AutomationPoint::new(2.0, 0.5))
71//!     .with_point(AutomationPoint::new(4.0, 1.0));
72//!
73//! // Index into points
74//! assert_eq!(env[0].time, 0.0);
75//!
76//! // Iterate over points
77//! let times: Vec<f64> = (&env).into_iter().map(|p| p.time).collect();
78//! assert_eq!(times, vec![0.0, 2.0, 4.0]);
79//!
80//! // Iterate over a clip's envelopes
81//! let clip = AutomationClip::new("Intro", 4.0)
82//!     .with_envelope("volume", AutomationEnvelope::new(Param::Volume)
83//!         .with_point(AutomationPoint::new(0.0, 0.0))
84//!         .with_point(AutomationPoint::new(4.0, 1.0)))
85//!     .with_envelope("cutoff", AutomationEnvelope::new(Param::Cutoff)
86//!         .with_point(AutomationPoint::new(0.0, 0.5))
87//!         .with_point(AutomationPoint::new(4.0, 1.0)));
88//!
89//! for (key, envelope) in &clip {
90//!     let _ = envelope.get_value_at(2.0);
91//!     let _ = key;
92//! }
93//! // Index by key
94//! assert!(clip["volume"].get_value_at(2.0).unwrap() > 0.0);
95//! ```
96
97#![no_std]
98
99extern crate alloc;
100
101#[cfg(test)]
102extern crate std;
103
104pub mod clip;
105pub mod curve;
106pub mod envelope;
107pub mod state;
108
109pub use clip::AutomationClip;
110pub use curve::CurveType;
111pub use envelope::{AutomationEnvelope, AutomationPoint, SampleIterator};
112pub use state::AutomationState;
113
114pub mod prelude {
115    pub use crate::clip::AutomationClip;
116    pub use crate::curve::CurveType;
117    pub use crate::envelope::{AutomationEnvelope, AutomationPoint, SampleIterator};
118    pub use crate::state::AutomationState;
119}