Skip to content

SuperInstance/tropical-synth

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

5 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

tropical-synth

Sound design via tropical geometry β€” draw a tropical curve, hear the sound.

The Problem

Synthesizer patch design is an art form. You twiddle knobs until something sounds right, but there's no mathematical framework that tells you why a patch works or how to smoothly morph between two patches. The space of possible sounds is vast and unstructured.

The Key Insight

Tropical geometry replaces addition with max and multiplication with addition. This simple change turns smooth algebraic curves into piecewise-linear ones with sharp corners and edges. And those corners and edges map perfectly to synthesizer parameters:

  • Each vertex of a tropical polynomial β†’ a distinct synth patch
  • Each edge between vertices β†’ a smooth morphing path between patches
  • The Newton polytope (the convex hull of exponent vectors) β†’ the entire timbre space

The "aha moment" is that tropical polynomials are the same as ReLU neural networks. A tropical polynomial max(c₁ + a₁·x, cβ‚‚ + aβ‚‚Β·x, ...) is exactly a single-layer ReLU network with specific weight constraints. This means:

  • Sound design = network architecture design
  • Patch morphing = interpolation along tropical edges
  • Timbre space = Newton polytope of the tropical polynomial

This crate implements:

  • The tropical semiring (max-plus algebra) with proper Add and Mul operators
  • Tropical polynomials with evaluation and active-region classification
  • Newton polytopes (vertices as synth patches)
  • SynthPatch β€” full synthesizer parameters derived from tropical vertices
  • MorphPath β€” linear interpolation between patches along tropical edges
  • TimbreSpace β€” the complete navigable sound-design space
  • MIDI CC mapping β€” convert any patch to standard MIDI control messages

Architecture

    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
    β”‚            TimbreSpace                        β”‚
    β”‚ (polynomial β†’ patches β†’ morph paths)          β”‚
    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                    β”‚
    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
    β”‚          TropicalPolynomial                   β”‚
    β”‚ (max of tropical monomials)                   β”‚
    β”‚ evaluate(), active_monomial(), classify_grid()β”‚
    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                    β”‚
         β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
         β”‚                     β”‚
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Tropical        β”‚  β”‚ Newton          β”‚
β”‚ Monomial        β”‚  β”‚ Polytope        β”‚
β”‚ (c βŠ— x₁^a₁ βŠ— …)β”‚  β”‚ (vertices =     β”‚
β”‚                 β”‚  β”‚  patches)       β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                              β”‚
                    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                    β”‚ SynthPatch        β”‚
                    β”‚ (oscillators,     β”‚
                    β”‚  filter, envelope,β”‚
                    β”‚  effects)         β”‚
                    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                              β”‚
              β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
              β”‚               β”‚               β”‚
     β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”
     β”‚  MorphPath    β”‚ β”‚  MIDI CC   β”‚ β”‚  Patch      β”‚
     β”‚  (lerp at t)  β”‚ β”‚  Mapper    β”‚ β”‚  from_vertexβ”‚
     β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Module Overview

Module Purpose
semiring The tropical semiring: Tropical(f64) with max-plus algebra
polynomial Tropical monomials, polynomials, Newton polytopes
patch SynthPatch with oscillators, filter, envelope, effects
morph MorphPath β€” linear interpolation between patches
timbre TimbreSpace β€” the full navigable sound space
midi MIDI CC mapping from patches to control messages
error Error types

The Math: Tropical Geometry

The Tropical Semiring (ℝ βˆͺ {βˆ’βˆž}, max, +)

Operation Standard Tropical
Addition (βŠ•) a + b max(a, b)
Multiplication (βŠ—) a Γ— b a + b
Zero (additive identity) 0 βˆ’βˆž
One (multiplicative identity) 1 0
Power: xⁿ x Γ— x Γ— ... Γ— x x + x + ... + x = nΒ·x
use tropical_synth::Tropical;

let a = Tropical(3.0);
let b = Tropical(5.0);

// Tropical addition = max
assert_eq!(a + b, Tropical(5.0));

// Tropical multiplication = addition
assert_eq!(a * b, Tropical(8.0));

// Identities
assert_eq!(Tropical::ZERO + a, a);  // -∞ βŠ• a = a
assert_eq!(Tropical::ONE * a, a);   // 0 βŠ— a = a

// Power = scalar multiplication
assert_eq!(Tropical(3.0).pow(4), Tropical(12.0));

Tropical Polynomials

A tropical polynomial is the max of tropical monomials:

p(x) = max(c₁ + a₁·x₁ + b₁·xβ‚‚, cβ‚‚ + aβ‚‚Β·x₁ + bβ‚‚Β·xβ‚‚, ...)

Each monomial is a hyperplane in the input space. The polynomial's graph is a piecewise-linear convex function whose "corners" are where the active monomial changes.

use tropical_synth::{TropicalPolynomial, TropicalMonomial};

let poly = TropicalPolynomial::new(vec![
    TropicalMonomial::new(0.0, vec![2, 0]),  // 2x₁
    TropicalMonomial::new(0.0, vec![0, 2]),  // 2xβ‚‚
    TropicalMonomial::new(3.0, vec![1, 1]),  // 3 + x₁ + xβ‚‚
]);

