---
title: Music Theory as Code
tags:
  - topic/hobbies/music
  - topic/software
---
# Music Theory as Code

%%

## TALK

For now a scratchpad for implementation,
ultimately to discuss the difficulty
and why every extant library
seems to have wildly different ergonomics and terminology
%%

PowerShell module to assist in translating between banjo fingerings and concert notes,
as well as between [[lilypond]] and conventional notation.

```powershell
$Db4 = [Pitch]::FromLilyPond("des'")
[Note]::($Db4,1/4).PlayInTime(120)

$str1 = [FrettedStringTuning]::FromOpen([Pitch]::FromLilyPond("d,,,"))
$str1c2 = $str1.Capo(2)

$openGtuning = [FrettedStringInstrumentTuning]::FromStringTunings(@(
    [FrettedStringTuning]::FromOpen([Pitch]::FromLilyPond("d,,,")),
    [FrettedStringTuning]::FromOpen([Pitch]::FromLilyPond("b,,")),
    [FrettedStringTuning]::FromOpen([Pitch]::FromLilyPond("g,")),
    [FrettedStringTuning]::FromOpen([Pitch]::FromLilyPond("d")),
    [FrettedStringTuning]::FromOpen([Pitch]::FromLilyPond("g'")),
    # note: the notation used above is concert octave,
    # banjo is transposed up one octave.
))
[Note]::($openGc2tuning.GetPitchFromFingering(4,11)/4).PlayInTime(120) # play Db4

$openGc2tuning = $openGtuning.Capo(2)
[Note]::($openGc2tuning.GetPitchFromFingering(4,9),1/4).PlayInTime(120) # play Db4

# TODO: class iFrettedStringInstrument
# class Banjo implements iFrettedStringInstrument

```

```powershell
class Pitch {
    [Pitch] TransposeOctave([Note]$note1,[Note]$note2) {}
    [Pitch] TransposeOctave([int]$modifier) {}
}

class Duration {
    # 1/4, 1/8, etc.
    # does not encode timing.
}

class Note {
    [Pitch]$_pitch
    [Duration]$_duration
}
```

```mermaid
classDiagram
    %% simple score definition, does not support polyphony
    class Score {
        List~Note~ notes
        float beatsPerMinute
        +Beep() void
    }

    Score *-- Note
    class Note {
        Pitch pitch
        float beats
        +BeepInTime(int bpm)
    }

    Note *-- Pitch
    class Pitch {
        +Transpose(Pitch from, Pitch to) Pitch
        +TransposeOctave(int modifier) Pitch
        +FromLilyPond(string text) Pitch
        +GetFrequency() float
        +Beep(int milliseconds) void
    }

    class Banjo {
        +FromNamedTuning(string tuningName) Banjo
    }

    Banjo <|.. iFrettedStringInstrument
    class iFrettedStringInstrument {
        -FrettedStringInstrumentTuning tuning
        +GetPitchFromFingering(int string,int fret) Pitch
        +GetFingeringsFromPitch(Pitch pitch) todo
    }

    iFrettedStringInstrument *-- FrettedStringInstrumentTuning
    class FrettedStringInstrumentTuning {
        -List~FrettedStringTuning~ stringTunings
        +GetPitchFromFingering(int string,int fret) Pitch
        +GetFingeringsFromPitch(Pitch pitch) todo
        +Capo(int fret) FrettedStringInstrumentTuning
    }

    FrettedStringInstrumentTuning *-- FrettedStringTuning
    class FrettedStringTuning {
        Pitch openPitch
        int fretOffset
        +GetPitchFromFret(int fret) Pitch
        +SetOffset(int fret) FrettedStringTuning
    }
```

[[music-theory]]

