def countCadencePercentages(): ballatas = cadencebook.BallataSheet() totalPieces = 0.0 firstNoteTotal = common.defHash(default = 0) lastNoteTotal = common.defHash(default = 0) for thisWork in ballatas: incipit = thisWork.incipit cadenceB = thisWork.cadenceA #BClos or thisWork.cadenceBOuvert # if thisWork.composer != 'A. Zacara' and thisWork.composer != 'Zacharias': # continue if incipit is None or cadenceB is None: continue incipitTenor = incipit.tenor cadenceBTenor = cadenceB.tenor if incipitTenor is None or cadenceBTenor is None: continue firstNotes = incipitTenor.getElementsByClass(note.Note) lastNotes = cadenceBTenor.getElementsByClass(note.Note) if len(firstNotes) == 0 or len(lastNotes) == 0: continue firstNote = firstNotes[0] lastNote = lastNotes[-1] print(thisWork.title, firstNote.name, lastNote.name) totalPieces += 1.0 # for float division later firstNoteTotal[firstNote.name] += 1 lastNoteTotal[lastNote.name] += 1 print ("First note distribution:") for thisName in firstNoteTotal: print (thisName, firstNoteTotal[thisName]/totalPieces) print ("Last note distribution:") for thisName in lastNoteTotal: print (thisName, lastNoteTotal[thisName]/totalPieces)
def simple3(): ''' reduce all measures of Chopin mazurkas to their rhythmic components and give the measure numbers (harder: render in notation) of all measures sorted by pattern. ''' def lsort(keyname): return len(rhythmicHash[keyname]) defaultPitch = music21.pitch.Pitch("C3") import copy from music21.converter import parse from music21.stream import Stream, Measure # semiFlat lets me get all Measures no matter where they reside in the tree structure measureStream = parse(testFiles.mazurka6).semiFlat[Measure] rhythmicHash = common.defHash(default = list, callDefault = True ) for thisMeasure in measureStream: if not almostEquals(thisMeasure.duration.quarterLength, 3.0): continue notes = thisMeasure.flat.getNotes() rhythmicStream = Measure() offsetString = "" ## comma separated string of offsets for thisNote in notes: rhythmNote = copy.deepcopy(thisNote) if rhythmNote.isNote: rhythmNote.pitch = defaultPitch elif rhythmNote.isChord: rhythmNote = music21.note.Note() rhythmNote.pitch = defaultPitch rhythmNote.duration = thisNote.duration if not rhythmNote.isRest: offsetString += str(rhythmNote.offset) + ", " if thisNote.isChord: thisNote.pitch = defaultPitch rhythmicStream.append(rhythmNote) notes[0].lyric = str(thisMeasure.number) if len(rhythmicHash[offsetString]) == 0: # if it is our first encounter with the rhythm, add the rhythm alone in blue for thisNote in rhythmicStream: thisNote.color = "blue" rhythmicHash[offsetString].append(rhythmicStream) thisMeasure.getNotes()[0].editorial.comment.text = str(thisMeasure.number) rhythmicHash[offsetString].append(thisMeasure) allLily = lily.LilyString() allLily += meter.TimeSignature('3/4').lily + " " for thisRhythmProfile in sorted(rhythmicHash, key=lsort, reverse=True): for thisMeasure in rhythmicHash[thisRhythmProfile]: thisLily = " " + str(thisMeasure.bestClef().lily) + " " + str(thisMeasure.lily) + "\n" allLily += thisLily allLily.showPNG()
def __init__(self, stringRep, storedDict=common.defHash(default=False)): noteObj = None storedtie = None self.debug = False if self.PRECTIE.match(stringRep): if self.debug is True: print("FOUND FRONT TIE") stringRep = self.PRECTIE.sub("", stringRep) storedtie = music21.note.Tie("stop") x = self.customPitchMatch(stringRep, storedDict) if x is not None: noteObj = x elif self.REST.match(stringRep) is not None: # rest noteObj = music21.note.Rest() elif self.OCTAVE2.match(stringRep): # BB etc. noteObj = self._getPitch(self.OCTAVE2.match(stringRep), 2) elif self.OCTAVE3.match(stringRep): noteObj = self._getPitch(self.OCTAVE3.match(stringRep), 3) elif self.OCTAVE5.match(stringRep): # must match octave 5 then 4! noteObj = self._getPitch(self.OCTAVE5.match(stringRep), 5) elif self.OCTAVE4.match(stringRep): noteObj = self._getPitch(self.OCTAVE4.match(stringRep), 4) else: raise TinyNotationException("could not get pitch information from " + str(stringRep)) if storedtie: noteObj.tie = storedtie ## get duration usedLastDuration = False if self.TYPE.search(stringRep): typeNum = self.TYPE.search(stringRep).group(1) if typeNum == "0": ## special case = full measure + fermata noteObj.duration = storedDict["barDuration"] newFerm = expressions.Fermata() noteObj.notations.append(newFerm) else: noteObj.duration.type = music21.duration.typeFromNumDict[int(typeNum)] else: noteObj.duration = copy.deepcopy(storedDict["lastDuration"]) usedLastDuration = True if noteObj.duration.tuplets: noteObj.duration.tuplets[0].type = "" # if it continues a tuplet it cannot be start; maybe end ## get dots; called out because subclassable self.getDots(stringRep, noteObj) ## get ties if self.TIE.search(stringRep): if self.debug is True: print("FOUND TIE") noteObj.tie = music21.note.Tie("start") ## use dict to set tuplets if (storedDict["inTrip"] == True or storedDict["inQuad"] == True) and usedLastDuration == False: newTup = music21.duration.Tuplet() newTup.durationActual.type = noteObj.duration.type newTup.durationNormal.type = noteObj.duration.type if storedDict["inQuad"] == True: newTup.numNotesActual = 4.0 newTup.numNotesNormal = 3.0 if storedDict["beginTuplet"]: newTup.type = "start" noteObj.duration.appendTuplet(newTup) if storedDict["inTrip"] == True and storedDict["endTuplet"]: noteObj.duration.tuplets[0].type = "stop" if storedDict["inQuad"] == True and storedDict["endTuplet"]: noteObj.duration.tuplets[0].type = "stop" storedDict["lastDuration"] = noteObj.duration ## get accidentals if isinstance(noteObj, music21.note.Note): if self.EDSHARP.search(stringRep): # must come before sharp acc1 = pitch.Accidental("sharp") noteObj.editorial.ficta = acc1 noteObj.editorial.misc["pmfc-ficta"] = acc1 elif self.EDFLAT.search(stringRep): # must come before flat acc1 = pitch.Accidental("flat") noteObj.editorial.ficta = acc1 noteObj.editorial.misc["pmfc-ficta"] = acc1 elif self.EDNAT.search(stringRep): acc1 = pitch.Accidental("natural") noteObj.editorial.ficta = acc1 noteObj.editorial.misc["pmfc-ficta"] = acc1 noteObj.accidental = acc1 elif self.SHARP.search(stringRep): noteObj.accidental = "sharp" elif self.FLAT.search(stringRep): noteObj.accidental = "flat" self.customNotationMatch(noteObj, stringRep, storedDict) if self.ID_EL.search(stringRep): noteObj.id = self.ID_EL.search(stringRep).group(1) if self.LYRIC.search(stringRep): noteObj.lyric = self.LYRIC.search(stringRep).group(1) self.note = noteObj
""" import music21 import unittest from re import match from music21.note import Note from music21 import interval from music21.trecento import cadencebook from music21 import lily from music21.lily import lilyString from music21.trecento import capua from music21.trecento import polyphonicSnippet from music21.common import defHash ph = lambda h={}: defHash(h, default=False) class TonalityCounter(object): """ The TonalityCounter object takes a list of Trecento Works (defined in music21.trecento.cadencebook) and when run() is called, stores a set of information about the cadence tonalities of the works. streamNumber can be 0 (cantus), 1 (tenor, default), or 2 (contratenor), or very rarely 3 (fourth voice). cadenceName can be "A" or "B" (which by default uses the second ending of cadence B if there are two endings) or an integer specifying which cadence to consult (-1 being