// Evaluate at a point
let val = poly.evaluate(&[1.0, 2.0]).unwrap();
// max(2Β·1, 2Β·2, 3+1+2) = max(2, 4, 6) = 6

// Which monomial is active?
let idx = poly.active_monomial(&[10.0, 0.0]).unwrap();
// At (10, 0): 2Β·10=20 wins β†’ monomial 0

Newton Polytopes

The Newton polytope of a tropical polynomial is the convex hull of the exponent vectors. Each vertex of this polytope corresponds to a monomial, and in this crate, to a synth patch.

The edges of the Newton polytope are the morph paths β€” smooth transitions between patches where one monomial hands off to another.

The Connection to ReLU Networks

A tropical polynomial max(c₁ + a₁·x, ..., cβ‚™ + aβ‚™Β·x) is exactly a single-layer ReLU network:

y = max_i (cα΅’ + aα΅’ Β· x) = max(WΒ·x + b)

This means:

  • Training a ReLU network = fitting a tropical polynomial
  • Network width = number of monomials
  • Network depth = degree of the polynomial
  • Sound design = network architecture design

Quick Start

use tropical_synth::{
    TropicalPolynomial, TropicalMonomial, TimbreSpace, MorphPath
};

// Define a tropical polynomial (3 patches in 2D parameter space)
let poly = TropicalPolynomial::new(vec![
    TropicalMonomial::new(0.0, vec![2, 0]),
    TropicalMonomial::new(0.0, vec![0, 2]),
    TropicalMonomial::new(3.0, vec![1, 1]),
]);

// Build the timbre space
let space = TimbreSpace::new(poly).unwrap();
println!("{} patches", space.len());

// Get the active patch at a parameter point
let patch = space.active_patch(&[5.0, 0.0]).unwrap();
println!("Filter cutoff: {:.0} Hz", patch.filter.cutoff_hz);

// Morph between two patches
let mut morph = space.morph(0, 1).unwrap();
morph.set_t(0.5).unwrap();
let mid = morph.current_patch();
println!("Midpoint cutoff: {:.0} Hz", mid.filter.cutoff_hz);

SynthPatch: Vertex β†’ Sound

Each vertex of the Newton polytope maps to a full synth patch:

use tropical_synth::SynthPatch;

// From a tropical vertex (exponents, coefficient)
let patch = SynthPatch::from_vertex(&[2, 1], 1.5);
// - Exponent sum β†’ number of oscillators (1-3)
// - First exponent β†’ waveform (saw, square, triangle, sine, noise)
// - Coefficient β†’ filter cutoff (logarithmic)
// - Second exponent β†’ envelope attack

println!("Oscillators: {}", patch.oscillators.len());
println!("Waveform: {:?}", patch.oscillators[0].waveform);
println!("Cutoff: {:.0} Hz", patch.filter.cutoff_hz);
println!("Attack: {:.3}s", patch.envelope.attack_s);

MIDI CC Mapping

Any patch can be converted to standard MIDI CC messages:

use tropical_synth::{SynthPatch, MidiCCMapper};

let mapper = MidiCCMapper::new(0); // channel 0
let patch = SynthPatch::simple();
let messages = mapper.map_patch(&patch).unwrap();

for msg in &messages {
    println!("CC{} = {} (ch{})", msg.cc, msg.value, msg.channel);
}
// Output: CC7 (volume), CC74 (brightness), CC73 (attack), CC72 (release), etc.

Standard CC mappings:

Parameter CC Number
Volume 7
Brightness (filter cutoff) 74
Filter resonance 71
Attack 73
Release 72
Decay 75
Sustain 70
Reverb 91
Chorus 93
Detune 94

Performance

  • Tropical evaluation: O(n) where n = number of monomials
  • Active monomial: O(n) linear scan
  • Grid classification: O(resolution^d) where d = dimensionality
  • Patch morphing: O(1) β€” linear interpolation of numeric fields
  • MIDI mapping: O(1) per patch

All operations are real-time safe β€” no allocation in the hot path.

Comparison

Feature tropical-synth Traditional synths Neural audio
Patch structure Tropical vertices Knob positions Network weights
Morphing Tropical edge interpolation Crossfade Latent interpolation
Space structure Newton polytope Unstructured Latent space
Mathematical foundation Tropical geometry / ReLU networks None Deep learning
MIDI output βœ… Built-in βœ… Native ❌
Patch from math βœ… from_vertex() ❌ ❌

SuperInstance Ecosystem

tropical-synth integrates with:

  • lotka-beats β€” species timbre profiles use tropical patches
  • groovemesh-plr β€” PLR transitions mapped to tropical morph paths
  • spreadsheet-engine β€” tropical polynomials as formula cell inputs
  • noether-guard β€” conservation checking for energy-like tropical quantities

License

MIT

About

πŸ”Ί Sound design via tropical geometry β€” tropical polynomials map to ReLU networks, Newton polytopes shape timbre

Topics

Resources

License

Code of conduct

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Packages

 
 
 

Contributors

Languages