コード例 #1
0
ファイル: UpdateManager.py プロジェクト: thomasmarsh/abjad
 def _get_measure_start_offsets(self, component):
     wrappers = []
     prototype = TimeSignature
     root = abjad_inspect(component).parentage().root
     for component_ in self._iterate_entire_score(root):
         wrappers_ = abjad_inspect(component_).wrappers(prototype)
         wrappers.extend(wrappers_)
     pairs = []
     for wrapper in wrappers:
         component = wrapper.component
         start_offset = abjad_inspect(component).timespan().start_offset
         time_signature = wrapper.indicator
         pair = start_offset, time_signature
         pairs.append(pair)
     offset_zero = Offset(0)
     default_time_signature = TimeSignature((4, 4))
     default_pair = (offset_zero, default_time_signature)
     if pairs and not pairs[0] == offset_zero:
         pairs.insert(0, default_pair)
     elif not pairs:
         pairs = [default_pair]
     pairs.sort(key=lambda x: x[0])
     score_stop_offset = abjad_inspect(root).timespan().stop_offset
     dummy_last_pair = (score_stop_offset, None)
     pairs.append(dummy_last_pair)
     measure_start_offsets = []
     for current_pair, next_pair in Sequence(pairs).nwise():
         current_start_offset, current_time_signature = current_pair
         next_start_offset, next_time_signature = next_pair
         measure_start_offset = current_start_offset
         while measure_start_offset < next_start_offset:
             measure_start_offsets.append(measure_start_offset)
             measure_start_offset += current_time_signature.duration
     return measure_start_offsets
コード例 #2
0
    def _attach_lilypond_one_voice(self):
        from .Voice import Voice

        anchor_leaf = self._get_on_beat_anchor_leaf()
        anchor_voice = abjad_inspect(anchor_leaf).parentage().get(Voice)
        final_anchor_leaf = abjad_inspect(anchor_voice).leaf(-1)
        next_leaf = abjad_inspect(final_anchor_leaf).leaf(1)
        literal = LilyPondLiteral(r"\oneVoice")
        if abjad_inspect(next_leaf).has_indicator(literal):
            return
        site = "abjad.OnBeatGraceContainer._attach_lilypond_one_voice()"
        tag = Tag(site)
        attach(literal, next_leaf, tag=tag)
コード例 #3
0
ファイル: UpdateManager.py プロジェクト: thomasmarsh/abjad
 def _get_before_grace_leaf_offsets(leaf):
     container = leaf._parent
     main_leaf = container._main_leaf
     main_leaf_start_offset = main_leaf._start_offset
     assert main_leaf_start_offset is not None
     displacement = -abjad_inspect(leaf).duration()
     sibling = leaf._sibling(1)
     while sibling is not None and sibling._parent is container:
         displacement -= abjad_inspect(sibling).duration()
         sibling = sibling._sibling(1)
     start_offset = Offset(main_leaf_start_offset,
                           displacement=displacement)
     displacement += abjad_inspect(leaf).duration()
     stop_offset = Offset(main_leaf_start_offset, displacement=displacement)
     return start_offset, stop_offset
コード例 #4
0
ファイル: UpdateManager.py プロジェクト: thomasmarsh/abjad
 def _update_now(
     self,
     component,
     offsets=False,
     offsets_in_seconds=False,
     indicators=False,
 ):
     assert offsets or offsets_in_seconds or indicators
     if component._is_forbidden_to_update:
         return
     parentage = abjad_inspect(component).parentage()
     for parent in parentage:
         if parent._is_forbidden_to_update:
             return
         (
             offsets_are_current,
             indicators_are_current,
             offsets_in_seconds_are_current,
         ) = self._get_score_tree_state_flags(parentage)
     root = parentage.root
     if offsets and not offsets_are_current:
         self._update_all_offsets(root)
     if offsets_in_seconds and not offsets_in_seconds_are_current:
         self._update_all_offsets_in_seconds(root)
     if indicators and not indicators_are_current:
         self._update_all_indicators(root)
コード例 #5
0
ファイル: UpdateManager.py プロジェクト: thomasmarsh/abjad
 def _update_measure_numbers(self, component):
     measure_start_offsets = self._get_measure_start_offsets(component)
     root = abjad_inspect(component).parentage().root
     for component in self._iterate_entire_score(root):
         measure_number = self._to_measure_number(component,
                                                  measure_start_offsets)
         component._measure_number = measure_number
コード例 #6
0
 def _set_leaf_durations(self):
     if self.leaf_duration is None:
         return
     for leaf in select(self).leaves():
         duration = abjad_inspect(leaf).duration()
         if duration != self.leaf_duration:
             multiplier = self.leaf_duration / duration
             leaf.multiplier = multiplier
コード例 #7
0
    def _attach_lilypond_one_voice(self):
        from .Voice import Voice

        anchor_leaf = self._get_on_beat_anchor_leaf()
        anchor_voice = abjad_inspect(anchor_leaf).parentage().get(Voice)
        final_anchor_leaf = abjad_inspect(anchor_voice).leaf(-1)
        next_leaf = abjad_inspect(final_anchor_leaf).leaf(1)
        literal = LilyPondLiteral(r"\oneVoice", format_slot="absolute_before")
        if abjad_inspect(next_leaf).has_indicator(literal):
            return
        if isinstance(next_leaf._parent, OnBeatGraceContainer):
            return
        if next_leaf._parent._is_on_beat_anchor_voice():
            return
        site = "abjad.OnBeatGraceContainer._attach_lilypond_one_voice()"
        tag = Tag(site)
        tag = tag.append(abjad_tags.ONE_VOICE_COMMAND)
        attach(literal, next_leaf, tag=tag)
