def test_reposition_dynamics_11():
    staff = abjad.Staff(r"c'1 d'1 e'1 r1\mf r1\ff f'1 r1 g'1")
    abjad.attach(abjad.Dynamic('niente', hide=True), staff[0])
    abjad.attach(abjad.Dynamic('niente', hide=True), staff[7])
    abjad.attach(abjad.StartHairpin('o<'), staff[0])
    abjad.attach(abjad.StartHairpin('>o'), staff[4])
    abjad.attach(abjad.StopHairpin(), staff[7])
    auxjad.mutate(staff[:]).reposition_dynamics()
    assert format(staff) == abjad.String.normalize(r"""
        \new Staff
        {
            c'1
            - \tweak circled-tip ##t
            \<
            d'1
            e'1
            r1
            \mf
            r1
            f'1
            \ff
            - \tweak circled-tip ##t
            \>
            r1
            \!
            g'1
        }
        """)
Example #2
0
def test_LilyPondParser__spanners__Hairpin_06():
    """
    With direction.
    """

    maker = abjad.NoteMaker()
    target = abjad.Staff(maker([0] * 5, [(1, 4)]))
    start_hairpin = abjad.StartHairpin("<", direction=abjad.Up)
    abjad.attach(start_hairpin, target[0])
    stop_hairpin = abjad.StopHairpin()
    abjad.attach(stop_hairpin, target[2])
    hairpin = abjad.StartHairpin(">", direction=abjad.Down)
    abjad.attach(hairpin, target[2])
    dynamic = abjad.Dynamic("ppp")
    abjad.attach(dynamic, target[-1])

    assert format(target) == abjad.String.normalize(r"""
        \new Staff
        {
            c'4
            ^ \<
            c'4
            c'4
            \!
            _ \>
            c'4
            c'4
            \ppp
        }
        """)

    parser = abjad.parser.LilyPondParser()
    result = parser(format(target))
    assert format(target) == format(result) and target is not result
Example #3
0
                    continue
                # if previous leaf is quarter note (or greater) ...
                if (isinstance(previous_leaf,
                               (abjad.Chord, abjad.Note)) and abjad.Duration(
                                   1, 4) <= previous_leaf.written_duration):
                    left = leaf.written_duration.flag_count  # left-pointing nib
                    right = next_leaf.written_duration.flag_count
                    beam_count = abjad.BeamCount(left=left, right=right)
                    abjad.attach(beam_count, leaf)

print("Stopping Hairpins ...")
for staff in abjad.iterate(score["Staff Group 1"]).components(abjad.Staff):
    for rest in abjad.iterate(staff).components(abjad.Rest):
        previous_leaf = abjad.inspect(rest).leaf(-1)
        if isinstance(previous_leaf, abjad.Note):
            abjad.attach(abjad.StopHairpin(), rest)
        elif isinstance(previous_leaf, abjad.Chord):
            abjad.attach(abjad.StopHairpin(), rest)
        elif isinstance(previous_leaf, abjad.Rest):
            pass

# attach instruments and clefs

print("Adding attachments ...")
bar_line = abjad.BarLine("||")
metro = abjad.MetronomeMark((1, 4), 60)
markup1 = abjad.Markup(r"\bold { A }")
markup2 = abjad.Markup(r"\bold { B }")
markup3 = abjad.Markup(r"\bold { C }")
markup4 = abjad.Markup(r"\bold { D }")
markup5 = abjad.Markup(r"\bold { E }")
Example #4
0
             "gs,",
             "gtqs,",
             "etqf,",
         ],
         forget=False,
     ),
     lambda _: abjad.Selection(_),
 ),
 evans.attach(
     "Voice 4",
     abjad.Dynamic("f"),
     baca.selectors.leaf(0),
 ),
 evans.attach("Voice 4", abjad.StartHairpin(">o"),
              baca.selectors.leaf(-2, pitched=True)),
 evans.attach("Voice 4", abjad.StopHairpin(), baca.selectors.leaf(-2)),
 evans.attach(
     "Voice 4",
     abjad.Markup(r"\markup { molto vibrato }", direction=abjad.Up),
     baca.selectors.leaf(-3, pitched=True),
 ),
 evans.call(
     "Voice 4",
     evans.GlissandoHandler(
         line_style="zigzag",
         boolean_vector=[1],
         forget=False,
         apply_to="runs",
     ),
     baca.selectors.leaves(pitched=True).get([-3, -2, -1]),
 ),
