Source code for musicscore.metronome

from musicscore.quarterduration import QuarterDuration
from musicscore.exceptions import QuarterDurationIsNotWritable, MetronomeWrongBeatUnitError
from musicscore.xmlwrapper import XMLWrapper
from musicxml.xmlelement.xmlelement import XMLMetronome, XMLBeatUnitDot, XMLSound


[docs]class Metronome(XMLWrapper): _ATTRIBUTES = {'per_minute', 'beat_unit'} XMLClass = XMLMetronome def __init__(self, per_minute, beat_unit=1, parenthesis=False, *args, **kwargs): super().__init__() self._xml_object = self.XMLClass(*args, **kwargs) self._per_minute = None self._beat_unit = None self._sound = XMLSound() self.per_minute = per_minute self.beat_unit = beat_unit def _set_xml_beat_unit(self): if self.beat_unit.denominator not in [1, 2, 4, 8, 16, 32]: raise MetronomeWrongBeatUnitError(self.beat_unit) try: self.xml_object.xml_beat_unit = self.beat_unit.get_type() except QuarterDurationIsNotWritable: raise MetronomeWrongBeatUnitError(self.beat_unit) self._set_xml_sound_tempo() def _set_xml_per_minute(self): self.xml_object.xml_per_minute = str(self.per_minute) self._set_xml_sound_tempo() def _set_xml_sound_tempo(self): if self.beat_unit: if not self._sound: self._sound = XMLSound() self._sound.tempo = int(self.beat_unit.value * self.per_minute) def _set_xml_beat_unit_dots(self): number_of_dots = self.beat_unit.get_number_of_dots() current_xml_unit_dots = [ch for ch in self.xml_object.get_children() if isinstance(ch, XMLBeatUnitDot)] number_of_superfluous_dots = len(current_xml_unit_dots) - number_of_dots if number_of_superfluous_dots > 0: for xml_unit_dot in current_xml_unit_dots[:number_of_superfluous_dots]: self.xml_object.remove(xml_unit_dot) elif number_of_superfluous_dots < 0: for _ in range(number_of_superfluous_dots * -1): self.xml_object.add_child(XMLBeatUnitDot()) else: pass @property def beat_unit(self): return self._beat_unit @beat_unit.setter def beat_unit(self, val): if not isinstance(val, QuarterDuration): val = QuarterDuration(val) self._beat_unit = val self._set_xml_beat_unit() self._set_xml_beat_unit_dots() @property def per_minute(self): return self._per_minute @per_minute.setter def per_minute(self, val): self._per_minute = val self._set_xml_per_minute() @property def sound(self): return self._sound
[docs] def get_xml_beat_dot_objects(self): return [ch for ch in self.get_children() if isinstance(ch, XMLBeatUnitDot)]