コード例 #8
0
ファイル: UpdateManager.py プロジェクト: thomasmarsh/abjad
 def _get_on_beat_grace_leaf_offsets(leaf):
     container = leaf._parent
     anchor_leaf = container._get_on_beat_anchor_leaf()
     anchor_leaf_start_offset = anchor_leaf._start_offset
     assert anchor_leaf_start_offset is not None
     anchor_leaf_start_offset = Offset(anchor_leaf_start_offset.pair)
     start_displacement = Duration(0)
     sibling = leaf._sibling(-1)
     while sibling is not None and sibling._parent is container:
         start_displacement += abjad_inspect(sibling).duration()
         sibling = sibling._sibling(-1)
     stop_displacement = start_displacement + abjad_inspect(leaf).duration()
     if start_displacement == 0:
         start_displacement = None
     start_offset = Offset(anchor_leaf_start_offset.pair,
                           displacement=start_displacement)
     stop_offset = Offset(anchor_leaf_start_offset.pair,
                          displacement=stop_displacement)
     return start_offset, stop_offset
コード例 #9
0
ファイル: UpdateManager.py プロジェクト: thomasmarsh/abjad
 def _update_all_indicators(self, root):
     """
     Updating indicators does not update offsets.
     On the other hand, getting an effective indicator does update
     offsets when at least one indicator of the appropriate type
     attaches to score.
     """
     components = self._iterate_entire_score(root)
     for component in components:
         for wrapper in abjad_inspect(component).wrappers():
             if wrapper.context is not None:
                 wrapper._update_effective_context()
         component._indicators_are_current = True
コード例 #10
0
ファイル: UpdateManager.py プロジェクト: thomasmarsh/abjad
 def _get_after_grace_leaf_offsets(leaf):
     container = leaf._parent
     main_leaf = container._main_leaf
     main_leaf_stop_offset = main_leaf._stop_offset
     assert main_leaf_stop_offset is not None
     displacement = -abjad_inspect(leaf).duration()
     sibling = leaf._sibling(1)
     while sibling is not None and sibling._parent is container:
         displacement -= abjad_inspect(sibling).duration()
         sibling = sibling._sibling(1)
     if leaf._parent is not None and leaf._parent._main_leaf is not None:
         main_leaf = leaf._parent._main_leaf
         sibling = main_leaf._sibling(1)
         if (sibling is not None
                 and hasattr(sibling, "_before_grace_container")
                 and sibling._before_grace_container is not None):
             before_grace_container = sibling._before_grace_container
             duration = abjad_inspect(before_grace_container).duration()
             displacement -= duration
     start_offset = Offset(main_leaf_stop_offset, displacement=displacement)
     displacement += abjad_inspect(leaf).duration()
     stop_offset = Offset(main_leaf_stop_offset, displacement=displacement)
     return start_offset, stop_offset
コード例 #11
0
    def _match_anchor_leaf(self):
        from .Chord import Chord
        from .Note import Note

        first_grace = abjad_inspect(self).leaf(0)
        if not isinstance(first_grace, (Note, Chord)):
            message = f"must start with note or chord:\n"
            message += f"    {repr(self)}"
            raise Exception(message)
        anchor_leaf = self._get_on_beat_anchor_leaf()
        if isinstance(anchor_leaf,
                      (Note, Chord)) and isinstance(first_grace,
                                                    (Note, Chord)):
            if isinstance(first_grace, Note):
                chord = Chord(first_grace)
                mutate(first_grace).replace(chord)
                first_grace = chord
            anchor_pitches = abjad_inspect(anchor_leaf).pitches()
            highest_pitch = list(sorted(anchor_pitches))[-1]
            if highest_pitch not in first_grace.note_heads:
                first_grace.note_heads.append(highest_pitch)
            grace_mate_head = first_grace.note_heads.get(highest_pitch)
            tweak(grace_mate_head).font_size = 0
            tweak(grace_mate_head).transparent = True
コード例 #12
0
ファイル: UpdateManager.py プロジェクト: thomasmarsh/abjad
 def _to_measure_number(self, component, measure_start_offsets):
     component_start_offset = (
         abjad_inspect(component).timespan().start_offset)
     displacement = component_start_offset.displacement
     if displacement is not None:
         component_start_offset = Offset(component_start_offset,
                                         displacement=None)
         # score-initial grace music only:
         if displacement < 0 and component_start_offset == 0:
             measure_number = 0
             return measure_number
     measure_start_offsets = measure_start_offsets[:]
     measure_start_offsets.append(mathtools.Infinity())
     pairs = Sequence(measure_start_offsets)
     pairs = pairs.nwise()
     for measure_index, pair in enumerate(pairs):
         if pair[0] <= component_start_offset < pair[-1]:
             measure_number = measure_index + 1
             return measure_number
     message = f"can not find measure number for {repr(component)}:\n"
     message += f"   {repr(measure_start_offsets)}"
     raise ValueError(message)
