# User’s Guide, Chapter 19: Advanced Durations (Complex, Ties, and Tuplets)¶

When last we encountered the `Duration` object, it was Chapter 3, and we didn’t know about Streams or any of a thousand other cool things that are now under our belts, so it seems a good idea to get back to Duration objects and look in a bit more depth at how they work.

We’ll recall that one thing that all `Music21Objects` have a `Duration` object stored on their `.duration` attributes:

```n = note.Note('C#4')
n.duration
```
``` <music21.duration.Duration 1.0>
```

...and that durations can be created directly:

```d = duration.Duration(4.0)
d
```
``` <music21.duration.Duration 4.0>
```

...and that all durations have `.type`, `.dots`, and `.quarterLength`.

```d = duration.Duration(1.5)
(d.type, d.dots, d.quarterLength)
```
``` ('quarter', 1, 1.5)
```

The standard `type` values range from tiny 2048th notes up through the immense duplex-maxima:

```startType = '2048th'
try:
while True:
print(startType, end=", ")
startType = duration.nextLargerType(startType)
except duration.DurationException:
pass
```
``` 2048th, 1024th, 512th, 256th, 128th, 64th, 32nd, 16th, eighth, quarter, half, whole, breve, longa, maxima, duplex-maxima,
```

The number of dots is limited only by your own imagination (or the limit of expressibility of your computer):

```for dots in range(12):
print(dots, duration.Duration(type='quarter', dots=dots))
```
``` 0 <music21.duration.Duration 1.0>
1 <music21.duration.Duration 1.5>
2 <music21.duration.Duration 1.75>
3 <music21.duration.Duration 1.875>
4 <music21.duration.Duration 1.9375>
5 <music21.duration.Duration 1.96875>
6 <music21.duration.Duration 1.984375>
7 <music21.duration.Duration 1.9921875>
8 <music21.duration.Duration 1.99609375>
9 <music21.duration.Duration 1.998046875>
10 <music21.duration.Duration 1.9990234375>
11 <music21.duration.Duration 1.99951171875>
```

For the very curious, try setting the number of dots to `float('inf')` and seeing what happens to `type`, `dots`, and `quarterLength`. (A little Easter egg...)

A lot of Duration values can be expressed with all these types and dots, but not all of them. We can get some more by moving on to Tuplets.

## Tuplets¶

Tuplets, such as triplets, can be set by giving a fraction or close approximation to a fraction as a quarter length:

```d = duration.Duration(0.3333333333333)
d
```
``` <music21.duration.Duration 1/3>
```

The quarterLength of a duration such as this will be expresssed as a `fractions.Fraction` class:

```d.quarterLength
```
``` Fraction(1, 3)
```

This can be converted to a floating point approximate representation by wrapping it in the `float()` function:

```float(d.quarterLength)
```
``` 0.3333333333333333
```

We can check that this duration represents a triplet by looking at the `.fullName` property of the duration:

```d.fullName
```
``` 'Eighth Triplet (1/3 QL)'
```

But where is the information about the triplet stored? It’s not in the type or dots:

```(d.type, d.dots)
```
``` ('eighth', 0)
```

Instead it’s to be found in the `.tuplets` property:

```d.tuplets
```
``` (<music21.duration.Tuplet 3/2/eighth>,)
```

One thing that we learn from the property is that there’s a separate class that defines tuplets, the `duration.Tuplet` class. Let’s look at what it can do. We can create a simple Tuplet by passing in the number of notes to be played in the place of another note. For instance, a 5-in-the-place-of-4 Tuplet is created like this:

```fiveInFour = duration.Tuplet(5, 4)
fiveInFour
```
``` <music21.duration.Tuplet 5/4>
```

Each Duration that has a 5:4 tuplet applied to it will be 4/5ths as long as it would be without it. I know this by querying the `.tupletMultiplier()` method

```fiveInFour.tupletMultiplier()
```
``` Fraction(4, 5)
```

At this point, the tuplet represents any 5:4 tuplet – whether 5 quarters in the place of 4 quarters, or 5 16ths in the place of 4 16ths. If it’s important to know that this represents 5 eighths in the place of 4 eighths, we can call `setDurationType()`:

```fiveInFour.setDurationType('eighth')
```

Now we can ask how many quarter notes (i.e., what quarterLength) will be necessary to fulfill the promise of the tuplet:

```fiveInFour.totalTupletLength()
```
``` 2.0
```

This changes if we change the durationType. Let’s say that it’s five dotted quarters in the place of four dotted quarters:

