Repository navigation
Version 3.1.0 (2026)
Version 3.1.0 builds on the generational overhaul of 3.0.0, adding a lot of
musical correctness changes, expanding on 3.0.0 features to push them to new
levels of musical maturity, plus significant performance optimisations to
drive the increasingly heavy musical machinery -- we're now both more powerful
than ever and faster than ever, by orders of magnitude.
A significant addition is the genJ generation route, which introduces an
entire new corpus trained on jazz standard repertoire, implementing a markov
walk through a much jazzier (:Change) space with an un-fixed voicing size.
Along with genJ, the new-as-of 3.0.0 genE (an extended version of gen)
has been conceptually expanded into a fully featured polytonal generator,
producing 3 tonal-context compatible harmonic progressions, sharing exactly
4 tones in combination of any 2, and 5 tones when merging all.
Further, music-literate key area detection has been added, and as well as
augmenting the walking bass algorithm, this module is used to generate
musically correct modes and pentatonic scales over all gen families,
apart from genE which has it's own polytonal combinatory paradigm.
The four families are much more coherrent now:
gen -- Triadic progressions with compatible pentatonic and mode layers.
genE -- Triadic polytonalism.
genJ -- Extended voicing jazz changes, with pentatonic and mode layers.
genP (I-XII) -- Authors own 'new system of music harmony organisation'.
The Corpus
corpus-v3 — Big improvements to data modelling and loading
which cumulatively add a higher quality graph and a whole new genre.
One published dump now carries both graphs: the classical
:Cadence transition graph (488 composer keys) and the jazz :Change
graph, loading with a single neo4j-admin database load.
The jazz corpus — The Bunks Jazz-Chord-Progressions-Corpus (2,612
tunes of leadsheet harmony, ISMIR 2023) ingests via stack run -- jazz:
all 123 chord qualities map to curated tone sets, symbols parse to
variable-arity pitch-class sets (2–6 tones), slash basses anchor the
zero-form, and the jazz namer names the entire corpus with zero refusals.
Jazz Generation (genJ)
genJ / genJ' / genJ'' — A Markov walk over the :Change graph
with variable voicing sizes, driven by the standard modifier chain
(seek "*" $ cue start $ len 8 $ entropy 0.3 $ genJ).
One seek spec, two corpora — Jazz names blend by corpus weight
("monk:60 coltrane:40", substring-matched); classical names steer the
jazz walk toward that composer's most plausible moves (steer sets the
strength); both combine freely in one string.
leadJ — Cue from a leadsheet symbol in the jazz-quality namespace.
Full tonal-context obedience — hcKey, hcRoots (including the
rise/fall direction specs, resolved per step exactly as in the
classical walk), dissonant/consonant drift and hcPedal all apply.
Polytonal Generation (genE)
gen4 becomes genE — and changes species — The four-note fusion
family is retired. genE now generates a foundation layer byte-identical
to gen plus two corpus-valid partner chains, sharing exactly two
pitch classes with the foundation per bar and unioning to exactly five.
Any two layers sound a 4-note structure; all three, a 5-tone pentad.
Layer selectors — T | S | M | TS | TM | SM | TSM | PT (pairs, the
pentad, the pivot tones), on every instrument and arrange, for every
family.
Divergence-ranked attempts — attempt scores all three layers (half
foundation, a quarter each partner) plus a divergence axis measuring how
far apart the layers stand. Divergence competes with quality rather than
breaking ties: raising K raises both.
Surface — genEReport prints every layer view; genFrom regenerates
polytonal contexts; design in documents/POLYTONAL.md.
Chordscale Layers (gen / genJ)
Real Pentatonic and Mode layers by key-area analysis — A cyclic
Viterbi infers over the progression. The M layer is the key expressed
as the mode on each bar's root; S (strata) is the anhemitonic pentatonic
best covering the bar's guide tones with the fewest changes across the
progression, allowed outside the key only where the harmony demands it.
Theory and calibration in documents/CHORDSCALE.md.
Walking Bass
Jazz bass vocabulary — The walk reads jazz harmony as a bass player
does. A curated per-beat algoritm plots musically viable linear harmony
lines that play though harmonic state, rather than vertically define it.
Usable as a walking bassline, or malleable into other groove and melody.
Key-area connectors — Connector tones draw on the same key-area
analysis behind the chordscale layers.
Generation Engine
Context-aware auto-cues — More intelligent cue/starting draws.
Cues are now always viable inside the context harmonic space.
Four families, one contract — Progression combinators preserve family
and provenance (fuse, rotate, excerpt, reverse, expandP,
interleave, octave transposeP); bar-substituting edits (insert,
switch, clone) downgrade honestly. Regen seams are walk-valid by
construction, traces renumber onto source bars, and empty sources refuse
loudly.
Loud filters — Unrecognised tokens in any overtones/key/roots string
are named once per generation; fall <1,2> parses with the space; prime
notation and subtraction work identically in every context.
Performance
Shared voicing cache — One voicing solve serves every instrument in a
launcher, the walking bass's beat-1 lookup included. A fifteen-block
tetrad launcher: 3.59 s → 0.20 s; evaluating a launcher no longer
interrupts the audio.
Compiled live sessions — live/bin/ghci loads the library as
optimised object code: a sixteen-bar five-tone voicing solve drops from
2.39 s to 53 ms. Voicings are identical; plain stack ghci stays
interpreted for development. One object-code session at a time is
enforced by a PID lock; concurrent spawns (the editor's autocomplete
probe) fall back to bytecode.
Steady-state walking bass — 0.1 ms per cycle, jazz and tetrad alike;
cache misses are silent rather than writing to stderr from the clock
thread.
Live Environment
The rig, documented — documents/LIVE_ENVIRONMENT.md covers editor
configuration, boot-file resolution, MIDI routing, SuperCollider startup
and the failure modes worth recognising; live/bin/livecode and
live/pulsar/ version the launcher and editor pieces as a worked example.
A gate for performance files — scripts/ci/check_corpus.py
type-checks real performance files against the library on every CI run.
Snippet curation — The Pulsar snippet library tightens to 22 prefixes
around a stated rule: a snippet prepares a repeated, fiddly syntax path.
Housekeeping
GPL-3.0 — The project is now licensed GPL-3.0 (was BSD-3-Clause),
matching its strongest dependency: the TidalCycles interface links
GPL-3.0 libraries.
Toolchain — Stackage lts-24.56 / GHC 9.10.3 / TidalCycles 1.10.3;
GHC2021 with a project-wide OverloadedStrings default; zero warnings
under -Wall.
Docs — The user guide gains SECTION 21 (jazz generation) in both
lockstep halves; third-party notices consolidate into NOTICES.md;
documents/CHORDSCALE.md and documents/POLYTONAL.md are new.
The composer graph
The corpus graph is published separately, as a single stable asset shared by every release:
- ycacl-graph.dump — load it with
neo4j-admin database load(Neo4j 5.26+); see README Installation → 2. Add the composer graph.
The library runs without it: pass seek "none" to generate offline from the built-in consonance fallback.
API documentation
Browse it online at https://docs.theharmonicalgorithm.com/, or download the attached haddock-*.zip for an offline copy.
Support
The Harmonic Algorithm is independent research, released under BSD-3-Clause.
If it is useful to you, you can buy me a coffee
or sponsor the project on GitHub.