Table Of Contents

Previous topic

music21.interval

Next topic

music21.note

This Page

music21.meter

music21.meter.fractionSum(fList)

Given a list of fractions represented as a list, find the sum

>>> fractionSum([(3,8), (5,8), (1,8)])
(9, 8)
>>> fractionSum([(1,6), (2,3)])
(5, 6)
>>> fractionSum([(3,4), (1,2)])
(5, 4)
>>> fractionSum([(1,13), (2,17)])
(43, 221)
music21.meter.fractionToSlashMixed(fList)

Given a list of fraction values, compact numerators by sum if denominators are the same

>>> fractionToSlashMixed([(3, 8), (2, 8), (5, 8), (3, 4), (2, 16), (1, 16), (4, 16)])
[('3+2+5', 8), ('3', 4), ('2+1+4', 16)]
music21.meter.slashCompoundToFraction(value)
>>> slashCompoundToFraction('3/8+2/8')
[(3, 8), (2, 8)]
>>> slashCompoundToFraction('5/8')
[(5, 8)]
>>> slashCompoundToFraction('5/8+2/4+6/8')
[(5, 8), (2, 4), (6, 8)]
music21.meter.slashMixedToFraction(valueSrc)

Given a mixture if possible meter fraction representations, return a list of pairs. If originally given as a summed numerator; break into separate fractions.

>>> slashMixedToFraction('3/8+2/8')
([(3, 8), (2, 8)], False)
>>> slashMixedToFraction('3+2/8')
([(3, 8), (2, 8)], True)
>>> slashMixedToFraction('3+2+5/8')
([(3, 8), (2, 8), (5, 8)], True)
>>> slashMixedToFraction('3+2+5/8+3/4')
([(3, 8), (2, 8), (5, 8), (3, 4)], True)
>>> slashMixedToFraction('3+2+5/8+3/4+2+1+4/16')
([(3, 8), (2, 8), (5, 8), (3, 4), (2, 16), (1, 16), (4, 16)], True)
>>> slashMixedToFraction('3+2+5/8+3/4+2+1+4')
...
MeterException: cannot match denominator to numerator in: 3+2+5/8+3/4+2+1+4
music21.meter.slashToFraction(value)
>>> slashToFraction('3/8')
(3, 8)
>>> slashToFraction('7/32')
(7, 32)

TimeSignature

class music21.meter.TimeSignature(value=None, partitionRequest=None)

inherits from: Music21Object

TimeSignature attributes

display
A meter sequence is a list of MeterTerminals, or other MeterSequences
beat
A meter sequence is a list of MeterTerminals, or other MeterSequences
accent
A meter sequence is a list of MeterTerminals, or other MeterSequences
beam
A meter sequence is a list of MeterTerminals, or other MeterSequences

Attributes without Documentation: symbolizeDenominator, symbol, summedNumerator, inherited

Attributes inherited from Music21Object: id, groups

TimeSignature properties

barDuration

Return a Duration object equal to the total length of this TimeSignature.

>>> ts = TimeSignature('5/16')
>>> ts.barDuration
<music21.duration.Duration 1.25>
beatBackgroundUnitCount

Return the count of background beat units, or the number of subdivisions in the beat unit in this TimeSignature.

>>> ts = TimeSignature('3/4')
>>> ts.beatBackgroundUnitCount
2
>>> ts = TimeSignature('6/8')
>>> ts.beatBackgroundUnitCount
3
>>> ts = TimeSignature('15/8')
>>> ts.beatBackgroundUnitCount
3
>>> ts = TimeSignature('3/8')
>>> ts.beatBackgroundUnitCount
2
>>> ts = TimeSignature('13/8')
>>> ts.beatBackgroundUnitCount
Traceback (most recent call last):
TimeSignatureException: cannot determine beat background for an unpartitioned beat
beatBackgroundUnitCountName

Return the beat count name, or the name given for the number of beat units. For example, 2/4 is duple; 9/4 is triple.

>>> ts = TimeSignature('3/4')
>>> ts.beatBackgroundUnitCountName
'Simple'
>>> ts = TimeSignature('6/8')
>>> ts.beatBackgroundUnitCountName
'Compound'
beatDivision

Return the beat division as a Stream of Duration objects, if and only if the TimeSignature has a uniform beat division for all beats.

