A microtonal geography of the cello fingerboard
  • OCaml 99.8%
  • Shell 0.1%
Find a file
2026-09-08 12:02:35 +02:00
.github/workflows Upgrade CI 2026-09-08 12:02:35 +02:00
.vscode Add spell entries 2026-03-17 20:51:06 +01:00
doc spell check and comment wrapping 2023-07-29 03:16:16 +02:00
src Improve myers and merge3 vendoring 2026-08-17 16:51:33 +02:00
systems Fix some typos 2026-05-18 16:46:57 +02:00
test Vendor ocaml-merge3 2026-05-18 16:16:58 +02:00
third-party-license Improve myers and merge3 vendoring 2026-08-17 16:51:33 +02:00
.gitattributes added gitattributes 2023-03-03 18:58:00 +01:00
.gitignore Update gitignore 2025-12-23 15:28:48 +01:00
.headache.config Change LICENSE to AGPL-3.0-or-later 2024-04-04 14:15:07 +02:00
.ocamlformat Upgrade ocamlformat to 0.29.0 2026-03-24 09:09:39 +01:00
CHANGES.md Fix some typos 2026-05-18 16:46:57 +02:00
CODEOWNERS Initiate code owners file for GH 2026-02-01 08:05:55 +01:00
COPYING Change LICENSE to AGPL-3.0-or-later 2024-04-04 14:15:07 +02:00
COPYING.HEADER Prepare license headers and notice 2026-03-18 07:04:12 +01:00
dune init project from template 2022-08-07 10:42:12 +02:00
dune-project Use implicit bound for ppxlib 2026-05-18 16:25:24 +02:00
dune-workspace.5.2 Upgrade CIs 2026-04-12 13:20:40 +02:00
dune-workspace.5.3 Upgrade CIs 2026-04-12 13:20:40 +02:00
dune-workspace.5.4 Upgrade CIs 2026-04-12 13:20:40 +02:00
dune-workspace.5.5 Upgrade OCaml to latest available versions 2026-09-08 10:03:51 +02:00
dunolint Add dunolint config 2025-12-24 11:07:21 +01:00
fingerboard-dev.opam Use implicit bound for ppxlib 2026-05-18 16:25:24 +02:00
fingerboard-system.opam Use implicit bound for ppxlib 2026-05-18 16:25:24 +02:00
fingerboard-tests.opam Use implicit bound for ppxlib 2026-05-18 16:25:24 +02:00
fingerboard.opam Increase lower bounds for maintainance 2026-01-28 10:13:12 +01:00
headache.sh Remove left-over unused var (shellcheck) 2026-03-17 11:31:19 +01:00
Makefile Install with-dev-setup 2024-09-08 17:50:31 +02:00
NOTICE.md Improve myers and merge3 vendoring 2026-08-17 16:51:33 +02:00
README.md Unwrap README paragraphs 2024-09-29 11:56:10 +02:00

fingerboard

CI Status Coverage Status

This project is meant to help me reason about and build a "microtonal geography of the cello fingerboard".

What's in the repo?

The repo implements the tools necessary to model microtonal geography systems based on various scales. As we go over some specific pythagorean, just and tempered scales and double stops, some specific notations are introduced for each of the fingerboard locations required to play each note. Then, we can reason about and exhibit various facts involving these positions, while being able to verify these facts programmatically, and display them with various format.

An example extracted from file systems/cello/just/scales.ml displaying the names of the positions involved in playing the E Major Just Scale on a cello tuned in perfect fifth:

