def __init__(self): InvertedMordent.__init__(self) self.size = interval.Interval("M2")
def __init__(self): Trill.__init__(self) self.size = interval.Interval("M2")
def createDoubleTrillMeasure(): ''' Returns a dictionary with the following keys returnDict = { "name": string, "midi": measure stream, "omr": measure stream, "expected": measure stream, } ''' noteDuration = duration.Duration('quarter') # GAGA Trill trill1NoteDuration = duration.Duration(.25) n0 = note.Note("G") n0.duration = noteDuration n1 = note.Note("G") n1.duration = trill1NoteDuration n2 = note.Note("A") n2.duration = trill1NoteDuration trill1 = [n1, n2, deepcopy(n1), deepcopy(n2)] # GAGA # CBCB Trill trill2NoteDuration = duration.Duration(.0625) n3 = note.Note("B3") # omr n3.duration = noteDuration n4 = note.Note("B3") n4.duration = trill2NoteDuration n5 = note.Note("C") n5.duration = trill2NoteDuration trill2 = [ n5, n4, deepcopy(n5), deepcopy(n4), deepcopy(n5), deepcopy(n4), deepcopy(n5), deepcopy(n4) ] midiMeasure = stream.Measure() midiMeasure.append(trill1) midiMeasure.append(trill2) omrMeasure = stream.Measure() omrMeasure.append([n0, n3]) expectedFixedOmrMeasure = stream.Measure() n0WithTrill = deepcopy(n0) n0Trill = expressions.Trill() n0Trill.size = interval.Interval('m-2') n0Trill.quarterLength = trill1NoteDuration.quarterLength n0WithTrill.expressions.append(n0Trill) n1WithTrill = deepcopy(n3) n1Trill = expressions.Trill() n1Trill.size = interval.Interval('M2') n1Trill.quarterLength = trill2NoteDuration.quarterLength n1WithTrill.expressions.append(n0Trill) expectedFixedOmrMeasure.append([n0WithTrill, n1WithTrill]) returnDict = { "name": "Double Trill Measure", "midi": midiMeasure, "omr": omrMeasure, "expected": expectedFixedOmrMeasure, } return returnDict
def __init__(self): Mordent.__init__(self) self.size = interval.Interval("m2")
def __init__(self): InvertedAppoggiatura.__init__(self) self.size = interval.Interval("M2")
def __init__(self): super().__init__() self.size = interval.Interval('M2') self.quarterLength = 0.25
def testRecognizeTrill(self): # set up the experiment testConditions = [] n1Duration = duration.Duration('quarter') t1NumNotes = 4 t1UpInterval = interval.Interval('M2') t1DownInterval = interval.Interval('M-2') n1Lower = note.Note("G") n1Lower.duration = n1Duration n1Upper = note.Note("A") n1Upper.duration = n1Duration t1 = expressions.Trill() t1NoteDuration = calculateTrillNoteDuration(t1NumNotes, n1Duration) t1.quarterLength = t1NoteDuration t1Notes = t1.realize(n1Lower)[0] # GAGA t1NotesWithRest = deepcopy(t1Notes) # GA_A r1 = note.Rest() r1.duration = duration.Duration(t1NoteDuration) t1NotesWithRest[2] = r1 testConditions.append( TestCondition( name="even whole step trill up without simple note", busyNotes=t1Notes, isOrnament=True, ornamentSize=t1UpInterval) ) testConditions.append( TestCondition( name="even whole step trill up from simple note", busyNotes=t1Notes, simpleNotes=[n1Lower], isOrnament=True, ornamentSize=t1UpInterval) ) testConditions.append( TestCondition( name="even whole step trill up to simple note", busyNotes=t1Notes, simpleNotes=[n1Upper], isOrnament=True, ornamentSize=t1DownInterval) ) testConditions.append( TestCondition( name="valid trill up to enharmonic simple note", busyNotes=t1Notes, simpleNotes=[note.Note("G##")], # A isOrnament=True, ornamentSize=t1DownInterval) ) testConditions.append( TestCondition( name="valid trill but not with simple note", busyNotes=t1Notes, simpleNotes=[note.Note("E")], isOrnament=False) ) testConditions.append( TestCondition( name="invalid trill has rest inside", busyNotes=t1NotesWithRest, isOrnament=False) ) n2Duration = duration.Duration('half') t2NumNotes = 5 t2UpInterval = interval.Interval('m2') t2DownInterval = interval.Interval('m-2') n2Lower = note.Note("G#") n2Lower.duration = n2Duration n2Upper = note.Note("A") n2Upper.duration = n2Duration t2NoteDuration = duration.Duration(calculateTrillNoteDuration(t2NumNotes, n2Duration)) t2n1 = note.Note("A") # trill2note1 t2n1.duration = t2NoteDuration t2n2 = note.Note("G#") t2n2.duration = t2NoteDuration t2Notes = stream.Stream() # A G# A G# A t2Notes.append([t2n1, t2n2, deepcopy(t2n1), deepcopy(t2n2), deepcopy(t2n1)]) testConditions.append( TestCondition( name="odd half step trill down without simple note", busyNotes=t2Notes, isOrnament=True, ornamentSize=t2DownInterval) ) testConditions.append( TestCondition( name="odd half step trill down to simple note", busyNotes=t2Notes, simpleNotes=[n2Lower], isOrnament=True, ornamentSize=t2UpInterval) ) testConditions.append( TestCondition( name="odd trill down from simple note", busyNotes=t2Notes, simpleNotes=[n2Upper], isOrnament=True, ornamentSize=t2DownInterval) ) n3Duration = duration.Duration('quarter') t3NumNotes = 8 t3UpInterval = interval.Interval('m2') t3DownInterval = interval.Interval('m-2') n3 = note.Note("B") n3.duration = n3Duration t3NoteDuration = duration.Duration(calculateTrillNoteDuration(t3NumNotes, n3Duration)) t3n1 = note.Note("C5") t3n1.duration = t3NoteDuration t3n2 = note.Note("B") t3n2.duration = t3NoteDuration nachschlagN1 = note.Note("D5") nachschlagN1.duration = t3NoteDuration nachschlagN2 = note.Note("E5") nachschlagN2.duration = t3NoteDuration nachschlagN3 = note.Note("F5") nachschlagN3.duration = t3NoteDuration t3Notes = stream.Stream() # CBCBCDEF t3Notes.append( [t3n1, t3n2, deepcopy(t3n1), deepcopy(t3n2), deepcopy(t3n1), nachschlagN1, nachschlagN2, nachschlagN3] ) testConditions.append( TestCondition( name="Nachschlag trill when not checking for nachschlag", busyNotes=t3Notes, isOrnament=False) ) testConditions.append( TestCondition( name="Nachschlag trill when checking for nachschlag", busyNotes=t3Notes, isNachschlag=True, isOrnament=True, ornamentSize=t3DownInterval) ) testConditions.append( TestCondition( name="Nachschlag trill when checking for nachschlag up to simple note", busyNotes=t3Notes, simpleNotes=[n3], isNachschlag=True, isOrnament=True, ornamentSize=t3UpInterval) ) t4Duration = duration.Duration('eighth') t4n1 = note.Note("A") t4n1.duration = t4Duration t4n2 = note.Note("G") t4n2.duration = t4Duration testConditions.append( TestCondition( name="One note not a trill", busyNotes=[t4n1], isOrnament=False) ) testConditions.append( TestCondition( name="Two notes not a trill", busyNotes=[t4n1, t4n2], isOrnament=False) ) t5NoteDuration = duration.Duration("eighth") t5n1 = note.Note("A") # trill2note1 t5n1.duration = t5NoteDuration t5n2 = note.Note("C") t5n2.duration = t5NoteDuration t5Notes = stream.Stream() # A C A C t5Notes.append([t5n1, t5n2, deepcopy(t5n1), deepcopy(t5n2)]) testConditions.append( TestCondition( name="Too big of oscillating interval to be trill", busyNotes=t5Notes, isOrnament=False) ) t6NoteDuration = duration.Duration("eighth") t6n1 = note.Note("F") # trill2note1 t6n1.duration = t6NoteDuration t6n2 = note.Note("E") t6n2.duration = t6NoteDuration t6n3 = note.Note("G") t6n3.duration = t2NoteDuration t5Notes = stream.Stream() # F E F G t5Notes.append([t6n1, t6n2, deepcopy(t6n1), t6n3]) testConditions.append( TestCondition( name="Right interval but not oscillating between same notes", busyNotes=t5Notes, isOrnament=False) ) # run test for cond in testConditions: trillRecognizer = TrillRecognizer() if cond.isNachschlag: trillRecognizer.checkNachschlag = True if cond.simpleNotes: trill = trillRecognizer.recognize(cond.busyNotes, simpleNotes=cond.simpleNotes) else: trill = trillRecognizer.recognize(cond.busyNotes) if cond.isOrnament: self.assertIsInstance(trill, expressions.Trill, cond.name) # ensure trill is correct self.assertEqual(trill.nachschlag, cond.isNachschlag, cond.name) if cond.ornamentSize: self.assertEqual(trill.size, cond.ornamentSize, cond.name) else: self.assertFalse(trill, cond.name)
def __init__(self): Ornament.__init__(self) self.size = interval.Interval(2)
def __init__(self, ): self.acceptableInterval = 3 self.minimumLengthForNachschlag = 6 self.acceptableIntervals = [interval.Interval("M2"), interval.Interval("M-2"), interval.Interval("m2"), interval.Interval("m-2"), interval.Interval("A2"), interval.Interval("A-2")]
def recognize(self, busyNotes, simpleNotes=None)\ -> Union[bool, expressions.Turn, expressions.InvertedTurn]: ''' Tries to identify the busy notes as a turn or inverted turn. When simple notes is provided, tries to identify busy notes as the turn shortened by simple notes. Currently only supports one simple note in simple notes. Turns and inverted turns have four notes separated by m2, M2, A2. Turns: start above base note go down to base note, go down again, and go back up to base note Inverted Turns: start below base note go up to base note, go up again, and go back down to base note When going up or down, must go to the adjacent note name, so A goes down to G, G#, G flat, G##, etc Returns: False if not possible or the Turn/Inverted Turn Expression ''' # number of notes/ duration of notes ok if len(busyNotes) != 4: return False if simpleNotes: eps = 0.1 totalBusyNotesDuration = 0 for n in busyNotes: totalBusyNotesDuration += n.duration.quarterLength if abs(simpleNotes[0].duration.quarterLength - totalBusyNotesDuration) > eps: return False # pitches ok if busyNotes[1].pitch.midi != busyNotes[3].pitch.midi: return False if simpleNotes and simpleNotes[0].pitch.midi != busyNotes[1].pitch.midi: return False # intervals ok firstInterval = interval.Interval(noteStart=busyNotes[0], noteEnd=busyNotes[1]) if not self.isAcceptableInterval(firstInterval): return False secondInterval = interval.Interval(noteStart=busyNotes[1], noteEnd=busyNotes[2]) if not self.isAcceptableInterval(secondInterval): return False thirdInterval = interval.Interval(noteStart=busyNotes[2], noteEnd=busyNotes[3]) if not self.isAcceptableInterval(thirdInterval): return False # goes in same direction if firstInterval.direction != secondInterval.direction: return False # and then in opposite direction if secondInterval.direction == thirdInterval.direction: return False # decide direction of turn to return if firstInterval.direction == interval.Interval("M-2").direction: # down turn = expressions.Turn() else: turn = expressions.InvertedTurn() turn.quarterLength = self.calculateOrnamentNoteQl(busyNotes, simpleNotes) return turn
def couldBeItalianA6Resolution(possibA, possibB, threePartChordInfo=None, restrictDoublings=True): ''' Speed-enhanced but designed to stand alone. Returns True if possibA is an Italian A6 chord and possibB could possibly be an acceptable resolution. If restrictDoublings is set to True, only the tonic can be doubled. Setting restrictDoublings to False opens up the chance that the root or the third can be doubled. Controlled in the :class:`~music21.figuredBass.rules.Rules` object by :attr:`~music21.figuredBass.rules.Rules.restrictDoublingsInItalianA6Resolution`. >>> from music21 import pitch >>> from music21.figuredBass import possibility >>> A2 = pitch.Pitch('A2') >>> Bb2 = pitch.Pitch('B-2') >>> Cs4 = pitch.Pitch('C#4') >>> D4 = pitch.Pitch('D4') >>> E4 = pitch.Pitch('E4') >>> Fs4 = pitch.Pitch('F#4') >>> Gs4 = pitch.Pitch('G#4') >>> A4 = pitch.Pitch('A4') >>> possibA1 = (Gs4, D4, D4, Bb2) >>> possibB1 = (A4, Cs4, E4, A2) >>> possibB2 = (A4, E4, Cs4, A2) >>> possibB3 = (A4, D4, Fs4, A2) >>> possibility.couldBeItalianA6Resolution(possibA1, possibB1) True >>> possibility.couldBeItalianA6Resolution(possibA1, possibB1) True >>> possibility.couldBeItalianA6Resolution(possibA1, possibB3) True A PossibilityException is raised if possibA is not an Italian A6 chord, but this only applies only if threePartChordInfo = None, because otherwise the chord information is coming from :class:`~music21.figuredBass.segment.Segment` and the fact that possibA is an It+6 chord is assumed. >>> possibA2 = (Gs4, E4, D4, Bb2) >>> possibB2 = (A4, E4, Cs4, A2) >>> possibility.couldBeItalianA6Resolution(possibA2, possibB2) Traceback (most recent call last): music21.figuredBass.possibility.PossibilityException: possibA does not spell out an It+6 chord. The method is called `couldBeItalianA6Resolution` as opposed to `isItalianA6Resolution` because it is designed to work in tandem with :meth:`~music21.figuredBass.possibility.parallelOctaves` and :meth:`~music21.figuredBass.possibility.isIncomplete` in a Segment. Consider the following examples with possibA1 above as the augmented sixth chord to resolve. >>> possibA1 = (Gs4, D4, D4, Bb2) >>> possibB4 = (A4, D4, D4, A2) # No 3rd >>> possibB5 = (A4, Cs4, Cs4, A2) # No 5th >>> possibility.couldBeItalianA6Resolution(possibA1, possibB4) True >>> possibility.couldBeItalianA6Resolution(possibA1, possibB5) # parallel octaves True >>> possibA3 = (Gs4, Gs4, D4, Bb2) >>> possibB6 = (A4, A4, Cs4, A2) >>> possibility.couldBeItalianA6Resolution(possibA3, possibB6, restrictDoublings=True) False >>> possibility.couldBeItalianA6Resolution(possibA3, possibB6, restrictDoublings=False) True ''' if threePartChordInfo is None: augSixthChord = chord.Chord(possibA) if not augSixthChord.isItalianAugmentedSixth(): raise PossibilityException( 'possibA does not spell out an It+6 chord.') bass = augSixthChord.bass() root = augSixthChord.root() third = augSixthChord.getChordStep(3) fifth = augSixthChord.getChordStep(5) threePartChordInfo = [bass, root, third, fifth] allowedIntervalNames = ['M3', 'm3', 'M2', 'm-2'] rootResolved = False [bass, root, third, fifth] = threePartChordInfo for pitchIndex in range(len(possibA)): pitchA = possibA[pitchIndex] pitchB = possibB[pitchIndex] if pitchA.name == fifth.name: if pitchA == pitchB: continue if abs(pitchA.ps - pitchB.ps) > 4.0: return False tt = interval.Interval(pitchA, pitchB) if tt.directedSimpleName not in allowedIntervalNames: return False elif pitchA.name == bass.name and pitchA == bass: if not (pitchA.ps - pitchB.ps) == 1.0: return False i = interval.Interval(pitchA, pitchB) if not i.directedName == 'm-2': return False elif pitchA.name == root.name: if rootResolved and restrictDoublings: # there can't be more than one root return False if not (pitchB.ps - pitchA.ps) == 1.0: return False i = interval.Interval(pitchA, pitchB) if not i.directedName == 'm2': return False rootResolved = True elif pitchA.name == third.name: if restrictDoublings: # there can't be more than one third, which is in the bass. return False if not (pitchA.ps - pitchB.ps) == 1.0: return False i = interval.Interval(pitchA, pitchB) if not i.directedName == 'm-2': return False # # Part 1: Check if possibA is A6 chord, and if it is properly formed. # bass = possibA[-1] # root = None # rootIndex = 0 # for pitchA in possibA[0:-1]: # if not (pitchA.ps - bass.ps) % 12 == 10: # rootIndex += 1 # continue # br = interval.Interval(bass, pitchA) # isAugmentedSixth = (br.directedSimpleName == 'A6') # if isAugmentedSixth: # root = pitchA # break # tonic = bass.transpose('M3') # # Restrict doublings, It+6 # for pitchIndex in range(len(possibA) - 1): # if pitchIndex == rootIndex: # continue # pitchA = possibA[pitchIndex] # if not pitchA.name == tonic.name: # return False # # # Part 2: If possibA is Italian A6 chord, check that it resolves properly in possibB. # fifth = root.transpose('m2') # pairsList = partPairs(possibA, possibB) # (bassA, bassB) = pairsList[-1] # (rootA, rootB) = pairsList[rootIndex] # if not (bassB.name == fifth.name and rootB.name == fifth.name): # return False # if not (bassB.ps - bassA.ps == -1.0 and rootB.ps - rootA.ps == 1.0): # return False # allowedIntervalNames = ['M3', 'm3', 'M2', 'm-2'] # for pitchIndex in range(len(pairsList) - 1): # if pitchIndex == rootIndex: # continue # (tonicA, tonicB) = pairsList[pitchIndex] # if tonicA == tonicB: # continue # tt = interval.Interval(tonicA, tonicB) # if not tt.directedSimpleName in allowedIntervalNames: # return False return True
def chordsToBassMelodictIntervalString(self, chordOne, chordTwo): bassPitchOne = min(chordOne) bassPitchTwo = min(chordTwo) bassMelodicInterval = interval.Interval(bassPitchOne, bassPitchTwo) bassMelodicIntervalString = bassMelodicInterval.directedName return bassMelodicIntervalString
def chordToIntervalString(self, chord): if len(chord) == 1: intervalString = 'P1' else: intervalString = interval.Interval(chord[0], chord[1]).name return intervalString
def __init__(self): Trill.__init__(self) self.size = interval.Interval("M2") self.quarterLength = 0.25
def recognize(self, busyNotes, simpleNotes=None) -> Union[bool, expressions.Trill]: ''' Tries to identify the busy notes as a trill. When simple notes is provided, tries to identify busy notes as the trill shortened by simple notes. Currently only supports one simple note in simple notes. Only when checkNachschlag is true, allows last few notes to break trill rules. Trill interval size is interval between busy notes. Returns: False if not possible or the Trill Expression ''' # Enough notes to trill if len(busyNotes) <= 2: return False # Oscillation pitches n1 = busyNotes[0] n2 = busyNotes[1] if not n1.isNote or not n2.isNote: return False if abs(n1.pitch.midi - n2.pitch.midi) > self.acceptableInterval: return False twoNoteOscillation = True i = 0 for i in range(len(busyNotes)): noteConsidering = busyNotes[i] if not noteConsidering.isNote: return False if i % 2 == 0 and noteConsidering.pitch != n1.pitch: twoNoteOscillation = False break elif i % 2 != 0 and noteConsidering.pitch != n2.pitch: twoNoteOscillation = False break isNachschlag = False if twoNoteOscillation: pass elif not self.checkNachschlag: return False else: lengthOk = len(busyNotes) >= self.minimumLengthForNachschlag notTooMuchNachschlag = i >= len(busyNotes) / 2 if lengthOk and notTooMuchNachschlag: isNachschlag = True else: return False # set up trill trill = expressions.Trill() trill.quarterLength = self.calculateOrnamentNoteQl(busyNotes, simpleNotes) if isNachschlag: trill.nachschlag = True if not simpleNotes: trill.size = interval.Interval(noteStart=n1, noteEnd=n2) return trill # currently ignore other notes in simpleNotes simpleNote = simpleNotes[0] # enharmonic invariant checker if not(simpleNote.pitch.midi == n1.pitch.midi or simpleNote.pitch.midi == n2.pitch.midi): return False endNote = n2 startNote = n1 if simpleNote.pitch.midi == n2.pitch.midi: endNote = n1 startNote = n2 distance = interval.Interval(noteStart=startNote, noteEnd=endNote) trill.size = distance return trill
def __init__(self): Ornament.__init__(self) self.size = interval.Interval("M2") self.quarterLength = 0.25
def transpose(self, value, *, inPlace=False): ''' Transpose the KeySignature by the user-provided value. If the value is an integer, the transposition is treated in half steps. If the value is a string, any Interval string specification can be provided. Alternatively, a :class:`music21.interval.Interval` object can be supplied. >>> a = key.KeySignature(2) >>> a <music21.key.KeySignature of 2 sharps> >>> a.asKey('major') <music21.key.Key of D major> >>> b = a.transpose('p5') >>> b <music21.key.KeySignature of 3 sharps> >>> b.asKey('major') <music21.key.Key of A major> >>> b.sharps 3 >>> c = b.transpose('-m2') >>> c.asKey('major') <music21.key.Key of G# major> >>> c.sharps 8 >>> d = c.transpose('-a3') >>> d.asKey('major') <music21.key.Key of E- major> >>> d.sharps -3 Transposition by semitone (or other chromatic interval) >>> c = key.KeySignature(0) >>> dFlat = c.transpose(1) >>> dFlat <music21.key.KeySignature of 5 flats> >>> d = dFlat.transpose(1) >>> d <music21.key.KeySignature of 2 sharps> >>> eFlat = d.transpose(1) >>> eFlat <music21.key.KeySignature of 3 flats> ''' if hasattr(value, 'diatonic'): # its an Interval class intervalObj = value elif hasattr(value, 'classes') and 'GenericInterval' in value.classes: intervalObj = value else: # try to process intervalObj = interval.Interval(value) if not inPlace: post = copy.deepcopy(self) else: post = self k1 = post.asKey('major') p1 = k1.tonic p2 = intervalObj.transposePitch(p1) if isinstance(value, int) and abs(pitchToSharps(p2)) > 6: p2 = p2.getEnharmonic() post.sharps = pitchToSharps(p2) post.clearCache() # mode is already set if not inPlace: return post else: return None
def __init__(self): Appoggiatura.__init__(self) self.size = interval.Interval("m2")
def transposePitchFromC(self, p: pitch.Pitch, *, inPlace=False) -> Optional[pitch.Pitch]: ''' Takes a pitch in C major and transposes it so that it has the same step position in the current key signature. Example: B is the leading tone in C major, so given a key signature of 3 flats, get the leading tone in E-flat major: >>> ks = key.KeySignature(-3) >>> p1 = pitch.Pitch('B') >>> p2 = ks.transposePitchFromC(p1) >>> p2.name 'D' Original pitch is unchanged: >>> p1.name 'B' >>> ks2 = key.KeySignature(2) >>> p2 = ks2.transposePitchFromC(p1) >>> p2.name 'C#' For out of scale pitches the relationship still works; note also that original octave is preserved. >>> p3 = pitch.Pitch('G-4') >>> p4 = ks.transposePitchFromC(p3) >>> p4.nameWithOctave 'B--4' If inPlace is True then nothing is returned and the original pitch is modified. >>> p5 = pitch.Pitch('C5') >>> ks.transposePitchFromC(p5, inPlace=True) >>> p5.nameWithOctave 'E-5' New method in v6. ''' transInterval = None transTimes = 0 originalOctave = p.octave if not inPlace: p = copy.deepcopy(p) if self.sharps == 0: if inPlace: return else: return p elif self.sharps < 0: transTimes = abs(self.sharps) transInterval = interval.Interval('P4') else: transTimes = self.sharps transInterval = interval.Interval('P5') for i in range(transTimes): transInterval.transposePitch(p, inPlace=True) if originalOctave is not None: p.octave = originalOctave if not inPlace: return p
def __init__(self): super().__init__() self.direction = '' # up or down self.size = None # interval.Interval (General, etc.) class self.quarterLength = 0.125 # 32nd note default self.size = interval.Interval(2)
def sharpsToPitch(sharpCount): ''' Given a number a positive/negative number of sharps, return a Pitch object set to the appropriate major key value. >>> key.sharpsToPitch(1) <music21.pitch.Pitch G> >>> key.sharpsToPitch(2) <music21.pitch.Pitch D> >>> key.sharpsToPitch(-2) <music21.pitch.Pitch B-> >>> key.sharpsToPitch(-6) <music21.pitch.Pitch G-> Note that these are :class:`music21.pitch.Pitch` objects not just names: >>> k1 = key.sharpsToPitch(6) >>> k1 <music21.pitch.Pitch F#> >>> k1.step 'F' >>> k1.accidental <accidental sharp> OMIT_FROM_DOCS The second time we do something it should be in the cache, so let's make sure it still works: >>> key.sharpsToPitch(1) <music21.pitch.Pitch G> >>> key.sharpsToPitch(1) <music21.pitch.Pitch G> >>> 1 in key._sharpsToPitchCache True >>> key._sharpsToPitchCache[1] <music21.pitch.Pitch G> ''' if sharpCount is None: sharpCount = 0 # fix for C major if sharpCount in _sharpsToPitchCache: # return a deepcopy of the pitch return copy.deepcopy(_sharpsToPitchCache[sharpCount]) pitchInit = pitch.Pitch('C') pitchInit.octave = None # keyPc = (self.sharps * 7) % 12 if sharpCount > 0: intervalStr = 'P5' elif sharpCount < 0: intervalStr = 'P-5' else: return pitchInit # C intervalObj = interval.Interval(intervalStr) for i in range(abs(sharpCount)): pitchInit = intervalObj.transposePitch(pitchInit) pitchInit.octave = None _sharpsToPitchCache[sharpCount] = pitchInit return pitchInit
def __init__(self): super().__init__() self.size = interval.Interval('M2')
def fix(self): super().fix() for (midiRef, omrRef, op) in self.changes: omrRef.color = "black" # if they're not notes, don't bother with rest if self.checkIfNoteInstance(midiRef, omrRef) is False: continue # if the are the same, don't bother to try changing it # 3 is the number of noChange Ops if isinstance( op, aligner.ChangeOps) and op == aligner.ChangeOps.NoChange: continue # don't bother with notes with too big of an interval between them if self.intervalTooBig(midiRef, omrRef, setint=5): continue # case 1: omr has extraneous natural sign in front of it, get rid of it if self.hasNatAcc(omrRef): if self.isEnharmonic(midiRef, omrRef): omrRef.pitch.accidental = None else: # case 2-1: midi note is sharp, omr note is one step higher and natural, # should be a flat instead. e.g midi = g#, gt = a-, omr = an # omr note has higher ps than midi-- on a higher # line or space than midi note if omrRef.pitch > midiRef.pitch: if omrRef.pitch.transpose( interval.Interval(-1)).isEnharmonic( midiRef.pitch): omrRef.pitch.accidental = pitch.Accidental('flat') # case 2-2: midi note is flat, omr note is one step lower and natural, # should be a flat instead. e.g midi = g-, gt = f#, omr = fn # omr note has lower ps than midi-- on a higher line # or space than midi note elif omrRef.pitch < midiRef.pitch: if omrRef.pitch.transpose( interval.Interval(1)).isEnharmonic( midiRef.pitch): omrRef.pitch.accidental = pitch.Accidental('sharp') # case 3: notes are on same step, but omr got read wrong. # e.g. midi = g#, gt = g#, omr = gn or omr = g- elif self.hasSharpFlatAcc(omrRef) and self.stepEq(midiRef, omrRef): if self.hasAcc(omrRef): omrRef.pitch.accidental = midiRef.pitch.accidental else: omrRef.pitch.accidental = None elif self.hasSharpFlatAcc(omrRef) and self.stepNotEq( midiRef, omrRef): # case 4-1: notes are on different step, off by an interval of 2, # omr note is higher and sharp # e.g. midi = g#, gt = a-, omr = a# if omrRef.pitch > midiRef.pitch: if omrRef.pitch.accidental == pitch.Accidental('sharp'): if omrRef.pitch.transpose( interval.Interval(-2)).isEnharmonic( midiRef.pitch): omrRef.pitch.accidental = pitch.Accidental('flat') # case 4-2: notes are on different step, off by an interval of 2, # omr note is lower and flat # e.g. midi = a-, gt = g#, omr = g- elif omrRef.pitch < midiRef.pitch: if omrRef.pitch.accidental == pitch.Accidental('flat'): if omrRef.pitch.transpose( interval.Interval(2)).isEnharmonic( midiRef.pitch): omrRef.pitch.accidental = pitch.Accidental('sharp') # case 5: same step, MIDI has accidental, # omr was read wrong (e.g. key signature not parsed) # e.g. midi = b-, gt = b-, omr= elif (omrRef.pitch != midiRef.pitch and self.hasSharpFlatAcc(midiRef) and self.stepEq(midiRef, omrRef)): omrRef.pitch = midiRef.pitch