```fiveInFour.setDurationType('quarter', dots=1)
fiveInFour.totalTupletLength()
```
``` 6.0
```

We can also create tuplets that represent unusual cases, such as 11 sixteenth-notes in the place of one doubly-dotted quarter note:

```oddTuplet = duration.Tuplet(11, 1)
oddTuplet.durationActual = '16th'
oddTuplet.durationNormal = duration.Duration('quarter', dots=2)
oddTuplet.totalTupletLength()
```
``` 1.75
```
```oddTuplet.tupletMultiplier()
```
``` Fraction(7, 11)
```

Okay, let’s get back to simpler tuplets. Like our 3:2 triplet.

Tuplets have a `.type` which is usually None:

```trip = duration.Tuplet(3, 2)
trip.type is None
```
``` True
```

the `.type` will be “start” if `music21` or a user of it has determined that this tuplet begins a tuplet bracket or grouping. It will be “stop” if it ends a grouping, and it’ll be startStop if it’s an isolated tuplet that both begins and ends a grouping. None means that no determination has been made about whether this is the beginning, middle, or end of a bracket. (Eventually we will support `False` to mean do not end a bracket here in any case).

Of course a bracket will only be drawn if you want one, which means that `.bracket` needs to be True.

```trip.bracket
```
``` True
```

And we’ll need to know what should go in the bracket. Usually, we just want the number “3” to go in the bracket:

```(trip.tupletActualShow, trip.tupletNormalShow)
```
``` ('number', None)
```

If we wanted “3:2” then we’d set “trip.tupletNormalShow” to “number”.

```n = note.Note()
n.duration = duration.Duration(2.0/3.0)
n.duration.tuplets[0].tupletNormalShow = 'number'
s = stream.Stream()
s.repeatAppend(n, 3)
s.insert(0, meter.TimeSignature('2/4'))
s.show()
```

We can also set it to “type” or “both” to add the note shape to the bracket, but unfortunately, no MusicXML client yet supports this display on input or output.

Now we’re ready to return to the `Duration` class. Since the `.tuplets` property returns a tuple (appropriately enough), it’s not something that can be manipulated directly. To add a tuplet to an existing duration, use the `.appendTuplet(t)` method:

```t = duration.Tuplet(5, 4)
t.setDurationType('16th')
d = duration.Duration('16th')
d.appendTuplet(t)
n = note.Note('E-4')
n.duration = d
s = stream.Stream()
s.repeatAppend(n, 20)
s.show()
```

Once a `Tuplet` is appended to a `Duration`, it becomes “frozen” and no further changes to its duration can be set (though its `.type` and display styles can still be changed). This is to prevent changes to the duration that won’t be reflected in the `Duration` object:

```t.frozen
```
``` True
```

Nested tuplets can be created by adding more than one tuplet to the duration:

```import copy
s = stream.Stream()
s.repeatAppend(note.Note(), 4)

t32h = duration.Tuplet(3, 2, 'half')
t54q = duration.Tuplet(5, 4, 'quarter')
n1 = note.Note()
n1.duration.type = 'half'
n1.duration.appendTuplet(copy.deepcopy(t32h))
s.append(n1)
for i in range(5):
n = note.Note(61 + i)
n.duration.type = 'quarter'
n.duration.appendTuplet(copy.deepcopy(t32h))
n.duration.appendTuplet(copy.deepcopy(t54q))
s.append(n)
s.notes[4].duration.tuplets[0].type = 'start'
s.notes[5].duration.tuplets[1].type = 'start'
s.notes[-1].duration.tuplets[0].type = 'stop'
s.notes[-1].duration.tuplets[1].type = 'stop'
s.repeatAppend(note.Note('G4'), 4)
s.show()
```

