Пример #1
0
 def _set_duration(self, new_duration, repeat_ties=False):
     import abjad
     new_duration = Duration(new_duration)
     # change LilyPond multiplier if leaf already has LilyPond multiplier
     if self._get_indicators(Multiplier):
         detach(Multiplier, self)
         multiplier = new_duration.__div__(self.written_duration)
         attach(multiplier, self)
         return select(self)
     # change written duration if new duration is assignable
     try:
         self.written_duration = new_duration
         return select(self)
     except exceptions.AssignabilityError:
         pass
     # make new notes or tuplets if new duration is nonassignable
     maker = abjad.NoteMaker(repeat_ties=repeat_ties, )
     components = maker(0, new_duration)
     if isinstance(components[0], Leaf):
         tied_leaf_count = len(components) - 1
         tied_leaves = tied_leaf_count * self
         all_leaves = [self] + tied_leaves
         for leaf, component in zip(all_leaves, components):
             leaf.written_duration = component.written_duration
         self._splice(tied_leaves, grow_spanners=True)
         if not inspect(self).has_spanner(abjad.Tie):
             tie = abjad.Tie()
             if tie._attachment_test(self):
                 tie = abjad.Tie(repeat=repeat_ties)
                 attach(tie, all_leaves)
         return select(all_leaves)
     else:
         assert isinstance(components[0], abjad.Tuplet)
         tuplet = components[0]
         components = tuplet[:]
         tied_leaf_count = len(components) - 1
         tied_leaves = tied_leaf_count * self
         all_leaves = [self] + tied_leaves
         for leaf, component in zip(all_leaves, components):
             leaf.written_duration = component.written_duration
         self._splice(tied_leaves, grow_spanners=True)
         if not inspect(self).has_spanner(abjad.Tie):
             tie = abjad.Tie()
             if tie._attachment_test(self):
                 tie = abjad.Tie(repeat=repeat_ties)
                 attach(tie, all_leaves)
         multiplier = tuplet.multiplier
         tuplet = abjad.Tuplet(multiplier, [])
         abjad.mutate(all_leaves).wrap(tuplet)
         return select(tuplet)
Пример #2
0
    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)
Пример #3
0
    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)
Пример #4
0
 def _split_by_durations(
     self,
     durations,
     cyclic=False,
     fracture_spanners=False,
     tie_split_notes=True,
     repeat_ties=False,
 ):
     import abjad
     durations = [Duration(_) for _ in durations]
     durations = sequence(durations)
     leaf_duration = inspect(self).duration()
     if cyclic:
         durations = durations.repeat_to_weight(leaf_duration)
     if sum(durations) < leaf_duration:
         last_duration = leaf_duration - sum(durations)
         durations = list(durations)
         durations.append(last_duration)
         durations = sequence(durations)
     durations = durations.truncate(weight=leaf_duration)
     result_selections = []
     # detach grace containers
     grace_container = self._detach_grace_container()
     after_grace_container = self._detach_after_grace_container()
     leaf_prolation = inspect(self).parentage().prolation
     for duration in durations:
         new_leaf = copy.copy(self)
         preprolated_duration = duration / leaf_prolation
         selection = new_leaf._set_duration(
             preprolated_duration,
             repeat_ties=repeat_ties,
         )
         result_selections.append(selection)
     result_components = sequence(result_selections).flatten(depth=-1)
     result_components = select(result_components)
     result_leaves = select(result_components).leaves()
     assert all(isinstance(_, abjad.Selection) for _ in result_selections)
     assert all(isinstance(_, Component) for _ in result_components)
     assert result_leaves.are_leaves()
     if inspect(self).has_spanner(abjad.Tie):
         for leaf in result_leaves:
             detach(abjad.Tie, leaf)
     # strip result leaves of indicators (other than multipliers)
     for leaf in result_leaves:
         multiplier = inspect(leaf).indicator(Multiplier)
         detach(object, leaf)
         if multiplier is not None:
             attach(multiplier, leaf)
     # replace leaf with flattened result
     selection = select(self)
     parent, start, stop = selection._get_parent_and_start_stop_indices()
     if parent:
         parent.__setitem__(slice(start, stop + 1), result_components)
     else:
         selection._give_dominant_spanners(result_components)
         selection._withdraw_from_crossing_spanners()
     # fracture spanners
     if fracture_spanners:
         first_selection = result_selections[0]
         for spanner in inspect(first_selection[-1]).spanners():
             index = spanner._index(first_selection[-1])
             spanner._fracture(index, direction=enums.Right)
         last_selection = result_selections[-1]
         for spanner in inspect(last_selection[0]).spanners():
             index = spanner._index(last_selection[0])
             spanner._fracture(index, direction=enums.Left)
         for middle_selection in result_selections[1:-1]:
             spanners = inspect(middle_selection[0]).spanners()
             for spanner in spanners:
                 index = spanner._index(middle_selection[0])
                 spanner._fracture(index, direction=enums.Left)
             spanners = inspect(middle_selection[-1]).spanners()
             for spanner in spanners:
                 index = spanner._index(middle_selection[-1])
                 spanner._fracture(index, direction=enums.Right)
     # move indicators
     first_result_leaf = result_leaves[0]
     last_result_leaf = result_leaves[-1]
     for indicator in inspect(self).indicators():
         if isinstance(indicator, Multiplier):
             continue
         detach(indicator, self)
         direction = getattr(indicator, '_time_orientation', enums.Left)
         if direction is enums.Left:
             attach(indicator, first_result_leaf)
         elif direction == enums.Right:
             attach(indicator, last_result_leaf)
         else:
             raise ValueError(direction)
     # move grace containers
     if grace_container is not None:
         container = grace_container[0]
         assert isinstance(container, abjad.GraceContainer), repr(container)
         attach(container, first_result_leaf)
     if after_grace_container is not None:
         container = after_grace_container[0]
         prototype = abjad.AfterGraceContainer
         assert isinstance(container, prototype), repr(container)
         attach(container, last_result_leaf)
     if isinstance(result_components[0], abjad.Tuplet):
         abjad.mutate(result_components).fuse()
     # tie split notes
     if isinstance(self, (abjad.Note, abjad.Chord)) and tie_split_notes:
         result_leaves._attach_tie_to_leaves(repeat_ties=repeat_ties, )
     assert isinstance(result_selections, list), repr(result_selections)
     assert all(isinstance(_, abjad.Selection) for _ in result_selections)
     return result_selections
