1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140
|
"""
Elements that can be inserted by MIDI events
"""
from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import QApplication
import ly.pitch
class Note:
LastPitch = ly.pitch.Pitch()
def __init__(self, midinote, notemapping):
# get correct note 0...11 = c...b
# and octave corresponding to octave modifiers ',' & '''
self._midinote = midinote
octave, note = divmod(midinote, 12)
octave -= 4
self._pitch = ly.pitch.Pitch(notemapping[note][0] % 7, notemapping[note][1], octave + notemapping[note][0] // 7)
def output(self, relativemode=False, language='nederlands'):
if relativemode:
pitch = self._pitch.copy()
pitch.makeRelative(Note.LastPitch)
Note.LastPitch.note = self._pitch.note
Note.LastPitch.octave = self._pitch.octave
else:
pitch = self._pitch
# also octavecheck if Shift is held
return pitch.output(language) + (('='+ly.pitch.octaveToString(self._pitch.octave)) if QApplication.keyboardModifiers() & Qt.SHIFT else '')
def midinote(self):
return self._midinote
class Chord(object):
def __init__(self):
self._notes = list()
def add(self, note):
self._notes.append(note)
def output(self, relativemode=False, language='nederlands'):
if len(self._notes) == 1: # only one note, no chord
return self._notes[0].output(relativemode, language)
else: # so we have a chord, print <chord>
sortednotes = sorted(self._notes, key=lambda note: note.midinote())
chord = ''
# temporary variables, to reset LastPitch after this chord
lastnote = sortednotes[0]._pitch.note
lastoctave = sortednotes[0]._pitch.octave
for n in sortednotes:
chord += n.output(relativemode, language) + ' '
Note.LastPitch.note = lastnote
Note.LastPitch.octave = lastoctave
return '<' + chord[:-1] + '>' # strip last space
class NoteMappings:
def to_sharp(self, note, alteration):
if alteration==0.5:
return (note, alteration)
return (note-1, 0.5)
def to_flat(self, note, alteration):
if alteration==-0.5:
return (note, alteration)
return (note+1, -0.5)
def __init__(self):
self.key_order_sharp = [6, 1, 8, 3, 10, 5, 0]
self.key_order_flat = [10, 3, 8, 1, 6, 11, 4]
# Transform: midinote (0-11) -> (note, accidental)
self.sharps = [(0, 0), # c
(0, 0.5), # cis
(1, 0), # d
(1, 0.5), # dis
(2, 0), # e
(3, 0), # f
(3, 0.5), # fis
(4, 0), # g
(4, 0.5), # gis
(5, 0), # a
(5, 0.5), # ais
(6, 0)] # b
self.flats = [(0, 0), # c
(1, -0.5), # des
(1, 0), # d
(2, -0.5), # es
(2, 0), # e
(3, 0), # f
(4, -0.5), # ges
(4, 0), # g
(5, -0.5), # aes
(5, 0), # a
(6, -0.5), # bes
(6, 0)] # b
# Construct all possible mappings using some replacement logic
# 7 flats, ... 1 flats, 0, 1 sharp, ..., 7 sharps
self.sharp_mappings = []
self.flat_mappings = []
for i in range(len(self.key_order_flat)-1, -1, -1):
flatmap = list(self.flats) # copy existing list
sharpmap = list(self.sharps) # copy existing list
for k in self.key_order_flat[:i+1]:
flatmap[k] = self.to_flat(*flatmap[k])
sharpmap[k] = self.to_flat(*sharpmap[k])
self.flat_mappings.append(flatmap)
self.sharp_mappings.append(sharpmap)
self.sharp_mappings.append(self.sharps) # Append C major signature -> no key alteration
self.flat_mappings.append(self.flats) # Append C major signature -> no key alteration
for i in range(len(self.key_order_sharp)):
flatmap = list(self.flats) # copy existing list
sharpmap = list(self.sharps) # copy existing list
for k in self.key_order_sharp[:i+1]:
flatmap[k] = self.to_sharp(*flatmap[k])
sharpmap[k] = self.to_sharp(*sharpmap[k])
self.flat_mappings.append(flatmap)
self.sharp_mappings.append(sharpmap)
class NoteMapping:
mappings = NoteMappings()
def __init__(self, keysignature, sharps=True):
if sharps:
self.mapping = NoteMapping.mappings.sharp_mappings[keysignature]
else:
self.mapping = NoteMapping.mappings.flat_mappings[keysignature]
def __len__(self):
return len(self.mapping)
def __getitem__(self, index):
return self.mapping[index]
|