Code to reproduce the analyses in:
Quantifying the evolution of harmony and novelty in western classical music. Preprint: arXiv:2308.03224
The pipeline represents each piece as a bar-by-bar sequence of local keys (via a variant of Elaine Chew's center of effect algorithm), and from it computes information-theoretic measures of key uncertainty, key diversity, and novelty in key transitions, together with composer-similarity and corpus-filtering analyses.
This GitHub repository contains code only. The datasets are distributed separately (they are large and partly third-party).
- Full dataset + code archive: https://doi.org/10.1184/R1/31714561
Download the archive and place its Data/ folder at Notebooks/Data/ so the tree
looks like the layout below.
Harmony_Evolution
├── setup.jl / setup.sh / setup.ps1 installers (see Installation)
├── Readme.md
├── LICENSE
└── Notebooks
├── Project.toml / Manifest.toml pinned Julia environment
├── ChordAccuracy.ipynb chord accuracy: CoE vs. Krumhansl–Schmuckler
├── KeyAccuracy.ipynb local-key accuracy: CoE vs. Krumhansl–Schmuckler
├── UncertaintyAndDiversity.ipynb per-piece key uncertainty & diversity
├── NoveltyTests.ipynb novelty / innovation trends (multi-threaded)
├── MarkovTests.ipynb Markov-chain corpus filtering → retained set
├── ComposerSimilarities.ipynb composer similarity matrices & rankings
├── BetaSensitivity.ipynb sensitivity to the β smoothing parameter
├── Plots.ipynb figures for the main text
├── KeyFindingExample.ipynb tutorial: the CoE key-finding algorithm
└── Data/ NOT on GitHub — obtain from the DOI above
├── Pieces_data.csv master metadata (all pieces)
├── Pieces_data_reviewed.csv reviewed metadata
├── retained_pieces.txt corpus retained by MarkovTests
├── CSVPieces/ per-piece key/note tables
├── DCML_Corpora/ third-party annotations (see Attribution)
└── files/ demo inputs (Mozart_16.mxl, HeyJoe.csv)
- Julia 1.11 — recommended via juliaup.
- Git.
- A Jupyter front-end is optional:
setup.jlregisters an IJulia kernel, and IJulia will bootstrap a minimal Jupyter via Conda if you don't already have one. VS Code (Julia extension) works without a separate Jupyter install.
No Python toolchain is needed.
Clone, then run the installer for your platform from the repository root:
git clone https://github.com/spiralizing/Harmony_Evolution.git Harmony_Evolution
cd Harmony_Evolution
./setup.sh # macOS / Linux
# setup.ps1 # Windows (PowerShell)
# julia setup.jl # any OS, directlysetup.jl instantiates the exact pinned environment in Notebooks/
(Pkg.instantiate() + precompile) and registers a project-bound Jupyter kernel
named "Julia (Harmony_Evolution)". This kernel is generated per machine and
points at this repository's environment, so running setup is required before
opening the notebooks.
Make sure Notebooks/Data/ is populated (see above), then launch Jupyter with the
project active and open a notebook:
julia --project=Notebooks -e 'using IJulia; notebook(dir="Notebooks")'or open the folder in VS Code and open a notebook in Notebooks/. In either
case select the "Julia (Harmony_Evolution)" kernel.
Notes:
- Work from the
Notebooks/directory — data paths are resolved relative to it. NoveltyTests.ipynbuses threads. To parallelize it, start Julia with threads before launching Jupyter, e.g.JULIA_NUM_THREADS=auto.
Notebooks/Project.toml+Notebooks/Manifest.tomlpin the full dependency tree to the exact versions used for the study (Julia 1.11).MusicSpiralRepresentationis unregistered and pinned by URL;Pkg.instantiate()fetches it automatically.- If you regenerate intermediate files from scratch, run in this order:
MarkovTests(writesData/retained_pieces.txt) →UncertaintyAndDiversityandNoveltyTests(write their per-piece CSVs) →ComposerSimilarities→Plots. Generated CSVs are written underData/.
See LICENSE.
The hand-annotated corpora under Data/DCML_Corpora/ were created and published by
the Digital and Cognitive Musicology Lab (DCML), EPFL, and are redistributed here
under their respective licenses (see the LICENSE/CITATION.cff files bundled in
each corpus directory):
- Beethoven string quartets (ABC). Neuwirth, M., Harasim, D., Moss, F. C., & Rohrmeier, M. (2018). The Annotated Beethoven Corpus (ABC): A Dataset of Harmonic Analyses of All Beethoven String Quartets. Frontiers in Digital Humanities, 5. https://doi.org/10.3389/fdigh.2018.00016
- Mozart piano sonatas. Hentschel, J., Neuwirth, M., & Rohrmeier, M. (2021). The Annotated Mozart Sonatas: Score, Harmony, and Cadence. Transactions of the International Society for Music Information Retrieval, 4(1), 67–80. https://doi.org/10.5334/tismir.6
- DCML corpora meta-repository: https://github.com/DCMLab/dcml_corpora
If you use this code, please cite the paper (arXiv:2308.03224) and, where relevant, the DCML datasets listed above.