The time module¶
Functionality to compute the time length of musical expressions.
-
class
Result(node, time)¶ Bases:
tupleThe result value (if not None) of the
position()andduration()methods.-
node¶ The topmost Music expression.
-
time¶ The position or duration time value.
-
-
class
Time(scope=None, wait=False)[source]¶ Bases:
objectCompute the length of musical expressions.
A
Scope, if given using thescopeparameter, is used to resolve include files. If no scope is given, only searches the current DOM document for variable assignments.If a scope is given, include commands are followed and
waitdetermines whether to wait for ongoing transformations of external DOM documents. If wait is False, and a transformation is not yet finished the include is not followed.An example:
>>> import parce, quickly.time >>> d = parce.Document(quickly.find('lilypond'), r''' ... music = { c4 d e f } ... ... { c2 \music g a b8 g f d } ... ''', transformer=True) >>> m = d.get_transform(True) >>> m.dump() <lily.Document (2 children)> ├╴<lily.Assignment music (3 children)> │ ├╴<lily.Identifier (1 child)> │ │ ╰╴<lily.Symbol 'music' [1:6]> │ ├╴<lily.EqualSign [7:8]> │ ╰╴<lily.MusicList (4 children) [9:21]> │ ├╴<lily.Note 'c' (1 child) [11:12]> │ │ ╰╴<lily.Duration Fraction(1, 4) [12:13]> │ ├╴<lily.Note 'd' [14:15]> │ ├╴<lily.Note 'e' [16:17]> │ ╰╴<lily.Note 'f' [18:19]> ╰╴<lily.MusicList (8 children) [23:49]> ├╴<lily.Note 'c' (1 child) [25:26]> │ ╰╴<lily.Duration Fraction(1, 2) [26:27]> ├╴<lily.IdentifierRef 'music' [28:34]> ├╴<lily.Note 'g' [35:36]> ├╴<lily.Note 'a' [37:38]> ├╴<lily.Note 'b' (1 child) [39:40]> │ ╰╴<lily.Duration Fraction(1, 8) [40:41]> ├╴<lily.Note 'g' [42:43]> ├╴<lily.Note 'f' [44:45]> ╰╴<lily.Note 'd' [46:47]> >>> t=quickly.time.Time() >>> t.position(m[1][0]) # first note in second expression Result(node=<lily.MusicList (8 children) [23:49]>, time=0) >>> t.position(m[1][1]) # \music identifier ref Result(node=<lily.MusicList (8 children) [23:49]>, time=Fraction(1, 2)) >>> t.position(m[1][2]) # the g after the \music ref Result(node=<lily.MusicList (8 children) [23:49]>, time=Fraction(3, 2)) >>> t.length(m[0][2]) # the \music expression Fraction(1, 1) >>> t.length(m[1]) # total length of second expression Fraction(3, 1) # referenced \music correctly counted in :) >>> t.duration(m[1][0], m[1][2])# length of "c2 \music g" part (g has duration 2) Result(node=<lily.MusicList (8 children) [23:49]>, time=Fraction(2, 1))
There are convenient methods to get the musical position of a parce
Cursor:>>> c = parce.Cursor(d, 44, 47) >>> c.text() # two notes 'f d' >>> t.cursor_position(c) # length or music before the cursor Result(node=<lily.MusicList (8 children) [23:49]>, time=Fraction(11, 4)) >>> t.cursor_duration(c) # duration of the selected music Result(node=<lily.MusicList (8 children) [23:49]>, time=Fraction(1, 4))
LilyPond music functions that alter durations are recognized, and are abstracted in simple transformations that alter log, dotcount and/or scaling. An example:
>>> from quickly.dom import read >>> m = read.lily(r"\tuplet 3/2 { c8 d e }") >>> t.length(m) Fraction(1, 4) >>> m[1][1] # a single note in the tuplet <lily.Note 'd'> >>> t.length(m[1][1]) Fraction(1, 12) >>> m = read.lily(r"\shiftDurations #1 #1 { c4 d e f }") >>> t.length(m) # note value halved and dot added, so should be 3/4 Fraction(3, 4) >>> m[2][2] <lily.Note 'e'> >>> t.length(m[2][2]) # autodiscovers the current duration transform Fraction(3, 16)
Note
As a
Timeinstance uses some caching for the duration of individual notes, don’t rely on its computations while also modifying durations of music notes, rests etc.-
wait= None¶ If True, parce transformations are waited for.
-
position(node, include=False)[source]¶ Return a
Resulttwo-tuple(node, time).The
nodeargument must be (a child of) aMusicinstance.The returned
nodeis the topmost Music element, and thetimeis the computed length of all preceding music nodes. Ifincludeis True, the node’s length itself is also added.
-
duration(start_node, end_node)[source]¶ Return a
Resulttwo-tuple(node, time) or None.The returned
nodeis the topmost Music element both nodes must be a descendant of. Both nodes must be (children of)Musicnodes. If they don’t share the same ancestor, None is returned. The returnedtimevalue can be negative when the end node precedes the start node.
-
cursor_position(cursor)[source]¶ Return a
Resulttwo-tuple(node, time) or None.The
nodeis the music expression the cursor is in, and thetimeis the time offset from the start of that expression to the cursor’s position.Returns None if the cursor is not in music.
-
cursor_duration(cursor)[source]¶ Return a
Resulttwo-tuple(node, time) or None.The
nodeis the music expression the cursor is in, and thetimeis the length of the selected music fragment.Returns None if there’s no selection or the selection’s start and/or end are not in music, or in different music expressions.
-
-
class
TimeContext(time, transform=None, properties=None)[source]¶ Bases:
objectEncapsulates the transform and properties during time calculations.
The transform (
Transform) determines the actual length of Durable objects, and the properties (Properties) are forwarded to child contexts, where inside thetime_length()of Music nodes values can be read and also modified.-
transform= None¶ The current Transform.
-
properties= None¶ The current Properties.
-
enter(node, time=None)[source]¶ Return a new TimeContext.
The returned TimeContext uses the new
Time(if given, otherwise the same as ours) and adds theTransformand thePropertiesof the specifiednodeto the current ones.
-
length(node, end=None)[source]¶ Return the length of any node.
Follows variable references using the scope (if given to the
Timeinstance) and callstime_length()for Music nodes. Returns 0 for any other, non-musical, node.
-