dynamic

digraph InheritanceGraph { graph [bgcolor=transparent, color=lightsteelblue2, fontname=Arial, fontsize=10, outputorder=edgesfirst, overlap=prism, penwidth=2, rankdir=LR, splines=spline, style="dashed, rounded", truecolor=true]; node [colorscheme=pastel19, fontname=Arial, fontsize=10, height=0, penwidth=2, shape=box, style="filled, rounded", width=0]; edge [color=lightslategrey, penwidth=1]; subgraph "cluster_abjad.dynamic" { graph [label="abjad.dynamic"]; node [color=1]; "abjad.dynamic.Dynamic" [URL="../api/abjad/dynamic.html#abjad.dynamic.Dynamic", color=black, fontcolor=white, label=Dynamic, target=_top]; } subgraph cluster_builtins { graph [label=builtins]; node [color=2]; "builtins.object" [URL="https://docs.python.org/3.10/library/functions.html#object", label=object, target=_top]; } "builtins.object" -> "abjad.dynamic.Dynamic"; }


Classes

Dynamic

Dynamic.

class abjad.dynamic.Dynamic(name='f', command=None, format_hairpin_stop=False, hide=False, leak=False, name_is_textual=False, ordinal=None)[source]

Dynamic.

Initializes from dynamic name:

>>> voice = abjad.Voice("c'8 d'8 e'8 f'8")
>>> dynamic = abjad.Dynamic("f")
>>> abjad.attach(dynamic, voice[0])
>>> abjad.show(voice)  

Initializes from other dynamic:

>>> dynamic_1 = abjad.Dynamic("f")
>>> dynamic_2 = abjad.Dynamic(dynamic_1)
>>> dynamic_1
Dynamic(name='f', command=None, format_hairpin_stop=False, hide=False, leak=False, name_is_textual=False, ordinal=2)
>>> dynamic_2
Dynamic(name='f', command=None, format_hairpin_stop=False, hide=False, leak=False, name_is_textual=False, ordinal=2)

Initializes niente:

>>> abjad.Dynamic("niente")
Dynamic(name='niente', command=None, format_hairpin_stop=False, hide=False, leak=False, name_is_textual=True, ordinal=NegativeInfinity())

Simultaneous dynamics in a single staff:

>>> voice_1 = abjad.Voice("e'8 g'8 f'8 a'8")
>>> abjad.attach(abjad.Dynamic("f"), voice_1[0], context="Voice")
>>> command = abjad.VoiceNumber(1)
>>> abjad.attach(command, voice_1[0])
>>> abjad.override(voice_1).DynamicLineSpanner.direction = abjad.UP
>>> voice_2 = abjad.Voice("c'2")
>>> command = abjad.VoiceNumber(2)
>>> abjad.attach(command, voice_2[0])
>>> abjad.attach(abjad.Dynamic("mf"), voice_2[0], context="Voice")
>>> staff = abjad.Staff([voice_1, voice_2], simultaneous=True)
>>> abjad.show(staff)  
>>> for leaf in abjad.select.leaves(staff):
...     dynamic = abjad.get.effective(leaf, abjad.Dynamic)
...     print(f"{leaf!r}:")
...     print(f"    {dynamic!r}")
... 
Note("e'8"):
    Dynamic(name='f', command=None, format_hairpin_stop=False, hide=False, leak=False, name_is_textual=False, ordinal=2)
Note("g'8"):
    Dynamic(name='f', command=None, format_hairpin_stop=False, hide=False, leak=False, name_is_textual=False, ordinal=2)
Note("f'8"):
    Dynamic(name='f', command=None, format_hairpin_stop=False, hide=False, leak=False, name_is_textual=False, ordinal=2)
Note("a'8"):
    Dynamic(name='f', command=None, format_hairpin_stop=False, hide=False, leak=False, name_is_textual=False, ordinal=2)
Note("c'2"):
    Dynamic(name='mf', command=None, format_hairpin_stop=False, hide=False, leak=False, name_is_textual=False, ordinal=1)

Errors on nondynamic input:

>>> abjad.Dynamic("text")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<string>", line 10, in __init__
  File "/Users/trevor/abjad/abjad/dynamic.py", line 685, in __post_init__
    raise Exception(message)
Exception: letter 't' (in 'text') is not a dynamic.

Tweaks:

>>> voice = abjad.Voice("c'4")
>>> dynamic = abjad.Dynamic("f")
>>> bundle = abjad.bundle(dynamic, r"- \tweak color #blue")
>>> abjad.attach(bundle, voice[0])
>>> abjad.show(voice)  

Use command like this:

>>> abjad.Dynamic("f", command=r"\sub_f").command
'\\sub_f'