>>> ts = TimeSignature('3/4')
>>> ts.beatDivision
[<music21.duration.Duration 0.5>, <music21.duration.Duration 0.5>]
>>> ts = TimeSignature('6/8')
>>> ts.beatDivision
[<music21.duration.Duration 0.5>, <music21.duration.Duration 0.5>, <music21.duration.Duration 0.5>]
beatLengthToQuarterLengthRatio
>>> a = TimeSignature('3/2')
>>> a.beatLengthToQuarterLengthRatio
2.0
beatSubDivision

Return a subdivision of the beat division, or a list of Duration objects representing each beat division divided by two.

>>> ts = TimeSignature('3/4')
>>> ts.beatSubDivision
[<music21.duration.Duration 0.25>, <music21.duration.Duration 0.25>, <music21.duration.Duration 0.25>, <music21.duration.Duration 0.25>]
>>> ts = TimeSignature('6/8')
>>> ts.beatSubDivision
[<music21.duration.Duration 0.25>, <music21.duration.Duration 0.25>, <music21.duration.Duration 0.25>, <music21.duration.Duration 0.25>, <music21.duration.Duration 0.25>, <music21.duration.Duration 0.25>]
beatUnit

Return a Duration object equal to the beat unit of this Time Signature, if and only if this TimeSignatyure has a uniform beat unit.

>>> ts = TimeSignature('3/4')
>>> ts.beatUnit
<music21.duration.Duration 1.0>
>>> ts = TimeSignature('6/8')
>>> ts.beatUnit
<music21.duration.Duration 1.5>
>>> ts = TimeSignature('7/8')
>>> ts.beatUnit
Traceback (most recent call last):
TimeSignatureException: cannot determine beat unit for an unpartitioned beat
beatUnitCount

Return the count of beat units, or the number of beats in this TimeSignature

>>> ts = TimeSignature('3/4')
>>> ts.beatUnitCount
3
beatUnitCountName

Return the beat count name, or the name given for the number of beat units. For example, 2/4 is duple; 9/4 is triple.

>>> ts = TimeSignature('3/4')
>>> ts.beatUnitCountName
'Triple'
>>> ts = TimeSignature('6/8')
>>> ts.beatUnitCountName
'Duple'
classification

Return the classification of this TimeSignature, such as Simple Triple or Compound Quadruple.

>>> ts = TimeSignature('3/4')
>>> ts.classification
'Simple Triple'
>>> ts = TimeSignature('6/8')
>>> ts.classification
'Compound Duple'
>>> ts = TimeSignature('4/32')
>>> ts.classification
'Simple Quadruple'
denominator

Return the denominator of the TimeSignature as a number

>>> ts = TimeSignature('3/4')
>>> ts.denominator
4
lily

returns the lilypond representation of the timeSignature

>>> a = TimeSignature('3/16')
>>> a.lily
\time 3/16
musicxml
Return a complete MusicXML string
mx

Returns a list of one mxTime object. Compound meters are represented as multiple pairs of beat and beat-type elements

>>> a = TimeSignature('3/4')
>>> b = a.mx
>>> a = TimeSignature('3/4+2/4')
>>> b = a.mx
numerator

Return the numerator of the TimeSignature as a number.

>>> ts = TimeSignature('3/4')
>>> ts.numerator
3
quarterLengthToBeatLengthRatio
No documentation.
totalLength

Total length of the TimeSignature, in Quarter Lengths.

>>> ts = TimeSignature('6/8')
>>> ts.totalLength
3.0

Properties inherited from Music21Object: duration, offset, parent, priority

TimeSignature methods

getAccent(qLenPos)

Return True or False if the qLenPos is at the start of an accent division.

>>> a = TimeSignature('3/4', 3)
>>> a.accent.partition([2,1])
>>> a.accent
<MeterSequence {2/4+1/4}>
>>> a.getAccent(0)
True
>>> a.getAccent(1)
False
>>> a.getAccent(2)
True
getAccentWeight(qLenPos, level=0)
Given a qLenPos, return an accent level.
getBeams(srcList)

Given a qLen position and a list of Duration objects, return a list of Beams object. Can alternatively provide a flat stream, from which Durations are extracted. Duration objects are assumed to be adjoining; offsets are not used. This can be modified to take lists of rests and notes Must process a list at time, because we cannot tell when a beam ends unless we see the context of adjoining durations.

