def testTrecentoMadrigal(self): from music21 import corpus # c = corpus.parse('beethoven/opus18no1', 2).measures(1, 19) c = corpus.parse('PMFC_06_Giovanni-05_Donna').measures(1, 30) # c = corpus.parse('PMFC_06_Giovanni-05_Donna').measures(90, 118) # c = corpus.parse('PMFC_06_Piero_1').measures(1, 10) # c = corpus.parse('PMFC_06-Jacopo').measures(1, 30) # c = corpus.parse('PMFC_12_13').measures(1, 40) # fix clef fixClef = True if fixClef: startClefs = c.parts[1].getElementsByClass( 'Measure').first().getElementsByClass('Clef') if startClefs: clef1 = startClefs[0] c.parts[1].getElementsByClass('Measure').first().remove(clef1) c.parts[1].getElementsByClass('Measure').first().insert( 0, clef.Treble8vbClef()) cr = ChordReducer() # cr.printDebug = True p = cr.multiPartReduction(c, maxChords=3) # p = cr.multiPartReduction(c, closedPosition=True) from music21 import key, roman cm = key.Key('G') for thisChord in p.recurse().getElementsByClass('Chord'): thisChord.lyric = roman.romanNumeralFromChord( thisChord, cm, preferSecondaryDominants=True).figure c.insert(0, p) if self.show: c.show()
def testTrecentoMadrigal(self): from music21 import corpus #c = corpus.parse('beethoven/opus18no1', 2).measures(1, 19) c = corpus.parse('PMFC_06_Giovanni-05_Donna').measures(1, 30) #c = corpus.parse('PMFC_06_Giovanni-05_Donna').measures(90, 118) #c = corpus.parse('PMFC_06_Piero_1').measures(1, 10) #c = corpus.parse('PMFC_06-Jacopo').measures(1, 30) #c = corpus.parse('PMFC_12_13').measures(1, 40) # fix clef fixClef = True if fixClef: from music21 import clef startClefs = c.parts[1].getElementsByClass( 'Measure')[0].getElementsByClass('Clef') if len(startClefs): clef1 = startClefs[0] c.parts[1].getElementsByClass('Measure')[0].remove(clef1) c.parts[1].getElementsByClass('Measure')[0].insert( 0, clef.Treble8vbClef()) cr = ChordReducer() #cr.printDebug = True p = cr.multiPartReduction(c, maxChords=3) #p = cr.multiPartReduction(c, closedPosition=True) c.insert(0, p) c.show()
def bestClef(self): '''Returns the clef that is the best fit for the stream.''' totalNotes = 0 totalHeight = 0.0 for thisNote in self.notesAndRests: if isinstance(thisNote, note.Note): totalNotes += 1 totalHeight += thisNote.diatonicNoteNum if thisNote.diatonicNoteNum > 33: # a4 totalHeight += 3 # bonus elif thisNote.diatonicNoteNum < 24: # Bass F or lower totalHeight += -3 # bonus if totalNotes == 0: averageHeight = 29 else: averageHeight = totalHeight / totalNotes if self.debug is True: print "Average Clef Height: " + str(averageHeight) + " " # c4 = 32 if (self.allowTreble8va == False): if averageHeight > 28: # c4 return clef.TrebleClef() else: return clef.BassClef() else: if averageHeight > 32: # g4 return clef.TrebleClef() elif averageHeight > 26: # a3 return clef.Treble8vbClef() else: return clef.BassClef()
def createClef(self, attributes): r''' Add a new clef to the current measure and return the currentClef. Clef lines should look like: \|Clef\|Type:ClefType or \|Clef\|Type:ClefType\|OctaveShift:Octave Down (or Up) >>> nwt = noteworthy.translate.NoteworthyTranslator() >>> nwt.currentMeasure = stream.Measure() >>> nwt.createClef({"Type": "Treble"}) >>> nwt.currentMeasure.show('text') {0.0} <music21.clef.TrebleClef> >>> nwt.currentClef 'TREBLE' >>> nwt.createClef({"Type" : "Bass", "OctaveShift" : "Octave Down"}) >>> nwt.currentMeasure.show('text') {0.0} <music21.clef.TrebleClef> {0.0} <music21.clef.Bass8vbClef> If no clef can be found then it raises a NoteworthyTranslate exception >>> nwt.createClef({"Type" : "OBonobo"}) Traceback (most recent call last): NoteworthyTranslateException: Did not find a proper clef in type, OBonobo ''' currentClef = None if 'OctaveShift' in attributes: if attributes['OctaveShift'] == 'Octave Down': octaveShift = -1 elif attributes['OctaveShift'] == 'Octave Up': octaveShift = 1 else: raise NoteworthyTranslateException( 'Did not get a proper octave shift from %s' % attributes[3]) else: octaveShift = 0 cl = attributes['Type'] if cl == "Treble": if octaveShift == 0: self.currentMeasure.append(clef.TrebleClef()) currentClef = "TREBLE" elif octaveShift == -1: self.currentMeasure.append(clef.Treble8vbClef()) currentClef = "TREBLE8dw" elif octaveShift == 1: self.currentMeasure.append(clef.Treble8vaClef()) currentClef = "TREBLE8up" elif cl == "Bass": if octaveShift == 0: self.currentMeasure.append(clef.BassClef()) currentClef = "BASS" elif octaveShift == -1: self.currentMeasure.append(clef.Bass8vbClef()) currentClef = "BASS8dw" elif octaveShift == 1: self.currentMeasure.append(clef.Bass8vaClef()) currentClef = "BASS8up" elif cl == "Alto": if octaveShift != 0: raise NoteworthyTranslateException('cannot shift octaves on an alto clef') self.currentMeasure.append(clef.AltoClef()) currentClef = "ALTO" elif cl == "Tenor": if octaveShift != 0: raise NoteworthyTranslateException('cannot shift octaves on a tenor clef') self.currentMeasure.append(clef.TenorClef()) currentClef = "TENOR" if currentClef is None: raise NoteworthyTranslateException('Did not find a proper clef in type, %s' % cl) self.currentClef = currentClef
def test_clef_to_lily_1(self): bee_ell = clef.Treble8vbClef() expected = u"\\clef \"treble_8\"\n" self.assertEqual(functions.clef_to_lily(bee_ell), expected)
def partPari(show = True): ''' generate the score of Arvo Pärt's "Pari Intervallo" algorithmically using music21.scale.ConcreteScale() to simulate Tintinabulation. ''' s = stream.Score() cminor = key.Key('c') #real Paert main = converter.parse("tinynotation: 4/4 E-1 C D E- F G F E- D C D E- G A- F G E- F G F E- D F G c B- c G A- B- c B- A- B- G c e- d c d c B- A- G F E- F G c E- F G E- D E- F E- D C E- G F E- C F E- D C E- D C D C~ C") # fake Paert #main = converter.parse("E-1 F G A- G F c d e- G A- F E- D d e- c B- A- c d A- G F G F A- B- A- c d A- B- c B- A- G F G F E-~ E-", '4/4') main.__class__ = stream.Part main.transpose('P8', inPlace=True) main.insert(0, cminor) main.insert(0, instrument.Recorder()) bass = copy.deepcopy(main.flat) for n in bass.notes: n.pitch.diatonicNoteNum = n.pitch.diatonicNoteNum - 9 if (n.pitch.step == 'A' or n.pitch.step == 'B') and n.pitch.octave == 2: n.accidental = pitch.Accidental('natural') else: n.accidental = cminor.accidentalByStep(n.step) if n.offset == (2-1) * 4 or n.offset == (74-1) * 4: n.pitch = pitch.Pitch("C3") # exceptions to rule elif n.offset == (73 - 1) * 4: n.tie = None n.pitch = pitch.Pitch("C3") top = copy.deepcopy(main.flat) main.insert(0, clef.Treble8vbClef()) middle = copy.deepcopy(main.flat) cMinorArpeg = scale.ConcreteScale(pitches = ["C2","E-2","G2"]) # dummy test on other data #myA = pitch.Pitch("A2") #myA.microtone = -15 #cMinorArpeg = scale.ConcreteScale(pitches = ["C2", "E`2", "F~2", myA]) lastNote = top.notes[-1] top.remove(lastNote) for n in top: if 'Note' in n.classes: n.pitch = cMinorArpeg.next(n.pitch, stepSize=2) if n.offset != (73-1)*4.0: # m. 73 is different n.duration.quarterLength = 3.0 top.insert(n.offset + 3, note.Rest()) else: n.duration.quarterLength = 6.0 n.tie = None r1 = note.Rest(type = 'half') top.insertAndShift(0, r1) top.getElementsByClass(key.Key)[0].setOffsetBySite(top, 0) lastNote = middle.notes[-1] middle.remove(lastNote) for n in middle: if 'Note' in n.classes: n.pitch = cMinorArpeg.next(n.pitch, direction=scale.DIRECTION_DESCENDING, stepSize=2) if n.offset != (73-1)*4.0: # m. 73 is different n.duration.quarterLength = 3.0 middle.insert(n.offset + 3, note.Rest()) else: n.duration.quarterLength = 5.0 n.tie = None r2 = note.Rest(quarterLength = 3.0) middle.insertAndShift(0, r2) middle.getElementsByClass(key.Key)[0].setOffsetBySite(middle, 0) ttied = top.makeMeasures().makeTies(inPlace=False) mtied = middle.makeMeasures().makeTies(inPlace=False) bass.makeMeasures(inPlace = True) main.makeMeasures(inPlace = True) s.insert(0, ttied) s.insert(0, main) s.insert(0, mtied) s.insert(0, bass) for p in s.parts: p.getElementsByClass(stream.Measure)[-1].rightBarline = bar.Barline('final') if show == True: s.show()
def makeCadenceExercise(score, numberOfBeatsToCut: int = 2, Alto: bool = True, Tenor: bool = True, Bass: bool = True, shortScore: bool = False, writeFile: bool = False, outPath='~/Desktop/', title=''): """ Creates cadence exercises by cutting parts out of a chorale at each fermata cadence. User chooses: number of beats to cut, which parts to cut (A, T, B, or a combination), and full- or short- score presentation. """ # Cut non-SATB parts # Possible TODO: return these instrumental parts at the end? (if not shortScore) legalList = ['Soprano', 'Alto', 'Tenor', 'Bass'] if len(score.parts) > 4: for i in range(len(score.parts))[::-1]: if score.parts[i].partName not in legalList: score.remove(score.parts[i]) # Identify fermataPositions fermataPositions = [] sopNotes = score.parts[0].recurse().notes # NB leave ties in for tied-to fermata. for note in sopNotes: if note.expressions: # TODO expressions.Fermata() not working uniqueOffsetID = note.getOffsetInHierarchy(score.parts[0]) fermataPositions.append(uniqueOffsetID) # Which to cut partsRefs = [] if Alto: partsRefs.append(1) if Tenor: partsRefs.append(2) if Bass: partsRefs.append(3) # Separate ex and soln exercise = deepcopy(score) solution = deepcopy(score) # Exercise for i in partsRefs: exPart = exercise.parts[i] for noteOrRest in exPart.recurse().notesAndRests: noteOrRest.stemDirection = 'unspecified' uniqueOffsetID = noteOrRest.getOffsetInHierarchy(exPart) for position in fermataPositions: if (position-numberOfBeatsToCut) <= uniqueOffsetID <= position: exPart.remove(noteOrRest, recurse=True) # Solution (same i references) solnPart = solution.parts[i] for noteOrRest in solnPart.recurse().notesAndRests: noteOrRest.stemDirection = 'unspecified' uniqueOffsetID = noteOrRest.getOffsetInHierarchy(solnPart) for position in fermataPositions: if (position-numberOfBeatsToCut) <= uniqueOffsetID <= position: noteOrRest.style.color = 'red' # NB Style if not title: title = score.metadata.title # Full or Short Score + writes and returns. Heavy-handed approach to clef. firstMeasure = exercise.parts[0].getElementsByClass('Measure')[0].measureNumber if shortScore: shortEx = exercise.implode() shortSoln = solution.implode() shortEx.parts[1].measure(firstMeasure).clef = clef.BassClef() shortSoln.parts[1].measure(firstMeasure).clef = clef.BassClef() if writeFile: shortEx.write('mxl', fp=f'{outPath}Exercise-{title}.mxl') shortSoln.write('mxl', fp=f'{outPath}Solution-{title}.mxl') return shortEx, shortSoln else: exercise.parts[2].measure(firstMeasure).clef = clef.Treble8vbClef() solution.parts[2].measure(firstMeasure).clef = clef.Treble8vbClef() if writeFile: exercise.write('mxl', fp=f'{outPath}Exercise-{title}.mxl') solution.write('mxl', fp=f'{outPath}Solution-{title}.mxl') return exercise, solution
def createClef(self, attributes): r''' Add a new clef to the current measure and return the currentClef. Clef lines should look like: \|Clef\|Type:ClefType or \|Clef\|Type:ClefType\|OctaveShift:Octave Down (or Up) >>> nwt = noteworthy.translate.NoteworthyTranslator() >>> nwt.currentMeasure = stream.Measure() >>> nwt.createClef({'Type': 'Treble'}) >>> nwt.currentMeasure.show('text') {0.0} <music21.clef.TrebleClef> >>> nwt.currentClef 'TREBLE' >>> nwt.createClef({'Type' : 'Bass', 'OctaveShift' : 'Octave Down'}) >>> nwt.currentMeasure.show('text') {0.0} <music21.clef.TrebleClef> {0.0} <music21.clef.Bass8vbClef> If no clef can be found then it raises a NoteworthyTranslate exception >>> nwt.createClef({'Type' : 'OrangeClef'}) Traceback (most recent call last): music21.noteworthy.translate.NoteworthyTranslateException: Did not find a proper clef in type, OrangeClef ''' currentClef = None if 'OctaveShift' in attributes: if attributes['OctaveShift'] == 'Octave Down': octaveShift = -1 elif attributes['OctaveShift'] == 'Octave Up': octaveShift = 1 else: raise NoteworthyTranslateException( f'Did not get a proper octave shift from {attributes[3]}') else: octaveShift = 0 cl = attributes['Type'] if cl == 'Treble': if octaveShift == 0: self.currentMeasure.append(clef.TrebleClef()) currentClef = 'TREBLE' elif octaveShift == -1: self.currentMeasure.append(clef.Treble8vbClef()) currentClef = 'TREBLE8dw' elif octaveShift == 1: self.currentMeasure.append(clef.Treble8vaClef()) currentClef = 'TREBLE8up' elif cl == 'Bass': if octaveShift == 0: self.currentMeasure.append(clef.BassClef()) currentClef = 'BASS' elif octaveShift == -1: self.currentMeasure.append(clef.Bass8vbClef()) currentClef = 'BASS8dw' elif octaveShift == 1: self.currentMeasure.append(clef.Bass8vaClef()) currentClef = 'BASS8up' elif cl == 'Alto': if octaveShift != 0: raise NoteworthyTranslateException( 'cannot shift octaves on an alto clef') self.currentMeasure.append(clef.AltoClef()) currentClef = 'ALTO' elif cl == 'Tenor': if octaveShift != 0: raise NoteworthyTranslateException( 'cannot shift octaves on a tenor clef') self.currentMeasure.append(clef.TenorClef()) currentClef = 'TENOR' if currentClef is None: raise NoteworthyTranslateException( f'Did not find a proper clef in type, {cl}') self.currentClef = currentClef