コード例 #13
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
コード例 #14
0
ファイル: UpdateManager.py プロジェクト: thomasmarsh/abjad
    def _update_component_offsets(class_, component):
        from abjad.core.AfterGraceContainer import AfterGraceContainer
        from abjad.core.BeforeGraceContainer import BeforeGraceContainer
        from abjad.core.OnBeatGraceContainer import OnBeatGraceContainer

        if isinstance(component, BeforeGraceContainer):
            pair = class_._get_before_grace_leaf_offsets(component[0])
            start_offset = pair[0]
            pair = class_._get_before_grace_leaf_offsets(component[-1])
            stop_offset = pair[-1]
        elif isinstance(component._parent, BeforeGraceContainer):
            pair = class_._get_before_grace_leaf_offsets(component)
            start_offset, stop_offset = pair
        elif isinstance(component, OnBeatGraceContainer):
            pair = class_._get_on_beat_grace_leaf_offsets(component[0])
            start_offset = pair[0]
            pair = class_._get_on_beat_grace_leaf_offsets(component[-1])
            stop_offset = pair[-1]
        elif isinstance(component._parent, OnBeatGraceContainer):
            pair = class_._get_on_beat_grace_leaf_offsets(component)
            start_offset, stop_offset = pair
        elif isinstance(component, AfterGraceContainer):
            pair = class_._get_after_grace_leaf_offsets(component[0])
            start_offset = pair[0]
            pair = class_._get_after_grace_leaf_offsets(component[-1])
            stop_offset = pair[-1]
        elif isinstance(component._parent, AfterGraceContainer):
            pair = class_._get_after_grace_leaf_offsets(component)
            start_offset, stop_offset = pair
        else:
            previous = component._sibling(-1)
            if previous is not None:
                start_offset = previous._stop_offset
            else:
                start_offset = Offset(0)
            # on-beat anchor leaf:
            if (component._parent is not None
                    and component._parent._is_on_beat_anchor_voice()
                    and component is component._parent[0]):
                anchor_voice = component._parent
                assert anchor_voice._is_on_beat_anchor_voice()
                on_beat_grace_container = None
                on_beat_wrapper = anchor_voice._parent
                assert on_beat_wrapper._is_on_beat_wrapper()
                index = on_beat_wrapper.index(anchor_voice)
                if index == 0:
                    on_beat_grace_container = on_beat_wrapper[1]
                else:
                    on_beat_grace_container = on_beat_wrapper[0]
                if on_beat_grace_container is not None:
                    durations = [
                        abjad_inspect(_).duration()
                        for _ in on_beat_grace_container
                    ]
                    start_displacement = sum(durations)
                    start_offset = Offset(start_offset,
                                          displacement=start_displacement)
            stop_offset = start_offset + component._get_duration()
        component._start_offset = start_offset
        component._stop_offset = stop_offset
        component._timespan._start_offset = start_offset
        component._timespan._stop_offset = stop_offset