>>> a = TimeSignature('2/4', 2)
>>> a.beam[0] = a.beam[0].subdivide(2)
>>> a.beam[1] = a.beam[1].subdivide(2)
>>> a.beam
<MeterSequence {{1/8+1/8}+{1/8+1/8}}>
>>> b = [duration.Duration('16th')] * 8
>>> c = a.getBeams(b)
>>> len(c) == len(b)
True
>>> print(c)
[<music21.note.Beams <music21.note.Beam 1/start>/<music21.note.Beam 2/start>>, <music21.note.Beams <music21.note.Beam 1/continue>/<music21.note.Beam 2/stop>>, <music21.note.Beams <music21.note.Beam 1/continue>/<music21.note.Beam 2/start>>, <music21.note.Beams <music21.note.Beam 1/stop>/<music21.note.Beam 2/stop>>, <music21.note.Beams <music21.note.Beam 1/start>/<music21.note.Beam 2/start>>, <music21.note.Beams <music21.note.Beam 1/continue>/<music21.note.Beam 2/stop>>, <music21.note.Beams <music21.note.Beam 1/continue>/<music21.note.Beam 2/start>>, <music21.note.Beams <music21.note.Beam 1/stop>/<music21.note.Beam 2/stop>>]
>>> a = TimeSignature('6/8')
>>> b = [duration.Duration('eighth')] * 6
>>> c = a.getBeams(b)
>>> print(c)
[<music21.note.Beams <music21.note.Beam 1/start>>, <music21.note.Beams <music21.note.Beam 1/continue>>, <music21.note.Beams <music21.note.Beam 1/stop>>, <music21.note.Beams <music21.note.Beam 1/start>>, <music21.note.Beams <music21.note.Beam 1/continue>>, <music21.note.Beams <music21.note.Beam 1/stop>>]
getBeat(qLenPos)

Given a quarterLength position, get the beat, where beats count from 1

>>> a = TimeSignature('3/4', 3)
>>> a.getBeat(0)
1
>>> a.getBeat(2.5)
3
>>> a.beat.partition(['3/8', '3/8'])
>>> a.getBeat(2.5)
2
getBeatDepth(qLenPos, align=quantize)
>>> a = TimeSignature('3/4', 3)
>>> a.getBeatDepth(0)
1
>>> a.getBeatDepth(1)
1
>>> a.getBeatDepth(2)
1
>>> b = TimeSignature('3/4', 1)
>>> b.beat[0] = b.beat[0].subdivide(3)
>>> b.beat[0][0] = b.beat[0][0].subdivide(2)
>>> b.beat[0][1] = b.beat[0][1].subdivide(2)
>>> b.beat[0][2] = b.beat[0][2].subdivide(2)
>>> b.getBeatDepth(0)
3
>>> b.getBeatDepth(.5)
1
>>> b.getBeatDepth(1)
2
getBeatProgress(qLenPos)

Given a quarterLength position, get the beat, where beats count from 1, and return the the amount of qLen into this beat the supplied qLenPos is.

>>> a = TimeSignature('3/4', 3)
>>> a.getBeatProgress(0)
(1, 0)
>>> a.getBeatProgress(0.75)
(1, 0.75)
>>> a.getBeatProgress(2.5)
(3, 0.5)
>>> a.beat.partition(['3/8', '3/8'])
>>> a.getBeatProgress(2.5)
(2, 1.0)
load(value, partitionRequest=None)
Loading a meter destroys all internal representations
loadRatio(numerator, denominator, partitionRequest=None)
Convenience method
quarterPositionToBeat(currentQtrPosition=0)
For backward compatibility. Ultimately, remove.
ratioEqual(other)
A basic form of comparison; does not determine if any internatl structures are equal; only outermost ratio.
setAccentWeight(weightList, level=0)

Set accent weight, or floating point scalars, for the accent MeterSequence. Provide a list of values; if this list is shorter than the length of the MeterSequence, it will be looped; if this list is longer, only the first relevant value will be used. If the accent MeterSequence is subdivided, the level of depth to set is given by the optional level argument.