Use to override LilyPond output when a custom dynamic has been defined in an external stylesheet. (In the example above, \sub_f is a nonstandard LilyPond dynamic. LilyPond will interpret the output above only when the command \sub_f is defined somewhere in an external stylesheet.)

Direction:

With direction unset:

>>> voice = abjad.Voice("c'2 c''2")
>>> abjad.attach(abjad.Dynamic("p"), voice[0])
>>> abjad.attach(abjad.Dynamic("f"), voice[1])
>>> abjad.show(voice)  

With direction=abjad.UP:

>>> voice = abjad.Voice("c'2 c''2")
>>> abjad.attach(abjad.Dynamic("p"), voice[0], direction=abjad.UP)
>>> abjad.attach(abjad.Dynamic("f"), voice[1], direction=abjad.UP)
>>> abjad.show(voice)  

With direction=abjad.DOWN:

>>> voice = abjad.Voice("c'2 c''2")
>>> abjad.attach(abjad.Dynamic("p"), voice[0], direction=abjad.DOWN)
>>> abjad.attach(abjad.Dynamic("f"), voice[1], direction=abjad.DOWN)
>>> abjad.show(voice)  

REGRESSION. Effort dynamics default to down:

>>> voice = abjad.Voice("c'2 c''2")
>>> abjad.attach(abjad.Dynamic('"p"'), voice[0])
>>> abjad.attach(abjad.Dynamic('"f"'), voice[1])
>>> abjad.show(voice)  

And may be overriden:

>>> voice = abjad.Voice("c'2 c''2")
>>> abjad.attach(abjad.Dynamic('"p"'), voice[0], direction=abjad.UP)
>>> abjad.attach(abjad.Dynamic('"f"'), voice[1], direction=abjad.UP)
>>> abjad.show(voice)  

Set hide=True when dynamic should not appear in output (but should still determine effective dynamic):

>>> voice = abjad.Voice("c'4 d' e' f'")
>>> abjad.attach(abjad.Dynamic("f"), voice[0])
>>> abjad.attach(abjad.Dynamic("mf", hide=True), voice[2])
>>> abjad.show(voice)  
>>> string = abjad.lilypond(voice)
>>> print(string)
\new Voice
{
    c'4
    \f
    d'4
    e'4
    f'4
}
>>> for leaf in abjad.iterate.leaves(voice):
...     dynamic = abjad.get.effective(leaf, abjad.Dynamic)
...     print(f"{leaf!r}:")
...     print(f"    {dynamic!r}")
... 
Note("c'4"):
    Dynamic(name='f', command=None, format_hairpin_stop=False, hide=False, leak=False, name_is_textual=False, ordinal=2)
Note("d'4"):
    Dynamic(name='f', command=None, format_hairpin_stop=False, hide=False, leak=False, name_is_textual=False, ordinal=2)
Note("e'4"):
    Dynamic(name='mf', command=None, format_hairpin_stop=False, hide=True, leak=False, name_is_textual=False, ordinal=1)
Note("f'4"):
    Dynamic(name='mf', command=None, format_hairpin_stop=False, hide=True, leak=False, name_is_textual=False, ordinal=1)

Set leak=True Is true to format LilyPond empty chord <> symbol:

Without leaked stop dynamic:

>>> voice = abjad.Voice("c'4 d' e' r")
>>> start_dynamic = abjad.Dynamic("mf")
>>> start_hairpin = abjad.StartHairpin(">")
>>> stop_dynamic = abjad.Dynamic("pp")
>>> abjad.attach(start_dynamic, voice[0])
>>> abjad.attach(start_hairpin, voice[0])
>>> abjad.attach(stop_dynamic, voice[-2])
>>> abjad.override(voice).DynamicLineSpanner.staff_padding = 4
>>> abjad.show(voice)  

With leaked stop dynamic:

>>> voice = abjad.Voice("c'4 d' e' r")
>>> start_dynamic = abjad.Dynamic("mf")
>>> start_hairpin = abjad.StartHairpin(">")
>>> stop_dynamic = abjad.Dynamic("pp", leak=True)
>>> abjad.attach(start_dynamic, voice[0])
>>> abjad.attach(start_hairpin, voice[0])
>>> abjad.attach(stop_dynamic, voice[-2])
>>> abjad.override(voice).DynamicLineSpanner.staff_padding = 4
>>> abjad.show(voice)  

Leaks format after spanners:

>>> voice = abjad.Voice("c'8 [ d' e' ] f'")
>>> start_dynamic = abjad.Dynamic("mf")
>>> start_hairpin = abjad.StartHairpin(">")
>>> stop_dynamic = abjad.Dynamic("pp", leak=True)
>>> abjad.attach(start_dynamic, voice[0])
>>> abjad.attach(start_hairpin, voice[0])
>>> abjad.attach(stop_dynamic, voice[-2])
>>> abjad.override(voice).DynamicLineSpanner.staff_padding = 4
>>> abjad.show(voice)  