Example #5
0
def reposition_dynamics(selection: abjad.Selection,
                        *,
                        allow_hairpins_under_rests: bool = False,
                        check_hairpin_trends: bool = True,
                        remove_repeated_dynamics: bool = True,
                        allow_hairpin_to_rest_with_dynamic: bool = True,
                        ) -> None:
    r"""Mutates an input |abjad.Selection| in place and has no return value;
    this function shifts all dynamics from rests to the next pitched leaves. It
    will also adjust hairpins if necessary.

    Basic usage:
        This function will shift dynamics under rests to the next pitched leaf.

        >>> staff = abjad.Staff(r"c'1\p d'2 r2\f r1 e'1")
        >>> abjad.show(staff)

        ..  docs::

            \new Staff
            {
                c'1
                \p
                d'2
                r2
                \f
                r1
                e'1
            }

        ..  figure:: ../_images/reposition_dynamics-sqwvevg7o9.png

        >>> staff = abjad.Staff(r"c'1\p d'2 r2\f r1 e'1")
        >>> auxjad.mutate.reposition_dynamics(staff[:])
        >>> abjad.show(staff)

        ..  docs::

            \new Staff
            {
                c'1
                \p
                d'2
                r2
                r1
                e'1
                \f
            }

        ..  figure:: ../_images/reposition_dynamics-v18uzh1zjs.png

    ..  note::

        Auxjad automatically adds this function as an extension function to
        |abjad.mutate|. It can thus be used from either |auxjad.mutate|_ or
        |abjad.mutate| namespaces. Therefore, the two lines below are
        equivalent:

        >>> auxjad.mutate.reposition_dynamics(staff[:])
        >>> abjad.mutate.reposition_dynamics(staff[:])

    Removing dynamics:
        If the next pitched leaf already contain a dynamic, this function will
        simply remove the dynamic under the rest.

        >>> staff = abjad.Staff(r"c'1\p d'2 r2\f r1\mf e'1\pp")
        >>> abjad.show(staff)

        ..  docs::

            \new Staff
            {
                c'1
                \p
                d'2
                r2
                \f
                r1
                \mf
                e'1
                \pp
            }

        ..  figure:: ../_images/reposition_dynamics-aom2qywcn9m.png

        >>> staff = abjad.Staff(r"c'1\p d'2 r2\f r1\mf e'1\pp")
        >>> auxjad.mutate.reposition_dynamics(staff[:])
        >>> abjad.show(staff)

        ..  docs::

            \new Staff
            {
                c'1
                \p
                d'2
                r2
                r1
                e'1
                \pp
            }

        ..  figure:: ../_images/reposition_dynamics-2ua73x102fp.png

    ``remove_repeated_dynamics``:
        By default indentical repeated dynamics are omitted.

        >>> staff = abjad.Staff(r"c'1\p d'1 r1\f e'1\p")
        >>> auxjad.mutate.reposition_dynamics(staff[:])
        >>> abjad.show(staff)

        ..  docs::

            \new Staff
            {
                c'1
                \p
                d'1
                r1
                e'1
            }

        ..  figure:: ../_images/reposition_dynamics-i4x8b1z1ak.png

        Set the optional keyword argument ``remove_repeated_dynamics`` to
        ``False`` to disable this behaviour.

        >>> staff = abjad.Staff(r"c'1\p d'1 r1\f e'1\p")
        >>> auxjad.mutate.reposition_dynamics(
        ...     staff[:],
        ...     remove_repeated_dynamics=False,
        ... )
        >>> abjad.show(staff)

        ..  docs::

            \new Staff
            {
                c'1
                \p
                d'1
                r1
                e'1
                \p
            }

        ..  figure:: ../_images/reposition_dynamics-se8a5aeqer.png

    ``allow_hairpins_under_rests``:
        This function will shorten hairpins until rests by default.

        >>> staff = abjad.Staff(r"c'1\p\< d'2 r2 r1\f e'1")
        >>> abjad.show(staff)

        ..  docs::

            \new Staff
            {
                c'1
                \p
                \<
                d'2
                r2
                r1
                \f
                e'1
            }

        ..  figure:: ../_images/reposition_dynamics-r28po3j3hd.png

        >>> staff = abjad.Staff(r"c'1\p\< d'2 r2 r1\f e'1")
        >>> auxjad.mutate.reposition_dynamics(staff[:])
        >>> abjad.show(staff)

        ..  docs::

            \new Staff
            {
                c'1
                \p
                \<
                d'2
                r2
                \!
                r1
                e'1
                \f
            }

        ..  figure:: ../_images/reposition_dynamics-n60vvnqrcnr.png

        Set the optional keyword argument ``allow_hairpins_under_rests`` to
        ``True`` to allow hairpins to extend cross rests.

        >>> staff = abjad.Staff(r"c'1\p\< d'2 r2 r1\f e'1")
        >>> auxjad.mutate.reposition_dynamics(
        ...     staff[:],
        ...     allow_hairpins_under_rests=True,
        ... )
        >>> abjad.show(staff)

        ..  docs::

            \new Staff
            {
                c'1
                \p
                \<
                d'2
                r2
                r1
                e'1
                \f
            }

        ..  figure:: ../_images/reposition_dynamics-ugit7ijz89h.png

    ``allow_hairpin_to_rest_with_dynamic``:
        Notice that if a hairpin leads to a rest with dynamic, that one is not
        removed.

        >>> staff = abjad.Staff(r"c'1\p\< d'2 r2\f r1 e'1")
        >>> auxjad.mutate.reposition_dynamics(staff[:])
        >>> abjad.show(staff)

        ..  docs::

            \new Staff
            {
                c'1
                \p
                \<
                d'2
                r2
                \f
                r1
                e'1
            }

        ..  figure:: ../_images/reposition_dynamics-t9z4y5zzj6.png

        Set the argument ``allow_hairpin_to_rest_with_dynamic`` to ``False`` to
        disable this behaviour.

        >>> staff = abjad.Staff(r"c'1\p\< d'2 r2\f r1 e'1")
        >>> auxjad.mutate.reposition_dynamics(
        ...     staff[:],
        ...     allow_hairpin_to_rest_with_dynamic=False,
        ... )
        >>> abjad.show(staff)

        ..  docs::

            \new Staff
            {
                c'1
                \p
                \<
                d'2
                r2
                \!
                r1
                e'1
                \f
            }

        ..  figure:: ../_images/reposition_dynamics-wpwweov55qf.png

    ``check_hairpin_trends``:
        This function will remove any hairpins connecting dynamics that grow in
        the opposite direction to the hairpin's trend, such as a diminuendo
        hairpin from piano to forte.

        >>> staff = abjad.Staff(r"c'1\p\> d'1\f\> e'1\p")
        >>> auxjad.mutate.reposition_dynamics(staff[:])
        >>> abjad.show(staff)

        ..  docs::

            \new Staff
            {
                c'1
                \p
                d'1
                \f
                \>
                e'1
                \p
            }

        ..  figure:: ../_images/reposition_dynamics-f0b4ppb71ii.png

        This behaviour can be disabled by setting the argument
        ``check_hairpin_trends`` to ``False``.

        >>> staff = abjad.Staff(r"c'1\p\> d'1\f\> e'1\p")
        >>> auxjad.mutate.reposition_dynamics(
        ...     staff[:],
        ...     check_hairpin_trends=False,
        ... )
        >>> abjad.show(staff)

        ..  docs::

            \new Staff
            {
                c'1
                \p
                \>
                d'1
                \f
                \>
                e'1
                \p
            }

        ..  figure:: ../_images/reposition_dynamics-1e2ugszm95fi.png

    ..  note::

        The behaviour described above is only applicable when a hairpin ends
        on a dynamic. Using the hairpin terminator ``\!`` before a dynamic
        change will not cause a hairpin to be removed as it is not considered
        to be connecting dynamics of the opposite trend.

        >>> staff = abjad.Staff(r"c'1\p\> d'1\! e'1\f\> f'1\p")
        >>> auxjad.mutate.reposition_dynamics(staff[:])
        >>> abjad.show(staff)

        ..  docs::

            \new Staff
            {
                c'1
                \p
                \>
                d'1
                \!
                e'1
                \f
                \>
                f'1
                \p
            }

        ..  figure:: ../_images/reposition_dynamics-77g0uwthbgd.png

    Types of hairpins:
        This function can handle multiple types of hairpins as well as niente
        dynamics.

        >>> staff = abjad.Staff(r"c'1 d'1 e'1 r1\mf r1\ff f'1 r1 g'1")
        >>> abjad.attach(abjad.Dynamic('niente', hide=True), staff[0])
        >>> abjad.attach(abjad.Dynamic('niente', hide=True), staff[7])
        >>> abjad.attach(abjad.StartHairpin('o<'), staff[0])
        >>> abjad.attach(abjad.StartHairpin('>o'), staff[4])
        >>> abjad.attach(abjad.StopHairpin(), staff[7])
        >>> auxjad.mutate.reposition_dynamics(staff[:])
        >>> abjad.show(staff)

        ..  docs::

            \new Staff
            {
                c'1
                - \tweak circled-tip ##t
                \<
                d'1
                e'1
                r1
                \mf
                r1
                f'1
                \ff
                - \tweak circled-tip ##t
                \>
                r1
                \!
                g'1
            }

        ..  figure:: ../_images/reposition_dynamics-m8it9awv1ce.png

        >>> staff = abjad.Staff(
        ...     r"c'1\p d'1\f\> e'1\ff\< r1\fff f'1\p\> g'1\ppp"
        ... )
        >>> abjad.attach(abjad.StartHairpin('--'), staff[0])
        >>> auxjad.mutate.reposition_dynamics(staff[:])
        >>> abjad.show(staff)

        ..  docs::

            \new Staff
            {
                c'1
                \p
                - \tweak stencil #constante-hairpin
                \<
                d'1
                \f
                e'1
                \ff
                \<
                r1
                \fff
                f'1
                \p
                \>
                g'1
                \ppp
            }

        ..  figure:: ../_images/reposition_dynamics-fosad5ltzj.png

    Multi-measure rests:
        Multi-measure rests are also supported.

        >>> staff = abjad.Staff(r"c'1\p R1\f d'1")
        >>> abjad.show(staff)

        ..  docs::

            \new Staff
            {
                c'1
                \p
                R1
                \f
                d'1
            }

        ..  figure:: ../_images/reposition_dynamics-uj6jasfs2uh.png

        >>> staff = abjad.Staff(r"c'1\p R1\f d'1")
        >>> auxjad.mutate.reposition_dynamics(staff[:])
        >>> abjad.show(staff)

        ..  docs::

            \new Staff
            {
                c'1
                \p
                R1
                d'1
                \f
            }

        ..  figure:: ../_images/reposition_dynamics-axpcbm9hocd.png

    ..  warning::

        The input selection must be a contiguous logical voice. When dealing
        with a container with multiple subcontainers (e.g. a score containing
        multiple staves), the best approach is to cycle through these
        subcontainers, applying this function to them individually.
    """
    if not isinstance(selection, abjad.Selection):
        raise TypeError("argument must be 'abjad.Selection'")
    if not abjad.select(selection).leaves().are_contiguous_logical_voice():
        raise ValueError("argument must be contiguous logical voice")
    if not isinstance(allow_hairpins_under_rests, bool):
        raise TypeError("'allow_hairpins_under_rests' must be 'bool'")
    if not isinstance(check_hairpin_trends, bool):
        raise TypeError("'check_hairpin_trends' must be 'bool'")
    if not isinstance(remove_repeated_dynamics, bool):
        raise TypeError("'remove_repeated_dynamics' must be 'bool'")
    if not isinstance(allow_hairpin_to_rest_with_dynamic, bool):
        raise TypeError("'allow_hairpin_to_rest_with_dynamic' must be 'bool'")

    leaves = selection.leaves()

    # shifting dynamics and hairpins from rests to notes
    shifted_dynamic = None
    shifted_hairpin = None
    active_hairpin = None
    for leaf in leaves:
        if isinstance(leaf, (abjad.Rest, abjad.MultimeasureRest)):
            if abjad.get.indicator(leaf, abjad.Dynamic) is not None:
                previous_leaf = abjad.select(leaf).with_previous_leaf()[0]
                if (allow_hairpin_to_rest_with_dynamic
                        and active_hairpin is not None
                        and not isinstance(
                            previous_leaf,
                            (abjad.Rest, abjad.MultimeasureRest),
                        )):
                    active_hairpin = None
                else:
                    shifted_dynamic = abjad.get.indicator(leaf, abjad.Dynamic)
                    abjad.detach(abjad.Dynamic, leaf)
            if abjad.get.indicator(leaf, abjad.StartHairpin) is not None:
                shifted_hairpin = abjad.get.indicator(leaf, abjad.StartHairpin)
                abjad.detach(abjad.StartHairpin, leaf)
        else:
            if abjad.get.indicator(leaf, abjad.Dynamic) is None:
                if shifted_dynamic is not None:
                    abjad.attach(shifted_dynamic, leaf)
                    if (abjad.get.indicator(leaf, abjad.StopHairpin)
                            is not None):
                        abjad.detach(abjad.StopHairpin, leaf)
                if shifted_hairpin is not None:
                    abjad.attach(shifted_hairpin, leaf)
            else:
                active_hairpin = None
            if abjad.get.indicator(leaf, abjad.StopHairpin) is not None:
                active_hairpin = None
            shifted_dynamic = None
            shifted_hairpin = None
            if active_hairpin is None:
                active_hairpin = abjad.get.indicator(leaf, abjad.StartHairpin)

    # stopping hairpins under rests if not allowed
    if not allow_hairpins_under_rests:
        effective_hairpin = None
        for leaf in leaves:
            start_hairpin = abjad.get.indicator(leaf, abjad.StartHairpin)
            if start_hairpin is not None:
                effective_hairpin = start_hairpin
                continue
            if isinstance(leaf, (abjad.Rest, abjad.MultimeasureRest)):
                if effective_hairpin is not None:
                    if abjad.get.indicator(leaf, abjad.StopHairpin) is None:
                        abjad.attach(abjad.StopHairpin(), leaf)
                    effective_hairpin = None
            else:
                dynamic = abjad.get.indicator(leaf, abjad.Dynamic)
                stop_hairpin = abjad.get.indicator(leaf, abjad.StopHairpin)
                if dynamic is not None or stop_hairpin is not None:
                    effective_hairpin = None

    # cleaning up hairpins
    effective_dynamic = None
    for index, leaf in enumerate(leaves[:-1]):
        if abjad.get.indicator(leaf, abjad.Dynamic) is not None:
            effective_dynamic = abjad.get.indicator(leaf, abjad.Dynamic)
        start_hairpin = abjad.get.indicator(leaf, abjad.StartHairpin)
        if start_hairpin is not None and check_hairpin_trends:
            for next_leaf in leaves[index + 1:]:
                next_dynamic = abjad.get.indicator(next_leaf, abjad.Dynamic)
                if next_dynamic is not None and effective_dynamic is not None:
                    if '<' in start_hairpin.shape:
                        if next_dynamic.ordinal <= effective_dynamic.ordinal:
                            abjad.detach(abjad.StartHairpin, leaf)
                    elif '>' in start_hairpin.shape:
                        if next_dynamic.ordinal >= effective_dynamic.ordinal:
                            abjad.detach(abjad.StartHairpin, leaf)
                    break
                elif (abjad.get.indicator(next_leaf, abjad.StopHairpin)
                        is not None):
                    break
    if abjad.get.indicator(leaves[-1], abjad.StartHairpin) is not None:
        abjad.detach(abjad.StartHairpin, leaves[-1])

    # removing unecessary StopHairpin's
    for leaf in leaves:
        if (abjad.get.indicator(leaf, abjad.StopHairpin) is not None
                and abjad.get.indicator(leaf, abjad.Dynamic) is not None):
            abjad.detach(abjad.StopHairpin, leaf)
    target_leaf = None
    for leaf in leaves[::-1]:
        if abjad.get.indicator(leaf, abjad.StopHairpin) is not None:
            if target_leaf is not None:
                abjad.detach(abjad.StopHairpin, target_leaf)
            target_leaf = leaf
        elif (abjad.get.indicator(leaf, abjad.StartHairpin) is not None
                or abjad.get.indicator(leaf, abjad.Dynamic)) is not None:
            target_leaf = None

    # removing repeated dynamics if required
    if remove_repeated_dynamics:
        remove_repeated_dynamics_(selection)