Пример #5
0
 def _detach_grace_container(self):
     if self._grace_container is not None:
         return detach(self._grace_container, self)
Пример #6
0
    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(TieIndicator, 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(TieIndicator, 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(TieIndicator, 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()
Пример #7
0
    def to_tuplet(self, proportions):
        r"""
        Changes logical tie to tuplet.

        ..  container:: example

            >>> staff = abjad.Staff(r"df'8 c'8 ~ c'16 cqs''4")
            >>> abjad.attach(abjad.Dynamic('p'), staff[0])
            >>> abjad.attach(abjad.HairpinIndicator('<'), staff[0])
            >>> abjad.attach(abjad.Dynamic('f'), staff[-1])
            >>> abjad.override(staff).dynamic_line_spanner.staff_padding = 3
            >>> time_signature = abjad.TimeSignature((9, 16))
            >>> abjad.attach(time_signature, staff[0])
            >>> abjad.show(staff) # doctest: +SKIP

            ..  docs::

                >>> abjad.f(staff)
                \new Staff
                \with
                {
                    \override DynamicLineSpanner.staff-padding = #3
                }
                {
                    \time 9/16
                    df'8
                    \p
                    \<
                    c'8
                    ~
                    c'16
                    cqs''4
                    \f
                }

            >>> logical_tie = abjad.inspect(staff[1]).logical_tie()
            >>> logical_tie.to_tuplet([2, 1, 1, 1])
            Tuplet(Multiplier(3, 5), "c'8 c'16 c'16 c'16")

            ..  docs::

                >>> abjad.f(staff)
                \new Staff
                \with
                {
                    \override DynamicLineSpanner.staff-padding = #3
                }
                {
                    \time 9/16
                    df'8
                    \p
                    \<
                    \tweak text #tuplet-number::calc-fraction-text
                    \times 3/5 {
                        c'8
                        c'16
                        c'16
                        c'16
                    }
                    cqs''4
                    \f
                }

            >>> abjad.show(staff) # doctest: +SKIP

        ..  container:: example

            >>> staff = abjad.Staff(r"c'8 ~ c'16 cqs''4")
            >>> abjad.hairpin('p < f', staff[:])
            >>> abjad.override(staff).dynamic_line_spanner.staff_padding = 3
            >>> time_signature = abjad.TimeSignature((7, 16))
            >>> abjad.attach(time_signature, staff[0])
            >>> abjad.show(staff) # doctest: +SKIP

            ..  docs::

                >>> abjad.f(staff)
                \new Staff
                \with
                {
                    \override DynamicLineSpanner.staff-padding = #3
                }
                {
                    \time 7/16
                    c'8
                    \p
                    \<
                    ~
                    c'16
                    cqs''4
                    \f
                }

        Returns tuplet.
        """
        from .Note import Note
        from .Note import Note
        from .NoteMaker import NoteMaker
        from .Tuplet import Tuplet
        proportions = Ratio(proportions)
        target_duration = self._get_preprolated_duration()
        prolated_duration = target_duration / sum(proportions.numbers)
        basic_written_duration = \
            prolated_duration.equal_or_greater_power_of_two
        written_durations = [
            _ * basic_written_duration for _ in proportions.numbers
            ]
        maker = NoteMaker()
        try:
            notes = [Note(0, _) for _ in written_durations]
        except exceptions.AssignabilityError:
            denominator = target_duration._denominator
            note_durations = [
                Duration(_, denominator)
                for _ in proportions.numbers
                ]
            notes = maker(0, note_durations)
        tuplet = Tuplet.from_duration(target_duration, notes)
        for leaf in self:
            detach(TieIndicator, leaf)
            detach(RepeatTie, leaf)
        mutate(self).replace(tuplet)
        return tuplet
Пример #8
0
    def _split_by_durations(
        self,
        durations,
        cyclic=False,
        tie_split_notes=True,
        repeat_ties=False,
        ):
        from .AfterGraceContainer import AfterGraceContainer
        from .Chord import Chord
        from .GraceContainer import GraceContainer
        from .Note import Note
        from .Selection import Selection
        from .Tuplet import Tuplet
        durations = [Duration(_) for _ in durations]
        durations = Sequence(durations)
        leaf_duration = inspect(self).duration()
        if cyclic:
            durations = durations.repeat_to_weight(leaf_duration)
        if sum(durations) < leaf_duration:
            last_duration = leaf_duration - sum(durations)
            durations = list(durations)
            durations.append(last_duration)
            durations = Sequence(durations)
        durations = durations.truncate(weight=leaf_duration)
        originally_tied = inspect(self).has_indicator(TieIndicator)
        originally_repeat_tied = inspect(self).has_indicator(RepeatTie)
        result_selections = []
        grace_container = self._detach_grace_container()
        after_grace_container = self._detach_after_grace_container()
        leaf_prolation = inspect(self).parentage().prolation
        for duration in durations:
            new_leaf = copy.copy(self)
            preprolated_duration = duration / leaf_prolation
            selection = new_leaf._set_duration(
                preprolated_duration,
                repeat_ties=repeat_ties,
                )
            result_selections.append(selection)
        result_components = Sequence(result_selections).flatten(depth=-1)
        result_components = select(result_components)
        result_leaves = select(result_components).leaves(grace_notes=False)
        assert all(isinstance(_, Selection) for _ in result_selections)
        assert all(isinstance(_, Component) for _ in result_components)
        assert result_leaves.are_leaves()
#        for leaf in result_leaves:
#            detach(Tie, leaf)
        # strip result leaves of all indicators
        for leaf in result_leaves:
            detach(object, leaf)
        # replace leaf with flattened result
        if self._parent is not None:
            mutate(self).replace(result_components)
        # move indicators
        first_result_leaf = result_leaves[0]
        last_result_leaf = result_leaves[-1]
        for indicator in inspect(self).indicators():
            detach(indicator, self)
            direction = getattr(indicator, '_time_orientation', enums.Left)
            if direction is enums.Left:
                attach(indicator, first_result_leaf)
            elif direction == enums.Right:
                attach(indicator, last_result_leaf)
            else:
                raise ValueError(direction)
        # move grace containers
        if grace_container is not None:
            container = grace_container[0]
            assert isinstance(container, GraceContainer), repr(container)
            attach(container, first_result_leaf)
        if after_grace_container is not None:
            container = after_grace_container[0]
            prototype = AfterGraceContainer
            assert isinstance(container, prototype), repr(container)
            attach(container, last_result_leaf)
        if isinstance(result_components[0], Tuplet):
            mutate(result_components).fuse()
        # tie split notes
        if (tie_split_notes and
            isinstance(self, (Note, Chord)) and
            1 < len(result_leaves)):
            result_leaves._attach_tie_to_leaves(repeat_ties=repeat_ties)
        #assert not inspect(result_leaves[0]).has_indicator(RepeatTie)
        detach(RepeatTie, result_leaves[0])
        #assert not inspect(result_leaves[-1]).has_indicator(TieIndicator)
        detach(TieIndicator, result_leaves[-1])
        if originally_repeat_tied:
            tie = RepeatTie()
            attach(tie, result_leaves[0])
        if originally_tied:
            tie = TieIndicator()
            attach(tie, result_leaves[-1])
        assert isinstance(result_leaves, Selection)
        assert all(isinstance(_, Leaf) for _ in result_leaves)
        return result_leaves
Пример #9
0
 def _move_indicators(self, recipient_component):
     for wrapper in inspect(self).wrappers():
         detach(wrapper, self)
         attach(wrapper, recipient_component)
Пример #10
0
def on_beat_grace_container(
    contents,
    anchor_voice_selection,
    *,
    anchor_voice_number=2,
    do_not_beam=None,
    do_not_slash=None,
    do_not_slur=None,
    do_not_stop_polyphony=None,
    font_size=-3,
    grace_voice_number=1,
    leaf_duration=None,
):
    r"""
    Makes on-beat grace container and wraps around ``selection``.

    ..  container:: example

        GRACE NOTES ABOVE.

        Note-to-note anchor:

        >>> music_voice = abjad.Voice("c'4 d' e' f'", name="Music_Voice")
        >>> string = "g'8 a' b' c'' d'' c'' b' a' b' c'' d''"
        >>> result = abjad.on_beat_grace_container(
        ...     string, music_voice[1:3], leaf_duration=(1, 30)
        ... )
        >>> staff = abjad.Staff([music_voice])
        >>> abjad.show(staff) # doctest: +SKIP

        ..  docs::

            >>> abjad.f(staff)
            \new Staff
            {
                \context Voice = "Music_Voice"
                {
                    c'4
                    <<
                        \context Voice = "On_Beat_Grace_Container"
                        {
                            \set fontSize = #-3 %! abjad.on_beat_grace_container(1)
                            \slash %! abjad.on_beat_grace_container(2)
                            \voiceOne %! abjad.on_beat_grace_container(3)
                            <
                                \tweak font-size #0
                                \tweak transparent ##t
                                d'
                                g'
                            >8 * 4/15
                            [
                            (
                            a'8 * 4/15
                            b'8 * 4/15
                            c''8 * 4/15
                            d''8 * 4/15
                            c''8 * 4/15
                            b'8 * 4/15
                            a'8 * 4/15
                            b'8 * 4/15
                            c''8 * 4/15
                            d''8 * 4/15
                            )
                            ]
                        }
                        \context Voice = "Music_Voice"
                        {
                            \voiceTwo %! abjad.on_beat_grace_container(4)
                            d'4
                            e'4
                        }
                    >>
                    \oneVoice %! abjad.on_beat_grace_container(5)
                    f'4
                }
            }

        Note-to-chord anchor:

        >>> music_voice = abjad.Voice(
        ...     "<a c'>4 <b d'> <c' e'> <d' f'>", name="Music_Voice"
        ... )
        >>> string = "g'8 a' b' c'' d'' c'' b' a' b' c'' d''"
        >>> result = abjad.on_beat_grace_container(
        ...     string, music_voice[1:3], leaf_duration=(1, 30)
        ... )
        >>> staff = abjad.Staff([music_voice])
        >>> abjad.show(staff) # doctest: +SKIP

        ..  docs::

            >>> abjad.f(staff)
            \new Staff
            {
                \context Voice = "Music_Voice"
                {
                    <a c'>4
                    <<
                        \context Voice = "On_Beat_Grace_Container"
                        {
                            \set fontSize = #-3 %! abjad.on_beat_grace_container(1)
                            \slash %! abjad.on_beat_grace_container(2)
                            \voiceOne %! abjad.on_beat_grace_container(3)
                            <
                                \tweak font-size #0
                                \tweak transparent ##t
                                d'
                                g'
                            >8 * 4/15
                            [
                            (
                            a'8 * 4/15
                            b'8 * 4/15
                            c''8 * 4/15
                            d''8 * 4/15
                            c''8 * 4/15
                            b'8 * 4/15
                            a'8 * 4/15
                            b'8 * 4/15
                            c''8 * 4/15
                            d''8 * 4/15
                            )
                            ]
                        }
                        \context Voice = "Music_Voice"
                        {
                            \voiceTwo %! abjad.on_beat_grace_container(4)
                            <b d'>4
                            <c' e'>4
                        }
                    >>
                    \oneVoice %! abjad.on_beat_grace_container(5)
                    <d' f'>4
                }
            }

        Chord-to-note anchor:

        >>> music_voice = abjad.Voice("c'4 d' e' f'", name="Music_Voice")
        >>> string = "<g' b'>8 a' b' c'' d'' c'' b' a' b' c'' d''"
        >>> result = abjad.on_beat_grace_container(
        ...     string, music_voice[1:3], leaf_duration=(1, 30)
        ... )
        >>> staff = abjad.Staff([music_voice])
        >>> abjad.show(staff) # doctest: +SKIP

        ..  docs::

            >>> abjad.f(staff)
            \new Staff
            {
                \context Voice = "Music_Voice"
                {
                    c'4
                    <<
                        \context Voice = "On_Beat_Grace_Container"
                        {
                            \set fontSize = #-3 %! abjad.on_beat_grace_container(1)
                            \slash %! abjad.on_beat_grace_container(2)
                            \voiceOne %! abjad.on_beat_grace_container(3)
                            <
                                \tweak font-size #0
                                \tweak transparent ##t
                                d'
                                g'
                                b'
                            >8 * 4/15
                            [
                            (
                            a'8 * 4/15
                            b'8 * 4/15
                            c''8 * 4/15
                            d''8 * 4/15
                            c''8 * 4/15
                            b'8 * 4/15
                            a'8 * 4/15
                            b'8 * 4/15
                            c''8 * 4/15
                            d''8 * 4/15
                            )
                            ]
                        }
                        \context Voice = "Music_Voice"
                        {
                            \voiceTwo %! abjad.on_beat_grace_container(4)
                            d'4
                            e'4
                        }
                    >>
                    \oneVoice %! abjad.on_beat_grace_container(5)
                    f'4
                }
            }

        Chord-to-chord anchor:

        >>> music_voice = abjad.Voice(
        ...     "<a c'>4 <b d'> <c' e'> <d' f'>", name="Music_Voice"
        ... )
        >>> string = "<g' b'>8 a' b' c'' d'' c'' b' a' b' c'' d''"
        >>> result = abjad.on_beat_grace_container(
        ...     string, music_voice[1:3], leaf_duration=(1, 30)
        ... )
        >>> staff = abjad.Staff([music_voice])
        >>> abjad.show(staff) # doctest: +SKIP

        ..  docs::

            >>> abjad.f(staff)
            \new Staff
            {
                \context Voice = "Music_Voice"
                {
                    <a c'>4
                    <<
                        \context Voice = "On_Beat_Grace_Container"
                        {
                            \set fontSize = #-3 %! abjad.on_beat_grace_container(1)
                            \slash %! abjad.on_beat_grace_container(2)
                            \voiceOne %! abjad.on_beat_grace_container(3)
                            <
                                \tweak font-size #0
                                \tweak transparent ##t
                                d'
                                g'
                                b'
                            >8 * 4/15
                            [
                            (
                            a'8 * 4/15
                            b'8 * 4/15
                            c''8 * 4/15
                            d''8 * 4/15
                            c''8 * 4/15
                            b'8 * 4/15
                            a'8 * 4/15
                            b'8 * 4/15
                            c''8 * 4/15
                            d''8 * 4/15
                            )
                            ]
                        }
                        \context Voice = "Music_Voice"
                        {
                            \voiceTwo %! abjad.on_beat_grace_container(4)
                            <b d'>4
                            <c' e'>4
                        }
                    >>
                    \oneVoice %! abjad.on_beat_grace_container(5)
                    <d' f'>4
                }
            }

    ..  container:: example

        GRACE NOTES BELOW.

        Note-to-note anchor:

        >>> music_voice = abjad.Voice("c'4 d' e' f'", name="Music_Voice")
        >>> string = "g8 a b c' d' c' b a b c' d'"
        >>> result = abjad.on_beat_grace_container(
        ...     string,
        ...     music_voice[1:3],
        ...     anchor_voice_number=1,
        ...     grace_voice_number=2,
        ...     leaf_duration=(1, 30),
        ... )
        >>> staff = abjad.Staff([music_voice])
        >>> abjad.show(staff) # doctest: +SKIP

        ..  docs::

            >>> abjad.f(staff)
            \new Staff
            {
                \context Voice = "Music_Voice"
                {
                    c'4
                    <<
                        \context Voice = "On_Beat_Grace_Container"
                        {
                            \set fontSize = #-3 %! abjad.on_beat_grace_container(1)
                            \slash %! abjad.on_beat_grace_container(2)
                            \voiceTwo %! abjad.on_beat_grace_container(3)
                            <
                                g
                                \tweak font-size #0
                                \tweak transparent ##t
                                d'
                            >8 * 4/15
                            [
                            (
                            a8 * 4/15
                            b8 * 4/15
                            c'8 * 4/15
                            d'8 * 4/15
                            c'8 * 4/15
                            b8 * 4/15
                            a8 * 4/15
                            b8 * 4/15
                            c'8 * 4/15
                            d'8 * 4/15
                            )
                            ]
                        }
                        \context Voice = "Music_Voice"
                        {
                            \voiceOne %! abjad.on_beat_grace_container(4)
                            d'4
                            e'4
                        }
                    >>
                    \oneVoice %! abjad.on_beat_grace_container(5)
                    f'4
                }
            }

        Note-to-chord anchor:

        >>> music_voice = abjad.Voice(
        ...     "<c' e'>4 <d' f'> <e' g'> <f' a'>", name="Music_Voice"
        ... )
        >>> string = "g8 a b c' d' c' b a b c' d'"
        >>> result = abjad.on_beat_grace_container(
        ...     string,
        ...     music_voice[1:3],
        ...     anchor_voice_number=1,
        ...     grace_voice_number=2,
        ...     leaf_duration=(1, 30),
        ... )
        >>> staff = abjad.Staff([music_voice])
        >>> abjad.show(staff) # doctest: +SKIP

        ..  docs::

            >>> abjad.f(staff)
            \new Staff
            {
                \context Voice = "Music_Voice"
                {
                    <c' e'>4
                    <<
                        \context Voice = "On_Beat_Grace_Container"
                        {
                            \set fontSize = #-3 %! abjad.on_beat_grace_container(1)
                            \slash %! abjad.on_beat_grace_container(2)
                            \voiceTwo %! abjad.on_beat_grace_container(3)
                            <
                                g
                                \tweak font-size #0
                                \tweak transparent ##t
                                f'
                            >8 * 4/15
                            [
                            (
                            a8 * 4/15
                            b8 * 4/15
                            c'8 * 4/15
                            d'8 * 4/15
                            c'8 * 4/15
                            b8 * 4/15
                            a8 * 4/15
                            b8 * 4/15
                            c'8 * 4/15
                            d'8 * 4/15
                            )
                            ]
                        }
                        \context Voice = "Music_Voice"
                        {
                            \voiceOne %! abjad.on_beat_grace_container(4)
                            <d' f'>4
                            <e' g'>4
                        }
                    >>
                    \oneVoice %! abjad.on_beat_grace_container(5)
                    <f' a'>4
                }
            }

        Chord-to-note anchor:

        >>> music_voice = abjad.Voice("c'4 d' e' f'", name="Music_Voice")
        >>> string = "<e g>8 a b c' d' c' b a b c' d'"
        >>> result = abjad.on_beat_grace_container(
        ...     string,
        ...     music_voice[1:3],
        ...     anchor_voice_number=1,
        ...     grace_voice_number=2,
        ...     leaf_duration=(1, 30),
        ... )
        >>> staff = abjad.Staff([music_voice])
        >>> abjad.show(staff) # doctest: +SKIP

        ..  docs::

            >>> abjad.f(staff)
            \new Staff
            {
                \context Voice = "Music_Voice"
                {
                    c'4
                    <<
                        \context Voice = "On_Beat_Grace_Container"
                        {
                            \set fontSize = #-3 %! abjad.on_beat_grace_container(1)
                            \slash %! abjad.on_beat_grace_container(2)
                            \voiceTwo %! abjad.on_beat_grace_container(3)
                            <
                                e
                                g
                                \tweak font-size #0
                                \tweak transparent ##t
                                d'
                            >8 * 4/15
                            [
                            (
                            a8 * 4/15
                            b8 * 4/15
                            c'8 * 4/15
                            d'8 * 4/15
                            c'8 * 4/15
                            b8 * 4/15
                            a8 * 4/15
                            b8 * 4/15
                            c'8 * 4/15
                            d'8 * 4/15
                            )
                            ]
                        }
                        \context Voice = "Music_Voice"
                        {
                            \voiceOne %! abjad.on_beat_grace_container(4)
                            d'4
                            e'4
                        }
                    >>
                    \oneVoice %! abjad.on_beat_grace_container(5)
                    f'4
                }
            }

        Chord-to-chord anchor:

        >>> music_voice = abjad.Voice(
        ...     "<c' e'>4 <d' f'> <e' g'> <f' a'>", name="Music_Voice"
        ... )
        >>> string = "<e g>8 a b c' d' c' b a b c' d'"
        >>> result = abjad.on_beat_grace_container(
        ...     string,
        ...     music_voice[1:3],
        ...     anchor_voice_number=1,
        ...     grace_voice_number=2,
        ...     leaf_duration=(1, 30),
        ... )
        >>> staff = abjad.Staff([music_voice])
        >>> abjad.show(staff) # doctest: +SKIP

        ..  docs::

            >>> abjad.f(staff)
            \new Staff
            {
                \context Voice = "Music_Voice"
                {
                    <c' e'>4
                    <<
                        \context Voice = "On_Beat_Grace_Container"
                        {
                            \set fontSize = #-3 %! abjad.on_beat_grace_container(1)
                            \slash %! abjad.on_beat_grace_container(2)
                            \voiceTwo %! abjad.on_beat_grace_container(3)
                            <
                                e
                                g
                                \tweak font-size #0
                                \tweak transparent ##t
                                f'
                            >8 * 4/15
                            [
                            (
                            a8 * 4/15
                            b8 * 4/15
                            c'8 * 4/15
                            d'8 * 4/15
                            c'8 * 4/15
                            b8 * 4/15
                            a8 * 4/15
                            b8 * 4/15
                            c'8 * 4/15
                            d'8 * 4/15
                            )
                            ]
                        }
                        \context Voice = "Music_Voice"
                        {
                            \voiceOne %! abjad.on_beat_grace_container(4)
                            <d' f'>4
                            <e' g'>4
                        }
                    >>
                    \oneVoice %! abjad.on_beat_grace_container(5)
                    <f' a'>4
                }
            }

    ..  container:: example

        Raises exception when duration of on-beat grace container exceeds
        duration of anchor container:

        >>> music_voice = abjad.Voice("c'4 d' e' f'", name="Music_Voice")
        >>> string = "g'8 a' b' c'' d'' c'' b' a' b' c'' d''"
        >>> result = abjad.on_beat_grace_container(
        ...     string, music_voice[1:2], leaf_duration=(1, 8)
        ... )
        Traceback (most recent call last):
            ...
        Exception: grace Duration(11, 8) exceeds anchor Duration(1, 4).

    """
    from .Container import Container
    from .Selection import Selection
    from .Voice import Voice
    from abjad.spanners import beam
    from abjad.spanners import slur

    def _site(n):
        return Tag(f"abjad.on_beat_grace_container({n})")

    assert isinstance(anchor_voice_selection, Selection)
    if not anchor_voice_selection.are_contiguous_same_parent(
            ignore_before_after_grace=True):
        message = "selection must be contiguous in same parent:\n"
        message += f"   {repr(anchor_voice_selection)}"
        raise Exception(message)
    on_beat_grace_container = OnBeatGraceContainer(contents,
                                                   leaf_duration=leaf_duration)
    if not isinstance(anchor_voice_selection, Selection):
        raise Exception(f"must be selection:\n {repr(anchor_voice_selection)}")
    anchor_leaf = abjad_inspect(anchor_voice_selection).leaf(0)
    anchor_voice = abjad_inspect(anchor_leaf).parentage().get(Voice)
    if anchor_voice.name is None:
        raise Exception(
            f"anchor voice must be named:\n   {repr(anchor_voice)}")
    anchor_voice_insert = Voice(name=anchor_voice.name)
    mutate(anchor_voice_selection).wrap(anchor_voice_insert)
    container = Container(simultaneous=True)
    mutate(anchor_voice_insert).wrap(container)
    container.insert(0, on_beat_grace_container)
    on_beat_grace_container._match_anchor_leaf()
    on_beat_grace_container._set_leaf_durations()
    insert_duration = abjad_inspect(anchor_voice_insert).duration()
    grace_container_duration = abjad_inspect(
        on_beat_grace_container).duration()
    if insert_duration < grace_container_duration:
        message = f"grace {repr(grace_container_duration)}"
        message += f" exceeds anchor {repr(insert_duration)}."
        raise Exception(message)
    if font_size is not None:
        string = rf"\set fontSize = #{font_size}"
        literal = LilyPondLiteral(string)
        attach(literal, on_beat_grace_container, tag=_site(1))
    if not do_not_beam:
        beam(on_beat_grace_container[:])
    if not do_not_slash:
        literal = LilyPondLiteral(r"\slash")
        attach(literal, on_beat_grace_container[0], tag=_site(2))
    if not do_not_slur:
        slur(on_beat_grace_container[:])
    voice_number_to_string = {
        1: r"\voiceOne",
        2: r"\voiceTwo",
        3: r"\voiceThree",
        4: r"\voiceFour",
    }
    first_grace = abjad_inspect(on_beat_grace_container).leaf(0)
    one_voice_literal = LilyPondLiteral(r"\oneVoice",
                                        format_slot="absolute_before")
    string = voice_number_to_string.get(grace_voice_number, None)
    if string is not None:
        literal
        detach(one_voice_literal, anchor_leaf)
        attach(LilyPondLiteral(string), first_grace, tag=_site(3))
    string = voice_number_to_string.get(anchor_voice_number, None)
    if string is not None:
        detach(one_voice_literal, anchor_leaf)
        attach(LilyPondLiteral(string), anchor_leaf, tag=_site(4))
    if not do_not_stop_polyphony:
        last_anchor_leaf = abjad_inspect(anchor_voice_selection).leaf(-1)
        next_leaf = abjad_inspect(last_anchor_leaf).leaf(1)
        if next_leaf is not None:
            literal = LilyPondLiteral(r"\oneVoice",
                                      format_slot="absolute_before")
            attach(literal, next_leaf, tag=_site(5))
    return on_beat_grace_container
Пример #11
0
 def _before_attach(self, argument):
     if self._ignore_before_attach:
         return
     for leaf in iterate(argument).leaves():
         detach(Tie, leaf)
Пример #12
0
    def _split_by_durations(self, durations, cyclic=False):
        from .Chord import Chord
        from .Note import Note
        from .Selection import Selection
        from .Tuplet import Tuplet

        durations = [Duration(_) for _ in durations]
        durations = Sequence(durations)
        leaf_duration = inspect(self).duration()
        if cyclic:
            durations = durations.repeat_to_weight(leaf_duration)
        if sum(durations) < leaf_duration:
            last_duration = leaf_duration - sum(durations)
            durations = list(durations)
            durations.append(last_duration)
            durations = Sequence(durations)
        durations = durations.truncate(weight=leaf_duration)
        originally_tied = inspect(self).has_indicator(Tie)
        originally_repeat_tied = inspect(self).has_indicator(RepeatTie)
        result_selections = []
        # detach grace containers
        before_grace_container = self._before_grace_container
        if before_grace_container is not None:
            detach(before_grace_container, self)
        after_grace_container = self._after_grace_container
        if after_grace_container is not None:
            detach(after_grace_container, self)
        # do other things
        leaf_prolation = inspect(self).parentage().prolation
        for duration in durations:
            new_leaf = copy.copy(self)
            preprolated_duration = duration / leaf_prolation
            selection = new_leaf._set_duration(preprolated_duration)
            result_selections.append(selection)
        result_components = Sequence(result_selections).flatten(depth=-1)
        result_components = select(result_components)
        result_leaves = select(result_components).leaves(grace=False)
        assert all(isinstance(_, Selection) for _ in result_selections)
        assert all(isinstance(_, Component) for _ in result_components)
        assert result_leaves.are_leaves()
        # strip result leaves of all indicators
        for leaf in result_leaves:
            detach(object, leaf)
        # replace leaf with flattened result
        if inspect(self).parentage().parent is not None:
            mutate(self).replace(result_components)
        # move indicators
        first_result_leaf = result_leaves[0]
        last_result_leaf = result_leaves[-1]
        for indicator in inspect(self).indicators():
            detach(indicator, self)
            direction = getattr(indicator, "_time_orientation", enums.Left)
            if direction is enums.Left:
                attach(indicator, first_result_leaf)
            elif direction == enums.Right:
                attach(indicator, last_result_leaf)
            else:
                raise ValueError(direction)
        # reattach grace containers
        if before_grace_container is not None:
            attach(before_grace_container, first_result_leaf)
        if after_grace_container is not None:
            attach(after_grace_container, last_result_leaf)
        # fuse tuplets
        if isinstance(result_components[0], Tuplet):
            mutate(result_components).fuse()
        # tie split notes
        if isinstance(self, (Note, Chord)) and 1 < len(result_leaves):
            result_leaves._attach_tie_to_leaves()
        if originally_repeat_tied and not inspect(
                result_leaves[0]).has_indicator(RepeatTie):
            attach(RepeatTie(), result_leaves[0])
        if originally_tied and not inspect(
                result_leaves[-1]).has_indicator(Tie):
            attach(Tie(), result_leaves[-1])
        assert isinstance(result_leaves, Selection)
        assert all(isinstance(_, Leaf) for _ in result_leaves)
        return result_leaves
Пример #13
0
 def _move_indicators(self, recipient_component):
     for wrapper in inspect(self).wrappers():
         detach(wrapper, self)
         attach(wrapper, recipient_component)
Пример #14
0
    def _split_by_durations(
        self, durations, cyclic=False, tie_split_notes=True, repeat_ties=False
    ):
        from .AfterGraceContainer import AfterGraceContainer
        from .Chord import Chord
        from .GraceContainer import GraceContainer
        from .Note import Note
        from .Selection import Selection
        from .Tuplet import Tuplet

        durations = [Duration(_) for _ in durations]
        durations = Sequence(durations)
        leaf_duration = inspect(self).duration()
        if cyclic:
            durations = durations.repeat_to_weight(leaf_duration)
        if sum(durations) < leaf_duration:
            last_duration = leaf_duration - sum(durations)
            durations = list(durations)
            durations.append(last_duration)
            durations = Sequence(durations)
        durations = durations.truncate(weight=leaf_duration)
        originally_tied = inspect(self).has_indicator(TieIndicator)
        originally_repeat_tied = inspect(self).has_indicator(RepeatTie)
        result_selections = []
        grace_container = self._detach_grace_container()
        after_grace_container = self._detach_after_grace_container()
        leaf_prolation = inspect(self).parentage().prolation
        for duration in durations:
            new_leaf = copy.copy(self)
            preprolated_duration = duration / leaf_prolation
            selection = new_leaf._set_duration(
                preprolated_duration, repeat_ties=repeat_ties
            )
            result_selections.append(selection)
        result_components = Sequence(result_selections).flatten(depth=-1)
        result_components = select(result_components)
        result_leaves = select(result_components).leaves(grace_notes=False)
        assert all(isinstance(_, Selection) for _ in result_selections)
        assert all(isinstance(_, Component) for _ in result_components)
        assert result_leaves.are_leaves()
        #        for leaf in result_leaves:
        #            detach(Tie, leaf)
        # strip result leaves of all indicators
        for leaf in result_leaves:
            detach(object, leaf)
        # replace leaf with flattened result
        if self._parent is not None:
            mutate(self).replace(result_components)
        # move indicators
        first_result_leaf = result_leaves[0]
        last_result_leaf = result_leaves[-1]
        for indicator in inspect(self).indicators():
            detach(indicator, self)
            direction = getattr(indicator, "_time_orientation", enums.Left)
            if direction is enums.Left:
                attach(indicator, first_result_leaf)
            elif direction == enums.Right:
                attach(indicator, last_result_leaf)
            else:
                raise ValueError(direction)
        # move grace containers
        if grace_container is not None:
            container = grace_container[0]
            assert isinstance(container, GraceContainer), repr(container)
            attach(container, first_result_leaf)
        if after_grace_container is not None:
            container = after_grace_container[0]
            prototype = AfterGraceContainer
            assert isinstance(container, prototype), repr(container)
            attach(container, last_result_leaf)
        if isinstance(result_components[0], Tuplet):
            mutate(result_components).fuse()
        # tie split notes
        if (
            tie_split_notes
            and isinstance(self, (Note, Chord))
            and 1 < len(result_leaves)
        ):
            result_leaves._attach_tie_to_leaves(repeat_ties=repeat_ties)
        # assert not inspect(result_leaves[0]).has_indicator(RepeatTie)
        detach(RepeatTie, result_leaves[0])
        # assert not inspect(result_leaves[-1]).has_indicator(TieIndicator)
        detach(TieIndicator, result_leaves[-1])
        if originally_repeat_tied:
            tie = RepeatTie()
            attach(tie, result_leaves[0])
        if originally_tied:
            tie = TieIndicator()
            attach(tie, result_leaves[-1])
        assert isinstance(result_leaves, Selection)
        assert all(isinstance(_, Leaf) for _ in result_leaves)
        return result_leaves
Пример #15
0
 def _detach_grace_container(self):
     if self._grace_container is not None:
         return detach(self._grace_container, self)