Leaked and nonleaked dynamic may be attached to the same leaf:

>>> voice = abjad.Voice("c'4 d' e' f'")
>>> abjad.attach(abjad.Dynamic("f"), voice[0])
>>> abjad.attach(abjad.Dynamic("p", leak=True), voice[0])
>>> abjad.show(voice)  

Leaks and tweaks on the same dynamic format correctly; LilyPond empty chord <> symbol appears before postevents:

>>> voice = abjad.Voice("r4 d' e' f'")
>>> dynamic = abjad.Dynamic("f", leak=True)
>>> bundle = abjad.bundle(dynamic, r"- \tweak color #blue")
>>> abjad.attach(bundle, voice[0])
>>> abjad.show(voice)  
>>> string = abjad.lilypond(voice)
>>> print(string)
\new Voice
{
    r4
    <>
    - \tweak color #blue
    \f
    d'4
    e'4
    f'4
}

Leak survives copy:

>>> import copy
>>> dynamic = abjad.Dynamic("pp", leak=True)
>>> copy.copy(dynamic)
Dynamic(name='pp', command=None, format_hairpin_stop=False, hide=False, leak=True, name_is_textual=False, ordinal=-3)

Niente dynamics format like this:

>>> voice = abjad.Voice("c'4 r r c'4")
>>> abjad.attach(abjad.Dynamic("p"), voice[0])
>>> abjad.attach(abjad.Dynamic("niente"), voice[1])
>>> abjad.attach(abjad.Dynamic("p"), voice[3])
>>> abjad.override(voice).DynamicLineSpanner.staff_padding = 4
>>> abjad.show(voice)  

Name-is-textual:

>>> abjad.Dynamic("f").name_is_textual
False
>>> abjad.Dynamic("niente").name_is_textual
True
>>> dynamic = abjad.Dynamic("appena udibile", name_is_textual=True)
>>> dynamic.name_is_textual
True

Textual dynamics format like this when initialized without an explicit command:

>>> voice = abjad.Voice("c'4 d' e' f'")
>>> dynamic = abjad.Dynamic("appena udibile", name_is_textual=True)
>>> abjad.attach(dynamic, voice[0])
>>> abjad.override(voice).DynamicLineSpanner.staff_padding = 4
>>> abjad.override(voice).DynamicText.X_extent = "#'(0 . 0)"
>>> abjad.override(voice).DynamicText.self_alignment_X = abjad.LEFT
>>> abjad.show(voice)  

Textual dynamics format like this when initialized with an explicit command:

>>> voice = abjad.Voice("c'4 d' e' f'")
>>> dynamic = abjad.Dynamic(
...     "appena udibile",
...     command=r"\appena_udibile",
...     name_is_textual=True,
... )
>>> abjad.attach(dynamic, voice[0])

Only LilyPond output is shown here because dynamic commands (like \appena_udibile shown here) are meant to be user-defined (and not included in Abjad):

>>> string = abjad.lilypond(voice)
>>> print(string)
\new Voice
{
    c'4
    \appena_udibile
    d'4
    e'4
    f'4
}

REGRESSION. Textual names work with replace:

>>> import dataclasses
>>> dynamic = abjad.Dynamic("niente")
>>> dataclasses.replace(dynamic)
Dynamic(name='niente', command=None, format_hairpin_stop=False, hide=False, leak=False, name_is_textual=True, ordinal=NegativeInfinity())
>>> dynamic = abjad.Dynamic("appena udibile", name_is_textual=True)
>>> dataclasses.replace(dynamic)
Dynamic(name='appena udibile', command=None, format_hairpin_stop=False, hide=False, leak=False, name_is_textual=True, ordinal=None)

Ordinal value of a dynamic:

>>> abjad.Dynamic("f").ordinal
2
>>> abjad.Dynamic("p").ordinal
-2
>>> abjad.Dynamic("niente").ordinal
NegativeInfinity()
>>> abjad.Dynamic('"f"').ordinal
2
>>> abjad.Dynamic('"p"').ordinal
-2

User-defined ordinals:

>>> barely_audible = abjad.Dynamic(
...     "barely audible",
...     name_is_textual=True,
...     ordinal=-99,
... )
>>> barely_audible.ordinal
-99
>>> extremely_loud = abjad.Dynamic(
...     "extremely loud",
...     name_is_textual=True,
...     ordinal=99,
... )
>>> extremely_loud.ordinal
99

