The rhythm module
Classes and convenience functions to manipulate the rhythm of music.
For all convenience functions: the music
argument may be a
parce.Document
, a parce Cursor
(optionally
only selecting a range of the document to edit), a node Range
or any Element
node (DOM tree).
- class EditRhythm[source]
Bases:
Edit
Base class for rhythm editing operations.
- static may_remove(node)[source]
Return True if the duration of this node may be removed.
A duration may not be removed if
node.duration_required
is True, or when the node’s right sibling has only the duration visible, such as is the case with an unpitched note or an empty lyric item.In that case, the current duration may not be removed, because the next duration would then be understood as the duration of the current node when rewriting the music text.
- class Remove[source]
Bases:
EditRhythm
Remove duration from Durable nodes, if allowed.
- class RemoveScaling[source]
Bases:
EditRhythm
Remove scaling from Durable nodes.
- class RemoveFractionScaling[source]
Bases:
EditRhythm
Remove scaling if it contains a fraction.
- class RhythmExplicit[source]
Bases:
EditRhythm
Add the current duration to all nodes that don’t have one.
- class RhythmImplicit[source]
Bases:
EditRhythm
Remove reoccurring durations.
- class RhythmImplicitPerLine[source]
Bases:
EditRhythm
Remove reoccurring durations within the same line, but always add a duration to the first Durable on a line.
This only works when editing from a parce Document, otherwise we don’t know the newlines in the original text. If there is no parce Document, the behaviour is the same as
RhythmImplicit
.
- class RhythmTransform(transform)[source]
Bases:
EditRhythm
Transform durations using a
Transform
.This can be used for all types of shift and scale operations. For example, to add a dot to all durations:
>>> from quickly.rhythm import RhythmTransform >>> from quickly.duration import Transform >>> from quickly.dom import read >>> music = read.lily_document(r"{ c4 d8 e16 f g2 }") >>> t = Transform(dotcount=1) # add a dot >>> RhythmTransform(t).edit(music) >>> music.write() '{ c4. d8. e16. f g2. }'
Remove a dot:
>>> t = Transform(dotcount=-1) >>> RhythmTransform(t).edit(music) >>> music.write() '{ c4 d8 e16 f g2 }'
Double durations:
>>> t = Transform(log=-1) >>> RhythmTransform(t).edit(music) >>> music.write() '{ c2 d4 e8 f g1 }'
Add a scaling factor:
>>> t = Transform(scale=1/3) >>> RhythmTransform(t).edit(music) >>> music.write() '{ c2*1/3 d4*1/3 e8*1/3 f g1*1/3 }'
Or modify all in one go:
>>> t = Transform(1, 1, 3) >>> RhythmTransform(t).edit(music) >>> music.write() '{ c4. d8. e16. f g2. }'
This function also modifies durations in
\tempo
,\tuplet
,\after
and\partial
commands.
- class CopyRhythm(explicit=False)[source]
Bases:
EditRhythm
Extract durations from a range in the form of (duration, scaling) tuples.
The durations are returned by
edit_range()
and thus also all other edit methods. Durables without duration yield a None ifexplicit
is False, otherwise the previous duration is repeated. Example:>>> from quickly.dom import read >>> music = read.lily_document(r"{ c4 d8 e16 f g2 }") >>> from quickly.rhythm import CopyRhythm >>> durations = CopyRhythm().edit(music) >>> durations [(Fraction(1, 4), 1), (Fraction(1, 8), 1), (Fraction(1, 16), 1), None, (Fraction(1, 2), 1.0)] >>> CopyRhythm(True).edit(music) [(Fraction(1, 4), 1), (Fraction(1, 8), 1), (Fraction(1, 16), 1), (Fraction(1, 16), 1), (Fraction(1, 2), 1)]
- readonly = True
If True, does not write back changes to the parce Document
- explicit
If True, yield every reoccurring duration explicit instead of None
- class PasteRhythm(durations, cycle=True)[source]
Bases:
EditRhythm
Paste durations such as returned by
CopyRhythm
into music.The durations are an iterable of either the two-tuple (duration, scaling) or None. If
cycle
is True, the pasted durations are endlessly repeated in the selected range. Example:>>> from fractions import Fraction >>> durations = [(Fraction(1, 4), 1), (Fraction(3, 16), 0.5), None] >>> from quickly.dom import read >>> music = read.lily_document(r"{ c4 d8 e16 f g2 }") >>> from quickly.rhythm import PasteRhythm >>> PasteRhythm(durations).edit(music) >>> music.write() '{ c4 d8.*1/2 e f4 g8.*1/2 }'
- remove(music)[source]
Remove all durations from music.
Does not remove the duration from
\skip
and Unpitched notes, and also not from durables that immediately precede Unpitched notes (or empty lyric items), because the Unpitched’s duration would then be mistakenly held for the duration of the preceding note.
- remove_fraction_scaling(music)[source]
Remove all scalings that contain a fraction (like
1/3
) from the durations in music.
- implicit(music, per_line=False)[source]
Remove all reoccuring durations from the music.
If
per_line
is True, the first duration in a text line is not removed, but rather added if absent. (This only works when editing a parce document or cursor, otherwise we can’t know the newlines in the original text.)An example:
>>> import parce >>> import quickly.rhythm >>> d=parce.Document(quickly.find('lilypond'), r'''music = { ... c4 d8 e8 f8 g8 a4 ... g f e4 d ... c d4 e2 ... } ... ''', transformer=True) >>> quickly.rhythm.implicit(d, True) >>> print(d.text()) music = { c4 d8 e f g a4 g4 f e d c4 d e2 }
- transform(music, log=0, dotcount=0, scale=1)[source]
Transform durations in music by modifying log, dot count and/or scaling.
Increasing the log by 1 halves the durations, decreasing the log doubles them. (See also the
duration
module.) An example, where the duration is halved and one dot is added:>>> from quickly.dom import read >>> from quickly import rhythm >>> m = read.lily_document("{ c4 d8 e16 f g2 }") >>> rhythm.transform(m, 1, 1) >>> m.write() '{ c8. d16. e32. f g4. }'
This function also modifies durations in
\tempo
,\tuplet
,\after
and\partial
commands.
- copy(music, explicit=False)[source]
Extract durations from music.
Every duration is a two-tuple of integers or fractions (duration, scaling), or, if
explicit
is False, None for Durables without duration. Ifexplicit
is True, the previous duration is repeated for Durables without duration.
- paste(music, durations, cycle=True)[source]
Replace durations in the music with the specified durations.
Every duration is a two-tuple of integers or fractions (duration, scaling), or None for Durables without duration. If
cycle
is True, the pasted durations are endlessly repeated in the selected range. An example:>>> from quickly.dom import read >>> from quickly.rhythm import copy, paste >>> durs = copy(read.lily_document("{ 8. 16 8 }")) >>> durs [(Fraction(3, 16), 1.0), (Fraction(1, 16), 1.0), (Fraction(1, 8), 1.0)] >>> music = read.lily_document("{ g a g c d c a b a f g f }") >>> paste(music, durs) >>> music.write() '{ g8. a16 g8 c8. d16 c8 a8. b16 a8 f8. g16 f8 }'