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}