REGRESSION. Textual names without explicit ordinal return none:

>>> dynamic = abjad.Dynamic("appena udibile", name_is_textual=True)
>>> dynamic.ordinal is None
True

Attributes Summary

__eq__

Is true when argument equals dynamic.

__hash__

Return hash(self).

__post_init__

__repr__

Return repr(self).

composite_dynamic_name_to_steady_state_dynamic_name

Changes composite name to steady state dynamic name.

context

directed

dynamic_name_to_dynamic_ordinal

Changes name to dynamic ordinal.

dynamic_ordinal_to_dynamic_name

Changes dynamic_ordinal to dynamic name.

effort

Is true when double quotes enclose dynamic.

is_dynamic_name

Is true when argument is dynamic name.

parameter

persistent

post_event

sforzando

Is true when dynamic name begins in s- and ends in -z.

site

spanner_stop


Special methods

overridden __eq__(argument)[source]

Is true when argument equals dynamic.

>>> dynamic_1 = abjad.Dynamic("p")
>>> dynamic_2 = abjad.Dynamic("p")
>>> dynamic_3 = abjad.Dynamic("f")
>>> dynamic_1 == dynamic_1
True
>>> dynamic_1 == dynamic_2
True
>>> dynamic_1 == dynamic_3
False
>>> dynamic_2 == dynamic_1
True
>>> dynamic_2 == dynamic_2
True
>>> dynamic_2 == dynamic_3
False
>>> dynamic_3 == dynamic_1
False
>>> dynamic_3 == dynamic_2
False
>>> dynamic_3 == dynamic_3
True
Return type:

bool

overridden __hash__()

Return hash(self).

__post_init__()[source]
overridden __repr__()

Return repr(self).


Class & static methods

static composite_dynamic_name_to_steady_state_dynamic_name(name)[source]

Changes composite name to steady state dynamic name.

>>> abjad.Dynamic.composite_dynamic_name_to_steady_state_dynamic_name("sfp")
'p'
>>> abjad.Dynamic.composite_dynamic_name_to_steady_state_dynamic_name("rfz")
'f'
Return type:

str

static dynamic_name_to_dynamic_ordinal(name)[source]

Changes name to dynamic ordinal.

>>> abjad.Dynamic.dynamic_name_to_dynamic_ordinal("fff")
4
>>> abjad.Dynamic.dynamic_name_to_dynamic_ordinal("niente")
NegativeInfinity()
static dynamic_ordinal_to_dynamic_name(dynamic_ordinal)[source]

Changes dynamic_ordinal to dynamic name.

>>> abjad.Dynamic.dynamic_ordinal_to_dynamic_name(-5)
'pppp'
>>> negative_infinity = abjad.math.NegativeInfinity()
>>> abjad.Dynamic.dynamic_ordinal_to_dynamic_name(negative_infinity)
'niente'
Return type:

str

static is_dynamic_name(argument)[source]

Is true when argument is dynamic name.

>>> abjad.Dynamic.is_dynamic_name("f")
True
>>> abjad.Dynamic.is_dynamic_name("sfz")
True
>>> abjad.Dynamic.is_dynamic_name("niente")
True
Return type:

bool


Read-only properties

effort

Is true when double quotes enclose dynamic.

>>> voice = abjad.Voice("c'4 r d' r e' r f' r")
>>> abjad.attach(abjad.Dynamic('"pp"'), voice[0])
>>> abjad.attach(abjad.Dynamic('"mp"'), voice[2])
>>> abjad.attach(abjad.Dynamic('"mf"'), voice[4])
>>> abjad.attach(abjad.Dynamic('"ff"'), voice[6])
>>> abjad.override(voice).DynamicLineSpanner.staff_padding = 4
>>> abjad.show(voice)  
>>> voice = abjad.Voice("c'4 r d' r e' r f' r")
>>> abjad.attach(abjad.Dynamic('"sf"'), voice[0])
>>> abjad.attach(abjad.Dynamic('"sfz"'), voice[2])
>>> abjad.attach(abjad.Dynamic('"rf"'), voice[4])
>>> abjad.attach(abjad.Dynamic('"rfz"'), voice[6])
>>> abjad.override(voice).DynamicLineSpanner.staff_padding = 4
>>> abjad.show(voice)  
sforzando

Is true when dynamic name begins in s- and ends in -z.

>>> abjad.Dynamic("f").sforzando
False
>>> abjad.Dynamic("sfz").sforzando
True
>>> abjad.Dynamic("sffz").sforzando
True
>>> abjad.Dynamic("sfp").sforzando
False
>>> abjad.Dynamic("sf").sforzando
False
>>> abjad.Dynamic("rfz").sforzando
False