MuseParse/classes/ObjectHierarchy/TreeClasses/VoiceNode.py
from MuseParse.classes.ObjectHierarchy.TreeClasses.BaseTree import Node
from MuseParse.classes.ObjectHierarchy.TreeClasses import NoteNode
from MuseParse.classes.ObjectHierarchy.ItemClasses.Note import Arpeggiate, NonArpeggiate, GraceNote, Tuplet
class VoiceNode(Node):
def __init__(self):
Node.__init__(self, rules=[NoteNode.NoteNode, NoteNode.Placeholder])
self.note_total = 0
self.note_types = []
def addNoteDuration(self, duration):
self.note_total += duration
self.note_types.append(duration)
def removeNoteDuration(self, duration):
self.note_total -= duration
self.note_types.remove(duration)
def GetAllNoteTypes(self):
""" method to collect all note values from each node
:return: list of note values
"""
return self.note_types
def RunNoteChecks(self):
children = self.GetChildrenIndexes()
previous = None
for child in range(len(children)):
note = self.GetChild(children[child])
item = note.GetItem()
if item is not None and isinstance(note, NoteNode.NoteNode):
# look for arpeggiates or non-arpeggiates, and update the note's childnodes
# used where a note is part of a chord (usually the case in
# arpeggiates)
arpeg = item.Search(Arpeggiate)
narpeg = item.Search(NonArpeggiate)
if arpeg is not None or narpeg is not None:
note.UpdateArpeggiates()
# now look for gracenotes
result = item.Search(GraceNote)
if result is not None and previous is None:
# if this is the first note in the bar, it must be the
# first gracenote
result.first = True
if len(children) == child + 1:
# if we're at the last note...
if result is not None:
# same check as arpeggiates - handles the case where
# notes are part of a chord
note.CheckForGraceNotes()
# look for timemods
if hasattr(item, "timeMod"):
result = item.Search(Tuplet)
if result is None:
item.close_timemod = True
if previous is not None:
if hasattr(previous.GetItem(), "timeMod"):
item.timeMod.first = False
else:
item.timeMod.first = True
else:
item.timeMod.first = True
else:
item.close_timemod = False
else:
# otherwise check the next item for gracenotes and time
# mods
next = self.GetChild(children[child + 1])
next_item = next.GetItem()
if next_item is not None and isinstance(
next,
NoteNode.NoteNode):
result = item.Search(GraceNote)
next_result = next_item.Search(GraceNote)
if result is not None:
if next_result is None:
note.CheckForGraceNotes()
else:
result.last = False
next_result.first = False
if hasattr(item, "timeMod"):
res = item.Search(Tuplet)
if not hasattr(
next_item,
"timeMod") and res is None:
item.close_timemod = True
else:
item.close_timemod = False
# not sure if checking next and previous is
# necessary?
if previous is not None and isinstance(
previous,
NoteNode.NoteNode):
if hasattr(previous.GetItem(), "timeMod"):
item.timeMod.first = False
else:
item.timeMod.first = True
else:
item.timeMod.first = True
previous = note
def toLily(self):
'''
Method which converts the object instance, its attributes and children to a string of lilypond code
:return: str of lilypond code
'''
lilystring = ""
children = self.GetChildrenIndexes()
total = self.note_total
counter = 0
for child in range(len(children)):
note = self.GetChild(children[child])
item = note.GetItem()
if item is not None:
item.autoBeam = self.autoBeam
if hasattr(note, "duration"):
try:
counter += int(note.duration)
except:
if note.duration == "\\longa":
counter += 0.25
if note.duration == "\\breve":
counter += 0.5
if counter > total / 2:
if hasattr(self, "mid_barline"):
lilystring += self.mid_barline.toLily()
self.__delattr__("mid_barline")
if hasattr(self, "rest") and hasattr(self, "total"):
lilystring += "R" + self.total
else:
lilystring += note.toLily() + " "
return lilystring