>>> a = TimeSignature('4/4', 4)
>>> len(a.accent)
4
>>> a.setAccentWeight([.8, .2])
>>> a.getAccentWeight(0)
0.800...
>>> a.getAccentWeight(.5)
0.800...
>>> a.getAccentWeight(1)
0.200...
>>> a.getAccentWeight(2.5)
0.800...
>>> a.getAccentWeight(3.5)
0.200...
setDisplay(value, partitionRequest=None)

Set an indendent display value

>>> a = TimeSignature()
>>> a.load('3/4')
>>> a.setDisplay('2/8+2/8+2/8')
>>> a.display
<MeterSequence {2/8+2/8+2/8}>
>>> a.beam
<MeterSequence {{1/8+1/8}+{1/8+1/8}+{1/8+1/8}}>
>>> a.beat
<MeterSequence {{1/8+1/8}+{1/8+1/8}+{1/8+1/8}}>
>>> a.setDisplay('3/4')
>>> a.display
<MeterSequence {3/4}>

Methods inherited from Music21Object: searchParentByAttr(), getContextAttr(), setContextAttr(), addContext(), addLocation(), addLocationAndParent(), freezeIds(), getContextByClass(), getOffsetBySite(), getSiteIds(), getSites(), hasContext(), isClass(), purgeLocations(), removeLocation(), setOffsetBySite(), show(), unfreezeIds(), unwrapWeakref(), wrapWeakref(), write()

CompoundTimeSignature

class music21.meter.CompoundTimeSignature(value=None, partitionRequest=None)
inherits from: TimeSignature, Music21Object

DurationDenominatorTimeSignature

class music21.meter.DurationDenominatorTimeSignature(value=None, partitionRequest=None)

If you have played Hindemith you know these, 3/(dot-quarter) etc.

inherits from: TimeSignature, Music21Object

MeterSequence

class music21.meter.MeterSequence(value=None, partitionRequest=None)

A meter sequence is a list of MeterTerminals, or other MeterSequences

inherits from: MeterTerminal

MeterSequence attributes

Attributes without Documentation: parenthesis, summedNumerator

MeterSequence properties

denominator
No documentation.
depth
Return how many unique levels deep this part is This should be optimized to store values unless the structure has changed.
flat

Retrun a new MeterSequence composed of the flattend representation.

>>> a = MeterSequence('3/4', 3)
>>> b = a.flat
>>> len(b)
3
>>> a[1] = a[1].subdivide(4)
>>> b = a.flat
>>> len(b)
6
>>> a[1][2] = a[1][2].subdivide(4)
>>> a
<MeterSequence {1/4+{1/16+1/16+{1/64+1/64+1/64+1/64}+1/16}+1/4}>
>>> b = a.flat
>>> len(b)
9
flatWeight
Retrun a list of flat weight valuess
numerator
No documentation.
weight
>>> a = MeterSequence('3/4')
>>> a.partition(3)
>>> a.weight = 1
>>> a[0].weight
0.333...
>>> b = MeterTerminal('1/4', .25)
>>> c = MeterTerminal('1/4', .25)
>>> d = MeterSequence([b, c])
>>> d.weight
0.5

Properties inherited from MeterTerminal: duration

MeterSequence methods

getLevel(level=0, flat=True)

Return a complete MeterSequence with the same numerator/denominator reationship but that represents any partitions found at the rquested level. A sort of flatness with variable depth.

>>> b = MeterSequence('4/4', 4)
>>> b[1] = b[1].subdivide(2)
>>> b[3] = b[3].subdivide(2)
>>> b[3][0] = b[3][0].subdivide(2)
>>> b
<MeterSequence {1/4+{1/8+1/8}+1/4+{{1/16+1/16}+1/8}}>
>>> b.getLevel(0)
<MeterSequence {1/4+1/4+1/4+1/4}>
>>> b.getLevel(1)
<MeterSequence {1/4+1/8+1/8+1/4+1/8+1/8}>
>>> b.getLevel(2)
<MeterSequence {1/4+1/8+1/8+1/4+1/16+1/16+1/8}>
getLevelSpan(level=0)

For a given level, return the time span of each terminal or sequnece

