Download: Cento's releases (the newest is at the top): Cento for Live (devices and a demo set) or Cento for Max (a patch for Max 9). Unzip it and open Read me first.
A recombinant composer for Max and Max for Live, in the style of David Cope's Experiments in Musical Intelligence (EMI) and his later program Emily Howell. A cento is a poem made entirely of lines from other poems; Cento makes music the same way, from beats of the works it has learned.
It analyzes a corpus of music in one style (Bach chorales first) and writes new pieces in that style by recombining beats from different works. Each recombination must preserve the voice-leading, the structural function of the beat (SPEAC) and the composer's recurring signatures. Then Magdalena, a layer in the spirit of Cope's Emily Howell, learns the user's taste from your ratings, and her style drifts as you keep her music in Magdalena's notebook. She is named after Anna Magdalena Bach, singer and copyist of Bach's music, whose notebooks collected the pieces she loved (explain Magdalena, in the pop-up window, says the same).
This is an independent project. It is not affiliated with David Cope; it implements ideas from his published books (see PLAN.md).
| Open this | Plays through | |
|---|---|---|
| Max version | patchers/cento.maxpat |
A MIDI port (AU DLS Synth, IAC to any app) or [vst~] instruments |
| Live version | patchers/cento.brain.amxd on one track, patchers/cento.voice.amxd on each voice track |
Live's tracks and instruments |
Both versions load the same emi.engine abstraction. Everything that differs
between them is in two thin adapters, emi.host.max and emi.host.live.
- Max 9, for the
[v8]JavaScript object. - Ableton Live 12 with Max for Live, running Max 9. Live 12.2.1 and later bundle Max 9; with an earlier version, point Live at your Max 9 installation.
- Node 20+, for tests and building the bundles (development only).
- Python 3 + music21 (optional), for more chorales than the 131 that come with Cento: More chorales from music21.
| What | Where | Notes |
|---|---|---|
| The repo (your clone) | wherever you cloned it, e.g. ~/Documents/GitHub/cento |
Run every command below from this folder |
| Cento's chorales | <repo>/corpus/bach-figured-bass/, bach-figured-bass-3-4/ |
118 chorales in 4/4 and 13 in 3/4 that come with Cento (CC BY 4.0: corpus/README.md). Listed in the corpora window the first time Cento opens; the 4/4 folder is switched on if the list was empty |
| Python for music21 (optional) | <repo>/.venv/ |
Made in step 4 below. About 300 MB, git-ignored, delete it to uninstall |
| music21's chorales (optional) | ~/Documents/cento/corpus/, corpus-both/, corpus-minor/, corpus-3-4/ |
Written by tools/export-chorales.py (step 5); outside the repo, because they're for your own use only |
| Exported pieces | ~/Documents/cento/out/ |
Where to save with export midi (a .mid, and for a composed piece a .json of where each beat came from); outside the repo |
| Listening tests | anywhere, e.g. ~/Documents/cento/ |
Written by listening test… (Max version, in more features…): one web page, opened in a browser |
| Magdalena's taste (M9) | ~/Documents/cento/cento.taste.json |
Your ratings, pins and strength, shared by both products. forget and recall taste set the old one aside as cento.taste.backup.json; delete both to start fresh |
| Stored tastes (optional) | e.g. ~/Documents/cento/emily/ |
Written by store taste in the pop-up window; read back by recall taste |
| Magdalena's notebook and snapshots (M10) | ~/Documents/cento/cento.emily.json, cento.snapshots.json |
Every piece or phrase you keep, and her last 30 snapshots (the files keep their names from before she was called Magdalena); shared by both products |
| Live's search path entry | <repo>/patchers/ |
Added once in Options → File Preferences |
| Remembered settings | ~/Documents/cento/cento.settings.json |
The corpus window's folders (which are on), seed and other settings; written by the patches. Delete it to start fresh |
Your Cento folder (M12): the settings and Magdalena's files live in
~/Documents/cento (any case: Cento is the same folder on a Mac). Cento
uses it if it's there, so make it in Finder if you don't have it yet. The
first time Cento finds it, it copies the files it kept in patchers/ until
M12 (they stay there too, git-ignored; delete them when you like). Without
that folder, Cento keeps its files in patchers/ as before. The Max window
says which folder it uses: cento: your Cento folder is ....
~ is your home folder, /Users/<your name>. <repo> is the folder you
cloned into.
Clone the repo wherever you like (GitHub Desktop's ~/Documents/GitHub is
fine), then run everything from inside it:
git clone https://github.com/nnokes/cento.git
cd cento # <repo>: all commands below run from here
npm test # engine tests
npm run hooks # pre-commit check: no personal paths, bundles up to dateCento's own chorales are already in the repo (corpus/). For music21's, see
More chorales from music21.
Tip: in Terminal, type cd (with a space), then drag the repo folder from
Finder into the window to paste its exact path.
Everything Max loads is in patchers/: on top, what you open
(cento.maxpat, cento.brain.amxd, cento.voice.amxd); in
patchers/parts/, the patches they're made of; in patchers/scripts/, the
generated script bundles. Max doesn't look in subfolders by itself, so both
Max and Live need patchers/ on their search path once, with Subfolders
ticked:
-
Max version: in Max, choose Options → File Preferences, click +, then Choose and select the repo's
patchersfolder. Make sure the Subfolders box in its row is ticked. Then openpatchers/cento.maxpat. -
Live version: Live's Max has its own File Preferences:
- In Live, drop a Max MIDI Effect on a track and click Edit.
- In that editor, choose Options → File Preferences, click +, then
Choose and select the repo's
patchersfolder. Tick Subfolders in its row. - Restart Live. In Live's browser, add the repo folder under Places.
Drag
patchers/cento.brain.amxdonto one MIDI track, andpatchers/cento.voice.amxdonto four MIDI tracks named Soprano, Alto, Tenor and Bass. Each voice device plays the voice its track is named for, and shows it.
To check the search path, type
emi.engineinto an object box in any device editor: a solid box means Live can see the files.
How Max finds files (learned the hard way in M0):
- Standalone Max searches the folder of the patch it opens, plus the search path; not the folder's subfolders, unless the search path entry has Subfolders ticked.
- A Max for Live device is a project: it finds files that belong to its project, plus the search path, but not other files in its own folder.
~/Documents/Max 9/Packages/is on the search path for Max and for Live.- Max doesn't follow symbolic links (or Finder aliases).
The alternative to the File Preferences step is to clone the repo directly
into ~/Documents/Max 9/Packages/ (a real folder, not a link).
Cento comes with 131 Bach chorales (corpus/). The free
music21 toolkit has more: 296 in 4/4 and 32 in
3/4. Their encodings are for your own use only: keep them on your
computer, and don't share them or add them to the repository. (That's why
Cento can't include them: PLAN.md,
§6.1.)
You do this once. It takes about 10 minutes, mostly downloading. You need an internet connection and about 400 MB of free space. You type every command into Terminal, then press Return.
1. Open Terminal. Press ⌘ Space, type Terminal, press Return.
2. Check Python. Type:
python3 --version- It prints
Python 3.and a number (e.g.Python 3.9.6): go to step 3. - macOS asks to install the command line developer tools instead: click
Install, agree, wait for it to finish (a few minutes), then type
python3 --versionagain.
3. Go to the Cento folder. Type cd and a space, then drag Cento's
folder (the repo, e.g. Documents/GitHub/cento) from Finder onto the
Terminal window, and press Return. To check, type ls: the list should
include patchers and tools.
4. Install music21. This makes a private Python just for Cento, in a
hidden folder .venv inside the Cento folder, and installs music21 there
(nothing else on your Mac changes):
python3 -m venv .venv
.venv/bin/pip install music21The second command prints a lot and ends with
Successfully installed ... music21-.... A yellow notice that "a new release
of pip is available" is harmless.
5. Export the chorales. Choose any of these, one command each (each takes a minute or two and lists every chorale it writes):
# All 296 chorales in 4/4, major and minor (the one most people want)
.venv/bin/python tools/export-chorales.py --mode any --out ~/Documents/cento/corpus-both
# Only the 142 major ones (the default), or only the 154 minor ones
.venv/bin/python tools/export-chorales.py --out ~/Documents/cento/corpus
.venv/bin/python tools/export-chorales.py --mode minor --out ~/Documents/cento/corpus-minor
# The 32 chorales in 3/4 (20 major, 12 minor)
.venv/bin/python tools/export-chorales.py --meter 3/4 --mode any --out ~/Documents/cento/corpus-3-4Each ends with wrote N chorales to /Users/<you>/Documents/cento/.... Each
chorale is a .mid file and a .json file. (--count 20 writes only the
first 20, for a quick try.)
6. Add them in Cento. In the Max patch or the Live device, click
corpora, then add folder, and choose the folder you exported to
(e.g. Documents/cento/corpus-both). It's added switched on. Leave Cento's
own bach-figured-bass on too, or use only for one folder alone: a
chorale that's in two folders counts once. Use 3/4 folders on their own
(only): the corpus has one meter.
To uninstall: delete the .venv folder inside the Cento folder (in
Finder, ⌘ Shift . shows hidden folders), and the folders you exported in
Documents/cento.
If something goes wrong:
No such file or directory: tools/export-chorales.py: Terminal isn't in the Cento folder. Repeat step 3..venv/bin/pip: No such file or directory: step 4's first command didn't run, or ran in another folder. Repeat steps 3 and 4.ModuleNotFoundError: No module named 'music21': you typedpython3instead of.venv/bin/pythonin step 5.- A few lines start with
skip: those chorales can't be used (no four voices, or chords in one voice). That's expected.
patchers/ what you open: cento.maxpat (Max version), cento.brain.amxd +
cento.voice.amxd (Live version)
parts/ the patches they're made of: emi.engine, emi.host.max,
emi.host.live, emi.panel (the shared controls), emily.panel
(Magdalena's ratings), emi.view (piano roll), emi.window (the
pop-up window), emi.corpora (the corpus window),
emi.instruments (the Max version's plug-in instruments),
emi.extras (the Max version's more features: listening
test, load a chorale, test phrase), emi.magdalena (about
Magdalena)
scripts/ the generated *.bundle.js scripts (npm run build; committed)
code/ [v8] wrappers: glue between Max messages and the engine
(emi.core.v8.js), and the piano roll (emi.view.v8ui.js)
code/lib/ the engine: plain JavaScript, no Max APIs, tested in Node
code/max/ Max-only helpers used by the wrappers (files, Live clips)
tests/ node --test, including the bundles in a simulated [v8] context
tools/ build, path check, git hook, chorale export, maxgen.py,
which writes every patch and device (the master copy), and
package.js, which makes the release zips (npm run package)
release/ what the downloads carry besides the builds: Read me first.html,
and the Cento folder's About this folder.txt
corpus/ Cento's own chorales (CC BY 4.0: corpus/README.md)
docs/ milestone checklists; controls.md: what every control does;
releasing.md: how to publish a version for others
Your working data (corpus, settings, Magdalena's taste and notebook, generated
music) lives in ~/Documents/cento/, outside the repository.
- Edit the engine in
code/lib/and the wrappers incode/. Keepnpm run build:watchrunning while Max is open: the[v8]objects reload their bundles automatically. - Never edit
patchers/scripts/*.bundle.jsby hand. CI fails if the bundles don't matchcode/. - The patches and devices in
patchers/(anddocs/controls.md) are written bytools/maxgen.py, the master copy: change a patch there and runnpm run patches(Python 3, standard library only), then commit both. A change made in Max alone is overwritten by the next run; CI fails if the patches don't match the script (npm run patches:check). - Patches always load the bundles, never
code/directly, so what you test in Max is exactly what gets frozen into a device. - Some tests need data that isn't in the repository, and skip without it:
EMI_CORPUS=<folder>runs the corpus tests on that folder (by default~/Documents/cento/corpus);EMI_SPEAC_REF=<folder>runs the golden test against Cope's Chopin analysis, given a clone of GolzitskyNikolay/SPEAC-analysis.
The code: MIT. The chorales in corpus/: CC BY 4.0, from the
Bach Chorales Figured Bass dataset (corpus/README.md).