Skip to content

Modulation matrix: assignable LFOs for evolving motion #4

Description

@philoking

Summary

Add a small modulation matrix: 2–3 assignable LFOs that can be routed to part parameters and ridden automatically. The README already wishes for "a really slow LFO on a Part's position" — this generalises that into a first-class, seed-deterministic modulation layer.

Why it fits

Modular Riffs already has the intensity envelope (a per-bar energy curve), but no free, cyclic modulators. Slow LFOs on octave, gate length, density, or arp position are what make a patch breathe over minutes — the difference between a loop and a living jam — and they're idiomatic to the gear the app is driving.

Proposed scope

New module js/modmatrix.js

  • 2–3 LFO sources, each with: shape (sine / ramp / saw / square / random / sample-&-hold), rate (tempo-synced in beats, or free in seconds), depth, and probability (a % chance the modulation applies on each evaluation — controlled chaos).
  • Fully driven by the existing seeded PRNG so a seed reproduces the ride exactly.

Destinations (read points in js/generator.js / js/intensity.js)

  • Per part: octave, gate length, density / Activity, arp position / register.
  • Global (optional): Energy, Swing.
  • Evaluate modulators once per step/bar in the generation path; clamp to each destination's valid range.

UI (js/app.js, maybe js/timeline.js)

  • A compact matrix: rows = LFOs, columns = shape / rate / depth / probability + a destination picker. Optionally draw the active LFOs as faint moving lines on the timeline so the modulation is visible.
  • Persist in state (rides presets / export).

Where

New js/modmatrix.js; hooks in js/generator.js (apply at read points), js/app.js (UI + state), optional js/timeline.js (viz).

Done when

  • At least 2 LFOs can be routed to per-part octave / gate / density / arp position.
  • Tempo-synced and free rates both work; probability gates the effect.
  • Modulation is seed-deterministic.
  • Routings persist in presets / JSON.

Open questions

  • Bipolar vs unipolar per destination (octave wants bipolar, gate wants unipolar)?
  • Should a modulator be allowed to target Evolve, or keep mutation separate from modulation?

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions