Tools for reading one-page West-African drum scores off a PDF, rendering play-along audio from them, and drilling the parts — particularly the dundun parts, where one hand plays the bell and the other the drum.
Pure Python, no third-party packages. The trainer is a single HTML page, plus nl.js for its Dutch text.
Learning a dundun part is mostly a coordination problem: the bell hand has to become automatic before the drum hand can do anything independent. What helps is being able to switch one hand off and play the other against the rest of the ensemble — which is what this does.
dundun-trainer.html — one page, no build step, no dependencies. For each
rhythm it shows every part on a grid, with the dundun parts split into separate
drum and bell lanes you can mute independently. Tempo down to 40 bpm,
sticking, a count, and the call.
It comes in English and Dutch, switched with the NL / EN buttons. Add
?lang=nl or ?lang=en to the URL to choose up front; without it the page
uses the last choice made in that browser, then the browser’s own language.
The English lives in the page; nl.js overlays the Dutch, and any line it lacks
falls back to English.
Browsers block fetch() on file://, so serve it rather than double-clicking:
python3 -m http.server 8000 # then open http://localhost:8000/dundun-trainer.html
tools/read_score.py |
Reads a score PDF: finds the staves, works out each one’s grid, prints the parts. Reports a period per line — since almost every part is a short loop, a line that is not periodic is usually a missed notehead, which is what makes the output checkable. |
tools/render_rhythm.py |
Renders WAVs per rhythm: the full ensemble, one file per part, and drum-only / bell-only for each dundun part. |
tools/build_pack.py |
Conditions raw sample downloads — trims to 3 ms before the attack, caps length, level-matches. |
python3 tools/read_score.py Rhythm.pdf --rows 261,461,658 --staves signal,djembe1,djembe2
python3 tools/render_rhythm.py --rhythm djole --bpm 100 --cycles 8
Rendered WAVs land in audio/, which is gitignored — the full set runs to over
a gigabyte and regenerates from the tools.
Scores live in the RHYTHMS dict in render_rhythm.py and in RHYTHMS in the
trainer, written on a subdivision grid:
. rest B bass T tone S slap
O open dundun tone M muted x bell
A signal part additionally carries pickup:true, which sounds a grace stroke
half a slot before each bar. Together with the stroke on the beat that is a
galop — one tone played very fast with both hands, left then right — and it
is how every call on these sheets begins.
div is subdivisions per beat — 4 for a binary rhythm, 3 for a ternary one like
Gidamba in 12/8. Bar lines, accents and tick labels all derive from it.
Modal synthesis was the starting point — damped sinusoids at the inharmonic
modes of a drum head, struck by a filtered noise transient — but recorded
samples turned out far more recognisable, so samples/ holds conditioned
one-shots and synthesis is only the fallback when a sample fails to load.
dundun-trainer.html needs nl.js and the samples/ folder beside it — it fetches the
WAVs at runtime by relative path. Copy both and it works anywhere static files
are served; there is nothing to build and no server-side code.
The source notation. These transcriptions were read from one-page scores
written by Michael Agbodo, who teaches these rhythms. The
rhythms themselves are traditional, but the scores are his work and he is
preparing a book of them, so they are not included here. The tools are written
against that layout, so to use read_score.py you will need your own scores in
a similar format.
Taught and notated by Michael Agbodo. The rhythms are traditional West-African repertoire; the scores they were transcribed from are his.
Drum samples come from Freesound; ten are CC0 and one
is CC BY 3.0. Per-file sources and licences are in samples/CREDITS.md.
MIT for the code — see LICENSE. The samples keep their own terms.