Expand description
§audio-automation
Generic automation system for audio parameters - framework-agnostic.
This crate provides:
- Automation curves - 20+ curve types including linear, exponential, bezier, and advanced easing
- Automation envelopes - Time-based parameter control with multiple points
- Automation states - DAW-style states (Off/Play/Write/Touch/Latch)
- Generic target system - Works with any parameter type via generics
- Serialization support - Save/load automation with serde
#![no_std]- Works on embedded and WASM targets (requiresalloc)
§Quick Start
use audio_automation::{AutomationEnvelope, AutomationPoint, CurveType};
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
enum Param { Volume, Cutoff }
let env = AutomationEnvelope::new(Param::Volume)
.with_point(AutomationPoint::new(0.0, 0.0))
.with_point(AutomationPoint::with_curve(4.0, 1.0, CurveType::Exponential))
.with_range(0.0, 1.0);
let value = env.get_value_at(2.0).unwrap();§Curve Types
- Linear - Straight line interpolation
- Exponential - Accelerating (ease-in)
- Logarithmic - Decelerating (ease-out)
- SCurve - S-shaped (ease in-out)
- Stepped - No interpolation (staircase)
- Bezier - Custom curve with control points
- Advanced Easing - Elastic, Bounce, Back, Circular, and polynomial variants
§Example: Transformations
use audio_automation::*;
let mut automation = AutomationEnvelope::new(Param::Volume)
.with_point(AutomationPoint::new(0.0, 0.0))
.with_point(AutomationPoint::with_curve(4.0, 1.0, CurveType::SCurve))
.with_point(AutomationPoint::new(8.0, 0.5));
automation
.shift_points(2.0)
.scale_time(1.5)
.clamp_values(0.0, 1.0);
assert!(automation.get_value_at(3.0).unwrap() < 0.1);§Example: Iterating and Indexing
use audio_automation::*;
let env = AutomationEnvelope::new(Param::Volume)
.with_point(AutomationPoint::new(0.0, 0.0))
.with_point(AutomationPoint::new(2.0, 0.5))
.with_point(AutomationPoint::new(4.0, 1.0));
// Index into points
assert_eq!(env[0].time, 0.0);
// Iterate over points
let times: Vec<f64> = (&env).into_iter().map(|p| p.time).collect();
assert_eq!(times, vec![0.0, 2.0, 4.0]);
// Iterate over a clip's envelopes
let clip = AutomationClip::new("Intro", 4.0)
.with_envelope("volume", AutomationEnvelope::new(Param::Volume)
.with_point(AutomationPoint::new(0.0, 0.0))
.with_point(AutomationPoint::new(4.0, 1.0)))
.with_envelope("cutoff", AutomationEnvelope::new(Param::Cutoff)
.with_point(AutomationPoint::new(0.0, 0.5))
.with_point(AutomationPoint::new(4.0, 1.0)));
for (key, envelope) in &clip {
let _ = envelope.get_value_at(2.0);
let _ = key;
}
// Index by key
assert!(clip["volume"].get_value_at(2.0).unwrap() > 0.0);Re-exports§
pub use clip::AutomationClip;pub use curve::CurveType;pub use envelope::AutomationEnvelope;pub use envelope::AutomationPoint;pub use envelope::SampleIterator;pub use state::AutomationState;