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 testExpandTurns(self): from music21 import note, stream, clef, key, meter p1 = stream.Part() m1 = stream.Measure() m2 = stream.Measure() p1.append(clef.TrebleClef()) p1.append(key.Key('F', 'major')) p1.append(meter.TimeSignature('2/4')) n1 = note.Note('C5', type='half') turn0 = Turn() n1.expressions.append(turn0) n2 = note.Note('B4', type='quarter') n2.duration.dots = 1 n2.expressions.append(InvertedTurn()) m1.append(n1) m2.append(key.KeySignature(5)) m2.append(n2) m2.append(note.Rest('eighth')) p1.append(m1) p1.append(m2) realized1 = realizeOrnaments(n1) realized2 = realizeOrnaments(n2) self.assertEqual('C5 D5 C5 B-4 C5', ' '.join(n.pitch.nameWithOctave for n in realized1)) self.assertEqual('B4 A#4 B4 C#5 B4', ' '.join(n.pitch.nameWithOctave for n in realized2)) self.assertEqual(realized1[0].quarterLength, 1.0) self.assertEqual(realized1[1].quarterLength, 0.25) self.assertEqual(realized2[0].quarterLength, 0.5) self.assertEqual(realized2[1].quarterLength, 0.25) turn0.quarterLength = 0.125 realized1b = realizeOrnaments(n1) self.assertEqual(realized1b[0].quarterLength, 1.5) self.assertEqual(realized1b[1].quarterLength, 0.125)
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 test_clef_to_lily_11(self): # transparent and different thing to append bee_ell = clef.TrebleClef() expected = u"\\once \\override Staff.Clef #'transparent = ##t hello \\clef treble hello " self.assertEqual( functions.clef_to_lily(bee_ell, invisible=True, append=u' hello '), expected)
def open_score(self, midi_file_to_open): # open midifile after manipulating duration data self.delta_change(midi_file_to_open) print("\n\n\nNow I'm going to print you the score\n\n\n") # convert to lily.png note_list = [] parts_stream = stream.Stream() parts_stream.insert(0, clef.TrebleClef()) # parts_stream.insert(0, meter.TimeSignature('8/4')) score_in = converter.parseFile( midi_file_to_open) # converts to a music21.stream.score # seperates out notes from rest of stream and makes notes_list for shuffle for n in score_in.recurse().notes: # print (f'Note: {n.pitch.name}, {n.pitch.octave}. {n.duration.quarterLength}') if n.duration.quarterLength != 0: # if note length is not 0 then add to list of notes note_list.append(n) for i, nt in enumerate(note_list): note_pop = note_list[i] parts_stream.append(note_pop) png_fp = 'data/output/png-' + self.current_time parts_stream.write('lily.png', fp=png_fp) return str(png_fp + '.png')
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_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 xtestExpandTrills(self): from music21 import note, stream, clef, key, meter p1 = stream.Part() m1 = stream.Measure() p1.append(clef.TrebleClef()) p1.append(key.Key('D', 'major')) p1.append(meter.TimeSignature('2/4')) n1 = note.Note('E4', type='eighth') n1.expressions.append(Trill()) m1.append(n1) p1.append(m1)
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 spliceAnalysis(book=3, madrigal=1): ''' splice an analysis of the madrigal under the analysis itself ''' #mad = corpus.parse('monteverdi/madrigal.%s.%s.xml' % (book, madrigal)) analysis = corpus.parse('monteverdi/madrigal.%s.%s.rntxt' % (book, madrigal)) # these are multiple parts in a score stream #excerpt = mad.measures(1,20) # get from first part aMeasures = analysis.parts[0].measures(1,20) aMeasures.getElementsByClass('Measure')[0].clef = clef.TrebleClef() for myN in aMeasures.flat.notesAndRests: myN.hideObjectOnPrint = True x = aMeasures.write() print (x)
def xtestExpandTurns(self): from music21 import note, stream, clef, key, meter p1 = stream.Part() m1 = stream.Measure() m2 = stream.Measure() p1.append(clef.TrebleClef()) p1.append(key.Key('F', 'major')) p1.append(meter.TimeSignature('2/4')) n1 = note.Note('C5', type='half') n1.expressions.append(Turn()) n2 = note.Note('B4', type='half') n2.expressions.append(InvertedTurn()) m1.append(n1) m2.append(key.KeySignature(5)) m2.append(n2) p1.append(m1) p1.append(m2)
def testExpandTrills(self): from music21 import note, stream, clef, key, meter p1 = stream.Part() m1 = stream.Measure() p1.append(clef.TrebleClef()) p1.append(key.Key('D', 'major')) p1.append(meter.TimeSignature('1/4')) n1 = note.Note('E4', type='eighth') n1.expressions.append(Trill()) m1.append(n1) p1.append(m1) realized = realizeOrnaments(n1) self.assertIsInstance(realized, list) self.assertEqual(len(realized), 4) self.assertIsInstance(realized[0], note.Note) self.assertEqual(realized[0].quarterLength, 0.125) self.assertEqual('E4 F#4 E4 F#4', ' '.join(n.pitch.nameWithOctave for n in realized))
def song(): """ Simple helper function that returns "Wlazł kotek na płotek" music stream """ s = stream.Stream() ts1 = meter.TimeSignature("3/4") p1 = stream.Part(number=1) p1.insert(0, ts1) p1.insert(0, key.KeySignature(0)) p1.insert(0, clef.TrebleClef()) m1 = stream.Measure(number=1) m1.append(note.Note("G")) m1.append(note.Note("E")) m1.append(note.Note("E", type="quarter")) m2 = stream.Measure(number=2) m2.append(note.Note("F")) m2.append(note.Note("D")) m2.append(note.Note("D")) m3 = stream.Measure(number=3) m3.append(note.Note("C", type="eighth")) m3.append(note.Note("E", type="eighth")) m3.append(note.Note("G", type="half")) p1.append(m1) p1.append(m2) p1.append(m3) m4 = stream.Measure(number=4) m4.append(note.Note("G")) m4.append(note.Note("E")) m4.append(note.Note("E", type="quarter")) m5 = stream.Measure(number=5) m5.append(note.Note("F")) m5.append(note.Note("D")) m5.append(note.Note("D")) m6 = stream.Measure(number=6) m6.append(note.Note("C4", type="eighth")) m6.append(note.Note("E4", type="eighth")) m6.append(note.Note("C4", type="half")) p1.append(m4) p1.append(m5) p1.append(m6) s.insert(0, p1) return s
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 ch1_writing_I_B_2(show=True, *arguments, **keywords): ''' Transcribe the melody into treble clef ''' # Mozart no. 41, 4th movement humdata = ''' **kern *clefC3 4g 4g 4G 4G *- ''' # this notation excerpt is incomplete ex = converter.parseData(humdata) clefOld = ex.flat.getElementsByClass(clef.Clef)[0] ex.flat.replace(clefOld, clef.TrebleClef()) if show: ex.show()
def ch1_writing_I_A_2(show=True, *arguments, **keywords): ''' p. 5 Rewrite one octave higher ''' humdata = ''' **kern 6e 6e 6e 6e 6f 6g *- ''' # this notation excerpt is incomplete ex = converter.parseData(humdata) ex = ex.transpose('p8') ex.insert(0, clef.TrebleClef()) # maintain clef if show: ex.show()
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 parse_data(note_stream, value_id): composition_file = open('../user_data/composition' + value_id + '.csv', mode='r') composition_reader = csv.DictReader(composition_file) for row in composition_reader: composition_meter = row['beats_per_bar'] + '/' + row['base_beat'] switch_enharmonic = row['enharmonic'] tempo_value = row['tempo'] note_stream.timeSignature = meter.TimeSignature(composition_meter) metronome_mark = tempo.MetronomeMark(number=int(tempo_value)) use_clef = clef.TrebleClef() note_stream.append([metronome_mark, use_clef]) composition_file.close() note_file = open('../user_data/notes' + value_id + '.csv', mode='r') note_reader = csv.DictReader(note_file) for row in note_reader: note_pitch_octave = row['pitch'] note_duration = row['duration'] if note_pitch_octave == 'rest': note_entry = note.Rest(quarterLength=float(note_duration)) else: pitch_value = pitch.Pitch(note_pitch_octave) if switch_enharmonic == 'flat': if "#" in pitch_value.name: pitch_value = pitch_value.getHigherEnharmonic() note_entry = note.Note(pitch_value, quarterLength=float(note_duration)) note_stream.append(note_entry) note_file.close() return note_stream
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 test_clef_to_lily_10(self): # different thing to append bee_ell = clef.TrebleClef() expected = u"\\clef treble hello" self.assertEqual(functions.clef_to_lily(bee_ell, append=u' hello'), expected)
ottava.addSpannedElements([note_1, note_2]) lh_interlude.append(ottava) lh_interlude.append(note_1) lh_interlude.append(note_2) lh_interlude.makeMeasures(inPlace=True, finalBarline=None) return lh_interlude # -------------------------------------------------------------------------------------------------- # Build the piece # -------------------------------------------------------------------------------------------------- # Create streams right_hand = stream.Part() left_hand = stream.Part() left_hand.clef = clef.TrebleClef() # Main Loop to build the nine sections for section_index in range(8): # Right hand # ----------------------------------------------------------------------------------------- # Create the m-voice m_voice = transformations.scalar_transposition(core_melody, section_index * -2, reference_scale) # Create the t-voice t_voice = tintinnabuli.create_t_voice( m_voice, t_chord, position=2, direction=tintinnabuli.Direction.DOWN) # Merge and append right hand streams
def test_clef_to_lily_5(self): bee_ell = clef.TrebleClef() expected = u"\\clef treble\n" self.assertEqual(functions.clef_to_lily(bee_ell), expected)
def test_clef_to_lily_9(self): # transparent bee_ell = clef.TrebleClef() expected = u"\\once \\override Staff.Clef #'transparent = ##t\n\\clef treble\n" self.assertEqual(functions.clef_to_lily(bee_ell, invisible=True), expected)
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 harmonicNote.notehead = "diamond" harmonicNote.noteheadFill = "no" c = chord.Chord(notes=[n, harmonicNote], duration=n.duration)
#s = corpus.parse('beethoven/opus18no1', 2).parts[0].measures(4,10) vfp = VexflowPickler() vfp.defaults[ 'm21URI'] = 'file:///Users/Cuthbert/git/music21j/src/music21' vfp.defaults[ 'requireURI'] = 'file:///Users/Cuthbert/git/music21j/ext/require/require.js' data = vfp.fromObject(s) fp = environLocal.getTempFile('.html') with open(fp, 'w') as f: f.write(data) environLocal.launch('vexflow', fp) if __name__ == "__main__": import music21 music21.mainTest(Test) from music21 import note, clef, meter s = stream.Measure() s.insert(0, clef.TrebleClef()) s.insert(0, meter.TimeSignature('1/4')) n = note.Note() n.duration.quarterLength = 1 / 3. s.repeatAppend(n, 3) p = stream.Part() p.repeatAppend(s, 2) p.show('vexflow', local=True) #s.show('vexflow')
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
def fromStream(s, *, layoutToBreaks=False): ''' Convert a Stream to Volpiano. These tests show how the same input converts back out: >>> volpianoInput = '1--c--d---f--d---ed--c--d---f---g--h--j---hgf--g--h---' >>> veniSancti = volpiano.toPart(volpianoInput) >>> volpiano.fromStream(veniSancti) '1---c-d-f-d-ed-c-d-f-g-h-j-hg-f-g-h-' >>> breakTest = volpiano.toPart('1---e-E--') >>> volpiano.fromStream(breakTest) '1---e-E-' >>> accTest = volpiano.toPart('1---e--we--e--We--e') >>> volpiano.fromStream(accTest) '1---e-we-e-We-e-' ''' volpianoTokens = [] def error(innerEl, errorLevel=ErrorLevel.LOG): msg = f'Could not convert token {innerEl!r} to Volpiano.' if errorLevel == ErrorLevel.WARN: environLocal.warn(msg + ' this can lead to incorrect data.') else: environLocal.printDebug(msg) def ap(tokens): for t in tokens: volpianoTokens.append(t) def popHyphens(): while volpianoTokens and volpianoTokens[-1] == '-': volpianoTokens.pop() distToAccidental = { -3: 'y', 0: 'w', 4: 'i', 7: 'x', 11: 'z', } def setAccFromPitch(dist, setNatural=False): if dist not in distToAccidental: error(f'{dist} above lowest line', ErrorLevel.WARN) return accidentalToken = distToAccidental[dist] if setNatural: accidentalToken = accidentalToken.upper() ap(accidentalToken) lastClef = clef.TrebleClef() bIsFlat = False eIsFlat = False for el in s.recurse(): elClasses = el.classes if 'Clef' in elClasses: lastClef = el if 'TrebleClef' in elClasses: ap('1---') elif 'BassClef' in elClasses: ap('2---') else: error(el, ErrorLevel.WARN) elif 'Barline' in elClasses: if el.type in ('double', 'final'): ap('---4') else: ap('---3') elif 'Note' in elClasses: n = el p = n.pitch dnn = p.diatonicNoteNum distanceFromLowestLine = dnn - lastClef.lowestLine indexInPitchString = distanceFromLowestLine + 5 if indexInPitchString < 0 or indexInPitchString >= len( normalPitches): error(n, ErrorLevel.WARN) continue if n.notehead == 'x' or (n.hasEditorialInformation and 'liquescence' in n.editorial and n.editorial.liquescence): tokenName = liquescentPitches[indexInPitchString] else: tokenName = normalPitches[indexInPitchString] if p.accidental is not None and p.accidental.alter != 0: if p.step not in ('B', 'E'): error(el, ErrorLevel.WARN) ap(tokenName) continue elif p.accidental.alter != -1: error(el, ErrorLevel.WARN) ap(tokenName) continue if p.step == 'B' and not bIsFlat: setAccFromPitch(distanceFromLowestLine) bIsFlat = True elif p.step == 'E' and not eIsFlat: setAccFromPitch(distanceFromLowestLine) eIsFlat = True elif p.name == 'B' and bIsFlat: setAccFromPitch(distanceFromLowestLine, setNatural=True) bIsFlat = False elif p.name == 'E' and eIsFlat: setAccFromPitch(distanceFromLowestLine, setNatural=True) eIsFlat = False ap(tokenName) neumeSpanner = n.getSpannerSites('Neume') if neumeSpanner and n is not neumeSpanner[0].getLast(): pass elif not n.lyric: ap('-') else: lyricObject = n.lyrics[0] syl = lyricObject.syllabic if syl in ('single', 'end'): ap('---') else: ap('--') elif 'SystemLayout' in elClasses and layoutToBreaks: popHyphens() ap('7---') elif 'PageLayout' in elClasses and layoutToBreaks: popHyphens() ap('77---') elif 'LineBreak' in elClasses: popHyphens() ap('7---') elif 'PageBreak' in elClasses: popHyphens() ap('77---') elif 'ColumnBreak' in elClasses: popHyphens() ap('777---') else: error(el, ErrorLevel.LOG) return ''.join(volpianoTokens)
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()