Skip to content

Releases: simonholliday/subsequence

v0.5.0 - API vocab overhaul, plus misc features and fixes

01 Jun 13:58

Choose a tag to compare

Breaking changes - API vocab has been unified for consistency:

  • Decorators @pattern/@layer/@triggerunit= -> step_duration=
  • p.strum()offset= -> spacing=
  • p.swing()amount= -> percent=
  • p.evolve()steps= -> length=
  • p.fibonacci()steps= -> count= (now a required argument)
  • p.branch()seed=(pitch list) -> pitches= (and a new integer seed= for the RNG)
  • p.cellular_2d(): the overloaded seed= split into initial_state= ("center"/"random"/grid) + an integer seed=
  • Generators (euclidean, bresenham, cellular, etc.): dropout= -> probability= - and the meaning flipped to "chance a note plays" (1.0 = always), consistent with hit_steps/sequence
  • Also removed the pre-existing cellular/generate_cellular_automaton no-op aliases

Behaviour change (not breaking but will sound different):

  • p.broken_chord() default velocity 100 -> 90, matching the softer chord/strum bucket. Velocity defaults are now routed through named constants (single 100 / chord 90 / generative 80 / cellular 60 / ghost 35).

New features:

  • Declarative chord progressions - new p.progression() and comp.chords(), plus between(low, high, step=...) for irregular/quantised harmonic rhythm (new progression.py + harmonic_rhythm.py modules, new public exports).
  • Per-device latency compensation - latency_ms can now be set at device initialization; the engine aligns faster devices to the slowest so multi-device rigs stay phase-tight.
  • Unified randomness controls - seed=/rng= are now accepted consistently across the generative methods (precedence rng > seed > the pattern's own RNG).

Instruments & harmony

  • Ambiguous GM drum mappings removed, drum map tidied; bumped to the latest PyMidiDefs.
  • Chord-graph refinements (functional-major, aeolian/dorian-minor, lydian-major, chromatic-mediant) making more diatonic colour chords reachable.

Also various fixes and documentation corrections.

Full Changelog: v0.4.1...v0.5.0

v0.4.1 - Feature Release

25 May 07:45

Choose a tag to compare

  • Create sandbox folder for local work
  • Documentation improvements
  • Add "detatched" articulation
  • Add universal velocity tuple syntax
  • Fix for crash in live-coding

Full Changelog: v0.4.0...v0.4.1

v0.4.0 - Feature Release

22 May 18:38

Choose a tag to compare

  • CC name maps - string-based CC access in p.cc() / p.cc_ramp() via cc_name_map= on the decorator
  • RPN/NRPN parameter control - p.nrpn(), p.rpn(), nrpn_ramp(), rpn_ramp() with name-map resolution and the same-pulse FIFO ordering fix in the sequencer
  • MIDI mirroring - mirrors=[(device, channel), ...] on patterns/layers/triggers; runtime composition.mirror() / unmirror() / unmirror_all()
  • Live coding (two flavours) - file-watching via composition.watch(path); in-memory string via composition.load_patterns(source); both share the diff-and-unregister pipeline via _apply_source_async. New composition.unregister(name) tears down sustaining notes across primary + mirrors.
  • Multi-device output and aliases - midi_output(), midi_input() can be called repeatedly to register additional devices with optional name aliases
  • Fixes to examples

Full Changelog: v0.3.4...v0.4.0

v0.3.4 - Features, Maintenance, Bug-Fixes

26 Mar 11:33

Choose a tag to compare

v0.3.4 - Features, Maintenance, Bug-Fixes

  • MIDI constant definitions now sourced from PyMidiDefs (canonical source for MIDI 1.0/2.0 standards)
  • All existing imports work unchanged: import subsequence.constants.midi_notes as notes, etc.
  • New capabilities now available:
    • notes.note_to_name(60) → "C4" and notes.name_to_note("Db4") → 61
    • Octave -1 notes (C_NEG1 through B_NEG1, MIDI 0-11)
    • GM instrument program map: import subsequence.constants.instruments.gm_instruments as gm
    • CC constants now explicitly available: import subsequence.constants.midi_cc as cc
  • Multi-device MIDI I/O (522e838, d299a0a, ebf9cf2, 137628c, 4d993c4) - full multi-input/output support with device aliases and cc_map/cc_forward routing
  • MidiEvent refactor + _has_pitch_at_beat() helper (9dc2c48) - cleaner dataclass conversion, refactored euclidean/bresenham/ghost_fill
  • Rounding error fix (91cdd95) - _has_pitch_at_beat() now uses truncation to match placement (beat-to-pulse consistency)
  • scale_notes docstring (6772a70) - documented key/low independence and the silent-skip behavior
  • CC realtime forwarding (ae64c80) - instant cc_forward with auto-routing
  • Ghost fill bias modification (9ea8065) - bias results can now be passed and modified
  • Tuner tone script (06853c9) - new example utility
  • CC filter params constants (1ce9f26) - new constants file

Upgrade Instructions:

pip install -e .  # Refreshes dependencies

Full Changelog: v0.3.3...v0.3.4

v0.3.3 - Features, Maintenance, Bug-Fixes

16 Mar 14:15

Choose a tag to compare

  • Reordered _run() in sequencer.py to resolve device indices and share configuration before opening hardware ports.
  • Internal MIDI setup now triggers before pattern building, ensuring the system tracks correctly even during the first cycle.
  • Fixed a bug in MIDI device alias storage and improved tracking for the primary input alias.
  • Resolved inconsistencies when following external clocks across multiple MIDI devices.
  • Added subsequence/constants/midi_cc.py containing a comprehensive map of MIDI CC definitions.
  • Added scripts/tuner_tone.py as a utility to help tune drifting analogue instruments using reference tones.
  • Updated the MIDI observer script to use intuitive 1-indexed channels instead of 0-based.
  • Standardized pulse lookups to use truncation

Full Changelog: v0.3.2...v0.3.3

v0.3.2 - Feature Release

14 Mar 13:54

Choose a tag to compare

  • Multiple MIDI Device Support: A major architectural update to Composition, Sequencer, and MidiUtils allowing multiple input and output devices to be managed simultaneously.
  • Customizable Ghost Fill Bias: You can now modify the results of a ghost fill bias calculation and pass them back into the ghost_fill method, enabling highly customized probability-based note placement.
  • MIDI CC Realtime Forwarding: Added the ability to forward incoming MIDI CC messages to output devices in realtime, with a dedicated with a dedicated midi.py module for handling these low-latency messages.

Full Changelog: v0.3.1...v0.3.2

v0.3.1 - Feature Release

13 Mar 13:29

Choose a tag to compare

  • MIDI 'sidechain' support using p.duck_map() - allows patterns to easily react to kick or other trigger steps for sidechain ducking effects
  • New easing & ramp helpers

Full Changelog: v0.3.0...v0.3.1

v0.3.0 - Feature Release

11 Mar 08:10

Choose a tag to compare

  • Added specific shortcuts/methods for calculating progress through musical phrases of specific lengths.
  • Added a MIDI observer script to facilitate MIDI controller setup and troubleshooting.
  • Improved external MIDI clock handling: the engine now estimates BPM from incoming clock ticks before the MIDI "start" message is received.
  • Added the ratchet pattern method for rapid subdivision of hits.

Full Changelog: v0.2.9...v0.3.0

v0.2.9 - Feature Release

10 Mar 07:56

Choose a tag to compare

  • Implementation of alternative tuning systems, including support for parsing Scala (.scl) files.

Full Changelog: v0.2.8...v0.2.9

v0.2.8 - Feature Release

09 Mar 19:51

Choose a tag to compare

  • Three new compositional mutation algorithms:
    • p.evolve() - looping pitch buffer with per-cycle drift mutation
    • p.branch() - fractal melodic variation via binary transform tree (retrograde, invert, transpose, rotate, compress, expand)
    • p.quantize(strength=) - probabilistic quantization (0.0–1.0)
  • Instrument emulations
    • Moog Labyrinth example (dual polymetric generative sequencers with CORRUPT mutation)
    • Moog Subharmonicon example (dual 4-step sequencers with subharmonic oscillators)
  • Removed ambiguous length= - replaced with beats=, bars=, steps=+unit=

Full Changelog: v0.2.7...v0.2.8