| midi | tone  | mod12 | concert-octave |
| ---- | ----- | ----- | -------------- |
| 0    | C     | 0     | -1             |
| 1    | C♯/D♭ | 1     | -1             |
| 2    | D     | 2     | -1             |
| 3    | D♯/E♭ | 3     | -1             |
| 4    | E     | 4     | -1             |
| 5    | F     | 5     | -1             |
| 6    | F♯/G♭ | 6     | -1             |
| 7    | G     | 7     | -1             |
| 8    | G♯/A♭ | 8     | -1             |
| 9    | A     | 9     | -1             |
| 10   | A♯/B♭ | 10    | -1             |
| 11   | B     | 11    | -1             |
| 12   | C     | 0     | 0              |
| 13   | C♯/D♭ | 1     | 0              |
| 14   | D     | 2     | 0              |
| 15   | D♯/E♭ | 3     | 0              |
| 16   | E     | 4     | 0              |
| 17   | F     | 5     | 0              |
| 18   | F♯/G♭ | 6     | 0              |
| 19   | G     | 7     | 0              |
| 20   | G♯/A♭ | 8     | 0              |
| 21   | A     | 9     | 0              |
| 22   | A♯/B♭ | 10    | 0              |
| 23   | B     | 11    | 0              |
| 24   | C     | 0     | 1              |
| 25   | C♯/D♭ | 1     | 1              |
| 26   | D     | 2     | 1              |
| 27   | D♯/E♭ | 3     | 1              |
| 28   | E     | 4     | 1              |
| 29   | F     | 5     | 1              |
| 30   | F♯/G♭ | 6     | 1              |
| 31   | G     | 7     | 1              |
| 32   | G♯/A♭ | 8     | 1              |
| 33   | A     | 9     | 1              |
| 34   | A♯/B♭ | 10    | 1              |
| 35   | B     | 11    | 1              |
| 36   | C     | 0     | 2              |
| 37   | C♯/D♭ | 1     | 2              |
| 38   | D     | 2     | 2              |
| 39   | D♯/E♭ | 3     | 2              |
| 40   | E     | 4     | 2              |
| 41   | F     | 5     | 2              |
| 42   | F♯/G♭ | 6     | 2              |
| 43   | G     | 7     | 2              |
| 44   | G♯/A♭ | 8     | 2              |
| 45   | A     | 9     | 2              |
| 46   | A♯/B♭ | 10    | 2              |
| 47   | B     | 11    | 2              |
| 48   | C     | 0     | 3              |
| 49   | C♯/D♭ | 1     | 3              |
| 50   | D     | 2     | 3              |
| 51   | D♯/E♭ | 3     | 3              |
| 52   | E     | 4     | 3              |
| 53   | F     | 5     | 3              |
| 54   | F♯/G♭ | 6     | 3              |
| 55   | G     | 7     | 3              |
| 56   | G♯/A♭ | 8     | 3              |
| 57   | A     | 9     | 3              |
| 58   | A♯/B♭ | 10    | 3              |
| 59   | B     | 11    | 3              |
| 60   | C     | 0     | 4              |
| 61   | C♯/D♭ | 1     | 4              |
| 62   | D     | 2     | 4              |
| 63   | D♯/E♭ | 3     | 4              |
| 64   | E     | 4     | 4              |
| 65   | F     | 5     | 4              |
| 66   | F♯/G♭ | 6     | 4              |
| 67   | G     | 7     | 4              |
| 68   | G♯/A♭ | 8     | 4              |
| 69   | A     | 9     | 4              |
| 70   | A♯/B♭ | 10    | 4              |
| 71   | B     | 11    | 4              |
| 72   | C     | 0     | 5              |
| 73   | C♯/D♭ | 1     | 5              |
| 74   | D     | 2     | 5              |
| 75   | D♯/E♭ | 3     | 5              |
| 76   | E     | 4     | 5              |
| 77   | F     | 5     | 5              |
| 78   | F♯/G♭ | 6     | 5              |
| 79   | G     | 7     | 5              |
| 80   | G♯/A♭ | 8     | 5              |
| 81   | A     | 9     | 5              |
| 82   | A♯/B♭ | 10    | 5              |
| 83   | B     | 11    | 5              |
| 84   | C     | 0     | 6              |
| 85   | C♯/D♭ | 1     | 6              |
| 86   | D     | 2     | 6              |
| 87   | D♯/E♭ | 3     | 6              |
| 88   | E     | 4     | 6              |
| 89   | F     | 5     | 6              |
| 90   | F♯/G♭ | 6     | 6              |
| 91   | G     | 7     | 6              |
| 92   | G♯/A♭ | 8     | 6              |
| 93   | A     | 9     | 6              |
| 94   | A♯/B♭ | 10    | 6              |
| 95   | B     | 11    | 6              |
| 96   | C     | 0     | 7              |
| 97   | C♯/D♭ | 1     | 7              |
| 98   | D     | 2     | 7              |
| 99   | D♯/E♭ | 3     | 7              |
| 100  | E     | 4     | 7              |
| 101  | F     | 5     | 7              |
| 102  | F♯/G♭ | 6     | 7              |
| 103  | G     | 7     | 7              |
| 104  | G♯/A♭ | 8     | 7              |
| 105  | A     | 9     | 7              |
| 106  | A♯/B♭ | 10    | 7              |
| 107  | B     | 11    | 7              |
| 108  | C     | 0     | 8              |
| 109  | C♯/D♭ | 1     | 8              |
| 110  | D     | 2     | 8              |
| 111  | D♯/E♭ | 3     | 8              |
| 112  | E     | 4     | 8              |
| 113  | F     | 5     | 8              |
| 114  | F♯/G♭ | 6     | 8              |
| 115  | G     | 7     | 8              |
| 116  | G♯/A♭ | 8     | 8              |
| 117  | A     | 9     | 8              |
| 118  | A♯/B♭ | 10    | 8              |
| 119  | B     | 11    | 8              |
| 120  | C     | 0     | 9              |
| 121  | C♯/D♭ | 1     | 9              |
| 122  | D     | 2     | 9              |
| 123  | D♯/E♭ | 3     | 9              |
| 124  | E     | 4     | 9              |
| 125  | F     | 5     | 9              |
| 126  | F♯/G♭ | 6     | 9              |
| 127  | G     | 7     | 9              |

| spelling | mod7 | mod12 |
| -------- | ---- | ----- |
| C        | 0    | 0     |
| C♯       | 0    | 1     |
| D♭       | 1    | 1     |
| D        | 1    | 2     |
| D♯       | 1    | 3     |
| E♭       | 2    | 3     |
| E        | 2    | 4     |
| F        | 3    | 5     |
| F♯       | 3    | 6     |
| G♭       | 4    | 6     |
| G        | 4    | 7     |
| G♯       | 4    | 8     |
| A♭       | 5    | 8     |
| A        | 5    | 9     |
| A♯       | 5    | 10    |
| B♭       | 6    | 10    |
| B        | 6    | 11    |

| difMod7 | genericInterval |
| ------- | --------------- |
| 0       | Unison          |

`mod12` pitch class
`mod7` staff position class
