MuseParse/classes/ObjectHierarchy/TreeClasses/PartNode.py
from MuseParse.classes.ObjectHierarchy.TreeClasses.BaseTree import IndexedNode
from MuseParse.classes.ObjectHierarchy.ItemClasses import Part
from MuseParse.classes.ObjectHierarchy.TreeClasses import MeasureNode
from MuseParse.classes.ObjectHierarchy.TreeClasses.StaffNode import StaffNode
from MuseParse import helpers
class PartNode(IndexedNode):
"""
Class representing the node holding the part.
"""
def __init__(self, index=0):
IndexedNode.__init__(self, rules=[StaffNode])
self.index = index
if self.item is None:
self.item = Part.Part()
def NewBeam(self, type, staff):
staff_obj = self.getStaff(staff)
staff_obj.NewBeam(type)
def Backup(self, measure_id, duration=0):
staves = self.GetChildrenIndexes()
for staff_id in staves:
staff = self.GetChild(staff_id)
measure = staff.GetChild(measure_id)
if measure is not None:
measure.Backup(duration=duration)
def Forward(self, measure_id, duration=0):
staves = self.GetChildrenIndexes()
for staff_id in staves:
staff = self.GetChild(staff_id)
measure = staff.GetChild(measure_id)
if measure is not None:
measure.Forward(duration=duration)
def AddBarline(self, staff=1, measure=1, location="left", item=None):
staff_obj = self.getStaff(staff)
if staff_obj is None:
self.AddChild(StaffNode(), staff)
staff_obj = self.getStaff(staff)
staff_obj.AddBarline(measure_id=measure, location=location, item=item)
def DoBarlineChecks(self):
staves = self.GetChildrenIndexes()
for s in staves:
staff = self.getStaff(s)
staff.DoBarlineChecks()
def CheckDivisions(self):
staves = self.GetChildrenIndexes()
for staff in staves:
child = self.getStaff(staff)
child.CheckDivisions()
def CheckTotals(self):
"""method to calculate the maximum total lilypond value for a measure without a time signature"""
staves = self.GetChildrenIndexes()
for staff in staves:
child = self.getStaff(staff)
child.CheckTotals()
def CheckMeasureDivisions(self, measure):
divisions = None
staves = self.GetChildrenIndexes()
for staff in staves:
measure_obj = self.getMeasure(measure, staff)
if measure_obj is not None:
if hasattr(measure_obj.GetItem(), "divisions"):
divisions = measure_obj.GetItem().divisions
elif divisions is not None:
measure_obj.GetItem().divisions = divisions
def CheckPreviousBarline(self, staff):
"""method which checks the bar before the current for changes we need to make to it's barlines"""
measure_before_last = self.getMeasureAtPosition(-2, staff)
last_measure = self.getMeasureAtPosition(-1, staff)
if last_measure is not None and measure_before_last is not None:
bline1 = measure_before_last.GetBarline("right")
bline2 = last_measure.GetBarline("left")
if bline1 is not None:
if hasattr(bline1, "ending"):
if bline2 is not None:
if not hasattr(bline2, "ending"):
bline1.ending.type = "discontinue"
else:
bline1.ending.type = "discontinue"
def CheckMeasureMeter(self, measure):
meter = None
staves = self.GetChildrenIndexes()
for staff in staves:
measure_obj = self.getMeasure(measure, staff)
if measure_obj is not None:
item = measure_obj.GetItem()
if hasattr(item, "meter"):
meter = item.meter
else:
if meter is not None:
item.meter = meter
def setDivisions(self, measure=1, divisions=1):
staves = self.GetChildrenIndexes()
for staff in staves:
measure_obj = self.getMeasure(measure, staff)
measure_obj.GetItem().divisions = divisions
def getMeasure(self, measure=1, staff=1):
staff_obj = self.GetChild(staff)
measure_obj = None
if staff_obj is not None:
measure_obj = staff_obj.GetChild(measure)
return measure_obj
def getMeasureAtPosition(self, index, staff=1):
staff_obj = self.getStaff(staff)
children = staff_obj.GetChildrenIndexes()
if abs(index) <= len(children):
return self.getMeasure(children[index], staff)
def getMeasureIDAtPosition(self, index, staff=1):
staff_obj = self.getStaff(staff)
children = staff_obj.GetChildrenIndexes()
if abs(index) <= len(children):
return children[index]
def getStaff(self, key):
return self.GetChild(key)
def addMeasure(self, item, measure=1, staff=1):
if self.getStaff(staff) is None:
self.AddChild(StaffNode(), staff)
staff_obj = self.getStaff(staff)
staff_obj.AddChild(item, measure)
def addEmptyMeasure(self, measure=1, staff=1):
self.addMeasure(
MeasureNode.MeasureNode(),
measure=measure,
staff=staff)
def CalculateVariable(self, name, staves):
variables = []
for staff in staves:
variable = ""
if len(name) > 0:
lcase = name.lower()
no_spaces = lcase.replace(' ', '')
no_dots = no_spaces.replace('.', '')
variable = ""
for letter in no_dots:
if letter in [str(i) for i in range(10)]:
variable += helpers.NumbersToWords(int(letter))
else:
variable += letter
variable += "staff" + helpers.NumbersToWords(staff)
variables.append(variable)
return variables
def addKey(self, item, measure_id):
staves = self.GetChildrenIndexes()
for staff_id in staves:
measure = self.getMeasure(measure_id, staff_id)
if measure is not None:
measure.addKey(item)
else:
self.addEmptyMeasure(measure_id, staff_id)
measure = self.getMeasure(measure_id, staff_id)
if measure is not None:
measure.addKey(item)
def addClef(self, item, measure_id, staff_id, voice):
measure = self.getMeasure(measure_id, staff_id)
if measure is not None:
measure.addClef(item, voice)
else:
self.addEmptyMeasure(measure_id, staff_id)
measure = self.getMeasure(measure_id, staff_id)
if measure is not None:
measure.addClef(item)
if item.sign == "percussion":
self.drum = True
else:
self.drum = False
if item.sign == "tab":
self.tab = True
else:
self.tab = False
def CheckIfTabStaff(self):
if hasattr(self, "tab") and self.tab:
return "TAB"
if hasattr(self, "drum") and self.drum:
return "DRUM"
def toLily(self):
'''
Method which converts the object instance, its attributes and children to a string of lilypond code
:return: str of lilypond code
'''
self.CheckDivisions()
self.CheckTotals()
staves = self.GetChildrenIndexes()
name = ""
shortname = ""
if hasattr(self.item, "name"):
name = self.item.name
name = helpers.SplitString(name)
if hasattr(self.item, "shortname"):
shortname = helpers.SplitString(self.item.shortname)
variables = self.CalculateVariable(str(self.index), staves)
first_part = ""
for staff, variable in zip(staves, variables):
staffstring = variable
if hasattr(
self.GetChild(staff),
"tab") and self.GetChild(staff).tab:
staffstring += " = \\new TabStaff"
elif hasattr(self.GetChild(staff), "drum") and self.GetChild(staff).drum:
staffstring += " = \\drums"
else:
staffstring += " = \\new Staff"
if len(staves) == 1:
if name != "":
staffstring += " \with {\n"
staffstring += "instrumentName = " + name + " \n"
if shortname != "":
staffstring += "shortInstrumentName = " + \
shortname + " \n"
staffstring += " }"
staffstring += "{" + self.GetChild(staff).toLily() + " }\n\n"
first_part += staffstring
second_part = ""
if len(variables) > 1:
second_part += "\\new StaffGroup "
if name != "":
second_part += "\with {\n"
second_part += "instrumentName = " + name + " \n"
second_part += " }"
second_part += "<<"
second_part += "\n".join(["\\" + var for var in variables])
if len(variables) > 1:
second_part += ">>"
return [first_part, second_part]