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 ch1_basic_II_A_2(show=True, *arguments, **keywords): ''' p3. Write letter names and octave designations for the pitches written in the treble and bass clefs below. ''' humdata = ''' **kern 1BBD 1C## 1B 1DD- 1f# 1FF 1D- 1d 1CC# 1AA- 1c 1F *- ''' exercise = converter.parseData(humdata) for n in exercise.flat.notes: # have to use flat here n.lyric = n.nameWithOctave exercise.insert(0, clef.BassClef()) exercise = exercise.sorted # need sorted to get clef if show: exercise.show()
def ch5_writing_IV_A(show=True, *arguments, **keywords): '''p. 50 Note the meter signature, then add bar lines. ''' from music21 import stream, meter, key ex = stream.Stream() ex.insert(clef.BassClef()) ex.insert(meter.TimeSignature('6/4')) ex.insert(key.KeySignature(3)) for p, d in [(None,1), ('f#3',1),('g#3',1),('a3',4), ('g#3',.5),('a#3',.5),('b3',2), ('a#3',.5),('g#3',.5),('a#3',.5),('b#3',.5), ('c#4',1.5),('b3',.5),('a3',.5),('c#4',.5),('b3',.5),('a3',.5), ('g#3',2),('f#3',3), (None,.5), ('c#4',.5),('c#4',.5), ('b3',.5),('b3',.5),('a#3',.5)]: if p == None: n = note.Rest() else: n = note.Note(p) n.quarterLength = d ex.append(n) if show: # calling show creates measures and allocates notes for the time sig ex.show() else: unused_post = musicxml.m21ToString.fromMusic21Object(ex)
class Instrument: # TODO ''' represents an instrument; associated with midi channel etc (see music21 docs) # TODO detector for whether instrument is capable of specific technique, # double-stop, etc. # TODO instruments like cello may use multiple clefs ''' name_to_instrument21 = { 'violin': instrument21.Violin(), 'viola': instrument21.Viola(), 'cello': instrument21.Violoncello() } name_to_clef21 = { 'violin': clef21.TrebleClef(), 'viola': clef21.AltoClef(), 'cello': clef21.BassClef() } def __init__(self, name): self.instrument = Instrument.name_to_instrument21[name] self.clef = Instrument.name_to_clef21[name] # there isn't a precise to_music21 analogue def check_pitch(self, pitch): # true if pitch within instrument's range low = self.instrument.lowestNote # assume these are always music21 Pitch objects high = self.instrument.highestNote pitch_21 = pitch.to_music21() if low is not None and low > pitch_21: return False if high is not None and high < pitch_21: return False return True
def ch1_basic_II_C_4(show=True, *arguments, **keywords): data = [[clef.TrebleClef(), 'b#4', 'e4', 'd#5'], [clef.AltoClef(), 'c-4'], [clef.BassClef(), 'f#3', 'c3']] ex = ch1_basic_II_C(data, '-h') if show: ex.show()
def ch1_basic_II_C_3(show=True, *arguments, **keywords): data = [[clef.BassClef(), 'f#2', 'c-3'], [clef.TrebleClef(), 'e4', 'b-5', 'a#4'], [clef.AltoClef(), 'f-3']] ex = ch1_basic_II_C(data, 'h') if show: ex.show()
def __init__(self): from music21 import stream, note, clef, meter, chord self.s = stream.Stream() self.s.repeatAppend(note.Note(), 300) self.s.repeatAppend(note.Rest(), 300) self.s.repeatAppend(chord.Chord(), 300) self.s.repeatInsert(meter.TimeSignature(), [0, 50, 100, 150]) self.s.repeatInsert(clef.BassClef(), [0, 50, 100, 150])
def _right_hand_interlude(): rh_interlude = stream.Stream() rh_interlude.append(meter.TimeSignature("6/4")) rh_interlude.append(clef.BassClef()) rh_interlude.repeatAppend( chord.Chord(["A1", "E2", "A2"], duration=duration.Duration(6)), 2) rh_interlude.makeMeasures(inPlace=True, finalBarline=None) return rh_interlude
def testPerformanceA(self): from music21 import common, stream, classCache, clef, meter, note s1 = stream.Stream() s1.repeatAppend(note.Note(), 300) s1.repeatAppend(note.Rest(), 300) s1.repeatInsert(meter.TimeSignature(), [0, 50, 100, 150]) s1.repeatInsert(clef.BassClef(), [0, 50, 100, 150]) t1 = common.Timer() t1.start() for i in range(50): s1.getElementsByClass('Rest') s1.getElementsByClass('Note') s1.getElementsByClass('GemeralNote') s1.getElementsByClass('BassClef') s1.getElementsByClass('TimeSignature') environLocal.printDebug(['Stream.getOffsetBySite()', t1]) #classCache.py: Stream.getOffsetBySite() 0.747 s2 = stream.Stream() s2.repeatAppend(note.Note(), 300) s2.repeatAppend(note.Rest(), 300) s2.repeatInsert(meter.TimeSignature(), [0, 50, 100, 150]) s2.repeatInsert(clef.BassClef(), [0, 50, 100, 150]) t1 = common.Timer() t1.start() cc = classCache.ClassCache() # simulate what would happen in getElementsByClass cc.load(s2) for i in range(50): s = stream.Stream() cc.getElementsByClass(s, ['Rest']) s = stream.Stream() cc.getElementsByClass(s, ['Note']) s = stream.Stream() cc.getElementsByClass(s, ['GeneralNote']) s = stream.Stream() cc.getElementsByClass(s, ['BassClef']) s = stream.Stream() cc.getElementsByClass(s, ['TimeSignature']) environLocal.printDebug(['Stream.getOffsetBySite()', t1])
def generateBassLine(self): ''' Generates the bass line as a :class:`~music21.stream.Score`. >>> from music21.figuredBass import realizer >>> from music21 import key >>> from music21 import meter >>> from music21 import note >>> fbLine = realizer.FiguredBassLine(key.Key('B'), meter.TimeSignature('3/4')) >>> fbLine.addElement(note.Note('B2')) >>> fbLine.addElement(note.Note('C#3'), '6') >>> fbLine.addElement(note.Note('D#3'), '6') >>> #_DOCS_SHOW fbLine.generateBassLine().show() .. image:: images/figuredBass/fbRealizer_bassLine.* :width: 200 >>> from music21 import corpus >>> sBach = corpus.parse('bach/bwv307') >>> sBach['bass'].measure(0).show('text') {0.0} ... {0.0} <music21.clef.BassClef> {0.0} <music21.key.Key of B- major> {0.0} <music21.meter.TimeSignature 4/4> {0.0} <music21.note.Note B-> {0.5} <music21.note.Note C> >>> fbLine = realizer.figuredBassFromStream(sBach['bass']) >>> fbLine.generateBassLine().measure(1).show('text') {0.0} <music21.clef.BassClef> {0.0} <music21.key.KeySignature of 2 flats> {0.0} <music21.meter.TimeSignature 4/4> {3.0} <music21.note.Note B-> {3.5} <music21.note.Note C> ''' bassLine = stream.Part() bassLine.append(clef.BassClef()) bassLine.append(key.KeySignature(self.inKey.sharps)) bassLine.append(copy.deepcopy(self.inTime)) r = None if self._paddingLeft != 0.0: r = note.Rest(quarterLength=self._paddingLeft) bassLine.append(r) for (bassNote, unused_notationString) in self._fbList: bassLine.append(bassNote) bl2 = bassLine.makeNotation(inPlace=False, cautionaryNotImmediateRepeat=False) if r is not None: m0 = bl2.getElementsByClass('Measure')[0] m0.remove(m0.getElementsByClass('Rest')[0]) m0.padAsAnacrusis() return bl2
def ch1_basic_II_C_1(show=True, *arguments, **keywords): ''' p. 4 Practice writing whole and half steps. Watch for changes in clef. Write whole steps ''' data = [[clef.TrebleClef(), 'g#4', 'b-4', 'd-4'], [clef.BassClef(), 'e3', 'a-2'], [clef.TenorClef(), 'c#']] ex = ch1_basic_II_C(data, 'w') if show: ex.show()
def generateSmoothBassLine(harmonyObjects): ''' accepts a list of harmony.chordSymbol objects and returns that same list with a computer generated octave assigned to each bass note. The algorithm is under development, but currently works like this: 1. assigns octave of 2 to the first bass note 2. iterates through each of the following bass notes corresponding to the chordSymbol i. creates three generic intervals between the previous bass note and the current bass note, all using the previous bass note's newly defined octave and one of three current bass note octaves: 1. the last bass note's octave 2. the last bass note's octave + 1 3. the last bass note's octave - 1 ii. evaluates the size of each of the three intervals above (using interval.generic.undirected) and finds the smallest size iii. assigns the bass note octave that yields this smallest interval to the current bass note - if the newly found octave is determined to be greater than 3 or less than 1, the bass note octave is assigned to the last bass note's octave iv. updates the previous bass note, and the iteration continues 3. returns list of chordSymbols, with computer generated octaves assigned ''' s = stream.Score() s.append(clef.BassClef()) harmonyObjects[0].bass().octave = 2 lastBass = harmonyObjects[0].bass() s.append(note.Note(lastBass)) for cs in harmonyObjects[1:]: cs.bass().octave = lastBass.octave sameOctave = interval.Interval(lastBass, copy.deepcopy(cs.bass())) cs.bass().octave += 1 octavePlus = interval.Interval(lastBass, copy.deepcopy(cs.bass())) cs.bass().octave = cs.bass().octave - 2 octaveMinus = interval.Interval(lastBass, copy.deepcopy(cs.bass())) l = [sameOctave, octavePlus, octaveMinus] minimum = sameOctave.generic.undirected ret = sameOctave for i in l: if i.generic.undirected < minimum: minimum = i.generic.undirected ret = i if ret.noteEnd.octave > 3 or ret.noteEnd.octave < 1: ret.noteEnd.octave = lastBass.octave cs.bass().octave = ret.noteEnd.octave lastBass = cs.bass() s.append(note.Note(cs.bass())) return harmonyObjects
def getQJ(): ''' loads Quod Jactatur from the corpus, transposes it to an easy to view range and stores it in the cache. >>> qj = getQJ() >>> qj.flat.notesAndRests[0] <music21.note.Note C> ''' qj = corpus.parse("ciconia/quod_jactatur") qjPart = qj.getElementsByClass(stream.Part)[0] qjPart.transpose("P-8", inPlace=True) qjPart.replace(qjPart.flat.getElementsByClass(clef.Clef)[0], clef.BassClef()) cachedParts['1-0-False-False'] = copy.deepcopy(qjPart) return qjPart
def test_note_beat_strength_indexer_2(self): # When the part has no Note or Rest objects in it expected = pandas.DataFrame({'0': pandas.Series()}) test_part = stream.Part() # add stuff to the test_part for i in range(1000): add_me = clef.BassClef() add_me.offset = i test_part.append(add_me) add_me = bar.Barline() add_me.offset = i test_part.append(add_me) # finished adding stuff to the test_part ip = IndexedPiece() ip.metadata('parts', expected.columns) ip._analyses['part_streams'] = [test_part] # supply part_streams. actual = ip._get_beat_strength()['meter.NoteBeatStrengthIndexer'] self.assertTrue(actual.equals(expected))
def test_note_rest_indexer_2(self): # When the part has no Note or Rest objects in it. Really this is a test for the methods between # _get_part_streams() and _get_noterest(). expected = pandas.DataFrame({'Part 1': pandas.Series()}) test_part = stream.Part() # add stuff to the test_part for i in range(1000): add_me = clef.BassClef() add_me.offset = i test_part.append(add_me) add_me = bar.Barline() add_me.offset = i test_part.append(add_me) ip = IndexedPiece() ip._analyses['part_streams'] = [test_part] ip.metadata('parts', _find_part_names(ip._analyses['part_streams'])) actual = ip.get('noterest')['noterest.NoteRestIndexer'] self.assertTrue(actual.equals(expected))
def testScoreLily(self): from copy import deepcopy from music21 import clef, meter, note, stream ts = meter.TimeSignature("2/4") p1 = stream.Part() p1.id = "P1" p1.append(clef.TrebleClef()) p1.append(ts) p1.append(note.Note("C4")) p1.append(note.Note("D4")) p2 = stream.Part() p2.id = "P2" p2.append(clef.BassClef()) p2.append(deepcopy(ts)) p2.append(note.Note("E2")) p2.append(note.Note("F2")) score1 = stream.Score() score1.insert(0, p1) score1.insert(0, p2) # score1.show('text') # score2 = score1.makeNotation() # score2.show('text') conv = LilypondConverter() outStr = conv.fromObject(score1) # print outStr # conv2 = LilypondConverter(score1) # conv2.showSVG() self.assertEqual( outStr, r''' \score { { << \new Staff { { \clef "treble" \time 2/4 c'4 d'4 } } \new Staff { { \clef "bass" \time 2/4 e,4 f,4 } } >> } }''')
def test_duration_indexer_2(self): # When the part has no Note or Rest objects in it expected = pandas.DataFrame({'0': pandas.Series()}) expected.columns = pandas.MultiIndex.from_product([ ('meter.DurationIndexer', ), ('0', ) ]) test_part = stream.Part() # add stuff to the test_part for i in range(10): add_me = clef.BassClef() add_me.offset = i test_part.append(add_me) add_me = bar.Barline() add_me.offset = i test_part.append(add_me) test_part = [test_part] # finished adding stuff to the test_part dur_indexer = meter.DurationIndexer(expected, test_part) actual = dur_indexer.run() self.assertTrue(actual.equals(expected))
def testSortorder(self): from music21 import stream, bar, clef, note, metadata m = stream.Measure() b = bar.Repeat() m.leftBarline = b c = clef.BassClef() m.append(c) n = note.Note() m.append(n) # check sort order self.assertEqual(m[0], b) self.assertEqual(m[1], c) self.assertEqual(m[2], n) # if we add metadata, it sorts ahead of bar md = metadata.Metadata() m.insert(0, md) self.assertEqual(m[0], md) self.assertEqual(m[1], b)
def testSubclassMatchingA(self): from music21 import stream, note, clef, meter, classCache, common, chord s2 = stream.Stream() s2.repeatAppend(note.Note(), 300) s2.repeatAppend(note.Rest(), 300) s2.repeatAppend(chord.Chord(), 300) s2.repeatInsert(meter.TimeSignature(), [0, 50, 100, 150]) s2.repeatInsert(clef.BassClef(), [0, 50, 100, 150]) t1 = common.Timer() t1.start() cc = classCache.ClassCache() # simulate what would happen in getElementsByClass cc.load(s2) s = stream.Stream() cc.getElementsByClass(s, ['Rest']) self.assertEqual(len(s), 300) s = stream.Stream() cc.getElementsByClass(s, ['Note']) self.assertEqual(len(s), 300) s = stream.Stream() cc.getElementsByClass(s, ['GeneralNote']) self.assertEqual(len(s), 900) s = stream.Stream() cc.getElementsByClass(s, ['NotRest']) self.assertEqual(len(s), 600) s = stream.Stream() cc.getElementsByClass(s, ['BassClef']) self.assertEqual(len(s), 4) s = stream.Stream() cc.getElementsByClass(s, ['Clef']) self.assertEqual(len(s), 4) s = stream.Stream() cc.getElementsByClass(s, ['TimeSignature']) self.assertEqual(len(s), 4)
def play_melody(gen_melody): v = stream.Voice() last_note_duration = 0 for n in gen_melody: if n[0] == 0: new_note = note.Rest() else: new_pitch = pitch.Pitch() # new_pitch.midi = 59.0 + n[0] - 24 new_pitch.midi = n[0] new_note = note.Note(new_pitch) new_note.offset = v.highestOffset + last_note_duration new_note.duration.quarterLength = n[2] last_note_duration = new_note.duration.quarterLength v.insert(new_note) s = stream.Stream() part = stream.Part() part.clef = clef.BassClef() part.append(instrument.Harpsichord()) part.insert(v) s.insert(part) return s
def test_Ch6_basic_II_A(self, *arguments, **keywords): '''p. 55 Write the specified melodic interval above the given note. ''' # combines 1 and 2 pitches1 = ['e-4', 'f#4', 'a-4', 'd4', 'f4'] intervals1 = ['M6', 'p5', 'M3', 'M7', 'P4'] pitches2 = ['c#4', 'f3', 'a3', 'b-3', 'e-3'] intervals2 = ['-M6', '-p5', '-M7', '-M2', '-P4'] pitches = pitches1 + pitches2 intervals = intervals1 + intervals2 s = stream.Stream() for i, p in enumerate(pitches): if i == 0: s.append(clef.TrebleClef()) if i == len(pitches1): s.append(clef.BassClef()) p = pitch.Pitch(p) # convert string to obj iObj = interval.Interval(intervals[i]) c = chord.Chord([p, p.transpose(iObj)], type='whole') s.append(c) if 'show' in keywords.keys() and keywords['show']: s.show() match = [] for c in s.getElementsByClass('Chord'): # append second pitch as a string match.append(str(c.pitches[1])) self.assertEqual(match, [ 'C5', 'C#5', 'C5', 'C#5', 'B-4', 'E3', 'B-2', 'B-2', 'A-3', 'B-2' ])
def matrix_to_score(self, matrix, verbose=False): ''' Takes a matrix of (P, T, 2) and turn it into a music21.stream.Score object, where P is the number of parts, T is the number of time slices, and dim is the note vector. ''' # (4 parts, # ticks, 2) assert len(matrix.shape) == 3, \ "Input matrix needs to have 3-dimensions." num_parts, num_ticks, num_dim = matrix.shape assert num_parts == 4, "Input matrix needs to have 4 parts." assert num_ticks > 0, "No time slices in this matrix." assert num_dim == 2, "Note vector size mismatch." # need to make sure all pieces start with an articulated note, even if # it's a rest. matrix[:, 0, 1] = [1, 1, 1, 1] score = Score() parts = list(map(self._matrix_to_part, matrix)) parts[0].insert(0, instrument.Violin()) parts[0].partName = "Violin I" parts[0].clef = clef.TrebleClef() parts[1].insert(0, instrument.Violin()) parts[1].partName = "Violin II" parts[1].clef = clef.TrebleClef() parts[2].insert(0, instrument.Viola()) parts[2].clef = clef.AltoClef() parts[3].insert(0, instrument.Violoncello()) parts[3].clef = clef.BassClef() _ = list(map(lambda part: score.append(part), parts)) return score
def ch1_writing_I_A_1(show=True, *arguments, **keywords): ''' p. 5 Rewrite these melodies from music literature, placing the pitches one octave higher or lower as specified, by using ledger lines. Do not change to a new clef. Rewrite one active higher ''' # Purcell, "Music for a While" humdata = ''' **kern 8C 8D 8E 8EE 8AA 8E 8F 8AA 8BB 8F# 8G 8BB 8C 8G# 8A 8C# *- ''' ex = converter.parseData(humdata) ex = ex.transpose('p8') ex.insert(0, clef.BassClef()) # maintain clef if show: ex.show()
def generateRealizationFromPossibilityProgression(self, possibilityProgression): ''' Generates a realization as a :class:`~music21.stream.Score` given a possibility progression. ''' sol = stream.Score() bassLine = stream.Part() bassLine.append( [copy.deepcopy(self._keySig), copy.deepcopy(self._inTime)]) r = None if self._paddingLeft != 0.0: r = note.Rest(quarterLength=self._paddingLeft) bassLine.append(copy.deepcopy(r)) if self.keyboardStyleOutput: rightHand = stream.Part() sol.insert(0.0, rightHand) rightHand.append( [copy.deepcopy(self._keySig), copy.deepcopy(self._inTime)]) if r is not None: rightHand.append(copy.deepcopy(r)) for segmentIndex in range(len(self._segmentList)): possibA = possibilityProgression[segmentIndex] bassNote = self._segmentList[segmentIndex].bassNote bassLine.append(copy.deepcopy(bassNote)) rhPitches = possibA[0:-1] rhChord = chord.Chord(rhPitches) rhChord.quarterLength = self._segmentList[ segmentIndex].quarterLength rightHand.append(rhChord) rightHand.insert(0.0, clef.TrebleClef()) rightHand.makeNotation(inPlace=True, cautionaryNotImmediateRepeat=False) if r is not None: rightHand[0].pop(3) rightHand[0].padAsAnacrusis() else: # Chorale-style output upperParts = [] for partNumber in range(len(possibilityProgression[0]) - 1): fbPart = stream.Part() sol.insert(0.0, fbPart) fbPart.append( [copy.deepcopy(self._keySig), copy.deepcopy(self._inTime)]) if r is not None: fbPart.append(copy.deepcopy(r)) upperParts.append(fbPart) for segmentIndex in range(len(self._segmentList)): possibA = possibilityProgression[segmentIndex] bassNote = self._segmentList[segmentIndex].bassNote bassLine.append(copy.deepcopy(bassNote)) for partNumber in range(len(possibA) - 1): n1 = note.Note(possibA[partNumber]) n1.quarterLength = self._segmentList[ segmentIndex].quarterLength upperParts[partNumber].append(n1) for upperPart in upperParts: upperPart.insert(0.0, upperPart.bestClef(True)) upperPart.makeNotation(inPlace=True, cautionaryNotImmediateRepeat=False) if r is not None: upperPart[0].pop(3) upperPart[0].padAsAnacrusis() bassLine.insert(0.0, clef.BassClef()) bassLine.makeNotation(inPlace=True, cautionaryNotImmediateRepeat=False) if r is not None: bassLine[0].pop(3) bassLine[0].padAsAnacrusis() sol.insert(0.0, bassLine) return sol
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 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 pendulumMusic(show = True, loopLength = 160.0, totalLoops = 1, maxNotesPerLoop = 40, totalParts = 16, scaleStepSize = 3, scaleType = scale.OctatonicScale, startingPitch = 'C1' ): totalLoops = totalLoops * 1.01 jMax = loopLength * totalLoops p = pitch.Pitch(startingPitch) if isinstance(scaleType, scale.Scale): octo = scaleType else: octo = scaleType(p) s = stream.Score() s.metadata = metadata.Metadata() s.metadata.title = 'Pendulum Waves' s.metadata.composer = 'inspired by http://www.youtube.com/watch?v=yVkdfJ9PkRQ' parts = [stream.Part(), stream.Part(), stream.Part(), stream.Part()] parts[0].insert(0, clef.Treble8vaClef()) parts[1].insert(0, clef.TrebleClef()) parts[2].insert(0, clef.BassClef()) parts[3].insert(0, clef.Bass8vbClef()) for i in range(totalParts): j = 1.0 while j < (jMax+1.0): ps = p.ps if ps > 84: active = 0 elif ps >= 60: active = 1 elif ps >= 36: active = 2 elif ps < 36: active = 3 jQuant = round(j*8)/8.0 establishedChords = parts[active].getElementsByOffset(jQuant) if len(establishedChords) == 0: c = chord.Chord([p]) c.duration.type = '32nd' parts[active].insert(jQuant, c) else: c = establishedChords[0] pitches = c.pitches pitches.append(p) c.pitches = pitches j += loopLength/(maxNotesPerLoop - totalParts + i) #j += (8+(8-i))/8.0 p = octo.next(p, stepSize = scaleStepSize) parts[0].insert(0, tempo.MetronomeMark(number = 120, referent = duration.Duration(2.0))) for i in range(4): parts[i].insert(int((jMax + 4.0)/4)*4, note.Rest(quarterLength=4.0)) parts[i].makeRests(fillGaps=True, inPlace=True) parts[i] = parts[i].makeNotation() s.insert(0, parts[i]) if show == True: #s.show('text') s.show('midi') s.show()
def test_clef_to_lily_6(self): bee_ell = clef.BassClef() expected = u"\\clef bass\n" self.assertEqual(functions.clef_to_lily(bee_ell), expected)
# Add time signatures, rests, clefs... # -------------------------------------------------------------------------------------------------- piano_right_hand.insertAndShift(0, note.Rest(duration=duration.Duration(2))) piano_right_hand.insert(0, meter.TimeSignature("3/4")) piano_right_hand.insert(key.KeySignature(-2)) piano_right_hand.notes[len(piano_right_hand.notes) - 1].duration = duration.Duration( 1.25 ) piano_right_hand.makeMeasures(inPlace=True) piano_left_hand.insertAndShift(0, note.Rest(duration=duration.Duration(2))) piano_left_hand.insert(key.KeySignature(-2)) piano_left_hand.insert(0, meter.TimeSignature("3/4")) piano_left_hand.notes[len(piano_left_hand.notes) - 1].duration = duration.Duration(1.25) piano_left_hand.insert(0, clef.BassClef()) for n in piano_left_hand.notes: if n.pitches == chord.Chord(["F4", "G#4", "Bb4"]).pitches: piano_left_hand.insert(n.offset, clef.TrebleClef()) if n.pitches == chord.Chord(["Ab3", "C#4"]).pitches: piano_left_hand.insert(n.offset, clef.BassClef()) piano_left_hand.makeMeasures(inPlace=True) cello.insertAndShift(0, note.Rest(duration=duration.Duration(5.5))) cello.insert(0, meter.TimeSignature("3/4")) cello.insert(key.KeySignature(-2)) cello.insert(0, clef.TenorClef()) cello.notes[len(cello.notes) - 1].duration = duration.Duration(2.5) # Extend final note for n in cello.notes: harmonicNote = note.Note() harmonicNote.pitch.ps = n.pitch.ps + 5
def toPart(volpianoText, *, breaksToLayout=False): # noinspection PyShadowingNames ''' Returns a music21 Part from volpiano text. >>> veniSancti = volpiano.toPart('1---c--d---f--d---ed--c--d---f' ... + '---g--h--j---hgf--g--h---') >>> veniSancti.show('text') {0.0} <music21.stream.Measure 0 offset=0.0> {0.0} <music21.clef.TrebleClef> {0.0} <music21.note.Note C> {1.0} <music21.note.Note D> {2.0} <music21.note.Note F> {3.0} <music21.note.Note D> {4.0} <music21.note.Note E> {5.0} <music21.note.Note D> {6.0} <music21.volpiano.Neume <music21.note.Note E><music21.note.Note D>> {6.0} <music21.note.Note C> {7.0} <music21.note.Note D> {8.0} <music21.note.Note F> {9.0} <music21.note.Note G> {10.0} <music21.note.Note A> {11.0} <music21.note.Note B> {12.0} <music21.note.Note A> {13.0} <music21.note.Note G> {14.0} <music21.note.Note F> {15.0} <music21.volpiano.Neume <music21.note.Note A><music21.note.Note G>> {15.0} <music21.note.Note G> {16.0} <music21.note.Note A> Clefs! >>> clefTest = volpiano.toPart('1---c--2---c') >>> clefTest.show('text') {0.0} <music21.stream.Measure 0 offset=0.0> {0.0} <music21.clef.TrebleClef> {0.0} <music21.note.Note C> {1.0} <music21.clef.BassClef> {1.0} <music21.note.Note E> >>> for n in clefTest.recurse().notes: ... n.nameWithOctave 'C4' 'E2' Flats and Naturals: >>> accTest = volpiano.toPart('1---e--we--e--We--e') >>> [n.name for n in accTest.recurse().notes] ['E', 'E-', 'E-', 'E', 'E'] Breaks and barlines >>> breakTest = volpiano.toPart('1---e-7-e-77-e-777-e-3-e-4') >>> breakTest.show('text') {0.0} <music21.stream.Measure 0 offset=0.0> {0.0} <music21.clef.TrebleClef> {0.0} <music21.note.Note E> {1.0} <music21.volpiano.LineBreak object at 0x105250fd0> {1.0} <music21.note.Note E> {2.0} <music21.volpiano.PageBreak object at 0x105262128> {2.0} <music21.note.Note E> {3.0} <music21.volpiano.ColumnBreak object at 0x105262240> {3.0} <music21.note.Note E> {4.0} <music21.bar.Barline type=regular> {4.0} <music21.stream.Measure 0 offset=4.0> {0.0} <music21.note.Note E> {1.0} <music21.bar.Barline type=double> As layout objects using breaksToLayout=True >>> breakTest = volpiano.toPart('1---e-7-e-77-e-777-e-3-e-4', breaksToLayout=True) >>> breakTest.show('text') {0.0} <music21.stream.Measure 0 offset=0.0> {0.0} <music21.clef.TrebleClef> {0.0} <music21.note.Note E> {1.0} <music21.layout.SystemLayout> {1.0} <music21.note.Note E> {2.0} <music21.layout.PageLayout> {2.0} <music21.note.Note E> {3.0} <music21.volpiano.ColumnBreak object at 0x105262240> {3.0} <music21.note.Note E> {4.0} <music21.bar.Barline type=regular> {4.0} <music21.stream.Measure 0 offset=4.0> {0.0} <music21.note.Note E> {1.0} <music21.bar.Barline type=double> Liquescence test: >>> breakTest = volpiano.toPart('1---e-E-') >>> breakTest.recurse().notes[0].editorial.liquescence False >>> breakTest.recurse().notes[0].notehead 'normal' >>> breakTest.recurse().notes[1].editorial.liquescence True >>> breakTest.recurse().notes[1].notehead 'x' Changed in v5.7 -- corrected spelling of liquescence. ''' p = stream.Part() m = stream.Measure() currentMeasure = m currentNeumeSpanner = None noteThatWouldGoInSpanner = None lastClef = clef.TrebleClef() continuousNumberOfBreakTokens = 0 bIsFlat = False eIsFlat = False for token in volpianoText: if token == '7': continuousNumberOfBreakTokens += 1 continue elif continuousNumberOfBreakTokens > 0: if not breaksToLayout: # default breakClass = classByNumBreakTokens[ continuousNumberOfBreakTokens] breakToken = breakClass() # pylint: disable=not-callable else: breakClass = classByNumBreakTokensLayout[ continuousNumberOfBreakTokens] if continuousNumberOfBreakTokens < 3: breakToken = breakClass(isNew=True) # pylint: disable=not-callable else: breakToken = breakClass() # pylint: disable=not-callable currentMeasure.append(breakToken) continuousNumberOfBreakTokens = 0 if token == '-': noteThatWouldGoInSpanner = None if currentNeumeSpanner: currentMeasure.append(currentNeumeSpanner) currentNeumeSpanner = None continue if token in '1234': noteThatWouldGoInSpanner = None currentNeumeSpanner = None if token in '12': if token == '1': c = clef.TrebleClef() else: c = clef.BassClef() lastClef = c m.append(c) elif token in '34': bl = bar.Barline() if token == '4': bl.type = 'double' m.rightBarline = bl p.append(m) m = stream.Measure() elif token in normalPitches or token in liquescentPitches: n = note.Note() n.stemDirection = 'noStem' if token in normalPitches: distanceFromLowestLine = normalPitches.index(token) - 5 n.editorial.liquescence = False else: distanceFromLowestLine = liquescentPitches.index(token) - 5 n.notehead = 'x' n.editorial.liquescence = True clefLowestLine = lastClef.lowestLine diatonicNoteNum = clefLowestLine + distanceFromLowestLine n.pitch.diatonicNoteNum = diatonicNoteNum if n.pitch.step == 'B' and bIsFlat: n.pitch.accidental = pitch.Accidental('flat') elif n.pitch.step == 'E' and eIsFlat: n.pitch.accidental = pitch.Accidental('flat') m.append(n) if noteThatWouldGoInSpanner is not None: currentNeumeSpanner = Neume([noteThatWouldGoInSpanner, n]) noteThatWouldGoInSpanner = None else: noteThatWouldGoInSpanner = n elif token in accidentalTokens: if token.lower() in eflatTokens and token in naturalTokens: eIsFlat = False elif token.lower() in bflatTokens and token in naturalTokens: bIsFlat = False elif token.lower() in eflatTokens and token in flatTokens: eIsFlat = True elif token.lower() in bflatTokens and token in flatTokens: bIsFlat = True else: # pragma: no cover raise VolpianoException('Unknown accidental: ' + token + ': Should not happen') if continuousNumberOfBreakTokens > 0: breakClass = classByNumBreakTokens[continuousNumberOfBreakTokens] breakToken = breakClass() # pylint: disable=not-callable currentMeasure.append(breakToken) if m: p.append(m) return p