"My music of today is so much based on the new musical technology. We use the technology as a material for our musical art" — Igor Stravinsky, 1957
This codebase is an expression of my musical mind -- it provides structure for navigating through and interacting with musical harmonic state in real time, while experiencing it. Traversing the harmonic space feels kind of like an 'LLM', but there's no AI here, just old school counting and music theory, implemented in Haskell.
The Harmonic Algorithm system, intergrated with TidalCycles, generates musical harmony states inside user defined musical constraints, then ranks it using a tailored 'cube' of Markov Chain matrices trained on the Yale Classical Archives Corpus. This presents a unique tool in the hands of the composer or performer which can be used as a composing aid, analysis device, for instrumental study or even in live performance.
This open-source project is based on a long term creative agenda that I've pursued for many years, originating from an interest as an electric bass player utilising the overtones of the instrument in performance and composition.
The Harmonic Algorithm takes the underpinning theoretical ideas from this research and realises them as a Haskell library with deep TidalCycles integration for live coding. Under the hood, harmonic transitions from over 500 composers are stored in a Neo4j graph database. The system memorises how harmony moves, and uses this knowledge to generate progressions that feel musically coherent while remaining endlessly surprising. No AI -- just counting and music theory.
The core idea draws on Geraint Wiggins' Creative Systems Framework: define the rules of what's harmonically possible, evaluate the quality of each option using corpus statistics and dissonance scoring, then traverse the space probabilistically, balancing between the familiar and the unexpected.
The project is built around four 'named entities':
-
The Harmonic Algorithm -- A Rules→Evaluation→Traversal pipeline that produces harmonic progressions from learned transition probabilities, originating in a 2016 exhaustive overtone analysis of bass guitar, realised computationally in Haskell with Neo4j as a graph traversal backend.
-
Algorithmic Orchestration -- Did you ever want to write for the orchestra using Haskell code? What if that system could only produce viable arrangements that could be notated and would be playable by a real orchestra? How about if The Harmonic Algorithm was the harmony engine powering it? What if I could 'play' the orchestra in real time in using TidalCycles? These are all questions I asked myself, so I built a system that can do it. It give the concept of composing functions a whole new meaning.
-
The Spectral Narrative -- A structural framework for musical form. Macro-level compositional arcs encoded as programmable 'kinetics' signals in seconds or bars, with smooth or snap transitions, carrying continuous intensity and dynamics envelopes that drive instrument activation, voice density, and harmonic layer switching. It's how I turn code into composition.
-
Octatripentatonics -- Where things get weird. A whole new system of harmonic organisation based on 8 note tonal areas (octa), divided into three overlapping pentatonic scales (tripentatonics) which any combination of two of will produce a different 7 tone key signature. You can ignore it or embrace it, but if you think that wacky music theory ideas are cool, then check out the system and tonal structure elements: (OCTATRIPENTATONICS.md, CHORDSCALE.md).
The system has grown with me over the years and I've mainly used it privately in the studio to have fun playing with synthesizers, orchestral modules, and as a very soliloquistic jamming-buddy that never drops from the session at the last minute. I've performed a few concerts here and there too.
I figure that it'd be nice to make the whole system available publicly as an open source project, whether for people to use creatively or to just enjoy the music and art that it can create, through art published on YouTube: The Harmonic Algorithm Youtube Channel
This is a longer form musical tour of The Harmonic Algorithm concepts, it is clipped from a longer stream and patterns synthesizers musically. There are some shorter quickstart/demonstrative style videos below.
The original 2016 research documents on which The Harmonic Algorithm draws influence can be accessed at the following links:
Core document: original core document (2016)
Reflective document: original reflective document (2016)
The accompanying document for this project which discusses The Harmonic Algorithm as a creative system can be accessed here: creative system document (2018)
Start simple: a starting chord, a length and an entropy value are all it takes to generate a progression, it is combined with a TidalCycles pattern that you can voice and play. Constraints then narrow the harmonic space to fit your musical context, here with a key and a falling root motion. You can also declare a progression by hand, like the Neapolitan cadence this example ends on:
The same starting chord can lead to radically different musical outcomes. Entropy controls the balance between familiar harmonic motion and surprising, exploratory leaps or less common harmonic textures:
The system also lets you blend the harmonic taste of different composers. These are the weighted combinations of learned transition probabilities:
The system also lets you blend the harmonic taste of different composers. These are the weighted combinations of learned transition probabilities. If you want to run the system without the graph:
seek "none"bypasses it entirely, so progressions are shaped by your context filters and entropy alone.
A named component, 'The Spectral Narrative' provides a macro level syntax to control 'kinetics' (a proxy for density or layering in arrangement), dynamics and modulation. This makes it very easy and flexible to create full compositions.
The project can be run just with the codebase and tooling, then setting up the graph in Docker allows full traversal of the composer corpus.
- Haskell Stack
with GHC 9.10.3 installed and set as default (e.g. via
ghcup) —
stack.yamlsetssystem-ghc: true, so Stack uses your system GHC rather than downloading its own - TidalCycles with SuperCollider + SuperDirt —
any editor will do;
LIVE_ENVIRONMENT.mddocuments the Pulsar rig this project is performed on, as one worked example - Docker — only for the composer graph (second path)
scripts/install-linux.sh wires all of this up and is safe to re-run. It
converges to the same state and reports what was already correct:
./scripts/install-linux.sh --check # report only, change nothing
./scripts/install-linux.sh # set everything up
./scripts/install-linux.sh --with-graph # and load the composer corpusIt installs no system packages, it checks for them and names the command to
install any that are missing. The one exception is GHC, which it fetches
through ghcup. Afterwards livecode is on your PATH.
It exists because several setup steps fail silently: without the root
CLAUDE.md stub the repo's own agent guidance never loads; without
SafeMIDIOut.sc the SuperCollider startup aborts before stamping sc_ready
and the launcher waits forever with no error; a copied rather than symlinked
snippets.cson drifts and prefixes stop expanding; and ppm install silently
wipes the local plugin patch on every upgrade. The script handles each, and
--check tells you which are outstanding.
There is no macOS equivalent yet; the repository files it configures are cross-platform, only the wiring is Linux-specific.
git clone https://github.com/OscarSouth/theHarmonicAlgorithm
cd theHarmonicAlgorithm
stack build # compile the library
stack test # verify everything worksBoot TidalCycles with live/BootTidal.hs and you're playing. Generation
runs on the built-in consonance fallback — pass "none" as the composer
string and everything in the guides works, shaped by your own filters and
entropy:
start <- lead "C maj"
s <- seek "none" $ cue start $ len 4 $ entropy 0.5 $ genYou can also explore in the REPL with stack ghci.
The graph holds harmonic transitions learned from 488 composers. Start Neo4j, then load the pre-built database published with the latest release:
# download the graph (98MB) and its checksum
curl -LO https://github.com/OscarSouth/theHarmonicAlgorithm/releases/download/corpus-v3/ycacl-graph.dump
curl -L https://github.com/OscarSouth/theHarmonicAlgorithm/releases/download/corpus-v3/SHA256SUMS | shasum -a 256 -c
# load it (the database must be offline), then start Neo4j
docker compose stop neo4j
docker run --rm -i -v "$PWD/neo4j/data:/data" neo4j:5.26 \
neo4j-admin database load neo4j --from-stdin --overwrite-destination < ycacl-graph.dump
docker compose up -d neo4jEvery seek string then works: "bach", "debussy",
"bach:30 debussy:70", "*".
Rebuilding the graph from source (advanced)
stack run populates Neo4j from data/artefacts/ycacl_sequences.csv, which is not
distributed with the repository. To produce it, obtain the Yale Classical
Archives Corpus yourself (see NOTICES.md for provenance) and run
the export helper documented in scripts/README.md:
Rscript scripts/export_ycacl.R <YCACL dir> <metadata csv> data/artefacts/ycacl_sequences.csv
stack runOnce you're up and running, there's plenty to explore:
User Guide — the full walkthrough in readable form, video slots and all, no running TidalCycles environment required.
Interactive User Guide — the same guide as a hands-on tutorial with examples you can run directly in TidalCycles.
Octatripentatonics — the theory frontier: strata, tristrata, and the three-layer harmony system, in full.
Polytonal — the genE framework: a foundation walk plus two partner triad chains, the overlap algebra behind the layer selectors, and the viability study the design rests on.
Chordscale — key-area analysis for gen and genJ: the composite-minor key lattice, the mode and pentatonic layer derivation, and the walking-bass unification.
Algorithmic Orchestration — scoring for a virtual orchestra on the JV-1010: instrument catalogue, voice lines, divisi, sections, blends, form and kinetics.
The Live Environment — the editor, boot and SuperCollider rig the project is performed on, and the instruments behind it: Pulsar configuration, the compiled-session wrapper, MIDI routing, the studio rig's channel map and MPC programs, the AIRA units, and the failure modes worth recognising.
API Reference — generated Haddock
documentation for all 50 modules, with worked examples on every user-facing
entry point. Start at Harmonic.Lib.
Architecture Guide — the technical deep dive into how the system works: the four-layer architecture, the R→E→T pipeline, zero-form cadence storage, and the graph database model.
Data Modelling — how corpus harmony becomes the cadence graph: zero-form abstraction, weighted interpretation, and consistent-path transition counting.
Composer Catalogue — every composer key in the graph and the query syntax for names and blends.
Changelog — V3 features and migration notes.
The original demo (V1, 2018–19) — a piece of history: the interactive terminal app this grew out of, walkthrough and animations preserved.
This project wouldn't exist without the work of:
- Geraint A. Wiggins — the Creative Systems Framework that underpins the algorithm's architecture
- Alex McLean — TidalCycles, which gave this project its voice
- Paul Hindemith — interval dissonance theory from The Craft of Musical Composition (1937), which informs the evaluation scoring
- UCI Machine Learning Repository — the Yale Classical Archives Corpus that trains the classical model
- Carey Bunks — the Jazz-Chord-Progressions-Corpus (ISMIR 2023) that trains the jazz model; full citation in NOTICES.md
Let me know if you have any feature suggestions or comments in general and feel free to get in touch through this repository's Issues section.
Alternatively, come hang out or contact me through the forum for my main performance project UDAGAN: https://forum.UDAGAN.uk/
If the project is useful to you and you'd like to help keep the research going, you can buy me a coffee — or use the Sponsor button at the top of this page. A star is free and helps just as much.
Oscar
GNU General Public License v3.0 — see LICENSE for details.





