Expand description
§mixed-signals
Primitives for signals, waveforms, noise, easing, RNG, and shuffling.
§Core Philosophy: Bipolar Core, Explicit Normalization
All oscillators and noise generators output bipolar [-1, 1] by default.
This matches audio/synthesis conventions and enables mathematically correct composition.
For TUI animation (opacity, brightness, progress bars), call .normalized() to get [0, 1]:
use mixed_signals::prelude::*;
// Core signals are bipolar [-1, 1]
let sine = Sine::default();
assert_eq!(sine.sample(0.25), 1.0); // Peak at +1
assert_eq!(sine.sample(0.75), -1.0); // Trough at -1
// For TUI work, normalize to [0, 1]
let opacity = sine.normalized();
assert_eq!(opacity.sample(0.0), 0.5); // Center maps to 0.5
assert_eq!(opacity.sample(0.25), 1.0); // Peak maps to 1.0§Why “mixed-signals”?
This library mixes signal generators with utilities commonly needed alongside them: shuffles, easing functions, physics solvers, and deterministic RNG. Built for terminal animations, but the primitives have broad application.
§Signal Categories
- Generators: Sine, Triangle, Square, Sawtooth, Pulse, Step, Ramp, Constant, Keyframes, SpatialCoordinateSignal, OscillatorBank
- Noise: WhiteNoise, PerlinNoise, PinkNoise, CorrelatedNoise, SpatialNoise
- Random: GaussianNoise, PoissonNoise, PerCharacterNoise, ImpulseNoise, StudentTNoise
- Envelopes: ADSR, Linear, Impact, LinearDecay, ExponentialDecay
- Physics: DampedSpring, BouncingDrop, FrictionDecay, Pendulum, Orbit, Projectile, Attractor
- Composition: Add, Multiply, Mix, WeightedMix, Scale, Sum, FrequencyMod
- Processing: Normalized, Abs, Invert, Clamp, Remap, Quantize
- Shuffle: fisher_yates, sattolo, weighted, constrained, riffle, overhand, and more
§Quick Start
use mixed_signals::prelude::*;
// Oscillators output bipolar [-1, 1]
let sine = Sine::new(2.0, 1.0, 0.0, 0.0);
let bipolar_value = sine.sample(0.25);
// For TUI: normalize to [0, 1]
let opacity = sine.normalized();
let tui_value = opacity.sample(0.25);
// Compose signals
let noise = PerlinNoise::with_seed(42);
let organic = sine.mix(noise, 0.2).normalized();
// Physics-based animation
let bounce = BouncingDrop::rubber_ball(0.0, 300.0, 500.0);
let y_position = bounce.sample(0.3);§RNG API
Use rng::Rng for traditional random number generation:
use mixed_signals::rng::Rng;
let mut rng = Rng::with_seed(42);
let dice = rng.uniform(1.0, 7.0).floor() as i32; // 1-6
let hit = rng.chance(0.7); // 70% probability
let color = rng.choose(&["red", "green", "blue"]);§Context-Aware Signals
Signals can use runtime context for deterministic, reproducible behavior:
use mixed_signals::prelude::*;
let noise = PerCharacterNoise::with_seed(99);
let ctx = SignalContext::new(100, 42).with_char_index(5);
// Same context always produces same value
let value = noise.sample_with_context(0.5, &ctx);§Spatial coordinate leaves
mixed-signals now also provides small, context-aware spatial coordinate
signals intended for authored field generation in downstream systems:
- normalized coordinates:
sample_norm_x,sample_norm_y - raw cell coordinates:
sample_cell_x,sample_cell_y - centered coordinates:
sample_centered_x,sample_centered_y - cell-space radial helpers:
sample_radius,sample_angle - configurable cell-space distance:
CellDistanceSignal::radius_from - surface/frame-space helpers:
sample_surface_centered_x,sample_surface_centered_y,sample_surface_radius - configurable surface-space distance:
SurfaceDistanceSignal::radius_from - configurable surface-space angle:
SurfaceAngleSignal::angle_from - aspect-corrected surface distance/angle:
SurfaceDistanceSignal::aspect_radius_from,SurfaceAngleSignal::aspect_angle_from
The math module also exposes small shared geometry helpers such as:
euclidean_distance_2dmanhattan_distance_2dchebyshev_distance_2dcell_distance_to_nearest_edge
These are for reusable geometry formulas that are not themselves authored signal leaves but still belong in the common spatial substrate.
The spatial leaves are meant to be combined with the existing composition operators so downstream libraries can build spotlight cones, shockwaves, sweeps, and other spatial fields without bespoke closures or duplicated coordinate math.
The key distinction is:
- cell-space leaves describe the sampled cell lattice
- surface-space helpers describe continuous frame/surface geometry
When those differ, prefer adding a new explicit basis/helper rather than mutating the semantics of an older leaf.
Modules§
- composition
- Signal combinators such as add, multiply, mix, weighted mix, and modulation.
- core
- Shared low-level helpers used by noise and random signal implementations.
- easing
- Easing curves for animation timing and interpolation.
- envelopes
- Envelope generators for time-shaped control signals.
- generators
- Oscillator and utility signal generators.
- math
- Math kernels and geometry helpers used throughout the signal library.
- noise
- Noise generators for continuous stochastic signals.
- physics
- Physics solvers for UI animations and simulations.
- prelude
- Convenient re-exports for common usage.
- processing
- Signal post-processing operators such as clamp, remap, normalize, and filters.
- random
- Random signal generators for stochastic and noise-based effects.
- rng
- Central RNG interface for common randomness needs.
- shuffle
- Shuffle algorithms for collections.
- traits
- Core traits, ranges, context, and extension methods for all signals.
- types
- Serializable and ergonomic value types, including
types::SignalSpec.