For nested tuplets, it’s important to explicitly state where tuplet brackets start and stop. As you can see from the output, MusicXML rendering of Nested tuplets is still hard for our partners at MuseScore which generated the image above (Finale renders a –5– bracket around the five quarter notes. However, MIDI rendering is correct:

```s.show('midi')
```

The effect of any set of tuplets on the overall duration of a note can be found through the `.aggregateTupletMultiplier()` method:

```d = duration.Duration('half')
d.appendTuplet(duration.Tuplet(3, 2))
d.appendTuplet(duration.Tuplet(7, 5))
d.aggregateTupletMultiplier()
```
``` Fraction(10, 21)
```

Each `Duration` object has four essential pieces of information, the `type` (whole, 16th, breve, etc.), the number of dots (or `dotGroups`, discussed below), a list of zero or more tuplets, and the overall length of the duration (`.quarterLength`). Generally speaking, changing one of these pieces of information changes the one or more of the others:

```d = duration.Duration(3.0)
(d.type, d.dots, d.tuplets, d.quarterLength)
```
``` ('half', 1, (), 3.0)
```
```d.quarterLength *= 4/5
(d.type, d.dots, d.tuplets, d.quarterLength)
```
``` ('whole', 0, (<music21.duration.Tuplet 5/3/whole>,), Fraction(12, 5))
```
```d.type = '16th'
d.dots = 2
(d.type, d.dots, d.tuplets, d.quarterLength)
```
``` ('16th', 2, (<music21.duration.Tuplet 5/3/whole>,), Fraction(21, 80))
```

However, there are times when we might want to separate one piece of information separate from another. For instance, in some pieces, Brahms uses a dotted half note to mean a note that is eleven sixteenth-notes long, rather than twelve. We can represent this in `music21` by setting up the type and dots and then setting `Duration.linked` to False.

```d = duration.Duration()
d.type = 'half'
d.dots = 1
(d.type, d.dots, d.quarterLength)
```
``` ('half', 1, 3.0)
```
```d.linked
```
``` True
```
```d.linked = False
d.quarterLength = 11/4
(d.type, d.dots, d.quarterLength)
```
``` ('half', 1, 2.75)
```

In theory, the musicXML spec allows us to preserve such note lengths in notation, but in practice no notation software will support this, correcting the error in the difference between .quarterLength (in MusicXML divisions) and type:

```r = note.Rest(type='16th')
n = note.Note()
n.duration = d
s = stream.Stream([meter.TimeSignature('3/4'), r, n])
s.show()
```

(but the output looks good for a single note.)

Unlinked durations come in handy if, for instance, we’re parsing in notes from MIDI or an audio file and we want to retain the exact quarterLength duration (or set qtr=60 and just store the number of seconds) but have type that represents the closest notateable type.

## DotGroups – a small digression from the Middle Ages...¶

There’s actually one more thing that durations store, and it’s a little bit silly for most uses, but reflects `music21`‘s commitment to being able to represent all the music that’s been notated over time. In the Middle Ages, it was common to have notes that were worth 9 or 27 times smaller note values. In modern transcriptions, a note worth 9 eighth notes is often notated as a dotted-dotted half note, that is to say, a dotted half note which is itself dotted (or 1.5x the length of a dotted half note). See the second example from my blog post about dots. These dotted-dotted notes are represented by “dotGroups” in music21, which is a list of the number of dots at each level of dotting. For instance:

```n = note.Note('C5', type='half')
n.duration.dotGroups = (1, 1)
n.show()
```

Since no current MusicXML readers support dot groups, they are represented by the closest acceptable notation unit, respecting the fact that they are essentially dotted-dotted notes.

## Durations that take no time at all.¶

Among the duration types, such as ‘half’, ‘whole’, etc. there’s one strange `type` called “zero”. Durations with type “zero” measure objects that don’t have any length at all. It’s used for measuring the conceptual length of grace notes, spaceless objects like `Clefs`, Liz Taylor’s marriages, etc.:

```k = key.KeySignature(3)
k.duration
```
``` <music21.duration.Duration 0.0>
```
```k.duration.type
```
``` 'zero'
```

We will talk more about zero-duration objects when we get to Grace Notes in Chapter 27.

## Complex Durations¶

Counting notes isn’t as easy as we might think. For instance, listen to this little “piece”:

```s = stream.Stream()
s.append(meter.TimeSignature('5/4'))
s.append(note.Note('C4', quarterLength=2.25))
s.append(note.Note('C#4', quarterLength=2.75))
s.show('midi')
```

That sounds like it has two notes in it to me! But look at the best representation of it on a page:

```s.show()
```

Now it looks like it has four notes in it! Which number is right? It depends on what is most important to you. Sometimes you will want to work with the specific graphical symbols on the page. Sometimes you only care about the number of distinct sounds. And quite often you’ll want to change from one representation to another within the same analysis task. `Music21` makes moving between these two representations possible and after a while quite simple using the concepts of ties and complex durations.

Complex `Durations` are those that can’t be expressed easily as a single written `Note` on a page. For instance, a `Note` lasting a half-note plus a sixteenth-note can’t be written as a single `Note` graphic, but it’s perfectly fine to use as a quarterLength.

```oddDuration = duration.Duration()
oddDuration.quarterLength = 2.25
```

The `type` for these odd values is called “complex”:

```oddDuration.type
```
``` 'complex'
```

Complex types have multiple “DurationTuple” objects in `.components` that represent the smaller, simple durations that make up the entire Duration:

```oddDuration.components
```
``` (DurationTuple(type='half', dots=0, quarterLength=2.0),
DurationTuple(type='16th', dots=0, quarterLength=0.25))
```

Some durations have multiple components even though they might not need them:

```d = duration.Duration(1.0)
d.components
```
``` (DurationTuple(type='quarter', dots=0, quarterLength=1.0),
DurationTuple(type='eighth', dots=0, quarterLength=0.5))
```
```d.type
```
``` 'complex'
```

For these durations, there’s a method called `.consolidate()` that will put both of these components together into one component. In this case, it’s a nice dotted quarter note:

```d.consolidate()
(d.type, d.dots, d.quarterLength)
```
``` ('quarter', 1, 1.5)
```
```d.components
```
``` (DurationTuple(type='quarter', dots=1, quarterLength=1.5),)
```

However, forcing something that really should have multiple components into one creates an “inexpressible” type that can’t be outputted to most formats:

```d = duration.Duration(5.0)
d.consolidate()
d.type
```
``` 'inexpressible'
```
```d.components
```
``` (DurationTuple(type='inexpressible', dots=0, quarterLength=5.0),)
```

To fix this situation, the easiest thing to do is just to assign the duration its own quarterLength.

```d.quarterLength = d.quarterLength
d.components
```
``` (DurationTuple(type='whole', dots=0, quarterLength=4.0),
DurationTuple(type='quarter', dots=0, quarterLength=1.0))
```

## Ties and Tied Objects¶

In the last section we ended up with a Duration object with two components, a whole-note’s duration and a quarter-note’s duration. We can conceive of either one note having this duration, or two notes with this duration that are tied together. Let’s look at how to move from one view to another, first by attaching the duration to a note.

```n = note.Note('F#4')
n.duration = d
n.show()
```

Now let’s split this Note according to its component durations using the `splitAtDurations()` method found on every `Music21Object`.

```split = n.splitAtDurations()
split
```
``` (<music21.note.Note F#>, <music21.note.Note F#>)
```
```[subNote.quarterLength for subNote in split]
```
``` [4.0, 1.0]
```

So now instead of one note with the duration of 5.0 quarter notes, we have two notes, one which is a whole note and the other which is a quarter note. If we put both of them into a stream, we can see how they look:

```s = stream.Stream()
s.append(split)
s.show()
```

Notice the one subtle difference between the two representations. In the second case, since there were two notes (and not explicit time signatures), the Stream was allowed to split the notes into two measures in order to use the more common time signature of 4/4.

But how does the Stream know that the two notes should have a tie connecting them? The answer is that `splitAtDurations` sets the `.tie` attribute on each of the notes:

```split[0].tie
```
``` <music21.tie.Tie start>
```
```split[1].tie
```
``` <music21.tie.Tie stop>
```

The `Tie` object lives all alone in its own tie module. A tie object has one essential attribute, `type`, which determines whether the tie is the start of a tie (`start`), the end of a tie (`stop`), or the end of one tie and the beginning of another (`continue`).

```split[0].tie.type
```
``` 'start'
```
```split[1].tie.type
```
``` 'stop'
```

Note that there is a separate `Tie` object applied to the first note than for the second note. Thus the `Tie` object really represents a tied-state for a given note rather than the graphical “tie” itself. However, that tie can be shaped by giving it a style among `'normal'`, `'dotted'`, `'dashed'`, or `'hidden'`.

```s = stream.Stream()
for style in ('normal', 'dotted', 'dashed', 'hidden'):
nStart = note.Note('E4')
tStart = tie.Tie('start')
tStart.style = style
nStart.tie = tStart
nStop = note.Note('E4')
tStop = tie.Tie('stop')
tStop.style = style # optional
nStop.tie = tStop
s.append([nStart, nStop])
s.show()
```

When splitting an object such as a `Rest` that doesn’t use ties, music21 is smart enough not to add ties:

```r = note.Rest(quarterLength=2.25)
s = stream.Stream()
s.append(r.splitAtDurations())
s.show()
```

Chords have a `.tie` object that represents whether any pitch in the chord is tied. If it is set, then all pitches in the chord are considered tied:

```c = chord.Chord('C#4 E4 G4')
c.tie = tie.Tie('start')
c2 = chord.Chord('C#4 E4 G4')
c2.tie = tie.Tie('stop')
s = stream.Stream()
s.append([c, c2])
s.show()
```

If we want to see the tie status for individual parts of a chord, set the `.tie` on the `Note` object found for each index of the chord:

```c1 = chord.Chord('C#4 E4 G4')
c2 = chord.Chord('C4 E4 G4')
c1[1].tie = tie.Tie('start')
c2[1].tie = tie.Tie('stop')
c1[2].tie = tie.Tie('start')
c1[2].tie.style = 'dotted'
c2[2].tie = tie.Tie('stop')
s = stream.Stream()
s.append([c1, c2])
s.show()
```

Hmm... the E tie intersects with the accidental and looks too confusing with a tie on the C# to C. However, there’s a `placement` attribute beginning in `music21` v.4 which can fix this:

```c1[1].tie.placement = 'above'
s.show()
```

To take a Stream with tied notes and change it into a Stream with tied notes represented by a single note, call `stripTies()` on the Stream:

```c = chord.Chord('C#4 E4 G4')
c.tie = tie.Tie('start')
c2 = chord.Chord('C#4 E4 G4')
c2.tie = tie.Tie('stop')
s = stream.Stream()
s.append([c, c2])
s2 = s.stripTies()
s2.show()
```

This method is really helpful for analyzing streams with ties above the barline:

```c = converter.parse('tinyNotation: 2/4 d4. e8~ e4 d4~ d8 f4.')
c.show()
```

How many notes of pitch “D” are there? This isn’t the right approach:

```numDs = 0
for n in c.recurse().notes:
if n.pitch.name == 'D':
numDs += 1
numDs
```
``` 3
```

All of the notes in this piece are essentially dotted quarter notes, but some of them are tied across the barline. To fix this, let’s get a score where the ties are stripped, but we’ll retain the measures.

```cStrip = c.stripTies(retainContainers=True)
```

Now let’s count the Ds:

```numDs = 0
for n in cStrip.recurse().notes:
if n.pitch.name == 'D':
numDs += 1
numDs
```
``` 2
```

That’s a lot better. Let’s look at cStrip in a bit more detail.

```cStrip.show('text', addEndTimes=True)
```
``` {0.0 - 3.0} <music21.stream.Measure 1 offset=0.0>
{0.0 - 0.0} <music21.clef.TrebleClef>
{0.0 - 0.0} <music21.meter.TimeSignature 2/4>
{0.0 - 1.5} <music21.note.Note D>
{1.5 - 3.0} <music21.note.Note E>
{2.0 - 4.5} <music21.stream.Measure 2 offset=2.0>
{1.0 - 2.5} <music21.note.Note D>
{4.0 - 6.0} <music21.stream.Measure 3 offset=4.0>
{0.5 - 2.0} <music21.note.Note F>
{2.0 - 2.0} <music21.bar.Barline style=final>
```

One thing to notice is that the note E extends now beyond the end of the first 2/4 measure. The second D, in measure 2, by contrast, does not begin at the beginning of the measure, but instead halfway through the first measure. This is why it’s sometimes most helpful to run `stripTies()` without retaining containers:

```cStrip2 = c.stripTies(retainContainers=False)
```
``` {0.0 - 1.5} <music21.note.Note D>
{1.5 - 3.0} <music21.note.Note E>
{3.0 - 4.5} <music21.note.Note D>
{4.5 - 6.0} <music21.note.Note F>
```

In this view, it’s easier to see what is going on with the lengths of the various notes and where they should begin.

Remember from chapter 17, that if we want to go from the strip-tie note to the original, we can use derivation. For instance, let’s put an accent mark on every other note of the original score, not counting tied notes:

```cStrip2.notes[1].derivation
```
``` <Derivation of <music21.note.Note E> from <music21.note.Note E> via "stripTies">
```
```for i, n in enumerate(cStrip2.notes):
if i % 2 == 1:
nOrigin = n.derivation.origin
nOrigin.articulations.append(articulations.Accent())
c.show()
```

## Conclusion¶

In this chapter we learned many of the advanced features of durations, such as how they can be composed of multiple components called `DurationTuples`, how triplets and other tuplets work, how durations can be linked or unlinked, and how Ties work and how stripping or splitting tied notes can shift between sounding and written representations of notes.

It’s been a while since we’ve put all our knowledge to work, so in Chapter 20, Examples 2 we’ll consolidate our knowledge in the service of analysis.