>>> b = MeterSequence('4/4', 4)
>>> b[1] = b[1].subdivide(2)
>>> b[3] = b[3].subdivide(2)
>>> b[3][0] = b[3][0].subdivide(2)
>>> b
<MeterSequence {1/4+{1/8+1/8}+1/4+{{1/16+1/16}+1/8}}>
>>> b.getLevelSpan(0)
[(0.0, 1.0), (1.0, 2.0), (2.0, 3.0), (3.0, 4.0)]
>>> b.getLevelSpan(1)
[(0.0, 1.0), (1.0, 1.5), (1.5, 2.0), (2.0, 3.0), (3.0, 3.5), (3.5, 4.0)]
>>> b.getLevelSpan(2)
[(0.0, 1.0), (1.0, 1.5), (1.5, 2.0), (2.0, 3.0), (3.0, 3.25), (3.25, 3.5), (3.5, 4.0)]
getLevelWeight(level=0)

The weightList is an array of weights found in the components. The MeterSequence has a ._weight attribute, but it is not used here

>>> a = MeterSequence('4/4', 4)
>>> a.getLevelWeight()
[0.25, 0.25, 0.25, 0.25]
>>> b = MeterSequence('4/4', 4)
>>> b.getLevelWeight(0)
[0.25, 0.25, 0.25, 0.25]
>>> b[1] = b[1].subdivide(2)
>>> b[3] = b[3].subdivide(2)
>>> b.getLevelWeight(0)
[0.25, 0.25, 0.25, 0.25]
>>> b[3][0] = b[3][0].subdivide(2)
>>> b
<MeterSequence {1/4+{1/8+1/8}+1/4+{{1/16+1/16}+1/8}}>
>>> b.getLevelWeight(0)
[0.25, 0.25, 0.25, 0.25]
>>> b.getLevelWeight(1)
[0.25, 0.125, 0.125, 0.25, 0.125, 0.125]
>>> b.getLevelWeight(2)
[0.25, 0.125, 0.125, 0.25, 0.0625, 0.0625, 0.125]
load(value, partitionRequest=None, autoWeight=False, targetWeight=None)

This method is called when a MeterSequence is created, or if a MeterSequece is re-set. User can enter a list of values or an abbreviated slash notation. autoWeight, if True, will attempt to set weights. tragetWeight, if given, will be used instead of self.weight

>>> a = MeterSequence()
>>> a.load('4/4', 4)
>>> str(a)
'{1/4+1/4+1/4+1/4}'
>>> a.load('4/4', 2) # request 2 beats
>>> str(a)
'{1/2+1/2}'
>>> a.load('5/8', 2) # request 2 beats
>>> str(a)
'{2/8+3/8}'
>>> a.load('5/8+4/4')
>>> str(a)
'{5/8+4/4}'
partition(value)

Partitioning creates and sets a number of MeterTerminals that make up this MeterSequence. A simple way to partition based on argument time. Single integers are treated as beat counts; lists are treated as numerator lists; MeterSequence objects are call partitionByOther().

>>> a = MeterSequence('5/4+3/8')
>>> len(a)
2
>>> b = MeterSequence('13/8')
>>> len(b)
1
>>> b.partition(13)
>>> len(b)
13
>>> a.partition(b)
>>> len(a)
13
partitionByCount(countRequest, loadDefault=True)

This will destroy any structure in the _partition

>>> a = MeterSequence('4/4')
>>> a.partitionByCount(2)
>>> str(a)
'{1/2+1/2}'
>>> a.partitionByCount(4)
>>> str(a)
'{1/4+1/4+1/4+1/4}'
partitionByList(numeratorList)

Given a numerator list, partition MeterSequence inot a new list of MeterTerminals

>>> a = MeterSequence('4/4')
>>> a.partitionByList([1,1,1,1])
>>> str(a)
'{1/4+1/4+1/4+1/4}'
>>> a.partitionByList(['3/4', '1/8', '1/8'])
>>> a
<MeterSequence {3/4+1/8+1/8}>
>>> a.partitionByList(['3/4', '1/8', '5/8'])
Traceback (most recent call last):
MeterException: Cannot set partition by ['3/4', '1/8', '5/8']
partitionByOther(other)

Set partition to that found in another object

>>> a = MeterSequence('4/4', 4)
>>> b = MeterSequence('4/4', 2)
>>> a.partitionByOther(b)
>>> len(a)
2
positionToAddress(qLenPos, includeCoincidentBoundaries=False)

Give a list of values that show all indices necessary to access the exact terminal at a given qLenPos. The len of the returned list also provides the depth at the specified qLen.

