music21.duration¶
The duration module contains Duration
objects
(among other objects and functions). Duration objects are a fundamental
component of Note
and all Music21Objects, such as
TimeSignature
objects.
Containers such as Stream
and
Score
also have durations which are equal to the
position of the ending of the last object in the Stream.
Music21 Durations are almost always measured in Quarter Notes, so an eighth note has a duration of 0.5. Different Duration-like objects support objects such as grace notes which take no duration on the page, have a short (but real) duration when played, and have a duration-type representation when performed.
Example usage:
>>> d = duration.Duration()
>>> d.quarterLength = 0.5
>>> d.type
'eighth'
>>> d.type = 'whole'
>>> d.quarterLength
4.0
>>> d.quarterLength = 0.166666666
>>> d.type
'16th'
>>> d.tuplets[0].numberNotesActual
3
>>> d.tuplets[0].numberNotesNormal
2
Duration¶
- class music21.duration.Duration(typeOrDuration: str | OffsetQLIn | DurationTuple | None = None, /, *, type: str | None = None, dots: int | None = 0, quarterLength: OffsetQLIn | None = None, durationTuple: DurationTuple | None = None, components: Iterable[DurationTuple] | None = None, client: base.Music21Object | None = None, **keywords)¶
Durations are one of the most important objects in music21. A Duration represents a span of musical time measurable in terms of quarter notes (or in advanced usage other units). For instance, “57 quarter notes” or “dotted half tied to quintuplet sixteenth note” or simply “quarter note.”
A Duration object is made of one or more immutable DurationTuple objects stored on the components list. A Duration created by setting quarterLength sets the attribute
expressionIsInferred
to True, which indicates that callers (such assplitElementsToCompleteTuplets()
) can express this Duration using another combination of components that sums to the quarterLength. Otherwise, expressionIsInferred is set to False, indicating that components are not allowed to mutate.Multiple DurationTuples in a single Duration may be used to express tied notes, or may be used to split duration across barlines or beam groups. Some Duration objects are not expressible as a single notation unit.
Duration objects are not Music21Objects.
If a single argument is passed to Duration() and it is a string, then it is assumed to be a type, such as ‘half’, ‘eighth’, or ‘16th’, etc. If that single argument is a number then it is assumed to be a quarterLength (2 for half notes, 0.5 for eighth notes, 0.75 for dotted eighth notes, 0.333333333 for a triplet eighth, etc.). If one or more named arguments are passed then the Duration() is configured according to those arguments. Supported arguments are ‘type’, ‘dots’, ‘quarterLength’, or ‘components’.
Example 1: a triplet eighth configured by quarterLength:
>>> d = duration.Duration(0.333333333) >>> d.type 'eighth'
>>> d.tuplets (<music21.duration.Tuplet 3/2/eighth>,)
Example 2: A Duration made up of multiple
music21.duration.DurationTuple
objects automatically configured by the specified quarterLength.>>> d2 = duration.Duration(0.625) >>> d2.type 'complex'
>>> d2.components (DurationTuple(type='eighth', dots=0, quarterLength=0.5), DurationTuple(type='32nd', dots=0, quarterLength=0.125))
>>> d2.expressionIsInferred True
Example 3: A Duration configured by keywords.
>>> d3 = duration.Duration(type='half', dots=2) >>> d3.quarterLength 3.5 >>> d3.expressionIsInferred False
Duration
bases
Duration
read-only properties
- Duration.fullName¶
Return the most complete representation of this Duration, providing dots, type, tuplet, and quarter length representation.
>>> d = duration.Duration(quarterLength=1.5) >>> d.fullName 'Dotted Quarter'
>>> d = duration.Duration(type='half') >>> d.fullName 'Half'
>>> d = duration.Duration(quarterLength=1.25) >>> d.fullName 'Quarter tied to 16th (1 1/4 total QL)'
>>> d = duration.Duration(quarterLength=0.333333) >>> d.fullName 'Eighth Triplet (1/3 QL)'
>>> d = duration.Duration(quarterLength=0.666666) >>> d.fullName 'Quarter Triplet (2/3 QL)'
>>> d = duration.Duration(quarterLength=0.571428) >>> d.fullName 'Quarter Septuplet (4/7 QL)'
>>> d = duration.Duration(quarterLength=0) >>> d.fullName 'Zero Duration (0 total QL)'
- Duration.isComplex¶
Returns True if this Duration has more than one DurationTuple object on the component list. That is to say if it’s a single Duration that need multiple tied noteheads to represent.
>>> aDur = duration.Duration() >>> aDur.quarterLength = 1.375 >>> aDur.isComplex True
>>> len(aDur.components) 2
>>> aDur.components (DurationTuple(type='quarter', dots=0, quarterLength=1.0), DurationTuple(type='16th', dots=1, quarterLength=0.375))
>>> cDur = duration.Duration() >>> cDur.quarterLength = 0.25 >>> cDur.isComplex False
>>> len(cDur.components) 1
- Duration.ordinal¶
Get the ordinal value of the Duration, where whole is 4, half is 5, etc.
>>> d = duration.Duration() >>> d.quarterLength = 2.0 >>> d.ordinal 5 >>> d.type = '16th' >>> d.ordinal 8
Complex values have an ordinal of the string ‘complex’. This might change to NaN in a later version.
>>> d.quarterLength = 2.5 >>> d.ordinal 'complex'
Zero durations have an ordinal of None
>>> d2 = duration.Duration(0.0) >>> print(d2.ordinal) None
- Duration.quarterLengthNoTuplets¶
Returns the quarter length of the duration without taking into account triplets.
Does not cache.
>>> d = duration.Duration(1/3) >>> d.quarterLengthNoTuplets 0.5
Read-only properties inherited from ProtoM21Object
:
Duration
read/write properties
- Duration.components¶
Returns or sets a tuple of the component DurationTuples of this Duration object
>>> d = duration.Duration(1.0) >>> d.components (DurationTuple(type='quarter', dots=0, quarterLength=1.0),)
Tuplets do not have the tuplet in their components.
>>> d = duration.Duration(1/3) >>> d.components (DurationTuple(type='eighth', dots=0, quarterLength=0.5),)
With a complex duration it becomes clearer why multiple components are needed. Here is a duration that cannot be expressed as a single note.
>>> d = duration.Duration(1.25) >>> d.type 'complex' >>> d.components (DurationTuple(type='quarter', dots=0, quarterLength=1.0), DurationTuple(type='16th', dots=0, quarterLength=0.25))
But it can be expressed another way and will output in that way in MusicXML and other readers:
>>> component0 = duration.DurationTuple(type='eighth', dots=0, quarterLength=0.5) >>> component1 = duration.DurationTuple(type='eighth', dots=1, quarterLength=0.75) >>> d.components = [component0, component1]
It is allowed but not advised to set components that do not add up to the current (pre-tuplet) quarterLength. In which case the quarterLength will be adjusted:
>>> d.components = [component0] >>> d <music21.duration.Duration 0.5> >>> d.type 'eighth'
- Duration.dotGroups¶
Dot groups are a convenience for transcribing medieval music. They represent dotted-dotted notes (written one above another). For instance a half note with dotGroups = (1, 1) represents a dotted half note that is itself dotted. Worth 9 eighth notes (dotted-half tied to dotted-quarter). It is not the same as a double-dotted half note, which is only worth 7 eighth notes.
>>> a = duration.Duration() >>> a.type = 'half' >>> a.dotGroups (0,) >>> a.dots = 1
>>> a.dotGroups = (1, 1) >>> a.quarterLength 4.5
- Duration.dots¶
Returns or sets the number of dots in the Duration if it is a simple Duration.
For returning only the number of dots on the first component is returned for complex durations. (Previously it could return None if it was not a simple duration which led to some terribly difficult to find errors.)
>>> a = duration.Duration() >>> a.type = 'quarter' >>> a.dots = 1 >>> a.quarterLength 1.5 >>> a.dots = 2 >>> a.quarterLength 1.75
If a duration is complex then setting dots has the effect of setting the number of dots to value on every component.
>>> DT = duration.durationTupleFromTypeDots >>> complexDuration = duration.Duration() >>> complexDuration.addDurationTuple(DT('half', 0)) >>> complexDuration.addDurationTuple(DT('eighth', 2)) >>> complexDuration.type 'complex' >>> complexDuration.quarterLength 2.875
In a complex duration, the number of dots comes from the first component:
>>> complexDuration.dots 0
But if set, applies to all components:
>>> complexDuration.dots = 1 >>> complexDuration.components (DurationTuple(type='half', dots=1, quarterLength=3.0), DurationTuple(type='eighth', dots=1, quarterLength=0.75)) >>> complexDuration.quarterLength 3.75
Dots can go pretty high.
>>> d = duration.Duration('half') >>> d.quarterLength 2.0 >>> d.dots = 5 >>> d.quarterLength 3.9375 >>> d.dots = 10 >>> d.quarterLength 3.998046875
Infinite dots gives an Easter egg:
>>> from math import inf >>> d.type = 'half' >>> d.dots = inf >>> d.quarterLength 4.0 >>> d.dots 0 >>> d.type 'whole'
- Duration.linked¶
Gets or sets the .linked property – if linked (default) then type, dots, tuplets are always coherent with quarterLength. If not, then they are separate.
>>> d = duration.Duration(0.5) >>> d.linked True
Linked durations change other values when one changes:
>>> d.type = '16th' >>> d.quarterLength 0.25
Unlinked values do not:
>>> d.linked = False >>> d.type = 'half' >>> d.quarterLength 0.25
- Duration.quarterLength¶
Returns the quarter note length or Sets the quarter note length to the specified value. May be expressed as a float or Fraction.
Currently (if the value is different from what is already stored) this wipes out any existing components, not preserving their type. So if you’ve set up Duration(1.5) as 3-eighth notes, setting Duration to 1.75 will NOT dot the last eighth note, but instead give you a single double-dotted half note.
>>> a = duration.Duration() >>> a.quarterLength = 3.5 >>> a.quarterLength 3.5
>>> for thisUnit in a.components: ... print(duration.unitSpec(thisUnit)) (3.5, 'half', 2, None, None, None)
>>> a.quarterLength = 2.5 >>> a.quarterLength 2.5
>>> for thisUnit in a.components: ... print(duration.unitSpec(thisUnit)) (2.0, 'half', 0, None, None, None) (0.5, 'eighth', 0, None, None, None)
Note that integer values of quarter lengths get silently converted to floats (internally opFracs):
>>> b = duration.Duration() >>> b.quarterLength = 5 >>> b.quarterLength 5.0 >>> b.type # complex because 5qL cannot be expressed as a single note. 'complex'
Float values will be converted to fractions if they are inexpressible exactly as floats:
>>> b = duration.Duration() >>> b.quarterLength = 1/3 >>> b.quarterLength Fraction(1, 3)
- Duration.tuplets¶
Return a tuple of Tuplet objects. Setting tuplets will inform the client (Note) that the duration has changed.
- Duration.type¶
Get or set the type of the Duration.
>>> a = duration.Duration() >>> a.type = 'half' >>> a.quarterLength 2.0
>>> a.type= '16th' >>> a.quarterLength 0.25
Duration
methods
- Duration.__eq__(other)¶
Two durations are the same if their type, dots, tuplets, and quarterLength are all the same.
>>> aDur = duration.Duration('quarter') >>> bDur = duration.Duration('16th') >>> cDur = duration.Duration('16th') >>> aDur == bDur False >>> aDur != bDur True
>>> cDur == bDur True
>>> dDur = duration.Duration(0.0) >>> eDur = duration.Duration(0.0) >>> dDur == eDur True
>>> tupDur1 = duration.Duration(2 / 3) >>> tupDur2 = duration.Duration(2 / 3) >>> tupDur1 == tupDur2 True
>>> graceDur1 = tupDur1.getGraceDuration() >>> graceDur1 == tupDur1 False >>> graceDur2 = tupDur2.getGraceDuration() >>> graceDur1 == graceDur2 True
Link status must be the same:
>>> tupDur1.linked = False >>> tupDur1 == tupDur2 False
- Duration.addDurationTuple(dur: DurationTuple | Duration | str | int | float | Fraction, *, _skipInform=False)¶
Add a DurationTuple or a Duration’s components to this Duration. Does not simplify the Duration. For instance, adding two quarter notes results in two tied quarter notes, not one half note. See consolidate below for more info on how to do that.
>>> a = duration.Duration('quarter') >>> b = duration.durationTupleFromTypeDots('quarter', 0) >>> a.addDurationTuple(b) >>> a.quarterLength 2.0 >>> a.type 'complex'
- Duration.aggregateTupletMultiplier() float | Fraction ¶
Returns the multiple of all the tuplet multipliers as an opFrac.
This method is needed for MusicXML time-modification among other places.
No tuplets:
>>> complexDur = duration.Duration('eighth') >>> complexDur.aggregateTupletMultiplier() 1.0
With tuplets:
>>> complexDur.appendTuplet(duration.Tuplet()) >>> complexDur.aggregateTupletMultiplier() Fraction(2, 3)
Nested tuplets are possible…
>>> tup2 = duration.Tuplet() >>> tup2.setRatio(5, 4) >>> complexDur.appendTuplet(tup2) >>> complexDur.aggregateTupletMultiplier() Fraction(8, 15)
- Duration.appendTuplet(newTuplet: Tuplet) None ¶
Adds a new Tuplet to a Duration, sets the Tuplet’s .frozen state to True, and then informs the client (Note) that the duration has changed.
>>> tup = duration.Tuplet(3, 2) >>> d = duration.Duration(1.0) >>> d.appendTuplet(tup) >>> d.quarterLength Fraction(2, 3) >>> t2 = duration.Tuplet(5, 4) >>> d.appendTuplet(t2) >>> d.quarterLength Fraction(8, 15) >>> tup.frozen True
- Duration.augmentOrDiminish(amountToScale, retainComponents=False)¶
Given a number greater than zero, creates a new Duration object after multiplying the current quarterLength of the duration by the number and resets the components for the duration (by default).
Returns a new duration that has the new length.
>>> aDur = duration.Duration() >>> aDur.quarterLength = 1.5 # dotted quarter >>> cDur = aDur.augmentOrDiminish(2) >>> cDur.quarterLength 3.0 >>> cDur.type 'half' >>> cDur.dots 1
aDur is not changed:
>>> aDur <music21.duration.Duration 1.5>
A complex duration that cannot be expressed as a single notehead (component)
>>> bDur = duration.Duration() >>> bDur.quarterLength = 2.125 # requires components >>> bDur.quarterLength 2.125 >>> len(bDur.components) 2 >>> bDur.components (DurationTuple(type='half', dots=0, quarterLength=2.0), DurationTuple(type='32nd', dots=0, quarterLength=0.125))
By default, when augmenting or diminishing, we will delete any unusual components or tuplets:
>>> dDur = duration.Duration(1.5) >>> dDur.appendTuplet(duration.Tuplet(3, 2)) >>> dDur <music21.duration.Duration 1.0> >>> dDur.dots 1 >>> dDur.tuplets (<music21.duration.Tuplet 3/2>,)
>>> eDur = dDur.augmentOrDiminish(2) >>> eDur <music21.duration.Duration 2.0> >>> eDur.dots 0 >>> eDur.tuplets ()
>>> eRetain = dDur.augmentOrDiminish(2, retainComponents=True) >>> eRetain <music21.duration.Duration 2.0> >>> eRetain.dots 1 >>> eRetain.tuplets (<music21.duration.Tuplet 3/2>,)
>>> fDur = duration.Duration(1.0) >>> fDur.addDurationTuple(duration.DurationTuple('quarter', 0, 1.0)) >>> fDur <music21.duration.Duration 2.0> >>> fDur.components (DurationTuple(type='quarter', dots=0, quarterLength=1.0), DurationTuple(type='quarter', dots=0, quarterLength=1.0))
>>> gDur = fDur.augmentOrDiminish(0.5) >>> gDur.components (DurationTuple(type='quarter', dots=0, quarterLength=1.0),)
>>> gRetain = fDur.augmentOrDiminish(0.5, retainComponents=True) >>> gRetain.components (DurationTuple(type='eighth', dots=0, quarterLength=0.5), DurationTuple(type='eighth', dots=0, quarterLength=0.5))
Negative values raise ValueError:
>>> fDur.augmentOrDiminish(-1) Traceback (most recent call last): ValueError: amountToScale must be greater than zero
- Duration.clear() None ¶
Permit all components to be removed. This is needed for resetting to zero duration.
>>> a = duration.Duration() >>> a.quarterLength = 6 >>> a.type 'whole' >>> a.components (DurationTuple(type='whole', dots=1, quarterLength=6.0),)
>>> a.clear()
>>> a.dots 0 >>> a.components () >>> a.type 'zero' >>> a.quarterLength 0.0
- Duration.componentIndexAtQtrPosition(quarterPosition)¶
returns the index number of the duration component sounding at the given quarter position.
Note that for 0 and the last value, the object is returned.
>>> components = [] >>> components.append(duration.Duration('quarter')) >>> components.append(duration.Duration('quarter')) >>> components.append(duration.Duration('quarter'))
>>> a = duration.Duration() >>> a.components = components >>> a.quarterLength 3.0 >>> a.componentIndexAtQtrPosition(0.5) 0 >>> a.componentIndexAtQtrPosition(1.5) 1 >>> a.componentIndexAtQtrPosition(2.5) 2
this is odd behavior:
e.g. given d1, d2, d3 as 3 quarter notes and self.components = [d1, d2, d3]
then
self.componentIndexAtQtrPosition(1.5) == d2 self.componentIndexAtQtrPosition(2.0) == d3 self.componentIndexAtQtrPosition(2.5) == d3
Currently sometimes returns the component itself. Changing in v7.
- Duration.componentStartTime(componentIndex: int) float ¶
For a valid component index value, this returns the quarter note offset at which that component would start.
This does not handle fractional arguments.
>>> components = [] >>> qdt = duration.DurationTuple('quarter', 0, 1.0) >>> components.append(qdt) >>> components.append(qdt) >>> components.append(qdt)
>>> a = duration.Duration() >>> a.components = components >>> a.quarterLength 3.0 >>> a.componentStartTime(0) 0.0 >>> a.componentStartTime(1) 1.0 >>> a.componentStartTime(3) Traceback (most recent call last): IndexError: invalid component index value 3 submitted; value must be an integer between 0 and 2
- Duration.consolidate()¶
Given a Duration with multiple components, consolidate into a single Duration. This can only be based on quarterLength; this is destructive: information is lost from components.
This cannot be done for all Durations, as DurationTuples cannot express all durations
>>> a = duration.Duration(1) >>> a.addDurationTuple(duration.DurationTuple('half', 0, 2.0)) >>> a.addDurationTuple(duration.DurationTuple('quarter', 0, 1.0)) >>> a.quarterLength 4.0 >>> len(a.components) 3 >>> a.type 'complex'
After consolidate:
>>> a.consolidate() >>> a.quarterLength 4.0 >>> len(a.components) 1
It gains a type!
>>> a.type 'whole'
If the type cannot be expressed then the type is inexpressible
>>> a = duration.Duration(1) >>> a.addDurationTuple(duration.DurationTuple('half', 0, 2.0)) >>> a.addDurationTuple(duration.DurationTuple('half', 0, 2.0)) >>> a.quarterLength 5.0 >>> len(a.components) 3 >>> a.type 'complex'
After consolidate:
>>> a.consolidate() >>> a.quarterLength 5.0 >>> len(a.components) 1 >>> a.components (DurationTuple(type='inexpressible', dots=0, quarterLength=5.0),)
It gains a type!
>>> a.type 'inexpressible'
For an ‘inexpressible’ duration, the opposite of consolidate is to set the duration’s quarterLength to itself. It won’t necessarily return to the original components, but it will usually create something that can be notated.
>>> a.quarterLength = a.quarterLength >>> a.type 'complex' >>> a.components (DurationTuple(type='whole', dots=0, quarterLength=4.0), DurationTuple(type='quarter', dots=0, quarterLength=1.0))
- Duration.currentComponents()¶
Advanced Method:
returns the current components WITHOUT running the component updater.
Needed by some internal methods. Components are made on the fly.
>>> d = duration.Duration(1.25) >>> d.currentComponents() ()
Like in quantum physics, an observation affects the state:
>>> d.type 'complex' >>> d.currentComponents() (DurationTuple(type='quarter', dots=0, quarterLength=1.0), DurationTuple(type='16th', dots=0, quarterLength=0.25))
Generally, just look at .components
>>> d = duration.Duration(1.25) >>> d.components (DurationTuple(type='quarter', dots=0, quarterLength=1.0), DurationTuple(type='16th', dots=0, quarterLength=0.25))
- Duration.getGraceDuration(appoggiatura=False) GraceDuration | AppoggiaturaDuration ¶
Return a deepcopy of this Duration as a GraceDuration instance with the same types.
>>> d = duration.Duration(1.25) >>> d <music21.duration.Duration 1.25> >>> d.components (DurationTuple(type='quarter', dots=0, quarterLength=1.0), DurationTuple(type='16th', dots=0, quarterLength=0.25))
>>> gd = d.getGraceDuration() >>> gd <music21.duration.GraceDuration unlinked type:complex quarterLength:0.0> >>> gd.quarterLength 0.0 >>> gd.components (DurationTuple(type='quarter', dots=0, quarterLength=0.0), DurationTuple(type='16th', dots=0, quarterLength=0.0))
d is unchanged.
>>> d.quarterLength 1.25
- Duration.informClient() bool ¶
A method that tells the client that something has changed.
Call informSites({‘changedAttribute’: ‘duration’, ‘quarterLength’: quarterLength}) on any call that changes the quarterLength, so that the client can make a change.
Returns False if there was no need to inform the client (like nothing has changed) or if .client is None. Otherwise returns True.
- Duration.sliceComponentAtPosition(quarterPosition)¶
Given a quarter position within a component, divide that component into two components.
>>> d = duration.Duration() >>> d.clear() # need to remove default >>> components = []
>>> d.addDurationTuple(duration.Duration('quarter')) >>> d.addDurationTuple(duration.Duration('quarter')) >>> d.addDurationTuple(duration.Duration('quarter')) >>> d.quarterLength 3.0 >>> d.sliceComponentAtPosition(0.5) >>> d.quarterLength 3.0 >>> len(d.components) 4 >>> d.components[0].type 'eighth' >>> d.components[1].type 'eighth' >>> d.components[2].type 'quarter'
- Duration.splitDotGroups(*, inPlace=False)¶
splits a dotGroup-duration (of 1 component) into a new duration of two components. Returns a new duration
Probably does not handle properly tuplets of dot-groups. Never seen one, so probably okay.
>>> d1 = duration.Duration(type='half') >>> d1.dotGroups = (1, 1) >>> d1.quarterLength 4.5 >>> d2 = d1.splitDotGroups() >>> d2.components (DurationTuple(type='half', dots=1, quarterLength=3.0), DurationTuple(type='quarter', dots=1, quarterLength=1.5)) >>> d2.quarterLength 4.5
Here’s how a system that does not support dotGroups can still display the notes accurately. N.B. MusicXML does this automatically, so no need.
>>> n1 = note.Note() >>> n1.duration = d1 >>> n1.duration = n1.duration.splitDotGroups() >>> n1.duration.components (DurationTuple(type='half', dots=1, quarterLength=3.0), DurationTuple(type='quarter', dots=1, quarterLength=1.5))
>>> s1 = stream.Stream() >>> s1.append(meter.TimeSignature('9/8')) >>> s1.append(n1) >>> s1.show('lily.png') .. image:: images/duration_splitDotGroups.*
>>> n2 = note.Note() >>> n2.duration.type = 'quarter' >>> n2.duration.dotGroups = (1, 1) >>> n2.quarterLength 2.25 >>> n2.show() # generates a dotted-quarter tied to dotted-eighth >>> n2.duration.splitDotGroups(inPlace=True) >>> n2.duration.dotGroups (1,) >>> n2.duration.components (DurationTuple(type='quarter', dots=1, quarterLength=1.5), DurationTuple(type='eighth', dots=1, quarterLength=0.75))
>>> n2 = note.Note() >>> n2.duration.type = 'quarter' >>> n2.duration.dotGroups = (1, 1, 1) >>> n2.quarterLength 3.375 >>> dSplit = n2.duration.splitDotGroups() >>> dSplit.quarterLength 3.375 >>> dSplit.components (DurationTuple(type='quarter', dots=1, quarterLength=1.5), DurationTuple(type='eighth', dots=1, quarterLength=0.75), DurationTuple(type='eighth', dots=1, quarterLength=0.75), DurationTuple(type='16th', dots=1, quarterLength=0.375))
Does NOT handle tuplets etc.
Methods inherited from ProtoM21Object
:
Duration
instance variables
- Duration.client¶
A duration’s “client” is the object that holds this duration as a property. It is informed whenever the duration changes.
>>> n = note.Note('C#5', type='whole') >>> d = n.duration >>> d.client is n True
- Duration.expressionIsInferred¶
Boolean indicating whether this duration was created from a number rather than a type and thus can be changed to another expression. For instance the duration of 0.5 is generally an eighth note, but in the middle of a triplet group might be better written as a dotted-eighth triplet. If expressionIsInferred is True then music21 can change it according to complex. If False, then the type, dots, and tuplets are considered immutable.
>>> d = duration.Duration(0.5) >>> d.expressionIsInferred True
>>> d = duration.Duration('eighth') >>> d.expressionIsInferred False
Tuplet¶
- class music21.duration.Tuplet(numberNotesActual: int = 3, numberNotesNormal: int = 2, durationActual: DurationTuple | Duration | str | tuple[str, int] | None = None, durationNormal: DurationTuple | Duration | str | tuple[str, int] | None = None, *, tupletId: int = 0, nestedLevel: int = 1, type: Literal['start', 'stop', 'startStop', False, None] = None, bracket: Literal[True, False, 'slur'] = True, placement: Literal['above', 'below'] = 'above', tupletActualShow: Literal['number', 'type', 'both', None] = 'number', tupletNormalShow: Literal['number', 'type', 'both', None] = None, frozen: bool = False, **keywords)¶
A tuplet object is a representation of a musical tuplet (like a triplet). It expresses a ratio that modifies duration values and are stored in Duration objects in a “tuple” (immutable list; since there can be nested tuplets) in the duration’s .tuplets property.
The primary representation uses two pairs of note numbers and durations.
The first pair of note numbers and durations describes the representation within the tuplet, or the value presented by the context. This is called “actual.” In a standard 8th note triplet this would be 3, eighth, meaning that a complete collection of this tuplet will be visually represented as three eighth notes. These attributes are numberNotesActual, durationActual.
The second pair of note numbers and durations describes the space that would have been occupied in a normal context. This is called “normal.” In a standard 8th note triplet this would be 2, eighth, meaning that a complete collection of notes under this tuplet will occupy the space of two eighth notes. These attributes are numberNotesNormal, durationNormal.
If duration values are not provided then durationActual and durationNormal are left as None – meaning that it is unspecified what the duration that completes the tuplet is. And this tuplet just represents a Ratio. PRIOR TO v4 durationActual and durationNormal were assumed to be eighths.
If only one duration, either durationActual or durationNormal, is provided, both are set to the same value.
Note that this is a duration modifier, or a generator of ratios to scale quarterLength values in Duration objects.
>>> myTup = duration.Tuplet(numberNotesActual=5, numberNotesNormal=4) >>> print(myTup.tupletMultiplier()) 4/5
We know that it is 5 in the place of 4, but 5 what in the place of 4 what?
>>> myTup.durationActual is None True >>> myTup <music21.duration.Tuplet 5/4>
But we can change that:
>>> myTup.setDurationType('eighth') >>> myTup.durationActual DurationTuple(type='eighth', dots=0, quarterLength=0.5) >>> myTup <music21.duration.Tuplet 5/4/eighth>
In this case, the tupletMultiplier is a float because it can be expressed as a binary number:
>>> myTup2 = duration.Tuplet(8, 5) >>> tm = myTup2.tupletMultiplier() >>> tm 0.625
Here, six sixteenth notes occupy the space of four sixteenth notes.
>>> myTup2 = duration.Tuplet(6, 4, '16th') >>> print(myTup2.durationActual.type) 16th >>> print(myTup2.durationNormal.type) 16th
>>> print(myTup2.tupletMultiplier()) 2/3
Tuplets may be frozen, in which case they become immutable. Tuplets which are attached to Durations are automatically frozen. Otherwise a tuplet could change without the attached duration knowing about it, which would be a real problem.
>>> myTup.frozen = True >>> myTup.tupletActual = [3, 2] Traceback (most recent call last): music21.duration.TupletException: A frozen tuplet (or one attached to a duration) has immutable length.
>>> myHalf = duration.Duration('half') >>> myHalf.appendTuplet(myTup2) >>> myTup2.tupletActual = [5, 4] Traceback (most recent call last): music21.duration.TupletException: A frozen tuplet (or one attached to a duration) has immutable length.
Note that if you want to create a note with a simple Tuplet attached to it, you can just change the quarterLength of the note:
>>> myNote = note.Note('C#4') >>> myNote.duration.quarterLength = 0.8 >>> myNote.duration.quarterLength Fraction(4, 5) >>> myNote.duration.fullName 'Quarter Quintuplet (4/5 QL)'
>>> myNote.duration.tuplets (<music21.duration.Tuplet 5/4/quarter>,)
Tuplet
bases
Tuplet
read-only properties
- Tuplet.fullName¶
Return the most complete representation of this tuplet in a readable form.
>>> tup = duration.Tuplet(numberNotesActual=5, numberNotesNormal=2) >>> tup.fullName 'Quintuplet'
>>> tup = duration.Tuplet(numberNotesActual=3, numberNotesNormal=2) >>> tup.fullName 'Triplet'
>>> tup = duration.Tuplet(numberNotesActual=17, numberNotesNormal=14) >>> tup.fullName 'Tuplet of 17/14ths'
Read-only properties inherited from ProtoM21Object
:
Tuplet
read/write properties
- Tuplet.durationActual¶
durationActual is a DurationTuple that represents the notes that are actually present and counted in a tuplet. For instance, in a 7 dotted-eighth in the place of 2 double-dotted quarter notes tuplet, the duration actual would be this:
>>> d = duration.Tuplet(7, 2) >>> print(d.durationActual) None >>> d.durationActual = duration.Duration('eighth', dots=1)
Notice that the Duration object gets converted to a DurationTuple.
>>> d.durationActual DurationTuple(type='eighth', dots=1, quarterLength=0.75)
>>> d.durationActual = 'quarter' >>> d.durationActual DurationTuple(type='quarter', dots=0, quarterLength=1.0)
- Tuplet.durationNormal¶
durationNormal is a DurationTuple that represents the notes that would be present in the space normally (if there were no tuplets). For instance, in a 7 dotted-eighth in the place of 2 double-dotted quarter notes tuplet, the durationNormal would be:
>>> d = duration.Tuplet(7, 2) >>> print(d.durationNormal) None >>> d.durationNormal = duration.Duration('quarter', dots=2)
Notice that the Duration object gets converted to a DurationTuple:
>>> d.durationNormal DurationTuple(type='quarter', dots=2, quarterLength=1.75)
>>> d.durationNormal = 'half' >>> d.durationNormal DurationTuple(type='half', dots=0, quarterLength=2.0)
- Tuplet.tupletActual¶
Get or set a two element list of number notes actual and duration actual.
- Tuplet.tupletNormal¶
Get or set a two element list of number notes actual and duration normal.
Tuplet
methods
- Tuplet.__eq__(other) bool ¶
Two Tuplets are equal if their numbers are equal and durations are equal.
Visual details (type, bracket, placement, tupletActualShow, etc.) do not matter.
>>> triplet1 = duration.Tuplet(3, 2) >>> triplet2 = duration.Tuplet(3, 2) >>> triplet1 == triplet2 True >>> quadruplet = duration.Tuplet(4, 3) >>> triplet1 == quadruplet False >>> triplet3 = duration.Tuplet(3, 2, 'half') >>> triplet1 == triplet3 False
- Tuplet.augmentOrDiminish(amountToScale: int | float)¶
Given a number greater than zero, multiplies the current quarterLength of the duration by the number and resets the components for the duration (by default). Or if inPlace is set to False, returns a new duration that has the new length.
# TODO: add inPlace setting.
>>> a = duration.Tuplet() >>> a.setRatio(6, 2) >>> a.tupletMultiplier() Fraction(1, 3) >>> a.setDurationType('eighth') >>> a.durationActual DurationTuple(type='eighth', dots=0, quarterLength=0.5)
>>> c = a.augmentOrDiminish(0.5) >>> c.durationActual DurationTuple(type='16th', dots=0, quarterLength=0.25)
>>> c.tupletMultiplier() Fraction(1, 3)
Raises ValueError if amountToScale is negative.
>>> a.augmentOrDiminish(-1) Traceback (most recent call last): ValueError: amountToScale must be greater than zero
- Tuplet.setDurationType(durType: str | int | float | Fraction, dots: int = 0) None ¶
Set both durationActual and durationNormal from either a string type or a quarterLength. optional dots can add dots to a string type (or I suppose a quarterLength.)
>>> a = duration.Tuplet() >>> a.tupletMultiplier() Fraction(2, 3) >>> a.totalTupletLength() 1.0 >>> a.setDurationType('half') >>> a.durationNormal DurationTuple(type='half', dots=0, quarterLength=2.0) >>> a.tupletMultiplier() Fraction(2, 3) >>> a.totalTupletLength() 4.0 >>> a.setDurationType('half', dots=1) >>> a.durationNormal DurationTuple(type='half', dots=1, quarterLength=3.0) >>> a.totalTupletLength() 6.0
>>> a.setDurationType(2.0) >>> a.totalTupletLength() 4.0 >>> a.setDurationType(4.0) >>> a.totalTupletLength() 8.0
- Tuplet.setRatio(actual: int, normal: int) None ¶
Set the ratio of actual divisions to represented in normal divisions. A triplet is 3 actual in the time of 2 normal.
>>> a = duration.Tuplet() >>> a.tupletMultiplier() Fraction(2, 3) >>> a.setRatio(6, 2) >>> a.numberNotesActual 6 >>> a.numberNotesNormal 2 >>> a.tupletMultiplier() Fraction(1, 3)
One way of expressing 6/4-ish triplets without numbers:
>>> a = duration.Tuplet() >>> a.setRatio(3, 1) >>> a.durationActual = duration.durationTupleFromTypeDots('quarter', 0) >>> a.durationNormal = duration.durationTupleFromTypeDots('half', 0) >>> a.tupletMultiplier() Fraction(2, 3) >>> a.totalTupletLength() 2.0
- Tuplet.totalTupletLength() float | Fraction ¶
The total duration in quarter length of the tuplet as defined, assuming that enough notes existed to fill all entire tuplet as defined.
For instance, 3 quarters in the place of 2 quarters = 2.0 5 half notes in the place of a 2 dotted half notes = 6.0 (In the end it’s only the denominator that matters)
If durationActual or durationNormal are None, then they will be assumed to be eighth notes (for the basic 3:2 eighth-note triplet)
>>> a = duration.Tuplet() >>> a.totalTupletLength() 1.0
>>> a.numberNotesActual = 3 >>> a.numberNotesNormal = 2 >>> a.setDurationType('half') >>> a.totalTupletLength() 4.0
Let’s make it five halfs in the place of four:
>>> a.setRatio(5, 4) >>> a.setDurationType('half') >>> a.totalTupletLength() 8.0
Now five halfs in the place of two whole notes (same thing):
>>> a.setRatio(5, 2) >>> a.totalTupletLength() 4.0 >>> a.durationNormal = duration.durationTupleFromTypeDots('whole', 0) >>> a.totalTupletLength() 8.0
- Tuplet.tupletMultiplier() float | Fraction ¶
Get a Fraction() by which to scale the duration that this Tuplet is associated with.
>>> myTuplet = duration.Tuplet() >>> myTuplet.tupletMultiplier() Fraction(2, 3) >>> myTuplet.tupletActual = [5, duration.Duration('eighth')] >>> myTuplet.numberNotesActual 5 >>> myTuplet.durationActual.type 'eighth' >>> print(myTuplet.tupletMultiplier()) 2/5 >>> myTuplet.numberNotesNormal = 4 >>> print(myTuplet.tupletMultiplier()) 4/5
Methods inherited from ProtoM21Object
:
GraceDuration¶
- class music21.duration.GraceDuration(typeOrDuration: str | int | float | Fraction | DurationTuple | None = None, **keywords)¶
A Duration that, no matter how it is created, always has a quarter length of zero.
GraceDuration can be created with an implied quarter length and type; these values are used to configure the duration, but then may not be relevant after instantiation.
>>> gd = duration.GraceDuration(type='half') >>> gd.quarterLength 0.0
>>> gd.type 'half'
>>> gd = duration.GraceDuration(0.25) >>> gd.type '16th'
>>> gd.quarterLength 0.0
>>> gd.linked False
>>> gd = duration.GraceDuration(1.25) >>> gd.type 'complex'
>>> gd.quarterLength 0.0
>>> [(x.quarterLength, x.type) for x in gd.components] [(0.0, 'quarter'), (0.0, '16th')]
GraceDuration
bases
GraceDuration
read-only properties
Read-only properties inherited from Duration
:
Read-only properties inherited from ProtoM21Object
:
GraceDuration
read/write properties
- GraceDuration.makeTime¶
True, False, or None (=unknown) whether the grace note should occupy time in performance. Default False. Currently not used in generated playback.
TODO: allow a duration object or number for duration.
- GraceDuration.slash¶
True, False, or None (=unknown) whether the grace note should have a slash through it. Default True.
Read/write properties inherited from Duration
:
GraceDuration
methods
Methods inherited from Duration
:
Methods inherited from ProtoM21Object
:
GraceDuration
instance variables
- GraceDuration.stealTimeFollowing¶
Float number from 0.0 to 1.0 or None (default) for the proportion of the following duration to steal from the following note.
- GraceDuration.stealTimePrevious¶
Float number from 0.0 to 1.0, or None (default) for the proportion of the previous duration to steal from the previous note.
Instance variables inherited from Duration
:
TupletFixer¶
- class music21.duration.TupletFixer(streamIn: stream.Stream | None = None)¶
The TupletFixer object takes in a flat stream and tries to fix the brackets and time modification values of the tuplet so that they reflect proper beaming, etc. It does not alter the quarterLength of any notes.
See
findTupletGroups()
andfixBrokenTupletDuration()
for demonstrations.
TupletFixer
methods
- TupletFixer.findTupletGroups(incorporateGroupings: bool = False) list[list[note.GeneralNote]] ¶
Finds all tuplets in the stream and puts them into groups.
If incorporateGroupings is True, then a tuplet.type=”stop” ends a tuplet group even if the next note is a tuplet.
This demonstration has three groups of tuplets, two sets of 8th note tuplets and one of 16ths:
>>> c = converter.parse( ... 'tinynotation: 4/4 trip{c8 d e} f4 trip{c#8 d# e#} g8 trip{c-16 d- e-}', ... makeNotation=False) >>> tf = duration.TupletFixer(c) # no need to flatten this stream >>> tupletGroups = tf.findTupletGroups() >>> tupletGroups [[<music21.note.Note C>, <music21.note.Note D>, <music21.note.Note E>], [<music21.note.Note C#>, <music21.note.Note D#>, <music21.note.Note E#>], [<music21.note.Note C->, <music21.note.Note D->, <music21.note.Note E->]]
These groups are stored in TupletFixer.allTupletGroups:
>>> tupletGroups is tf.allTupletGroups True
Demonstration with incorporateGroupings:
>>> s = stream.Stream() >>> for i in range(9): ... n = note.Note() ... n.pitch.ps = 60 + i ... n.duration.quarterLength = 1/3 ... if i % 3 == 2: ... n.duration.tuplets[0].type = 'stop' ... s.append(n) >>> tf = duration.TupletFixer(s) >>> tupletGroups = tf.findTupletGroups(incorporateGroupings=True) >>> tupletGroups [[<music21.note.Note C>, <music21.note.Note C#>, <music21.note.Note D>], [<music21.note.Note E->, <music21.note.Note E>, <music21.note.Note F>], [<music21.note.Note F#>, <music21.note.Note G>, <music21.note.Note G#>]]
Without incorporateGroupings we just get one big set of tuplets
>>> tupletGroups = tf.findTupletGroups() >>> len(tupletGroups) 1 >>> len(tupletGroups[0]) 9
- TupletFixer.fixBrokenTupletDuration(tupletGroup: list[note.GeneralNote]) None ¶
Tries to fix cases like triplet quarter followed by triplet eighth to be a coherent tuplet.
Requires a tuplet group from findTupletGroups() or TupletFixer.allTupletGroups. Note: this works on a single tupletGroup while findTupletGroups() returns a list of groups.
>>> s = stream.Stream()
>>> n1 = note.Note('C') >>> n1.duration.quarterLength = 2/3 >>> n1.duration.quarterLength Fraction(2, 3) >>> s.append(n1) >>> n2 = note.Note('D') >>> n2.duration.quarterLength = 1/3 >>> n2.duration.quarterLength Fraction(1, 3) >>> s.append(n2)
Here are the current tuplets for the two notes:
>>> n1.duration.tuplets[0] <music21.duration.Tuplet 3/2/quarter> >>> n2.duration.tuplets[0] <music21.duration.Tuplet 3/2/eighth>
Notice how the first note is waiting for 3 triplet quarters to complete itself. But it could be 2/3 of a quarter note divided into eighth note triplets. TupletFixer will work on this.
It takes in a flattened stream, like this one:
>>> tf = duration.TupletFixer(s)
Find the tuplet groups. Returning a list of one group, which has two notes in it:
>>> tupletGroups = tf.findTupletGroups() >>> tupletGroups [[<music21.note.Note C>, <music21.note.Note D>]]
Now fix that single group:
>>> tg0 = tupletGroups[0] >>> [n.duration.tuplets[0].type for n in tg0] [None, None]
>>> tf.fixBrokenTupletDuration(tg0)
Now the first quarter-note triplet knows that its group will be complete after the next note:
>>> n1.duration.tuplets[0] <music21.duration.Tuplet 3/2/eighth> >>> n1.duration.quarterLength Fraction(2, 3) >>> n2.duration.tuplets[0] <music21.duration.Tuplet 3/2/eighth>
Note that the tuplet type is not affected by this call:
>>> [n.duration.tuplets[0].type for n in tg0] [None, None]
To do that, call
makeTupletBrackets()
on the flattened stream:>>> stream.makeNotation.makeTupletBrackets(s, inPlace=True) >>> [n.duration.tuplets[0].type for n in tg0] ['start', 'stop']
More complex example, from a piece by Josquin:
>>> humdrumExcerpt = '**kern *M3/1 3.c 6d 3e 3f 3d 3%2g 3e 3f#' >>> humdrumLines = '\n'.join(humdrumExcerpt.split())
There is a side format of humdrum that the Josquin Research Project uses for long notes like the 3%2.
>>> humdrum.spineParser.flavors['JRP'] = True
Since Humdrum parsing is going to apply TupletFixer, we will temporarily disable it:
>>> saved_fixed_broken = duration.TupletFixer.fixBrokenTupletDuration >>> duration.TupletFixer.fixBrokenTupletDuration = lambda x,y: None
>>> s = converter.parse(humdrumLines, format='humdrum')
>>> m1 = s.parts.first().measure(1) >>> m1.show('text', addEndTimes=True) {0.0 - 0.0} <music21.meter.TimeSignature 3/1> {0.0 - 2.0} <music21.note.Note C> {2.0 - 2.6667} <music21.note.Note D> {2.6667 - 4.0} <music21.note.Note E> {4.0 - 5.3333} <music21.note.Note F> {5.3333 - 6.6667} <music21.note.Note D> {6.6667 - 9.3333} <music21.note.Note G> {9.3333 - 10.6667} <music21.note.Note E> {10.6667 - 12.0} <music21.note.Note F#>
>>> duration.TupletFixer.fixBrokenTupletDuration = saved_fixed_broken >>> tf = duration.TupletFixer(m1) >>> tupletGroups = tf.findTupletGroups(incorporateGroupings=True) >>> tupletGroups [[<music21.note.Note C>, <music21.note.Note D>, <music21.note.Note E>], [<music21.note.Note F>, <music21.note.Note D>, <music21.note.Note G>, <music21.note.Note E>, <music21.note.Note F#>]]
There’s a problem with the last group: it contains 5 notes and the third note is twice as long as the others, so none of them form a coherent triplet.
>>> [n.duration.tuplets[0] for n in tupletGroups[1]] [<music21.duration.Tuplet 3/2/half>, <music21.duration.Tuplet 3/2/half>, <music21.duration.Tuplet 3/2/whole>, <music21.duration.Tuplet 3/2/half>, <music21.duration.Tuplet 3/2/half>] >>> [n.duration.tuplets[0].type for n in tupletGroups[1]] ['start', None, None, None, 'stop']
Fix the last broken tuplet group.
>>> tf.fixBrokenTupletDuration(tupletGroups[1]) >>> [n.duration.tuplets[0] for n in tupletGroups[1]] [<music21.duration.Tuplet 3/2/whole>, <music21.duration.Tuplet 3/2/whole>, <music21.duration.Tuplet 3/2/whole>, <music21.duration.Tuplet 3/2/whole>, <music21.duration.Tuplet 3/2/whole>]
Note that the changes appear in the notes in the Stream as well.
>>> m1.last().duration.tuplets[0] <music21.duration.Tuplet 3/2/whole>
Again, TupletFixer is automatically called when parsing from Humdrum. (MusicXML specifies its tuplet groups explicitly.) But you may need it when building up a stream from scratch in your own projects.
- TupletFixer.setStream(streamIn: stream.Stream) None ¶
Define a stream to work on and reset all temporary variables.
AppoggiaturaDuration¶
- class music21.duration.AppoggiaturaDuration(typeOrDuration: str | int | float | Fraction | DurationTuple | None = None, **keywords)¶
Renamed in v6 to correct spelling.
AppoggiaturaDuration
bases
AppoggiaturaDuration
read-only properties
Read-only properties inherited from Duration
:
Read-only properties inherited from ProtoM21Object
:
AppoggiaturaDuration
read/write properties
Read/write properties inherited from GraceDuration
:
Read/write properties inherited from Duration
:
AppoggiaturaDuration
methods
Methods inherited from Duration
:
Methods inherited from ProtoM21Object
:
AppoggiaturaDuration
instance variables
Instance variables inherited from GraceDuration
:
Instance variables inherited from Duration
:
DurationTuple¶
- class music21.duration.DurationTuple(type, dots, quarterLength)¶
DurationTuple
read-only properties
- DurationTuple.ordinal¶
Converts type to an ordinal number where maxima = 1 and 1024th = 14; whole = 4 and quarter = 6. Based on duration.ordinalTypeFromNum
>>> a = duration.DurationTuple('whole', 0, 4.0) >>> a.ordinal 4
>>> b = duration.DurationTuple('maxima', 0, 32.0) >>> b.ordinal 1
>>> c = duration.DurationTuple('1024th', 0, 1/256) >>> c.ordinal 14
DurationTuple
methods
- DurationTuple.augmentOrDiminish(amountToScale)¶
FrozenDuration¶
- class music21.duration.FrozenDuration(*arguments, **keywords)¶
A FrozenDuration is one that must have all of its arguments specified at the time of construction. After that, it is immutable, like a Tuple and thus can be shared across different objects (like in MeterTerminals) or used as a hash.
>>> fd = duration.FrozenDuration(type='half', dots=2) >>> fd.quarterLength 3.5 >>> fd.dots = 1 Traceback (most recent call last): TypeError: This FrozenDuration instance is immutable.
FrozenDurations can be used as set/dict keys with stability.
>>> {fd} {<music21.duration.FrozenDuration 3.5>}
Copying a FrozenDuration returns the original, so it is super fast.
>>> import copy >>> copy.deepcopy(fd) is fd True
FrozenDuration
bases
FrozenDuration
read-only properties
Read-only properties inherited from Duration
:
Read-only properties inherited from ProtoM21Object
:
FrozenDuration
read/write properties
Read/write properties inherited from Duration
:
FrozenDuration
methods
Methods inherited from EqualSlottedObjectMixin
:
Methods inherited from Duration
:
Methods inherited from ProtoM21Object
:
FrozenDuration
instance variables
Instance variables inherited from Duration
:
QuarterLengthConversion¶
- class music21.duration.QuarterLengthConversion(components, tuplet)¶
Functions¶
- music21.duration.convertQuarterLengthToType(qLen: int | float | Fraction) str ¶
Return a type if there exists a type that is exactly equal to the duration of the provided quarterLength. Similar to quarterLengthToClosestType() but this function only returns exact matches.
>>> duration.convertQuarterLengthToType(2) 'half' >>> duration.convertQuarterLengthToType(0.125) '32nd' >>> duration.convertQuarterLengthToType(0.33333) Traceback (most recent call last): music21.duration.DurationException: cannot convert quarterLength 0.33333 exactly to type
- music21.duration.convertTypeToNumber(dType: str) float ¶
Convert a duration type string (dType) to a numerical scalar representation that shows how many of that duration type fits within a whole note.
>>> duration.convertTypeToNumber('quarter') 4.0 >>> duration.convertTypeToNumber('half') 2.0 >>> duration.convertTypeToNumber('1024th') 1024.0 >>> duration.convertTypeToNumber('maxima') 0.125
These other types give these results:
>>> duration.convertTypeToNumber('zero') 0.0 >>> duration.convertTypeToNumber('complex') Traceback (most recent call last): music21.duration.DurationException: Could not determine durationNumber from complex
- music21.duration.convertTypeToQuarterLength(dType: str, dots: int = 0, tuplets: list[music21.duration.Tuplet] | None = None, dotGroups=None) float | Fraction ¶
Given a rhythm type (dType), number of dots (dots), an optional list of Tuplet objects (tuplets), and a (very) optional list of Medieval dot groups (dotGroups), return the equivalent quarter length.
>>> duration.convertTypeToQuarterLength('whole') 4.0 >>> duration.convertTypeToQuarterLength('16th') 0.25 >>> duration.convertTypeToQuarterLength('quarter', 2) 1.75
>>> tup = duration.Tuplet(numberNotesActual=5, numberNotesNormal=4) >>> duration.convertTypeToQuarterLength('quarter', 0, [tup]) Fraction(4, 5) >>> duration.convertTypeToQuarterLength('quarter', 1, [tup]) Fraction(6, 5)
>>> tup = duration.Tuplet(numberNotesActual=3, numberNotesNormal=4) >>> duration.convertTypeToQuarterLength('quarter', 0, [tup]) Fraction(4, 3)
Also can handle those rare medieval dot groups (such as dotted-dotted half notes that take a full measure of 9/8. Conceptually, these are dotted-(dotted-half) notes. See trecento.trecentoCadence for more information ). >>> duration.convertTypeToQuarterLength(‘half’, dots=1, dotGroups=[1, 1]) 4.5
Unknown values raise DurationException:
>>> duration.convertTypeToQuarterLength('minim') Traceback (most recent call last): music21.duration.DurationException: no such type (minim) available for conversion
- music21.duration.dottedMatch(qLen: int | float | Fraction, maxDots=4) tuple[int, str] | tuple[Literal[False], Literal[False]] ¶
Given a quarterLength, determine if there is a dotted (or non-dotted) type that exactly matches. Returns a pair of (numDots, type) or (False, False) if no exact matches are found.
Returns a maximum of four dots by default.
>>> duration.dottedMatch(3.0) (1, 'half') >>> duration.dottedMatch(1.75) (2, 'quarter')
This value is not equal to any dotted note length
>>> duration.dottedMatch(1.6) (False, False)
maxDots can be lowered for certain searches
>>> duration.dottedMatch(1.875) (3, 'quarter') >>> duration.dottedMatch(1.875, 2) (False, False)
>>> duration.dottedMatch(0.00001, 2) (False, False)
- music21.duration.durationTupleFromQuarterLength(ql=1.0) DurationTuple ¶
Returns a DurationTuple for a given quarter length if the ql can be expressed as a type and number of dots (no tuplets, no complex duration, etc.). If it can’t be expressed, returns an “inexpressible” DurationTuple.
>>> dt = duration.durationTupleFromQuarterLength(3.0) >>> dt DurationTuple(type='half', dots=1, quarterLength=3.0)
If it’s not possible, we return an “inexpressible” type:
>>> dt = duration.durationTupleFromQuarterLength(2.5) >>> dt DurationTuple(type='inexpressible', dots=0, quarterLength=2.5)
- music21.duration.durationTupleFromTypeDots(durType='quarter', dots=0)¶
Returns a DurationTuple (which knows its quarterLength) for a given type and dots (no tuplets)
>>> dt = duration.durationTupleFromTypeDots('quarter', 0) >>> dt DurationTuple(type='quarter', dots=0, quarterLength=1.0) >>> dt2 = duration.durationTupleFromTypeDots('quarter', 0) >>> dt is dt2 True
Also with keyword arguments.
>>> dt = duration.durationTupleFromTypeDots(durType='zero', dots=0) >>> dt DurationTuple(type='zero', dots=0, quarterLength=0.0)
Unknown values raise DurationException:
>>> dt = duration.durationTupleFromTypeDots(durType='minim', dots=0) Traceback (most recent call last): music21.duration.DurationException: Unknown type: minim
- music21.duration.nextLargerType(durType: str) str ¶
Given a type (such as 16th or quarter), return the next larger type.
>>> duration.nextLargerType('16th') 'eighth'
>>> duration.nextLargerType('whole') 'breve'
>>> duration.nextLargerType('duplex-maxima') Traceback (most recent call last): music21.duration.DurationException: cannot get the next larger of duplex-maxima
- music21.duration.nextSmallerType(durType: str) str ¶
Given a type (such as 16th or quarter), return the next smaller type.
>>> duration.nextSmallerType('16th') '32nd' >>> duration.nextSmallerType('whole') 'half' >>> duration.nextSmallerType('1024th') '2048th' >>> duration.nextSmallerType('2048th') Traceback (most recent call last): music21.duration.DurationException: cannot get the next smaller of 2048th
- music21.duration.quarterLengthToClosestType(qLen: int | float | Fraction) tuple[str, bool] ¶
Returns a two-unit tuple consisting of
1. The type string (“quarter”) that is smaller than or equal to the quarterLength of provided.
Boolean, True or False, whether the conversion was exact.
>>> duration.quarterLengthToClosestType(0.5) ('eighth', True) >>> duration.quarterLengthToClosestType(0.75) ('eighth', False) >>> duration.quarterLengthToClosestType(1.8) ('quarter', False)
Some extremely close types will return True for exact conversion:
>>> duration.quarterLengthToClosestType(2.0000000000000001) ('half', True)
Very long durations are fine:
>>> duration.quarterLengthToClosestType(129.99) ('duplex-maxima', False)
Durations smaller than 2048th note raise a DurationException
>>> qL = duration.typeToDuration['2048th'] >>> qL 0.001953125
>>> qL = qL * 0.75 >>> duration.quarterLengthToClosestType(qL) Traceback (most recent call last): music21.duration.DurationException: Cannot return types smaller than 2048th; qLen was: 0.00146484375
- music21.duration.quarterLengthToNonPowerOf2Tuplet(qLen: int | float | Fraction) tuple[music21.duration.Tuplet, music21.duration.DurationTuple] ¶
Slow, last chance function that returns a tuple of a single tuplet, probably with a non power of 2 denominator (such as 7:6) that represents the quarterLength and the DurationTuple that should be used to express the note.
This could be a double-dotted note, but also a tuplet:
>>> duration.quarterLengthToNonPowerOf2Tuplet(7) (<music21.duration.Tuplet 8/7/quarter>, DurationTuple(type='breve', dots=0, quarterLength=8.0))
>>> duration.quarterLengthToNonPowerOf2Tuplet(7/16) (<music21.duration.Tuplet 8/7/64th>, DurationTuple(type='eighth', dots=0, quarterLength=0.5))
>>> duration.quarterLengthToNonPowerOf2Tuplet(7/3) (<music21.duration.Tuplet 12/7/16th>, DurationTuple(type='whole', dots=0, quarterLength=4.0))
And of course:
>>> duration.quarterLengthToNonPowerOf2Tuplet(1) (<music21.duration.Tuplet 1/1/quarter>, DurationTuple(type='quarter', dots=0, quarterLength=1.0))
- music21.duration.quarterLengthToTuplet(qLen: int | float | Fraction, maxToReturn: int = 4, tupletNumerators=(3, 5, 7, 11, 13)) list[music21.duration.Tuplet] ¶
Returns a list of possible Tuplet objects for a given qLen (quarterLength). As there may be more than one possible solution, the maxToReturn integer specifies the maximum number of values returned.
Searches for numerators specified in duration.defaultTupletNumerators (3, 5, 7, 11, 13). Does not return dotted tuplets, nor nested tuplets.
Note that 4:3 tuplets won’t be found, but will be found as dotted notes by dottedMatch.
>>> duration.quarterLengthToTuplet(0.33333333) [<music21.duration.Tuplet 3/2/eighth>, <music21.duration.Tuplet 3/1/quarter>]
>>> duration.quarterLengthToTuplet(0.20) [<music21.duration.Tuplet 5/4/16th>, <music21.duration.Tuplet 5/2/eighth>, <music21.duration.Tuplet 5/1/quarter>]
By specifying only 1 maxToReturn, a single-length list containing the Tuplet with the smallest type will be returned.
>>> duration.quarterLengthToTuplet(0.3333333, 1) [<music21.duration.Tuplet 3/2/eighth>]
>>> tup = duration.quarterLengthToTuplet(0.3333333, 1)[0] >>> tup.tupletMultiplier() Fraction(2, 3)
- music21.duration.unitSpec(durationObjectOrObjects)¶
DEPRECATED and to be removed in v10.
A simple data representation of most Duration objects. Processes a single Duration or a List of Durations, returning a single or list of unitSpecs.
A unitSpec is a tuple of qLen, durType, dots, tupleNumerator, tupletDenominator, and tupletType (assuming top and bottom tuplets are the same).
This function does not deal with nested tuplets, etc.
>>> aDur = duration.Duration() >>> aDur.quarterLength = 3 >>> duration.unitSpec(aDur) (3.0, 'half', 1, None, None, None)
>>> bDur = duration.Duration() >>> bDur.quarterLength = 1.125 >>> duration.unitSpec(bDur) (1.125, 'complex', 0, None, None, None)
>>> cDur = duration.Duration() >>> cDur.quarterLength = 0.3333333 >>> duration.unitSpec(cDur) (Fraction(1, 3), 'eighth', 0, 3, 2, 'eighth')
>>> duration.unitSpec([aDur, bDur, cDur]) [(3.0, 'half', 1, None, None, None), (1.125, 'complex', 0, None, None, None), (Fraction(1, 3), 'eighth', 0, 3, 2, 'eighth')]