((IV ((E2 M3p) (F#2 A4p)))
 (III ((G#2 A1z) (A2 M2p) (B2 M3p) (C#3 A4z)))
 (II ((D#3 A1z) (E3 M2p) (F#3 M3p) (G#3 A4z)))
  (I
  ((A3 0) (B3 M2p) (C#4 M3z) (D#4 A4z) (E4 5p) (F#4 M6p) (G#4 M7z) (A4 0-1)
   (B4 M2p-1) (C#5 M3z-1) (D#5 A4z-1) (E5 5p-1) (F#5 M6p-1) (G#5 M7z-1)
   (A5 0-2) (B5 M2p-2) (C#6 M3z-2) (D#6 A4z-2) (E6 5p-2))))

Another example from file systems/cello/e53/scales.ml explores the difference between the scales of D Flat Major Pythagorean and its Just counterpart, approximated in a 53 edo system mapped onto the cello fingerboard.

D Flat Major Pythagorean in a 53 edo system:

((IV ((Db2 A1z-e53) (Eb2 m3p-e53) (F2 4p-e53) (Gb2 A4z-e53)))
 (III ((Ab2 A1z-e53) (Bb2 m3p-e53) (C3 4p-e53) (Db3 A4z-e53)))
 (II ((Eb3 A1z-e53) (F3 m3p-e53) (Gb3 M3z-e53) (Ab3 A4z-e53)))
 (I
  ((Bb3 A1z-e53) (C4 m3p-e53) (Db4 M3z-e53) (Eb4 A4z-e53) (F4 m6p-e53)
   (Gb4 M6z-e53) (Ab4 M7z-e53) (Bb4 A1z-e53-1) (C5 m3p-e53-1) (Db5 M3z-e53-1)
   (Eb5 A4z-e53-1) (F5 m6p-e53-1) (Gb5 M6z-e53-1) (Ab5 M7z-e53-1)
   (Bb5 A1z-e53-2) (C6 m3p-e53-2) (Db6 M3z-e53-2) (Eb6 A4z-e53-2)
   (F6 m6p-e53-2))))

D Flat Major Just in the same 53 edo system:

((IV ((Db2 m2z-e53) (Eb2 m3z-e53) (F2 4p-e53) (Gb2 d5z-e53)))
 (III ((Ab2 m2z-e53) (Bb2 m3p-e53) (C3 4p-e53) (Db3 d5z-e53)))
 (II ((Eb3 m2z-e53) (F3 m3p-e53) (Gb3 M3p-e53) (Ab3 d5z-e53)))
 (I
  ((Bb3 A1z-e53) (C4 m3p-e53) (Db4 M3p-e53) (Eb4 d5z-e53) (F4 m6p-e53)
   (Gb4 M6p-e53) (Ab4 M7p-e53) (Bb4 A1z-e53-1) (C5 m3p-e53-1) (Db5 M3p-e53-1)
   (Eb5 d5z-e53-1) (F5 m6p-e53-1) (Gb5 M6p-e53-1) (Ab5 M7p-e53-1)
   (Bb5 A1z-e53-2) (C6 m3p-e53-2) (Db6 M3p-e53-2) (Eb6 d5z-e53-2)
   (F6 m6p-e53-2))))

Example of positions and intervals in the E flat Major double stops scale in thirds from systems/cello/just/thirds.ml:

┌─────┬────────┬───────┬───────┬──────┬────────┬───────┬───────┬──────────────────┬───────┐
│ Low │ String │ Pos   │ Cents │ High │ String │ Pos   │ Cents │ Interval         │ Cents │
├─────┼────────┼───────┼───────┼──────┼────────┼───────┼───────┼──────────────────┼───────┤
│ Eb2 │ IV     │ m3z   │ 316   │ G2   │ III    │ 0     │ 0     │ M3 - 5 / 2^2     │ 386   │
│ F2  │ IV     │ 4p    │ 498   │ Ab2  │ III    │ m2z   │ 112   │ m3 - (2 * 3) / 5 │ 316   │
│ G2  │ IV     │ 5p    │ 702   │ Bb2  │ III    │ m3z   │ 316   │ m3 - (2 * 3) / 5 │ 316   │
│ Ab2 │ IV     │ m6z   │ 814   │ C3   │ III    │ 4p    │ 498   │ M3 - 5 / 2^2     │ 386   │
│ Bb2 │ III    │ m3z   │ 316   │ D3   │ II     │ 0     │ 0     │ M3 - 5 / 2^2     │ 386   │
│ C3  │ III    │ 4p    │ 498   │ Eb3  │ II     │ m2z   │ 112   │ m3 - (2 * 3) / 5 │ 316   │
│ D3  │ III    │ 5p    │ 702   │ F3   │ II     │ m3z   │ 316   │ m3 - (2 * 3) / 5 │ 316   │
│ Eb3 │ III    │ m6z   │ 814   │ G3   │ II     │ 4p    │ 498   │ M3 - 5 / 2^2     │ 386   │
│ G3  │ II     │ 4p    │ 498   │ Bb3  │ I      │ m2z   │ 112   │ m3 - (2 * 3) / 5 │ 316   │
│ Ab3 │ II     │ d5z   │ 610   │ C4   │ I      │ m3p   │ 294   │ M3 - 5 / 2^2     │ 386   │
│ Bb3 │ II     │ m6z   │ 814   │ D4   │ I      │ 4p    │ 498   │ M3 - 5 / 2^2     │ 386   │
│ C4  │ II     │ m7p   │ 996   │ Eb4  │ I      │ d5z   │ 610   │ m3 - (2 * 3) / 5 │ 316   │
│ D4  │ II     │ 0-1   │ 1200  │ F4   │ I      │ m6z   │ 814   │ m3 - (2 * 3) / 5 │ 316   │
│ Eb4 │ II     │ m2z-1 │ 1312  │ G4   │ I      │ m7p   │ 996   │ M3 - 5 / 2^2     │ 386   │
│ F4  │ II     │ m3p-1 │ 1494  │ Ab4  │ I      │ d8z   │ 1108  │ m3 - (2 * 3) / 5 │ 316   │
│ G4  │ II     │ 4p-1  │ 1698  │ Bb4  │ I      │ m2z-1 │ 1312  │ m3 - (2 * 3) / 5 │ 316   │
│ Ab4 │ II     │ d5z-1 │ 1810  │ C5   │ I      │ m3p-1 │ 1494  │ M3 - 5 / 2^2     │ 386   │
│ Bb4 │ II     │ m6z-1 │ 2014  │ D5   │ I      │ 4p-1  │ 1698  │ M3 - 5 / 2^2     │ 386   │
│ C5  │ II     │ m7p-1 │ 2196  │ Eb5  │ I      │ d5z-1 │ 1810  │ m3 - (2 * 3) / 5 │ 316   │
│ D5  │ II     │ 0-2   │ 2400  │ F5   │ I      │ m6z-1 │ 2014  │ m3 - (2 * 3) / 5 │ 316   │
│ Eb5 │ II     │ m2z-2 │ 2512  │ G5   │ I      │ m7p-1 │ 2196  │ M3 - 5 / 2^2     │ 386   │
│ F5  │ II     │ m3p-2 │ 2694  │ Ab5  │ I      │ d8z-1 │ 2308  │ m3 - (2 * 3) / 5 │ 316   │
│ G5  │ II     │ 4p-2  │ 2898  │ Bb5  │ I      │ m2z-2 │ 2512  │ m3 - (2 * 3) / 5 │ 316   │
│ Ab5 │ II     │ d5z-2 │ 3010  │ C6   │ I      │ m3p-2 │ 2694  │ M3 - 5 / 2^2     │ 386   │
│ Bb5 │ II     │ m6z-2 │ 3214  │ D6   │ I      │ 4p-2  │ 2898  │ M3 - 5 / 2^2     │ 386   │
│ C6  │ II     │ m7p-2 │ 3396  │ Eb6  │ I      │ d5z-2 │ 3010  │ m3 - (2 * 3) / 5 │ 316   │
└─────┴────────┴───────┴───────┴──────┴────────┴───────┴───────┴──────────────────┴───────┘

Code Documentation

The code documentation of the latest release is built with odoc and published to GitHub pages here.