>>> a = MeterSequence('3/4', 3)
>>> a[1] = a[1].subdivide(4)
>>> a
<MeterSequence {1/4+{1/16+1/16+1/16+1/16}+1/4}>
>>> len(a)
3
>>> a.positionToAddress(.5)
[0]
>>> a[0]
<MeterTerminal 1/4>
>>> a.positionToAddress(1.0)
[1, 0]
>>> a.positionToAddress(1.5)
[1, 2]
>>> a[1][2]
<MeterTerminal 1/16>
>>> a.positionToAddress(1.99)
[1, 3]
>>> a.positionToAddress(2.5)
[2]
positionToDepth(qLenPos, align=quantize)

Given a qLenPos, return the maximum available depth at this position

>>> b = MeterSequence('4/4', 4)
>>> b[1] = b[1].subdivide(2)
>>> b[3] = b[3].subdivide(2)
>>> b[3][0] = b[3][0].subdivide(2)
>>> b
<MeterSequence {1/4+{1/8+1/8}+1/4+{{1/16+1/16}+1/8}}>
>>> b.positionToDepth(0)
3
>>> b.positionToDepth(0.25) # quantizing active by default
3
>>> b.positionToDepth(1)
3
>>> b.positionToDepth(1.5)
2
positionToIndex(qLenPos, includeCoincidentBoundaries=False)

Given a qLen pos (0 through self.duration.quarterLength), return the active MeterTerminal or MeterSequence

>>> a = MeterSequence('4/4')
>>> a.positionToIndex(5)
...
MeterException: cannot access from qLenPos 5 where total duration is 4.0
>>> a = MeterSequence('4/4')
>>> a.positionToIndex(.5)
0
>>> a.positionToIndex(3.5)
0
>>> a.partition(4)
>>> a.positionToIndex(0.5)
0
>>> a.positionToIndex(3.5)
3
>>> a.partition([1,2,1])
>>> len(a)
3
>>> a.positionToIndex(2.9)
1
positionToSpan(qLenPos)

Given a lenPos, return the span of the active region. Only applies to the top most level of partitions

>>> a = MeterSequence('3/4', 3)
>>> a.positionToSpan(.5)
(0, 1.0)
>>> a.positionToSpan(1.5)
(1.0, 2.0)

Methods inherited from MeterTerminal: ratioEqual(), subdivide(), subdivideByCount(), subdivideByList()

MeterTerminal

class music21.meter.MeterTerminal(slashNotation=None, weight=1)

A MeterTerminal is a nestable primitive of rhythmic division

>>> a = MeterTerminal('2/4')
>>> a.duration.quarterLength
2.0
>>> a = MeterTerminal('3/8')
>>> a.duration.quarterLength
1.5
>>> a = MeterTerminal('5/2')
>>> a.duration.quarterLength
10.0

MeterTerminal properties

denominator
No documentation.
depth
Return how many levels deep this part is. Depth of a terminal is always 1
duration

barDuration gets or sets a duration value that is equal in length to the totalLength

>>> a = MeterTerminal()
>>> a.numerator = 3
>>> a.denominator = 8
>>> d = a.duration
>>> d.type
'quarter'
>>> d.dots
1
>>> d.quarterLength
1.5
numerator
No documentation.
weight
No documentation.

MeterTerminal methods

ratioEqual(other)
Compare the numerator and denominator of another object. Note that these have to be exact matches; 3/4 is not the same as 6/8
subdivide(value)
Subdivision takes a MeterTerminal and, making it into a a collection of MeterTerminals, Returns a MeterSequence. This is different than a partitioning a MeterSequence in that this does not happen in place and instead returns a new object. If an integer is provided, assume it is a partition count
subdivideByCount(countRequest=None)

retrun a MeterSequence

>>> a = MeterTerminal('3/4')
>>> b = a.subdivideByCount(3)
>>> isinstance(b, MeterSequence)
True
>>> len(b)
3
subdivideByList(numeratorList)

Return a MeterSequence countRequest is within the context of the beatIndex

>>> a = MeterTerminal('3/4')
>>> b = a.subdivideByList([1,1,1])
>>> len(b)
3

NonPowerOfTwoTimeSignature

class music21.meter.NonPowerOfTwoTimeSignature(value=None, partitionRequest=None)
inherits from: TimeSignature, Music21Object