def searchForNotes(notesStr): '''the notesStr is a string of notes in the following form: "C4 D4 E4 B3 C4" that's it: name, octave. With no accidentals. If octave is 0 then it means do not bother checking for octaves. Currently octave is ignored anyhow. ''' notesArr = notesStr.split() noteObjArr = [] for tN in notesArr: tNName = tN[0] if tNName.lower() != "r": tNObj = note.Note() tNObj.name = tN[0] tNObj.octave = int(tN[1]) else: tNObj = note.Rest() noteObjArr.append(tNObj) ballataObj = cadencebook.BallataSheet() searcher1 = NoteSearcher(noteObjArr) streamOpus = stream.Opus() for thisWork in ballataObj: for thisCadence in thisWork.snippets: if thisCadence is None: continue for i in range(len(thisCadence.parts)): colorFound(searcher1, thisCadence, streamOpus, thisWork, i) if any(streamOpus): streamOpus.show('lily.png')
def abcToStreamOpus(abcHandler, inputM21=None, number=None): '''Convert a multi-work stream into one or more complete works packed into a an Opus Stream. If a `number` argument is given, and a work is defined by that number, that work is returned. ''' if inputM21 is None: opus = stream.Opus() else: opus = inputM21 #environLocal.printDebug(['abcToStreamOpus: got number', number]) # returns a dictionary of numerical key if abcHandler.definesReferenceNumbers(): abcDict = abcHandler.splitByReferenceNumber() if number is not None and number in abcDict: # get number from dictionary; set to new score opus = abcToStreamScore(abcDict[number]) # return a score, not an opus else: # build entire opus into an opus stream scoreList = [] for key in sorted(abcDict.keys()): # do not need to set work number, as that will be gathered # with meta data in abcToStreamScore try: scoreList.append(abcToStreamScore(abcDict[key])) except IndexError: environLocal.warn("Failure for piece number %d" % key) for scoreDocument in scoreList: opus.coreAppend(scoreDocument, setActiveSite=False) opus.coreElementsChanged() else: # just return single entry in opus object opus.append(abcToStreamScore(abcHandler)) return opus
def searchForIntervals(notesStr): ''' notesStr is the same as above. Now however we check to see if the generic intervals are the same, rather than the note names. Useful if the clef is missing. ''' notesArr = notesStr.split() noteObjArr = [] for tN in notesArr: tNObj = note.Note() tNObj.name = tN[0] tNObj.octave = int(tN[1]) noteObjArr.append(tNObj) interObjArr = [] for i in range(len(noteObjArr) - 1): int1 = interval.notesToInterval(noteObjArr[i], noteObjArr[i + 1]) interObjArr.append(int1) #print interObjArr searcher1 = IntervalSearcher(interObjArr) ballataObj = cadencebook.BallataSheet() streamOpus = stream.Opus() for thisWork in ballataObj: print(thisWork.title) for thisCadence in thisWork.snippets: if thisCadence is None: continue for i in range(len(thisCadence.parts)): colorFound(searcher1, thisCadence, streamOpus, thisWork, i) if any(streamOpus): streamOpus.show('lily.png')
def romanTextToStreamOpus(rtHandler, inputM21=None): '''The main processing routine for RomanText objects that may or may not be multi movement. Takes in a romanText.rtObjects.RTFile() object, or a string as rtHandler. Runs `romanTextToStreamScore()` as its main work. If inputM21 is None then it will create a Score or Opus object. Return either a Score object, or, if a multi-movement work is defined, an Opus object. ''' from music21 import stream if common.isStr(rtHandler): rtf = rtObjects.RTFile() rtHandler = rtf.readstr(rtHandler) # return handler, processes tokens if rtHandler.definesMovements(): # create an opus if inputM21 == None: s = stream.Opus() else: s = inputM21 # copy the common header to each of the sub-handlers handlerBundles = rtHandler.splitByMovement(duplicateHeader=True) # see if we have header information for h in handlerBundles: #print h, len(h) # append to opus s.append(romanTextToStreamScore(h)) return s # an opus else: # create a Score return romanTextToStreamScore(rtHandler, inputM21=inputM21)
def asOpus(self): ''' returns all snippets as a :class:`~music21.stream.Opus` object >>> deduto = alpha.trecento.cadencebook.BallataSheet().workByTitle('deduto') >>> deduto.title 'Deduto sey a quel' >>> dedutoScore = deduto.asOpus() >>> dedutoScore <music21.stream.Opus ...> >>> #_DOCS_SHOW dedutoScore.show('lily.png') ''' o = stream.Opus() md = metadata.Metadata() o.insert(0, md) o.metadata.composer = self.composer o.metadata.title = self.title bs = self.snippets for thisSnippet in bs: if thisSnippet is None: continue if (thisSnippet.tenor is None and thisSnippet.cantus is None and thisSnippet.contratenor is None): continue s = stream.Score() for dummy in range(self.totalVoices): s.insert(0, stream.Part()) for partNumber, snippetPart in enumerate( thisSnippet.getElementsByClass('TrecentoCadenceStream')): if thisSnippet.snippetName != "" and partNumber == self.totalVoices - 1: textEx = expressions.TextExpression( thisSnippet.snippetName) textEx.style.absoluteY = 'below' if 'FrontPaddedSnippet' in thisSnippet.classes: if snippetPart.hasMeasures(): snippetPart.getElementsByClass( 'Measure')[-1].insert(0, textEx) else: snippetPart.append(textEx) else: if snippetPart.hasMeasures(): snippetPart.getElementsByClass( 'Measure')[0].insert(0, textEx) else: snippetPart.insert(0, textEx) # if currentTs is None or timeSig != currentTs: # s.append(timeSig) # currentTs = timeSig try: currentScorePart = s.parts[partNumber] except IndexError: continue # error in coding for thisElement in snippetPart: if 'TimeSignature' in thisElement.classes: continue currentScorePart.append(thisElement) o.insert(0, s) return o
def makePDFfromPieces(start=1, finish=2): ''' make a PDF from the pieces, in order of their PMFC volumes >>> #_DOCS_SHOW makePDFfromPieces(200, 209) ''' from music21 import stream ballataObj = music21.trecento.cadencebook.BallataSheet() retrievedPieces = [] for i in range(start, finish): ## some random pieces # try: randomPiece = ballataObj.makeWork(i) # if randomPiece.incipit is not None: retrievedPieces.append(randomPiece) # except: # pass #raise Exception("Ugg " + str(i)) opus = stream.Opus() retrievedPieces.sort(key=sortByPMFC) for randomPiece in retrievedPieces: #print(randomPiece.title.encode('utf-8')) randomOpus = randomPiece.asOpus() for s in randomOpus.scores: opus.insert(0, s) opus.show('lily.pdf')
def catalog(): opus_catalog = stream.Opus() for work in corpus.chorales.Iterator(1, 26): first_time_signature = work.parts[0].measure(1).getTimeSignatures()[0] if first_time_signature.ratioString == '3/4': incipit = work.measures(0, 2) opus_catalog.insert(0, incipit.implode()) opus_catalog.show()
def find(startRow=2, endRow=469, searchInterval=7): opus = stream.Opus() ballatas = cadencebook.BallataSheet() for row in range(startRow, endRow): ballata = ballatas.makeWork(row) if findInWork(ballata, searchInterval): print(ballata.title + ' has a generic interval of %d somewhere' % searchInterval) opus.insert(0, ballata.asScore()) if any(opus): opus.show('lily.pdf')
def find(): ballatas = cadencebook.BallataSheet() opus = stream.Opus() i = 0 for ballata in ballatas: if i > 10: break if (ballata.timeSigBegin == "6/8" or ballata.timeSigBegin == "9/8"): incipit = ballata.incipit if incipit != None: i += 1 opus.insert(0, incipit) opus.show('lily.pdf')
def searchForIntervals(notesStr): ''' notesStr is the same as above. Now however we check to see if the generic intervals are the same, rather than the note names. Useful if the clef is missing. ''' notesArr = notesStr.split() noteObjArr = [] for tN in notesArr: tNObj = note.Note() tNObj.name = tN[0] tNObj.octave = int(tN[1]) noteObjArr.append(tNObj) interObjArr = [] for i in range(len(noteObjArr) - 1): int1 = interval.notesToInterval(noteObjArr[i], noteObjArr[i + 1]) interObjArr.append(int1) #print interObjArr searcher1 = IntervalSearcher(interObjArr) ballataObj = cadencebook.BallataSheet() streamOpus = stream.Opus() for thisWork in ballataObj: print(thisWork.title) for thisCadence in thisWork.snippets: if thisCadence is None: continue for i in range(len(thisCadence.parts)): if searcher1.compareToStream( thisCadence.parts[i].flat) is True: notesStr = "" for thisNote in thisCadence.parts[i].flat.notesAndRests: #thisNote.editorial.color = "blue" if thisNote.isRest is False: notesStr += thisNote.nameWithOctave + " " else: notesStr += "r " streamOpus.insert(0, thisCadence) # streamLily += "\\score {" + \ # "<< \\time " + str(thisCadence.timeSig) + \ # "\n \\new Staff {" + str(thisCadence.parts[i].lily) + "} >>" + \ # thisCadence.header() + "\n}\n" print(u"In piece %r found in stream %d: %s" % (thisWork.title, i, notesStr)) if len(streamOpus) > 0: streamOpus.show('lily.png')
def searchForNotes(notesStr): '''the notesStr is a string of notes in the following form: "C4 D4 E4 B3 C4" that's it: name, octave. With no accidentals. If octave is 0 then it means do not bother checking for octaves. Currently octave is ignored anyhow. ''' notesArr = notesStr.split() noteObjArr = [] for tN in notesArr: tNName = tN[0] if tNName.lower() != "r": tNObj = note.Note() tNObj.name = tN[0] tNObj.octave = int(tN[1]) else: tNObj = note.Rest() noteObjArr.append(tNObj) ballataObj = cadencebook.BallataSheet() searcher1 = NoteSearcher(noteObjArr) streamOpus = stream.Opus() for thisWork in ballataObj: for thisCadence in thisWork.snippets: if thisCadence is None: continue for i in range(len(thisCadence.parts)): if searcher1.compareToStream( thisCadence.parts[i].flat) is True: notesStr = "" for thisNote in thisCadence.parts[i].flat.notesAndRests: #thisNote.editorial.color = "blue" if thisNote.isRest is False: notesStr += thisNote.nameWithOctave + " " else: notesStr += "r " streamOpus.insert(0, thisCadence) # streamLily += "\\score {" + \ # "<< \\time " + str(thisCadence.timeSig) + \ # "\n \\new Staff {" + str(thisCadence.parts[i].lily) + "} >>" + \ # thisCadence.header() + "\n}\n" print(u"In piece %r found in stream %d: %s" % (thisWork.title, i, notesStr)) if len(streamOpus) > 0: streamOpus.show('lily.png')
def testShowFourA(self): ballataObj = cadencebook.BallataSheet() showStream = stream.Opus() for i in range(2, 45): #459): # all ballate pieceObj = ballataObj.makeWork(i) ## N.B. -- we now use Excel column numbers theseSnippets = pieceObj.snippets for thisSnippet in theseSnippets: if thisSnippet is None: continue appendSnippet = False theseStreams = thisSnippet.parts for thisStream in theseStreams: if capuaRuleFourA(thisStream) > 0: appendSnippet = True if appendSnippet is True: showStream.insert(0, thisSnippet) showStream.show('lily.pdf')
def findCorrections(correctionType="Maj3", startPiece=2, endPiece=459): ''' Find all cases where a Major 3rd moves inward to unison (within the next two or three notes, excluding rests) and see how often the PMFC editors correct it to minor 3rd and how often Capua gets it. or if correctionType == "min6" find all instances of a minor 6th moving outward to octave and see how often the PMFC editors correct it to a Major 6th and how often Capua gets it. # # >>> (totalDict, foundPieceOpus) = findCorrections(correctionType="Maj3", 2, 50) # >>> print(totalDict) # {'potentialChange': 82, 'capuaAlt': 30, 'pmfcAndCapua': 3, 'capuaNotPmfc': 27, 'pmfcAlt': 4, 'pmfcNotCapua': 1, 'totalNotes': 82} # >>> foundPieceOpus.show('lily.pdf') # >>> (totalDict, foundPieceOpus) = findCorrections(correctionType="min6") # >>> print(totalDict) # {'potentialChange': 82, 'capuaAlt': 30, 'pmfcAndCapua': 3, 'capuaNotPmfc': 27, 'pmfcAlt': 4, 'pmfcNotCapua': 1, 'totalNotes': 82} # >>> foundPieceOpus.show('lily.pdf') # >>> #_DOCS_SHOW (totalDict, foundPieceOpus) = trecento.capua.correctedMin6() # >>> totalDict = {'potentialChange': 82, 'capuaAlt': 30, 'pmfcAndCapua': 3, 'capuaNotPmfc': 27, 'pmfcAlt': 4, 'pmfcNotCapua': 1, 'totalNotes': 82} #_DOCS_HIDE # >>> print(totalDict) # {'alterAll': 82, 'capuaAlt': 30, 'pmfcAndCapua': 3, 'capuaNotPmfc': 27, 'pmfcAlt': 4, 'pmfcNotCapua': 1, 'totalNotes': 82} # >>> #_DOCS_SHOW foundPieceOpus.show('lily.pdf') ''' ballataObj = cadencebook.BallataSheet() totalDict = { 'totalNotes': 0, 'pmfcAlt': 0, 'capuaAlt': 0, 'pmfcNotCapua': 0, 'capuaNotPmfc': 0, 'pmfcAndCapua': 0, 'potentialChange': 0 } if correctionType == 'Maj3': notesToCheck = 1 simpleNameToCheck = 'm3' elif correctionType == "min6": notesToCheck = 2 # allows Landini cadences, but not much more simpleNameToCheck = 'M6' else: raise CapuaException( "Invalid correctionType to check; I can check 'Maj3' or 'min6'") foundPieceOpus = stream.Opus() for i in range(startPiece, endPiece): # all ballate # for i in range(2, 29): # small number of ballate # for i in range(232, 373): # all of Landini ballate pieceObj = ballataObj.makeWork( i) ## N.B. -- we now use Excel column numbers if pieceObj.incipit is None: continue environLocal.warn("Working on piece number %d, %s " % (i, pieceObj.title)) for thisSnippet in pieceObj.snippets: thisSnippetAppended = False if thisSnippet is None: continue if "Incipit" in thisSnippet.classes: continue thisSnippetParts = thisSnippet.parts if len(thisSnippetParts) < 2: continue srcStream1 = thisSnippetParts['C'].flat.notesAndRests srcStream2 = thisSnippetParts[ 'T'].flat.notesAndRests ## ignore 3rd voice for now... srcStream1.attachIntervalsBetweenStreams(srcStream2) srcStream2.attachIntervalsBetweenStreams(srcStream1) if thisSnippetAppended is False: foundPieceOpus.insert(0, thisSnippet) thisSnippetAppended = True applyCapuaToStream(srcStream1) applyCapuaToStream(srcStream2) for ss in [srcStream1, srcStream2]: srcStreamNotes = ss.notes # get rid of rests srcStreamLen = len(srcStreamNotes) for (i, note1) in enumerate(srcStreamNotes): if note1.editorial.harmonicInterval is None or \ note1.editorial.harmonicInterval.simpleName != simpleNameToCheck: continue if i >= srcStreamLen - notesToCheck: if i == srcStreamLen - 1: continue else: nextFewNotes = srcStreamNotes[i + 1:] else: nextFewNotes = srcStreamNotes[i + 1:i + 1 + notesToCheck] #nextFewNotes = srcStream1.notesFollowingNote(note1, notesToCheck, allowRests = False) foundP8 = False for thisNote in nextFewNotes: if thisNote is None: raise CapuaException( "This was only supposed to return non-None, what is up???" ) if thisNote.editorial.harmonicInterval is None: continue ## probably a rest; should not happen if correctionType == 'Maj3': if thisNote.editorial.harmonicInterval.simpleName == "P1": foundP8 = True elif correctionType == 'min6': if thisNote.editorial.harmonicInterval.semiSimpleName == "P8": foundP8 = True if foundP8 is False: continue newResults = compareNoteCapuaToEditor(note1) newResults['potentialChange'] = 1 for thisKey in newResults: if thisKey == 'alterAll': continue if thisKey == 'capuaNotPmfc' and newResults[ thisKey] == 1: if thisSnippetAppended is False: foundPieceOpus.insert(0, thisSnippet) thisSnippetAppended = True totalDict[thisKey] += newResults[thisKey] return (totalDict, foundPieceOpus)
def run(self): from music21 import stream output = "" streamName = self.streamName allScores = stream.Opus() myDict = {'A': defaultdict(lambda:False), 'B': defaultdict(lambda:False), 'C': defaultdict(lambda:False), 'D': defaultdict(lambda:False), 'E': defaultdict(lambda:False), 'F': defaultdict(lambda:False), 'G': defaultdict(lambda:False)} for thisWork in self.worksList: incip = thisWork.incipit if self.cadenceName == "A": cadence = thisWork.cadenceA elif self.cadenceName == "B": cadence = thisWork.cadenceBclos try: if (cadence is None or cadence.parts[streamName] is None): cadence = thisWork.cadenceB except KeyError: cadence = thisWork.cadenceB elif isinstance(self.cadenceName, int): try: cadence = thisWork.snippets[self.cadenceName] except IndexError: continue else: raise Exception("Cannot deal with cadence type %s" % self.cadenceName) if incip is None or cadence is None: continue try: incipSN = incip.parts[streamName] cadenceSN = cadence.parts[streamName] except KeyError: continue try: firstNote = incipSN.pitches[0] cadenceNote = cadenceSN.pitches[-1] except IndexError: output += thisWork.title + "\n" continue myDict[firstNote.step][cadenceNote.step] += 1 if firstNote.step == cadenceNote.step: allScores.insert(0, incip) allScores.insert(0, cadence) output += "%30s %4s %4s\n" % (thisWork.title[0:30], firstNote.name, cadenceNote.name) bigTotalSame = 0 bigTotalDiff = 0 for outKey in sorted(myDict): outKeyDiffTotal = 0 for inKey in sorted(myDict[outKey]): if outKey == inKey: output += "**** " bigTotalSame += myDict[outKey][inKey] else: output += " " outKeyDiffTotal += myDict[outKey][inKey] bigTotalDiff += myDict[outKey][inKey] output += "%4s %4s %4d\n" % (outKey, inKey, myDict[outKey][inKey]) output += " %4s diff %4d\n" % (outKey, outKeyDiffTotal) output += "Total Same %4d %3.1f%%\n" % (bigTotalSame, (bigTotalSame * 100.0) / (bigTotalSame + bigTotalDiff)) output += "Total Diff %4d %3.1f%%\n" % (bigTotalDiff, (bigTotalDiff * 100.0) / (bigTotalSame + bigTotalDiff)) self.storedDict = myDict self.displayStream = allScores self.output = output