--- id: aliases: [] title: Music Theory as Code tags: dg-publish: true --- # 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