Example #6
0
import abjad
import baca
import evans

from hamon_shu.materials.score_structure.clef_handlers import clef_handlers
from hamon_shu.materials.score_structure.instruments import instruments as insts
from hamon_shu.materials.score_structure.score_structure import score
from hamon_shu.materials.score_structure.segment_02.time_signatures import (
    time_signatures,
)
from hamon_shu.materials.timespans.segment_02.convert_timespans import (
    handler_commands,
    rhythm_commands,
)

commands = [evans.attach("Voice 1", abjad.StopHairpin(), baca.selectors.leaf(0))]

maker = evans.SegmentMaker(
    instruments=insts,
    names=['"Violin I"', '"Violin II"', '"Viola"', '"Violoncello"'],
    abbreviations=['"vn. I"', '"vn. II"', '"va."', '"vc."'],
    score_template=score,
    time_signatures=time_signatures,
    clef_handlers=clef_handlers,
    commands=[
        rhythm_commands,
        evans.call(
            "score",
            evans.SegmentMaker.transform_brackets,
            lambda _: abjad.Selection(_).components(abjad.Score),
        ),
Example #7
0
 evans.attach(
     "Voice 1", abjad.Dynamic("pp"), baca.selectors.leaf(0, pitched=True)
 ),
 evans.attach(
     "Voice 1", abjad.StartHairpin("<"), baca.selectors.leaf(0, pitched=True)
 ),
 evans.attach(
     "Voice 1",
     abjad.Markup(
         r"""\markup \box "cresc. a m.196 (ff)" """,
         direction=abjad.Down,
     ),
     baca.selectors.leaf(0, pitched=True),
 ),
 evans.attach(
     "Voice 1", abjad.StopHairpin(), baca.selectors.leaf(9, pitched=True)
 ),
 evans.attach(
     "Voice 1", abjad.Dynamic("ff"), baca.selectors.leaf(9, pitched=True)
 ),
 evans.attach(
     "Voice 2",
     noise_poco_a_poco,
     baca.selectors.leaf(96),
 ),
 evans.attach(
     "Voice 2",
     abjad.StopTextSpan(),
     baca.selectors.leaf(109),
 ),
 evans.attach(
Example #8
0
     _attach_marks,
     lambda _: abjad.Selection(_).logical_ties(),
 ),
 evans.attach(
     "Global Context",
     section_title,
     baca.selectors.leaf(0),
 ),
 evans.attach(
     "Voice 1",
     abjad.StartHairpin("<"),
     baca.selectors.leaf(0, pitched=True),
 ),
 evans.attach(
     "Voice 1",
     abjad.StopHairpin(),
     baca.selectors.leaf(-1, pitched=True),
 ),
 evans.attach(
     "Voice 2",
     abjad.StartHairpin("<"),
     baca.selectors.leaf(0, pitched=True),
 ),
 evans.attach(
     "Voice 2",
     abjad.StopHairpin(),
     baca.selectors.leaf(-1, pitched=True),
 ),
 evans.attach(
     "Voice 3",
     abjad.StartHairpin("<"),