remove_repeated_dynamics¶
- auxjad.mutate.remove_repeated_dynamics(selection: abjad.select.Selection, *, ignore_hairpins: bool = False, reset_after_rests: bool = False, reset_after_duration: Optional[Union[float, int, str, tuple, abjad.duration.Duration]] = None) → None[source]¶
Mutates an input
abjad.Selection
in place and has no return value; this function removes all consecutive repeated dynamic markings.- Basic usage:
When two consecutive leaves have identical dynamics, the second one is removed:
>>> staff = abjad.Staff(r"\time 3/8 c'4\pp d'8\pp | c'4\f d'8\f") >>> abjad.show(staff)
>>> auxjad.mutate.remove_repeated_dynamics(staff[:]) >>> abjad.show(staff)
Note
Auxjad automatically adds this function as an extension function to
abjad.mutate
. It can thus be used from eitherauxjad.mutate
orabjad.mutate
namespaces. Therefore, the two lines below are equivalent:>>> auxjad.mutate.remove_repeated_dynamics(staff[:]) >>> abjad.mutate.remove_repeated_dynamics(staff[:])
- Dynamic structure:
The function also removes dynamics that are separated by an arbitrary number of leaves without dynamics:
>>> staff = abjad.Staff(r"\time 3/8 c'4\p d'8 | e'4.\p | c'4\p d'8\f") >>> abjad.show(staff)
>>> auxjad.mutate.remove_repeated_dynamics(staff[:]) >>> abjad.show(staff)
- Subcontainers:
The container from which the selection is made can also have subcontainers:
>>> staff = abjad.Staff([abjad.Note("c'2"), ... abjad.Chord("<d' f'>2"), ... abjad.Tuplet((2, 3), "g2 a2 b2"), ... ]) >>> abjad.attach(abjad.Dynamic('ppp'), staff[0]) >>> abjad.attach(abjad.Dynamic('ppp'), staff[1]) >>> abjad.attach(abjad.Dynamic('ppp'), staff[2][0]) >>> abjad.show(staff)
>>> auxjad.mutate.remove_repeated_dynamics(staff[:]) >>> abjad.show(staff)
ignore_hairpins
:By default, repeated dynamics with hairpins in between are not removed, but consecutive ones will.
>>> staff = abjad.Staff(r"c'2\p\< d'2\f\> | c'2\f d'2\f | e'1\p") >>> abjad.show(staff)
>>> auxjad.mutate.remove_repeated_dynamics(staff[:]) >>> abjad.show(staff)
To override the previous behaviour, set
ignore_hairpins=True
and hairpins will be ignored.>>> staff = abjad.Staff(r"c'2\p\< d'2\f\> | c'2\f d'2\f | e'1\p") >>> abjad.show(staff)
>>> auxjad.mutate.remove_repeated_dynamics( ... staff[:], ... ignore_hairpins=True, ... ) >>> abjad.show(staff)
reset_after_rests
:By default, rests are treated just like any other leaf and thus notes with an identical dynamic separated by an arbitrary number of rests will be considered as repeated and the second dynamic will be removed.
>>> staff = abjad.Staff(r"c'4\pp r2. | c'1\pp") >>> auxjad.mutate.remove_repeated_dynamics(staff[:]) >>> abjad.show(staff)
To override the previous behaviour, set
reset_after_rests
toTrue
and dynamics will always be restated after a rest.>>> staff = abjad.Staff(r"c'4\pp r2. | c'1\pp") >>> auxjad.mutate.remove_repeated_dynamics( ... staff[:], ... reset_after_rests=True, ... ) >>> abjad.show(staff)
reset_after_duration
:With
reset_after_rests
is set toTrue
, it is possible to specify a minimum duration of silence required for the dynamics to be restated using the argumentreset_after_duration
. It takes anabjad.Duration
or alsostr
,tuple
,float
, etc. This sets the maximum length of rests before which identical dynamics are restated. If the total length of rests falls below that value, then repeated dynamics are removed.In the case below, a rest of
r2
. is shorter than a duration of(4, 4)
, so the repeated dynamic is removed.>>> staff = abjad.Staff(r"c'4\pp r2. | c'1\pp") >>> auxjad.mutate.remove_repeated_dynamics( ... staff[:], ... reset_after_rests=True, ... reset_after_duration=(4, 4), ... ) >>> abjad.show(staff)
But setting the duration to
2/4
forces the dynamic to be restated.>>> staff = abjad.Staff(r"c'4\pp r2. | c'1\pp") >>> auxjad.mutate.remove_repeated_dynamics( ... staff[:], ... reset_after_rests=True, ... reset_after_duration=2 / 4, ... ) >>> abjad.show(staff)
reset_after_rests
:The function also handles measure rests with
reset_after_rests
.>>> staff = abjad.Staff(r"c'4\pp r2. | c'4\pp r2. | R1 | c'1\pp") >>> auxjad.mutate.remove_repeated_dynamics( ... staff[:], ... reset_after_rests=True, ... reset_after_duration=abjad.Duration(4, 4), ... ) >>> abjad.show(staff)
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.