def _add_or_remove_notes_to_achieve_written_duration( self, new_written_duration): from abjad.spanners import tie as abjad_tie from .NoteMaker import NoteMaker from .Tuplet import Tuplet new_written_duration = Duration(new_written_duration) maker = NoteMaker() if new_written_duration.is_assignable: self[0].written_duration = new_written_duration for leaf in self[1:]: mutate(leaf).extract() detach(Tie, self[0]) detach(RepeatTie, self[0]) elif new_written_duration.has_power_of_two_denominator: durations = maker(0, [new_written_duration]) for leaf, token in zip(self, durations): leaf.written_duration = token.written_duration if len(self) == len(durations): pass elif len(durations) < len(self): for leaf in self[len(durations):]: mutate(leaf).extract() elif len(self) < len(durations): # detach(Tie, self[0]) detach(Tie, self[0]) detach(RepeatTie, self[0]) difference = len(durations) - len(self) extra_leaves = self[0] * difference for extra_leaf in extra_leaves: # detach(Tie, extra_leaf) detach(Tie, extra_leaf) detach(RepeatTie, extra_leaf) extra_tokens = durations[len(self):] for leaf, token in zip(extra_leaves, extra_tokens): leaf.written_duration = token.written_duration parent = inspect(self[-1]).parentage().parent index = parent.index(self[-1]) next_ = index + 1 parent[next_:next_] = extra_leaves leaves = self.leaves + extra_leaves # attach(Tie(), leaves) abjad_tie(leaves) else: components = maker(0, new_written_duration) assert isinstance(components[0], Tuplet) tuplet = components[0] logical_tie = tuplet[0]._get_logical_tie() duration = logical_tie._get_preprolated_duration() leaves_ = self._add_or_remove_notes_to_achieve_written_duration( duration) multiplier = tuplet.multiplier tuplet = Tuplet(multiplier, []) # mutate(self.leaves).wrap(tuplet) mutate(leaves_).wrap(tuplet) return self[0]._get_logical_tie()
def _set_duration(self, new_duration): from .Chord import Chord from .Note import Note from .NoteMaker import NoteMaker from .Tuplet import Tuplet from abjad.spanners import tie as abjad_tie new_duration = Duration(new_duration) if self.multiplier is not None: multiplier = new_duration.__div__(self.written_duration) self.multiplier = multiplier return select(self) try: self.written_duration = new_duration return select(self) except exceptions.AssignabilityError: pass maker = NoteMaker() components = maker(0, new_duration) new_leaves = select(components).leaves() following_leaf_count = len(new_leaves) - 1 following_leaves = following_leaf_count * self all_leaves = [self] + following_leaves for leaf, new_leaf in zip(all_leaves, new_leaves): leaf.written_duration = new_leaf.written_duration logical_tie = self._get_logical_tie() logical_tie_leaves = list(logical_tie.leaves) for leaf in logical_tie: detach(Tie, leaf) detach(RepeatTie, leaf) if self._parent is not None: index = self._parent.index(self) next_ = index + 1 self._parent[next_:next_] = following_leaves index = logical_tie_leaves.index(self) next_ = index + 1 logical_tie_leaves[next_:next_] = following_leaves if 1 < len(logical_tie_leaves) and isinstance(self, (Note, Chord)): abjad_tie(logical_tie_leaves) if isinstance(components[0], Leaf): return select(all_leaves) else: assert isinstance(components[0], Tuplet) assert len(components) == 1 tuplet = components[0] multiplier = tuplet.multiplier tuplet = Tuplet(multiplier, []) mutate(all_leaves).wrap(tuplet) return select(tuplet)
def _set_duration(self, new_duration, repeat_ties=False): from .Chord import Chord from .Note import Note from .NoteMaker import NoteMaker from .Tuplet import Tuplet from abjad.spanners import tie as abjad_tie new_duration = Duration(new_duration) if self.multiplier is not None: multiplier = new_duration.__div__(self.written_duration) self.multiplier = multiplier return select(self) try: self.written_duration = new_duration return select(self) except exceptions.AssignabilityError: pass maker = NoteMaker(repeat_ties=repeat_ties) components = maker(0, new_duration) new_leaves = select(components).leaves() following_leaf_count = len(new_leaves) - 1 following_leaves = following_leaf_count * self all_leaves = [self] + following_leaves for leaf, new_leaf in zip(all_leaves, new_leaves): leaf.written_duration = new_leaf.written_duration logical_tie = self._get_logical_tie() logical_tie_leaves = list(logical_tie.leaves) for leaf in logical_tie: detach(TieIndicator, leaf) detach(RepeatTie, leaf) if self._parent is not None: index = self._parent.index(self) next_ = index + 1 self._parent[next_:next_] = following_leaves index = logical_tie_leaves.index(self) next_ = index + 1 logical_tie_leaves[next_:next_] = following_leaves if 1 < len(logical_tie_leaves) and isinstance(self, (Note, Chord)): abjad_tie(logical_tie_leaves) if isinstance(components[0], Leaf): return select(all_leaves) else: assert isinstance(components[0], Tuplet) assert len(components) == 1 tuplet = components[0] multiplier = tuplet.multiplier tuplet = Tuplet(multiplier, []) mutate(all_leaves).wrap(tuplet) return select(tuplet)
def _make_tied_leaf( class_, duration, increase_monotonic=None, forbidden_duration=None, multiplier=None, pitches=None, tag=None, tie_parts=True, repeat_ties=False, ): from abjad.spanners import tie as abjad_tie duration = Duration(duration) if forbidden_duration is not None: assert forbidden_duration.is_assignable assert forbidden_duration.numerator == 1 # find preferred numerator of written durations if necessary if forbidden_duration is not None and forbidden_duration <= duration: denominators = [ 2 * forbidden_duration.denominator, duration.denominator, ] denominator = mathtools.least_common_multiple(*denominators) forbidden_duration = NonreducedFraction(forbidden_duration) forbidden_duration = forbidden_duration.with_denominator( denominator ) duration = NonreducedFraction(duration) duration = duration.with_denominator(denominator) forbidden_numerator = forbidden_duration.numerator assert forbidden_numerator % 2 == 0 preferred_numerator = forbidden_numerator / 2 # make written duration numerators numerators = [] parts = mathtools.partition_integer_into_canonic_parts( duration.numerator ) if forbidden_duration is not None and forbidden_duration <= duration: for part in parts: if forbidden_numerator <= part: better_parts = LeafMaker._partition_less_than_double( part, preferred_numerator ) numerators.extend(better_parts) else: numerators.append(part) else: numerators = parts # reverse numerators if necessary if increase_monotonic: numerators = list(reversed(numerators)) # make one leaf per written duration result = [] for numerator in numerators: written_duration = Duration(numerator, duration.denominator) if pitches is not None: arguments = (pitches, written_duration) else: arguments = (written_duration,) result.append(class_(*arguments, multiplier=multiplier, tag=tag)) result = Selection(result) # tie if required if tie_parts and 1 < len(result): if not issubclass(class_, (Rest, Skip)): abjad_tie(result, repeat=repeat_ties) return result
def _make_tied_leaf( class_, duration, increase_monotonic=None, forbidden_duration=None, multiplier=None, pitches=None, tag=None, tie_parts=True, repeat_ties=False, ): from abjad.spanners import tie as abjad_tie duration = Duration(duration) if forbidden_duration is not None: assert forbidden_duration.is_assignable assert forbidden_duration.numerator == 1 # find preferred numerator of written durations if necessary if (forbidden_duration is not None and forbidden_duration <= duration): denominators = [ 2 * forbidden_duration.denominator, duration.denominator, ] denominator = mathtools.least_common_multiple(*denominators) forbidden_duration = NonreducedFraction(forbidden_duration) forbidden_duration = forbidden_duration.with_denominator( denominator) duration = NonreducedFraction(duration) duration = duration.with_denominator(denominator) forbidden_numerator = forbidden_duration.numerator assert forbidden_numerator % 2 == 0 preferred_numerator = forbidden_numerator / 2 # make written duration numerators numerators = [] parts = mathtools.partition_integer_into_canonic_parts( duration.numerator) if (forbidden_duration is not None and forbidden_duration <= duration): for part in parts: if forbidden_numerator <= part: better_parts = LeafMaker._partition_less_than_double( part, preferred_numerator, ) numerators.extend(better_parts) else: numerators.append(part) else: numerators = parts # reverse numerators if necessary if increase_monotonic: numerators = list(reversed(numerators)) # make one leaf per written duration result = [] for numerator in numerators: written_duration = Duration( numerator, duration.denominator, ) if pitches is not None: arguments = (pitches, written_duration) else: arguments = (written_duration, ) result.append(class_(*arguments, multiplier=multiplier, tag=tag)) result = Selection(result) # tie if required if tie_parts and 1 < len(result): if not issubclass(class_, (Rest, Skip)): abjad_tie(result, repeat=repeat_ties) return result