コード例 #15
0
ファイル: LilyPondFile.py プロジェクト: tuchang/abjad
    def rhythm(
        class_,
        selections,
        divisions=None,
        attach_lilypond_voice_commands=None,
        implicit_scaling=None,
        pitched_staff=None,
        simultaneous_selections=None,
        time_signatures=None,
    ):
        r"""
        Makes rhythm-styled LilyPond file.

        ..  container:: example

            Makes rhythmic staff:

            >>> divisions = [(3, 4), (4, 8), (1, 4)]
            >>> maker = abjad.NoteMaker()
            >>> selections = [
            ...     maker(6 * [0], [(1, 8)]),
            ...     maker(8 * [0], [(1, 16)]),
            ...     maker(2 * [0], [(1, 8)]),
            ...     ]
            >>> for selection in selections:
            ...     abjad.beam(selection[:])
            ...
            >>> lilypond_file = abjad.LilyPondFile.rhythm(
            ...     selections,
            ...     divisions,
            ...     )
            >>> abjad.show(lilypond_file) # doctest: +SKIP

            ..  docs::

                >>> score = lilypond_file[abjad.Score]
                >>> abjad.f(score)
                \new Score
                <<
                    \new GlobalContext
                    {
                        \time 3/4
                        s1 * 3/4
                        \time 4/8
                        s1 * 1/2
                        \time 1/4
                        s1 * 1/4
                    }
                    \new RhythmicStaff
                    {
                        c'8
                        [
                        c'8
                        c'8
                        c'8
                        c'8
                        c'8
                        ]
                        c'16
                        [
                        c'16
                        c'16
                        c'16
                        c'16
                        c'16
                        c'16
                        c'16
                        ]
                        c'8
                        [
                        c'8
                        ]
                    }
                >>

        ..  container:: example

            Set time signatures explicitly:

            >>> divisions = [(3, 4), (4, 8), (1, 4)]
            >>> maker = abjad.NoteMaker()
            >>> selections = [
            ...     maker(6 * [0], [(1, 8)]),
            ...     maker(8 * [0], [(1, 16)]),
            ...     maker(2 * [0], [(1, 8)]),
            ...     ]
            >>> for selection in selections:
            ...     abjad.beam(selection[:])
            ...
            >>> lilypond_file = abjad.LilyPondFile.rhythm(
            ...     selections,
            ...     [(6, 8), (4, 8), (2, 8)],
            ...     )
            >>> abjad.show(lilypond_file) # doctest: +SKIP

            ..  docs::

                >>> score = lilypond_file[abjad.Score]
                >>> abjad.f(score)
                \new Score
                <<
                    \new GlobalContext
                    {
                        \time 6/8
                        s1 * 3/4
                        \time 4/8
                        s1 * 1/2
                        \time 2/8
                        s1 * 1/4
                    }
                    \new RhythmicStaff
                    {
                        c'8
                        [
                        c'8
                        c'8
                        c'8
                        c'8
                        c'8
                        ]
                        c'16
                        [
                        c'16
                        c'16
                        c'16
                        c'16
                        c'16
                        c'16
                        c'16
                        ]
                        c'8
                        [
                        c'8
                        ]
                    }
                >>

        ..  container:: example

            Makes pitched staff:

            >>> divisions = [(3, 4), (4, 8), (1, 4)]
            >>> maker = abjad.NoteMaker()
            >>> selections = [
            ...     maker(6 * [0], [(1, 8)]),
            ...     maker(8 * [0], [(1, 16)]),
            ...     maker(2 * [0], [(1, 8)]),
            ...     ]
            >>> for selection in selections:
            ...     abjad.beam(selection[:])
            ...
            >>> lilypond_file = abjad.LilyPondFile.rhythm(
            ...     selections,
            ...     divisions,
            ...     pitched_staff=True,
            ...     )
            >>> abjad.show(lilypond_file) # doctest: +SKIP

            ..  docs::

                >>> abjad.f(lilypond_file[abjad.Score])
                \new Score
                <<
                    \new GlobalContext
                    {
                        \time 3/4
                        s1 * 3/4
                        \time 4/8
                        s1 * 1/2
                        \time 1/4
                        s1 * 1/4
                    }
                    \new Staff
                    {
                        c'8
                        [
                        c'8
                        c'8
                        c'8
                        c'8
                        c'8
                        ]
                        c'16
                        [
                        c'16
                        c'16
                        c'16
                        c'16
                        c'16
                        c'16
                        c'16
                        ]
                        c'8
                        [
                        c'8
                        ]
                    }
                >>

        ..  container:: example

            Makes simultaneous voices:

            >>> divisions = [(3, 4), (4, 8), (1, 4)]
            >>> maker = abjad.NoteMaker()
            >>> selections = [
            ...     maker(6 * [0], [(1, 8)]),
            ...     maker(8 * [0], [(1, 16)]),
            ...     maker(2 * [0], [(1, 8)]),
            ...     ]
            >>> for selection in selections:
            ...     abjad.beam(selection[:])
            ...
            >>> for note in abjad.iterate(selections).components(abjad.Note):
            ...     note.written_pitch = abjad.NamedPitch("e'")
            ...
            >>> selection_1 = selections[0] + selections[1] + selections[2]
            >>> selections = [
            ...     maker(12 * [0], [(1, 16)]),
            ...     maker(16 * [0], [(1, 32)]),
            ...     maker(4 * [0], [(1, 16)]),
            ...     ]
            >>> for selection in selections:
            ...     abjad.beam(selection[:])
            ...
            >>> selection_2 = selections[0] + selections[1] + selections[2]
            >>> selections = {
            ...     'Voice_1': selection_1,
            ...     'Voice_2': selection_2,
            ... }
            >>> lilypond_file = abjad.LilyPondFile.rhythm(
            ...     selections,
            ...     divisions,
            ...     )
            >>> voice_1 = lilypond_file['Voice_1']
            >>> literal = abjad.LilyPondLiteral(r'\voiceOne', "opening")
            >>> abjad.attach(literal, voice_1)
            >>> voice_2 = lilypond_file['Voice_2']
            >>> literal = abjad.LilyPondLiteral(r'\voiceTwo', "opening")
            >>> abjad.attach(literal, voice_2)
            >>> abjad.show(lilypond_file) # doctest: +SKIP

            ..  docs::

                >>> abjad.f(lilypond_file[abjad.Score])
                \new Score
                <<
                    \new GlobalContext
                    {
                        s1 * 3/4
                        s1 * 1/2
                        s1 * 1/4
                    }
                    \new Staff
                    <<
                        \context Voice = "Voice_1"
                        {
                            \voiceOne
                            e'8
                            [
                            e'8
                            e'8
                            e'8
                            e'8
                            e'8
                            ]
                            e'16
                            [
                            e'16
                            e'16
                            e'16
                            e'16
                            e'16
                            e'16
                            e'16
                            ]
                            e'8
                            [
                            e'8
                            ]
                        }
                        \context Voice = "Voice_2"
                        {
                            \voiceTwo
                            c'16
                            [
                            c'16
                            c'16
                            c'16
                            c'16
                            c'16
                            c'16
                            c'16
                            c'16
                            c'16
                            c'16
                            c'16
                            ]
                            c'32
                            [
                            c'32
                            c'32
                            c'32
                            c'32
                            c'32
                            c'32
                            c'32
                            c'32
                            c'32
                            c'32
                            c'32
                            c'32
                            c'32
                            c'32
                            c'32
                            ]
                            c'16
                            [
                            c'16
                            c'16
                            c'16
                            ]
                        }
                    >>
                >>

        Returns LilyPond file.
        """
        if isinstance(selections, Selection):
            pass
        elif isinstance(selections, list):
            for selection in selections:
                if not isinstance(selection, Selection):
                    raise TypeError(f"must be selection: {selection!r}.")
        elif isinstance(selections, dict):
            for selection in selections.values():
                if not isinstance(selection, Selection):
                    raise TypeError(f"must be selection: {selection!r}.")
        else:
            raise TypeError(f"must be list or dictionary: {selections!r}.")
        score = Score()
        lilypond_file = LilyPondFile.new(
            score, includes=["default.ily", "rhythm-maker-docs.ily"]
        )
        if pitched_staff is None:
            if isinstance(selections, (list, Selection)):
                selections_ = selections
            elif isinstance(selections, dict):
                selections_ = selections.values()
            else:
                raise TypeError(selections)
            for note in select(selections_).notes():
                if note.written_pitch != NamedPitch("c'"):
                    pitched_staff = True
                    break
            chords = select(selections_).chords()
            if chords:
                pitched_staff = True
        if isinstance(selections, (list, Selection)):
            if divisions is None:
                duration = abjad_inspect(selections).duration()
                divisions = [duration]
            time_signatures = time_signatures or divisions
            time_signatures = [TimeSignature(_) for _ in time_signatures]
            if pitched_staff:
                staff = Staff()
            else:
                staff = Staff(lilypond_type="RhythmicStaff")
            staff.extend(selections)
        elif isinstance(selections, dict):
            voices = []
            for voice_name in sorted(selections):
                selections_ = selections[voice_name]
                selections_ = sequence(selections_).flatten(depth=-1)
                selections_ = copy.deepcopy(selections_)
                voice = Voice(selections_, name=voice_name)
                if attach_lilypond_voice_commands:
                    voice_name_to_command_string = {
                        "Voice_1": "voiceOne",
                        "Voice_2": "voiceTwo",
                        "Voice_3": "voiceThree",
                        "Voice_4": "voiceFour",
                    }
                    command_string = voice_name_to_command_string.get(voice_name)
                    if command_string:
                        command = LilyPondLiteral("\\" + command_string)
                        attach(command, voice)
                voices.append(voice)
            staff = Staff(voices, simultaneous=True)
            if divisions is None:
                duration = abjad_inspect(staff).duration()
                divisions = [duration]
        else:
            message = "must be list or dictionary of selections:"
            message += f" {selections!r}."
            raise TypeError(message)
        score.append(staff)
        assert isinstance(divisions, collections.abc.Sequence), repr(divisions)
        time_signatures = time_signatures or divisions
        context = Context(lilypond_type="GlobalContext")
        skips = []
        for time_signature in time_signatures:
            skip = Skip(1)
            skip.multiplier = time_signature
            attach(time_signature, skip, context="Score")
            skips.append(skip)
        context.extend(skips)
        score.insert(0, context)
        return lilypond_file
