def lyricFromVerse(self, verse): ''' returns a :class:`~music21.note.Lyric` object from a <verse> tag >>> ci = capella.fromCapellaXML.CapellaImporter() >>> verse = ci.domElementFromText('<verse i="0" hyphen="true">di"</verse>') >>> ci.lyricFromVerse(verse) <music21.note.Lyric number=1 syllabic=begin text="di""> Does not yet support 'align' attribute if the text is empty, returns None ''' verseNumber = 1 syllabic = 'single' if 'i' in verse.attrib: verseNumber = int(verse.attrib['i']) + 1 if 'hyphen' in verse.attrib and verse.attrib['hyphen'] == 'true': syllabic = 'begin' text = verse.text if text is None or text == "": return None else: lyric = note.Lyric(text=text, number=verseNumber, syllabic=syllabic, applyRaw=True) return lyric
def lyricFromVerse(self, verse): ''' returns a :class:`~music21.note.Lyric` object from a <verse> tag >>> ci = capella.fromCapellaXML.CapellaImporter() >>> verse = ci.domElementFromText('<verse i="0" hyphen="true">di"</verse>') >>> ci.lyricFromVerse(verse) <music21.note.Lyric number=1 syllabic=begin text="di""> Does not yet support 'align' attribute if the text is empty, returns None ''' verseNumber = 1 syllabic = 'single' text = None if 'i' in verse._attrs: verseNumber = int(verse._attrs['i'].value) + 1 if 'hyphen' in verse._attrs and verse._attrs['hyphen'].value == 'true': syllabic = 'begin' for d in verse.childNodes: if d.nodeType == xml.dom.Node.TEXT_NODE: text = d.nodeValue if text is None: return None else: lyric = note.Lyric(text=text, number=verseNumber, syllabic=syllabic, applyRaw=True) return lyric
def lyric(self, value): notes = self.flat.notes if len(notes) > 0: if type(value) is str: l = note.Lyric(text=value, applyRaw=True) notes[0].lyrics = [l] elif isinstance(value, note.Lyric): notes[0].lyrics = [value] else: self.editorial.lyric = value
def addOptionalTieAndLyrics(self, rn, lastChord): ''' Adds ties to chords that are the same. Adds lyrics to chords that change. ''' same = self.isSame(rn, lastChord) if same is False and lastChord is not None and lastChord.tie is not None: lastChord.tie.type = 'stop' if same is False and (self.parent is None or self.parent.labelRomanNumerals is True): rn.lyrics.append(note.Lyric(rn.figure, number=1)) if same is True and lastChord is not None and lastChord.tie is None: lastChord.tie = tie.Tie('start') rn.tie = tie.Tie('stop') elif same is True and lastChord is not None and lastChord.tie is not None: lastChord.tie.type = 'continue' rn.tie = tie.Tie('stop')
def testBasicA(self): from music21 import note unused_t1 = note.Lyric('test') #print t1.json n1 = note.Note('G#3', quarterLength=3) n1.lyric = 'testing' self.assertEqual(n1.pitch.nameWithOctave, 'G#3') self.assertEqual(n1.quarterLength, 3.0) self.assertEqual(n1.lyric, 'testing') n2 = note.Note() raw = freezeThaw.JSONFreezer(n1).json freezeThaw.JSONThawer(n2).json = raw self.assertEqual(n2.pitch.nameWithOctave, 'G#3') self.assertEqual(n2.quarterLength, 3.0)
def testSimpleFile(self): s = GregorianStream() s.append(clef.AltoClef()) n = GregorianNote("C4") l = note.Lyric("Po") l.syllabic = "start" n.lyrics.append(l) n.oriscus = True s.append(n) n2 = GregorianNote("D4") s.append(n2) n3 = GregorianNote("C4") n3.stropha = True s.append(n3) n4 = GregorianNote("B3") n4.stropha = True s.append(n4) gabcText = s.toGABCText() bsc = BaseScoreConverter() bsc.score = gabcText bsc.incipit = "Populus" bsc.mode = 'VII' fn = bsc.writeFile("style: modern;\n\n%%\n" + gabcText) texfn = bsc.launchGregorio(fn) texfh = open(texfn) texcontents = texfh.read() texfh.close() bsc.score = texcontents dtw = DefaultTeXWrapper() newgabcText = dtw.substituteInfo(bsc) texfh2 = open(texfn, 'w') texfh2.write(newgabcText) texfh2.close() pdffn = bsc.launchLaTeX(texfn) os.system('open %s' % pdffn)
def expand(self, ts=None, ks=None): ''' The meat of it all -- expand one rule completely and return a list of Measure objects. ''' if ts is None: ts = meter.TimeSignature('4/4') if ks is None: ks = key.Key('C') measures = [] lastRegularAtom = None lastChord = None for content, sep, numReps in self._measureGroups(): lastChordIsInSameMeasure = False if sep == "$": if content not in self.parent.rules: raise CTRuleException( "Cannot expand rule {0} in {2}".format(content, self)) rule = self.parent.rules[content] for i in range(numReps): returnedMeasures = rule.expand(ts, ks) self.insertKsTs(returnedMeasures[0], ts, ks) for m in returnedMeasures: tsEs = m.iter.getElementsByClass('TimeSignature') for returnedTs in tsEs: if returnedTs is not ts: # the TS changed mid-rule; create a new one for return. ts = copy.deepcopy(ts) measures.extend(returnedMeasures) elif sep == "|": m = stream.Measure() atoms = content.split() # key/timeSig pass... regularAtoms = [] for atom in atoms: if atom.startswith('['): atomContent = atom[1:-1] if atomContent == '0': ts = meter.TimeSignature('4/4') # irregular meter. Cannot fully represent; #TODO: replace w/ senza misura when possible. elif '/' in atomContent: # only one key / ts per measure. ts = meter.TimeSignature(atomContent) else: ks = key.Key( key.convertKeyStringToMusic21KeyString( atomContent)) elif atom == '.': if lastRegularAtom is None: raise CTRuleException(" . w/o previous atom: %s" % self) regularAtoms.append(lastRegularAtom) elif atom in ("", None): pass else: regularAtoms.append(atom) lastRegularAtom = atom numAtoms = len(regularAtoms) if numAtoms == 0: continue # maybe just ts and ks setting self.insertKsTs(m, ts, ks) atomLength = common.opFrac(ts.barDuration.quarterLength / numAtoms) for atom in regularAtoms: if atom == 'R': rest = note.Rest(quarterLength=atomLength) lastChord = None lastChordIsInSameMeasure = False m.append(rest) else: atom = self.fixupChordAtom(atom) rn = roman.RomanNumeral(atom, ks) if self.isSame(rn, lastChord) and lastChordIsInSameMeasure: lastChord.duration.quarterLength += atomLength m.elementsChanged() else: rn.duration.quarterLength = atomLength self.addOptionalTieAndLyrics(rn, lastChord) lastChord = rn lastChordIsInSameMeasure = True m.append(rn) measures.append(m) for i in range(1, numReps): measures.append(copy.deepcopy(m)) else: environLocal.warn( "Rule found without | or $, ignoring: '{0}','{1}': in {2}". format(content, sep, self.text)) #pass if len(measures) > 0: for m in measures: noteIter = m.recurse().notes if (noteIter and (self.parent is None or self.parent.labelSubsectionsOnScore is True) and self.LHS != 'S'): rn = noteIter[0] lyricNum = len(rn.lyrics) + 1 rn.lyrics.append(note.Lyric(self.LHS, number=lyricNum)) break return measures
def lowerLines(): restLengths = [ 0, 16, 12, 11, 10, 7, 6, 7, 6, 5, 4, 3, 8, 10, 12, 14, 16, 17, 18, 19, 20 ] correctTranspositions = [-1, 2, -3, -3, 1, 1, 6, 3, -2] # correct the first note of rotations 13-21 fixLastNoteLengths = {11: 4.5, 12: 3, 13: 2.5, 14: 2, 15: 1.5, 20: 10.5} currentNote = 0 rotationNumber = 1 myRow = stream.Part() for phraseNumber in range(1, 21): myRow.append(note.Rest(quarterLength=restLengths[phraseNumber] / 2.0)) if phraseNumber == 8: ## inconsistency in RCS's scheme currentNote += 2 for addNote in range(21 - phraseNumber): if rotationNumber <= 10 or rotationNumber >= 20: #default appendNote = copy.deepcopy(rowNotes[currentNote % 10]) else: # second set of rotations is up a step: appendNote = rowNotes[currentNote % 10].transpose(2) # if phraseNumber == 8 and addNote == 9: # mistaken transpositions by RCS # appendNote = appendNote.transpose(-1) # appendNote.lyrics.append(note.Lyric(text="*", number=3)) # # elif phraseNumber == 9 and addNote == 6: # appendNote = appendNote.transpose(2) # appendNote.lyrics.append(note.Lyric(text="*", number=3)) if addNote == 0: if phraseNumber != 8: appendNote.lyrics.append( note.Lyric(text="p" + str(phraseNumber), number=1)) else: appendNote.lyrics.append(note.Lyric(text="p8*", number=1)) if (currentNote % 10 == (rotationNumber + 8) % 10) and (currentNote != 0): currentNote += 2 rotationNumber += 1 else: if (currentNote % 10 == (rotationNumber + 9) % 10): appendNote.lyrics.append( note.Lyric(text="r" + str(rotationNumber), number=2)) if rotationNumber in range(13, 22): appendNote.transpose( correctTranspositions[rotationNumber - 13], inPlace=True) appendNote.pitch.simplifyEnharmonic(inPlace=True) appendNote.lyrics.append(note.Lyric(text="*", number=3)) currentNote += 1 if addNote == 20 - phraseNumber: # correct Last Notes #if phraseNumber == 12: # bug in Finale for accidental display? # appendNote.pitch.accidental.displayStatus = True if phraseNumber in fixLastNoteLengths: appendNote.quarterLength = fixLastNoteLengths[phraseNumber] myRow.append(appendNote) #retrograde totalNotes = len(myRow) for i in range(2, totalNotes + 1): #skip last note el = myRow[totalNotes - i] if 'Note' in el.classes: elNote = el.transpose('A1') elNote.pitch.simplifyEnharmonic(inPlace=True) elNote.lyrics = [] myRow.append(elNote) else: elRest = copy.deepcopy(el) # rests if i == 2: elRest.quarterLength = 11.5 myRow.append(elRest) myRow.insert(0, meter.TimeSignature('2/2')) myRow.show()