Skip to main content

Crate mixed_signals

Crate mixed_signals 

Source
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