コード例 #16
0
    def rhythm(
        class_,
        selections,
        divisions=None,
        attach_lilypond_voice_commands=None,
        implicit_scaling=None,
        pitched_staff=None,
        simultaneous_selections=None,
        time_signatures=None,
        ):
        r"""
        Makes rhythm-styled LilyPond file.

        ..  container:: example

            Makes rhythmic staff:

            >>> divisions = [(3, 4), (4, 8), (1, 4)]
            >>> maker = abjad.NoteMaker()
            >>> selections = [
            ...     maker(6 * [0], [(1, 8)]),
            ...     maker(8 * [0], [(1, 16)]),
            ...     maker(2 * [0], [(1, 8)]),
            ...     ]
            >>> for selection in selections:
            ...     abjad.attach(abjad.Beam(), selection[:])
            ...
            >>> lilypond_file = abjad.LilyPondFile.rhythm(
            ...     selections,
            ...     divisions,
            ...     )
            >>> abjad.show(lilypond_file) # doctest: +SKIP

            ..  docs::

                >>> score = lilypond_file[abjad.Score]
                >>> abjad.f(score)
                \new Score
                <<
                    \new GlobalContext
                    {
                        {   % measure
                            \time 3/4
                            s1 * 3/4
                        }   % measure
                        {   % measure
                            \time 4/8
                            s1 * 1/2
                        }   % measure
                        {   % measure
                            \time 1/4
                            s1 * 1/4
                        }   % measure
                    }
                    \new RhythmicStaff
                    {
                        {   % measure
                            \time 3/4
                            c'8
                            [
                            c'8
                            c'8
                            c'8
                            c'8
                            c'8
                            ]
                        }   % measure
                        {   % measure
                            \time 4/8
                            c'16
                            [
                            c'16
                            c'16
                            c'16
                            c'16
                            c'16
                            c'16
                            c'16
                            ]
                        }   % measure
                        {   % measure
                            \time 1/4
                            c'8
                            [
                            c'8
                            ]
                        }   % measure
                    }
                >>

        ..  container:: example

            Set time signatures explicitly:

            >>> divisions = [(3, 4), (4, 8), (1, 4)]
            >>> maker = abjad.NoteMaker()
            >>> selections = [
            ...     maker(6 * [0], [(1, 8)]),
            ...     maker(8 * [0], [(1, 16)]),
            ...     maker(2 * [0], [(1, 8)]),
            ...     ]
            >>> for selection in selections:
            ...     abjad.attach(abjad.Beam(), selection[:])
            ...
            >>> lilypond_file = abjad.LilyPondFile.rhythm(
            ...     selections,
            ...     [(6, 8), (4, 8), (2, 8)],
            ...     )
            >>> abjad.show(lilypond_file) # doctest: +SKIP

            ..  docs::

                >>> score = lilypond_file[abjad.Score]
                >>> abjad.f(score)
                \new Score
                <<
                    \new GlobalContext
                    {
                        {   % measure
                            \time 6/8
                            s1 * 3/4
                        }   % measure
                        {   % measure
                            \time 4/8
                            s1 * 1/2
                        }   % measure
                        {   % measure
                            \time 2/8
                            s1 * 1/4
                        }   % measure
                    }
                    \new RhythmicStaff
                    {
                        {   % measure
                            \time 6/8
                            c'8
                            [
                            c'8
                            c'8
                            c'8
                            c'8
                            c'8
                            ]
                        }   % measure
                        {   % measure
                            \time 4/8
                            c'16
                            [
                            c'16
                            c'16
                            c'16
                            c'16
                            c'16
                            c'16
                            c'16
                            ]
                        }   % measure
                        {   % measure
                            \time 2/8
                            c'8
                            [
                            c'8
                            ]
                        }   % measure
                    }
                >>

        ..  container:: example

            Makes pitched staff:

            >>> divisions = [(3, 4), (4, 8), (1, 4)]
            >>> maker = abjad.NoteMaker()
            >>> selections = [
            ...     maker(6 * [0], [(1, 8)]),
            ...     maker(8 * [0], [(1, 16)]),
            ...     maker(2 * [0], [(1, 8)]),
            ...     ]
            >>> for selection in selections:
            ...     abjad.attach(abjad.Beam(), selection[:])
            ...
            >>> lilypond_file = abjad.LilyPondFile.rhythm(
            ...     selections,
            ...     divisions,
            ...     pitched_staff=True,
            ...     )
            >>> abjad.show(lilypond_file) # doctest: +SKIP

            ..  docs::

                >>> abjad.f(lilypond_file[abjad.Score])
                \new Score
                <<
                    \new GlobalContext
                    {
                        {   % measure
                            \time 3/4
                            s1 * 3/4
                        }   % measure
                        {   % measure
                            \time 4/8
                            s1 * 1/2
                        }   % measure
                        {   % measure
                            \time 1/4
                            s1 * 1/4
                        }   % measure
                    }
                    \new Staff
                    {
                        {   % measure
                            \time 3/4
                            c'8
                            [
                            c'8
                            c'8
                            c'8
                            c'8
                            c'8
                            ]
                        }   % measure
                        {   % measure
                            \time 4/8
                            c'16
                            [
                            c'16
                            c'16
                            c'16
                            c'16
                            c'16
                            c'16
                            c'16
                            ]
                        }   % measure
                        {   % measure
                            \time 1/4
                            c'8
                            [
                            c'8
                            ]
                        }   % measure
                    }
                >>

        ..  container:: example

            Makes simultaneous voices:

            >>> divisions = [(3, 4), (4, 8), (1, 4)]
            >>> maker = abjad.NoteMaker()
            >>> selections = [
            ...     maker(6 * [0], [(1, 8)]),
            ...     maker(8 * [0], [(1, 16)]),
            ...     maker(2 * [0], [(1, 8)]),
            ...     ]
            >>> for selection in selections:
            ...     abjad.attach(abjad.Beam(), selection[:])
            ...
            >>> for note in abjad.iterate(selections).components(abjad.Note):
            ...     note.written_pitch = abjad.NamedPitch("e'")
            ...
            >>> selection_1 = selections[0] + selections[1] + selections[2]
            >>> selections = [
            ...     maker(12 * [0], [(1, 16)]),
            ...     maker(16 * [0], [(1, 32)]),
            ...     maker(4 * [0], [(1, 16)]),
            ...     ]
            >>> for selection in selections:
            ...     abjad.attach(abjad.Beam(), selection[:])
            ...
            >>> selection_2 = selections[0] + selections[1] + selections[2]
            >>> selections = {
            ...     'Voice 1': selection_1,
            ...     'Voice 2': selection_2,
            ... }
            >>> lilypond_file = abjad.LilyPondFile.rhythm(
            ...     selections,
            ...     divisions,
            ...     )
            >>> voice_1 = lilypond_file['Voice 1']
            >>> abjad.attach(abjad.LilyPondLiteral(r'\voiceOne'), voice_1)
            >>> voice_2 = lilypond_file['Voice 2']
            >>> abjad.attach(abjad.LilyPondLiteral(r'\voiceTwo'), voice_2)
            >>> abjad.show(lilypond_file) # doctest: +SKIP

            ..  docs::

                >>> abjad.f(lilypond_file[abjad.Score])
                \new Score
                <<
                    \new GlobalContext
                    {
                        {   % measure
                            \time 3/4
                            s1 * 3/4
                        }   % measure
                        {   % measure
                            \time 4/8
                            s1 * 1/2
                        }   % measure
                        {   % measure
                            \time 1/4
                            s1 * 1/4
                        }   % measure
                    }
                    \new Staff
                    <<
                        \context Voice = "Voice 1"
                        {
                            \voiceOne
                            e'8
                            [
                            e'8
                            e'8
                            e'8
                            e'8
                            e'8
                            ]
                            e'16
                            [
                            e'16
                            e'16
                            e'16
                            e'16
                            e'16
                            e'16
                            e'16
                            ]
                            e'8
                            [
                            e'8
                            ]
                        }
                        \context Voice = "Voice 2"
                        {
                            \voiceTwo
                            c'16
                            [
                            c'16
                            c'16
                            c'16
                            c'16
                            c'16
                            c'16
                            c'16
                            c'16
                            c'16
                            c'16
                            c'16
                            ]
                            c'32
                            [
                            c'32
                            c'32
                            c'32
                            c'32
                            c'32
                            c'32
                            c'32
                            c'32
                            c'32
                            c'32
                            c'32
                            c'32
                            c'32
                            c'32
                            c'32
                            ]
                            c'16
                            [
                            c'16
                            c'16
                            c'16
                            ]
                        }
                    >>
                >>

        Returns LilyPond file.
        """
        if isinstance(selections, list):
            for selection in selections:
                if not isinstance(selection, Selection):
                    message = f'must be selection: {selection!r}.'
                    raise TypeError(message)
        elif isinstance(selections, dict):
            for selection in selections.values():
                if not isinstance(selection, Selection):
                    message = f'must be selection: {selection!r}.'
                    raise TypeError(message)
        else:
            message = f'must be list or dictionary: {selections!r}.'
            raise TypeError(message)
        score = Score()
        lilypond_file = LilyPondFile.new(
            score,
            includes=['default.ily', 'rhythm-maker-docs.ily'],
            )
        if pitched_staff is None:
            if isinstance(selections, list):
                selections_ = selections
            elif isinstance(selections, dict):
                selections_ = selections.values()
            else:
                raise TypeError(selections)
            for note in iterate(selections_).leaves(Note):
                if note.written_pitch != NamedPitch("c'"):
                    pitched_staff = True
                    break
        if isinstance(selections, list):
            if divisions is None:
                duration = abjad_inspect(selections).duration()
                divisions = [duration]
            time_signatures = time_signatures or divisions
            maker = MeasureMaker(implicit_scaling=implicit_scaling)
            measures = maker(time_signatures)
            if pitched_staff:
                staff = Staff(measures)
            else:
                staff = Staff(measures, lilypond_type='RhythmicStaff')
            selections = sequence(selections).flatten(depth=-1)
            selections_ = copy.deepcopy(selections)
            try:
                agent = mutate(staff)
                measures = agent.replace_measure_contents(selections)
            except StopIteration:
                if pitched_staff:
                    staff = Staff(selections_)
                else:
                    staff = Staff(
                        selections_,
                        lilypond_type='RhythmicStaff',
                        )
        elif isinstance(selections, dict):
            voices = []
            for voice_name in sorted(selections):
                selections_ = selections[voice_name]
                selections_ = sequence(selections_).flatten(depth=-1)
                selections_ = copy.deepcopy(selections_)
                voice = Voice(selections_, name=voice_name)
                if attach_lilypond_voice_commands:
                    voice_name_to_command_string = {
                        'Voice 1': 'voiceOne',
                        'Voice 2': 'voiceTwo',
                        'Voice 3': 'voiceThree',
                        'Voice 4': 'voiceFour',
                        }
                    command_string = voice_name_to_command_string.get(
                        voice_name,
                        )
                    if command_string:
                        command = LilyPondLiteral('\\' + command_string)
                        attach(command, voice)
                voices.append(voice)
            staff = Staff(voices, is_simultaneous=True)
            if divisions is None:
                duration = abjad_inspect(staff).duration()
                divisions = [duration]
        else:
            message = 'must be list or dictionary of selections:'
            message += f' {selections!r}.'
            raise TypeError(message)
        score.append(staff)
        assert isinstance(divisions, collections.Sequence), repr(divisions)
        time_signatures = time_signatures or divisions
        context = Context(lilypond_type='GlobalContext')
        maker = MeasureMaker(implicit_scaling=implicit_scaling)
        measures = maker(time_signatures)
        context.extend(measures)
        score.insert(0, context)
        return lilypond_file
