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, 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_2d
  • manhattan_distance_2d
  • chebyshev_distance_2d
  • cell_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.