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
- 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);Modules§
- composition
- core
- easing
- envelopes
- Envelope generators for time-shaped control signals.
- generators
- Oscillator and utility signal generators.
- math
- noise
- Noise generators for continuous stochastic signals.
- physics
- Physics solvers for UI animations and simulations.
- prelude
- Convenient re-exports for common usage.
- processing
- random
- Random signal generators for stochastic and noise-based effects.
- rng
- Central RNG interface for common randomness needs.
- shuffle
- Shuffle algorithms for collections.
- traits
- types