コード例 #17
0
ファイル: LilyPondFile.py プロジェクト: Abjad/abjad
    def rhythm(
        class_,
        selections,
        divisions=None,
        attach_lilypond_voice_commands=None,
        implicit_scaling=None,
        pitched_staff=None,
        simultaneous_selections=None,
        time_signatures=None,
    ):
        r"""
        Makes rhythm-styled LilyPond file.

        ..  container:: example

            Makes rhythmic staff:

            >>> divisions = [(3, 4), (4, 8), (1, 4)]
            >>> maker = abjad.NoteMaker()
            >>> selections = [
            ...     maker(6 * [0], [(1, 8)]),
            ...     maker(8 * [0], [(1, 16)]),
            ...     maker(2 * [0], [(1, 8)]),
            ...     ]
            >>> for selection in selections:
            ...     abjad.beam(selection[:])
            ...
            >>> lilypond_file = abjad.LilyPondFile.rhythm(
            ...     selections,
            ...     divisions,
            ...     )
            >>> abjad.show(lilypond_file) # doctest: +SKIP

            ..  docs::

                >>> score = lilypond_file[abjad.Score]
                >>> abjad.f(score)
                \new Score
                <<
                    \new GlobalContext
                    {
                        \time 3/4
                        s1 * 3/4
                        \time 4/8
                        s1 * 1/2
                        \time 1/4
                        s1 * 1/4
                    }
                    \new RhythmicStaff
                    {
                        c'8
                        [
                        c'8
                        c'8
                        c'8
                        c'8
                        c'8
                        ]
                        c'16
                        [
                        c'16
                        c'16
                        c'16
                        c'16
                        c'16
                        c'16
                        c'16
                        ]
                        c'8
                        [
                        c'8
                        ]
                    }
                >>

        ..  container:: example

            Set time signatures explicitly:

            >>> divisions = [(3, 4), (4, 8), (1, 4)]
            >>> maker = abjad.NoteMaker()
            >>> selections = [
            ...     maker(6 * [0], [(1, 8)]),
            ...     maker(8 * [0], [(1, 16)]),
            ...     maker(2 * [0], [(1, 8)]),
            ...     ]
            >>> for selection in selections:
            ...     abjad.beam(selection[:])
            ...
            >>> lilypond_file = abjad.LilyPondFile.rhythm(
            ...     selections,
            ...     [(6, 8), (4, 8), (2, 8)],
            ...     )
            >>> abjad.show(lilypond_file) # doctest: +SKIP

            ..  docs::

                >>> score = lilypond_file[abjad.Score]
                >>> abjad.f(score)
                \new Score
                <<
                    \new GlobalContext
                    {
                        \time 6/8
                        s1 * 3/4
                        \time 4/8
                        s1 * 1/2
                        \time 2/8
                        s1 * 1/4
                    }
                    \new RhythmicStaff
                    {
                        c'8
                        [
                        c'8
                        c'8
                        c'8
                        c'8
                        c'8
                        ]
                        c'16
                        [
                        c'16
                        c'16
                        c'16
                        c'16
                        c'16
                        c'16
                        c'16
                        ]
                        c'8
                        [
                        c'8
                        ]
                    }
                >>

        ..  container:: example

            Makes pitched staff:

            >>> divisions = [(3, 4), (4, 8), (1, 4)]
            >>> maker = abjad.NoteMaker()
            >>> selections = [
            ...     maker(6 * [0], [(1, 8)]),
            ...     maker(8 * [0], [(1, 16)]),
            ...     maker(2 * [0], [(1, 8)]),
            ...     ]
            >>> for selection in selections:
            ...     abjad.beam(selection[:])
            ...
            >>> lilypond_file = abjad.LilyPondFile.rhythm(
            ...     selections,
            ...     divisions,
            ...     pitched_staff=True,
            ...     )
            >>> abjad.show(lilypond_file) # doctest: +SKIP

            ..  docs::

                >>> abjad.f(lilypond_file[abjad.Score])
                \new Score
                <<
                    \new GlobalContext
                    {
                        \time 3/4
                        s1 * 3/4
                        \time 4/8
                        s1 * 1/2
                        \time 1/4
                        s1 * 1/4
                    }
                    \new Staff
                    {
                        c'8
                        [
                        c'8
                        c'8
                        c'8
                        c'8
                        c'8
                        ]
                        c'16
                        [
                        c'16
                        c'16
                        c'16
                        c'16
                        c'16
                        c'16
                        c'16
                        ]
                        c'8
                        [
                        c'8
                        ]
                    }
                >>

        ..  container:: example

            Makes simultaneous voices:

            >>> divisions = [(3, 4), (4, 8), (1, 4)]
            >>> maker = abjad.NoteMaker()
            >>> selections = [
            ...     maker(6 * [0], [(1, 8)]),
            ...     maker(8 * [0], [(1, 16)]),
            ...     maker(2 * [0], [(1, 8)]),
            ...     ]
            >>> for selection in selections:
            ...     abjad.beam(selection[:])
            ...
            >>> for note in abjad.iterate(selections).components(abjad.Note):
            ...     note.written_pitch = abjad.NamedPitch("e'")
            ...
            >>> selection_1 = selections[0] + selections[1] + selections[2]
            >>> selections = [
            ...     maker(12 * [0], [(1, 16)]),
            ...     maker(16 * [0], [(1, 32)]),
            ...     maker(4 * [0], [(1, 16)]),
            ...     ]
            >>> for selection in selections:
            ...     abjad.beam(selection[:])
            ...
            >>> selection_2 = selections[0] + selections[1] + selections[2]
            >>> selections = {
            ...     'Voice_1': selection_1,
            ...     'Voice_2': selection_2,
            ... }
            >>> lilypond_file = abjad.LilyPondFile.rhythm(
            ...     selections,
            ...     divisions,
            ...     )
            >>> voice_1 = lilypond_file['Voice_1']
            >>> abjad.attach(abjad.LilyPondLiteral(r'\voiceOne'), voice_1)
            >>> voice_2 = lilypond_file['Voice_2']
            >>> abjad.attach(abjad.LilyPondLiteral(r'\voiceTwo'), voice_2)
            >>> abjad.show(lilypond_file) # doctest: +SKIP

            ..  docs::

                >>> abjad.f(lilypond_file[abjad.Score])
                \new Score
                <<
                    \new GlobalContext
                    {
                        s1 * 3/4
                        s1 * 1/2
                        s1 * 1/4
                    }
                    \new Staff
                    <<
                        \context Voice = "Voice_1"
                        {
                            \voiceOne
                            e'8
                            [
                            e'8
                            e'8
                            e'8
                            e'8
                            e'8
                            ]
                            e'16
                            [
                            e'16
                            e'16
                            e'16
                            e'16
                            e'16
                            e'16
                            e'16
                            ]
                            e'8
                            [
                            e'8
                            ]
                        }
                        \context Voice = "Voice_2"
                        {
                            \voiceTwo
                            c'16
                            [
                            c'16
                            c'16
                            c'16
                            c'16
                            c'16
                            c'16
                            c'16
                            c'16
                            c'16
                            c'16
                            c'16
                            ]
                            c'32
                            [
                            c'32
                            c'32
                            c'32
                            c'32
                            c'32
                            c'32
                            c'32
                            c'32
                            c'32
                            c'32
                            c'32
                            c'32
                            c'32
                            c'32
                            c'32
                            ]
                            c'16
                            [
                            c'16
                            c'16
                            c'16
                            ]
                        }
                    >>
                >>

        Returns LilyPond file.
        """
        if isinstance(selections, list):
            for selection in selections:
                if not isinstance(selection, Selection):
                    raise TypeError(f"must be selection: {selection!r}.")
        elif isinstance(selections, dict):
            for selection in selections.values():
                if not isinstance(selection, Selection):
                    raise TypeError(f"must be selection: {selection!r}.")
        else:
            raise TypeError(f"must be list or dictionary: {selections!r}.")
        score = Score()
        lilypond_file = LilyPondFile.new(
            score, includes=["default.ily", "rhythm-maker-docs.ily"]
        )
        if pitched_staff is None:
            if isinstance(selections, list):
                selections_ = selections
            elif isinstance(selections, dict):
                selections_ = selections.values()
            else:
                raise TypeError(selections)
            for note in iterate(selections_).leaves(Note):
                if note.written_pitch != NamedPitch("c'"):
                    pitched_staff = True
                    break
        if isinstance(selections, list):
            if divisions is None:
                duration = abjad_inspect(selections).duration()
                divisions = [duration]
            time_signatures = time_signatures or divisions
            time_signatures = [TimeSignature(_) for _ in time_signatures]
            if pitched_staff:
                staff = Staff()
            else:
                staff = Staff(lilypond_type="RhythmicStaff")
            staff.extend(selections)
        elif isinstance(selections, dict):
            voices = []
            for voice_name in sorted(selections):
                selections_ = selections[voice_name]
                selections_ = sequence(selections_).flatten(depth=-1)
                selections_ = copy.deepcopy(selections_)
                voice = Voice(selections_, name=voice_name)
                if attach_lilypond_voice_commands:
                    voice_name_to_command_string = {
                        "Voice_1": "voiceOne",
                        "Voice_2": "voiceTwo",
                        "Voice_3": "voiceThree",
                        "Voice_4": "voiceFour",
                    }
                    command_string = voice_name_to_command_string.get(
                        voice_name
                    )
                    if command_string:
                        command = LilyPondLiteral("\\" + command_string)
                        attach(command, voice)
                voices.append(voice)
            staff = Staff(voices, is_simultaneous=True)
            if divisions is None:
                duration = abjad_inspect(staff).duration()
                divisions = [duration]
        else:
            message = "must be list or dictionary of selections:"
            message += f" {selections!r}."
            raise TypeError(message)
        score.append(staff)
        assert isinstance(divisions, collections.abc.Sequence), repr(divisions)
        time_signatures = time_signatures or divisions
        context = Context(lilypond_type="GlobalContext")
        skips = []
        for time_signature in time_signatures:
            skip = Skip(1)
            skip.multiplier = time_signature
            attach(time_signature, skip, context="Score")
            skips.append(skip)
        context.extend(skips)
        score.insert(0, context)
        return lilypond_file