Previous topic

music21.search.segment

Next topic

music21.sieve

Table Of Contents

Table Of Contents

This Page

music21.serial

This module defines objects for defining and manipulating structures common to serial and/or twelve-tone music, including ToneRow subclasses.

Functions

music21.serial.findMultisets(inputStream, searchList, reps='skipConsecutive', includeChords=True)

Finds all instances of given multisets of pitch classes within a Stream. A multiset is a generalization of a set, in which the order of the elements in the multiset does not matter, but multiple instances of the same thing (in this case, same pitch class) are treated as distinct elements. Thus, two multisets of pitch classes are considered to be equal if and only if the number of times any given pitch class appears in one multiset is the same as the number of times the pitch class appears in the other multiset.

The inputStream is Stream; as in getContiguousSegmentsOfLength(), the inputStream can contain at most one Score its notes must be contained in measures. However, the inputStream may have multiple parts. The searchList is a list of multisets to be searched for, each multiset being given as a list of pitch classes. Note that the order of pitch classes given in a multiset does not matter. The reps and includeChords settings specify how repeated pitches and chords, respectively, are handled; the possible settings are the same as those in getContiguousSegmentsOfLength().

Returns a list of ContiguousSegmentOfNotes objects for the activeSegment, interpreted as a multiset, matches at least one of the elements of the searchList, subject to the settings specified in reps and includeChords.

>>> part = stream.Part()
>>> n1 = note.Note('e4')
>>> n1.quarterLength = 4
>>> n2 = note.Note('e4')
>>> n2.quarterLength = 4
>>> n3 = note.Note('f4')
>>> n3.quarterLength = 4
>>> n4 = note.Note('e4')
>>> n4.quarterLength = 4
>>> part.append(n1)
>>> part.append(n2)
>>> part.append(n3)
>>> part.append(n4)
>>> part.makeMeasures(inPlace = True)
>>> part.show('text')
{0.0} <music21.stream.Measure 1 offset=0.0>
    {0.0} <music21.clef.TrebleClef>
    {0.0} <music21.meter.TimeSignature 4/4>
    {0.0} <music21.note.Note E>
{4.0} <music21.stream.Measure 2 offset=4.0>
    {0.0} <music21.note.Note E>
{8.0} <music21.stream.Measure 3 offset=8.0>
    {0.0} <music21.note.Note F>
{12.0} <music21.stream.Measure 4 offset=12.0>
    {0.0} <music21.note.Note E>
    {4.0} <music21.bar.Barline style=final>
>>> part.show()
../_images/serial-findMultisets.png

Find all instances of the multiset [5,4,4] in the part

>>> EEF = serial.findMultisets(part, [[5, 4, 4]], 'includeAll', includeChords = False)
>>> [(seg.activeSegment, seg.startMeasureNumber) for seg in EEF]
[([4, 4, 5], 1), ([4, 5, 4], 2)]
>>> EF = serial.findMultisets(part, [[4, 5]], 'ignoreAll')
>>> [seg.segment for seg in EF]
[[<music21.note.Note E>, <music21.note.Note E>, <music21.note.Note F>], 
[<music21.note.Note E>, <music21.note.Note F>], 
[<music21.note.Note E>, <music21.note.Note E>, <music21.note.Note F>, <music21.note.Note E>], 
[<music21.note.Note E>, <music21.note.Note F>, <music21.note.Note E>], 
[<music21.note.Note F>, <music21.note.Note E>]]    

Consider the following examples, with chords.

>>> sc0 = stream.Score()
>>> part0 = stream.Part()
>>> part0.append(note.Note('c4'))
>>> part0.append(note.Note('d4'))
>>> part0.append(note.Note('e4'))
>>> part0.append(chord.Chord(['f4', 'e5']))
>>> part0 = part0.makeMeasures()
>>> sc0.insert(0, part0)
>>> [seg.segment for seg in serial.findMultisets(sc0, [[0, 2, 4]], 'ignoreAll')]
[[<music21.note.Note C>, <music21.note.Note D>, <music21.note.Note E>]]

Also:

>>> sc1 = stream.Score()
>>> part1 = stream.Part()
>>> part1.append(note.Note('c4'))
>>> part1.append(note.Note('d4'))
>>> part1.append(chord.Chord(['e4', 'f4']))
>>> part1 = part1.makeMeasures()
>>> sc1.insert(0, part1)
>>> [seg.getDistinctPitchClasses() for seg in serial.getContiguousSegmentsOfLength(sc1, 3)]
[[0, 2, 4, 5], [2, 4, 5]]
>>> serial.findMultisets(sc1, [[0, 2, 5]])
[]
music21.serial.findSegments(inputStream, searchList, reps='skipConsecutive', includeChords=True)

Finds all instances of given contiguous segments of pitch classes within a Stream.

The inputStream is a Stream; as in getContiguousSegmentsOfLength(), the inputStream can contain at most one Score and its notes must be contained in measures. The searchList is a list of contiguous segments to be searched for, each segment being given as a list of pitch classes. The reps and includeChords settings specify how repeated pitches and chords, respectively, are handled; the possible settings are the same as those in getContiguousSegmentsOfLength().

Returns a list of ContiguousSegmentOfNotes objects for which the activeSegment matches at least one of the elements of the searchList, subject to the settings specified in reps and includeChords.

>>> sc = stream.Score()
>>> part = stream.Part()
>>> sig = meter.TimeSignature('2/4')
>>> part.append(sig)
>>> n1 = note.Note('e4')
>>> n1.quarterLength = 6
>>> part.append(n1)
>>> n2 = note.Note('f4')
>>> n2.quarterLength = 1
>>> part.append(n2)
>>> n3 = chord.Chord(['g4', 'b4'])
>>> n3.quarterLength = 1
>>> part.append(n3)
>>> n4 = note.Note('g4')
>>> n4.quarterLength = 1
>>> part.repeatAppend(n4, 2)
>>> n5 = note.Note('a4')
>>> n5.quarterLength = 3
>>> part.repeatAppend(n5, 2)
>>> n6 = note.Note('b4')
>>> n6.quarterLength = 1
>>> part.append(n6)
>>> n7 = note.Note('c5')
>>> n7.quarterLength = 1
>>> part.append(n7)
>>> newpart = part.makeMeasures()
>>> newpart.makeTies()
>>> newpart.show()
../_images/serial-findSegments.png
>>> sc.insert(0, newpart)
>>> GABandABC = serial.findSegments(sc, [[7, 9, 11], [9, 11, 0]], includeChords = False)
>>> print(GABandABC)
[<music21.serial.ContiguousSegmentOfNotes object...]
>>> len(GABandABC)
2
>>> GABandABC[0].segment, GABandABC[1].segment
([<music21.note.Note G>, <music21.note.Note A>, <music21.note.Note B>], 
[<music21.note.Note A>, <music21.note.Note B>, <music21.note.Note C>])
>>> GABandABC[0].startMeasureNumber, GABandABC[1].startMeasureNumber
(5, 6)

In case it is not clear, we can use the matchedSegment property to determine, to which element of the original searchList the found contiguous segments were matched.

>>> GABandABC[0].matchedSegment
[7, 9, 11]
>>> GABandABC[1].matchedSegment
[9, 11, 0]

One can also search for segments of different lengths, simultaneously. Below, ‘B’ refers to the pitch class 11, which only coincidentally is the same as that of the note B.

>>> len(serial.findSegments(sc, [[7, 9, 11], ['B', 0]], includeChords = False))
2

Below, we can see what happens when we include the chords.

>>> [seg.segment for seg in serial.findSegments(newpart, [[5, 7, 'B']], 'ignoreAll')]
[[<music21.note.Note F>, <music21.chord.Chord G4 B4>]]

As expected, the pitch classes found segment are read in the order 5, 7, 11 (‘B’), as the pitches in the chord are read from bottom to top.

Consider the following other example with chords, which is somewhat more complex:

>>> sc0 = stream.Score()
>>> p0 = stream.Part()
>>> c1 = chord.Chord(['c4', 'd4'])
>>> c2 = chord.Chord(['e4', 'f4'])
>>> p0.append(c1)
>>> p0.append(c2)
>>> p0 = p0.makeMeasures()
>>> sc0.insert(0, p0)
>>> [(seg.segment, seg.activeSegment) for seg in serial.findSegments(sc0, [[0, 2, 4]])]
[([<music21.chord.Chord C4 D4>, <music21.chord.Chord E4 F4>], [0, 2, 4])]
>>> [(seg.segment, seg.activeSegment) for seg in serial.findSegments(sc0, [[2, 4, 5]])]
[([<music21.chord.Chord C4 D4>, <music21.chord.Chord E4 F4>], [2, 4, 5])]

In the two function calls, despite the fact that two different segments of pitch classes were searched for, the same ContiguousSegmentOfNotes object was found for each. This is because the found object can be read in two ways as a sequence of three pitch classes: either as [0, 2, 4], by taking the two notes of the first chord in order and the bottom note of the second, or as [2, 4, 5], by taking the top note of the first chord and the two notes of the second chord in order. Both times, the chords are read from bottom to top.

music21.serial.findTransformedSegments(inputStream, searchList, reps='skipConsecutive', includeChords='skipChords')

Finds all instances of given contiguous segments of pitch classes, with serial transformations, within a Stream.

The inputStream is Stream; as in getContiguousSegmentsOfLength(), the inputStream can contain at most one Score and its notes must be contained in measures. The searchList is a list of contiguous segments to be searched for, each segment being given as a list of pitch classes. The reps and includeChords settings specify how repeated pitches and chords, respectively, are handled; the possible settings are the same as those in getContiguousSegmentsOfLength(). The convention for serial transformations must be specified to either ‘zero’ or ‘original’, as described in zeroCenteredTransformation() and originalCenteredTransformation() - the default setting is ‘original’, as to relate found segments directly to the given segments, without first transposing the given segment to begin on the pitch class 0.

Returns a list of ContiguousSegmentOfNotes objects for which some transformation of the activeSegment matches at least one of the elements of the searchList, subject to the settings specified in reps and includeChords.

>>> n1 = note.Note('c#4')
>>> n2 = note.Note('e4')
>>> n3 = note.Note('d#4')
>>> n4 = note.Note('f4')
>>> n5 = note.Note('e4')
>>> n6 = note.Note('g4')
>>> notelist = [n1, n2, n3, n4, n5, n6]
>>> part = stream.Part()
>>> for n in notelist:
...    n.quarterLength = 1
...    part.append(n)
>>> part = part.makeMeasures()
>>> part.show()
../_images/serial-findTransformedSegments.png
>>> row = [2, 5, 4]    
>>> rowInstances = serial.findTransformedSegments(part, [row], 'rowsOnly', includeChords = False)
>>> len(rowInstances)
2
>>> firstInstance = rowInstances[0]
>>> firstInstance.activeSegment, firstInstance.startMeasureNumber
([1, 4, 3], 1)
>>> firstInstance.originalCenteredTransformationsFromMatched
[('T', 11)]

We have thus found that the first instance of the row [2, 5, 4] within our stream appears as a transposition down a semitone, beginning in measure 1. We can do a similar analysis on the other instance of the row.

>>> secondInstance = rowInstances[1]
>>> secondInstance.activeSegment, secondInstance.startMeasureNumber
([5, 4, 7], 1)
>>> secondInstance.zeroCenteredTransformationsFromMatched
[('RI', 7)]

Let us give an example of this function used with chords included and reps set to ‘ignoreAll’.

>>> s = stream.Stream()
>>> n1 = note.Note('e4')
>>> n2 = note.Note('f4')
>>> n3 = note.Note('g4')
>>> c = chord.Chord(['b4', 'g5', 'a5'])
>>> s.append(n1)
>>> s.append(n2)
>>> s.append(n3)
>>> s.append(c)
>>> s = s.makeMeasures()
>>> [seg.segment for seg in serial.findTransformedSegments(s, [[6, 4, 3]], 'ignoreAll')]
[[<music21.note.Note E>, <music21.note.Note F>, <music21.note.Note G>]]
>>> [seg.segment for seg in serial.findTransformedSegments(s, [[6, 8, 4]], 'ignoreAll')]
[[<music21.note.Note G>, <music21.chord.Chord B4 G5 A5>], [<music21.chord.Chord B4 G5 A5>]]
>>> [seg.activeSegment for seg in serial.findTransformedSegments(s, [[6, 8, 4]], 'ignoreAll')]
[[7, 11, 9], [11, 7, 9]]
>>> [seg.originalCenteredTransformationsFromMatched for seg in serial.findTransformedSegments(s, [[6, 8, 4]], 'ignoreAll')]
[[('R', 3)], [('RI', 3)]]

Pitch classes are extracted from segments in order of appearance, with pitches in chords being read from bottom to top. However, only the first instance of each pitch class is considered, as seen in the activeSegment calls. As long as the first and last pitch classes in the active segment first appear in the first and last elements of the found segment, respectively, the segment will be matched to the segment being searched for. To make this more clear, consider the following example in the same stream s:

>>> [(seg.segment, seg.activeSegment) for seg in serial.findTransformedSegments(s, [[4, 0, 4]], 'includeAll')]
[([<music21.note.Note G>, <music21.chord.Chord B4 G5 A5>], [7, 11, 7])]

Above, the pitch classes of the found segment are read in the order 7, 11, 7, 9. Because a subsequence of this, [7, 11, 7], is an inversion of the search segment, [4, 0, 4], and furthermore, the first 7 is part of the first note of the segment (G), and the last 7 is part of the last chord of the segment, the found segment is matched to the segment being searched for.

music21.serial.findTransposedAndInvertedMultisets(inputStream, searchList, reps='skipConsecutive', includeChords=True)

Finds all instances of given multisets of pitch classes, with transpositions and inversions, within a Stream. A multiset is a generalization of a set, as described in findMultisets().

The inputStream is Stream; as in getContiguousSegmentsOfLength(), it can contain at most one Score, and its notes must be contained in measures. The multisetList is a list of multisets to be searched for, each multiset being given as a list of pitch classes. Note that the order of pitch classes given in a multiset does not matter. The reps and includeChords settings specify how repeated pitches and chords, respectively, are handled; the possible settings are the same as those in getContiguousSegmentsOfLength().

Returns a list of ContiguousSegmentOfNotes objects for some transposition or inversion of the activeSegment, interpreted as a multiset, matches at least one of the elements of the searchList, subject to the settings specified in reps and includeChords.

>>> s = stream.Stream()
>>> n1 = note.Note('c4')
>>> n2 = note.Note('e-4')
>>> n3 = note.Note('g4')
>>> n4 = note.Note('e4')
>>> n5 = note.Note('c4')
>>> for n in [n1, n2, n3, n4]:
...     n.quarterLength = 1
...     s.append(n)
>>> n5.quarterLength = 4
>>> s.append(n5)
>>> s = s.makeMeasures()
>>> s.show()
../_images/serial-findTransposedAndInvertedMultisets.png
>>> majTriads = serial.findTransposedAndInvertedMultisets(s, [[0, 4, 7], [0, 3, 7]], 'ignoreAll', includeChords = False)
>>> [(maj.segment, maj.startOffset) for maj in majTriads]
[([<music21.note.Note G>, <music21.note.Note E>, <music21.note.Note C>], 2.0), 
([<music21.note.Note C>, <music21.note.Note E->, <music21.note.Note G>], 0.0)]
>>> [maj.matchedSegment for maj in majTriads]
[[0, 4, 7], [0, 4, 7]]

Note that when we search for both [0, 4, 7] and [0, 3, 7], which are related to each other by the composition of an inversion and a transposition, each found segment is only matched to one of the multisets in the searchList; thus each found segment appears still appears at most once in the returned list of contiguous segments. Accordingly, calling matchedSegment returns only one element of the searchList for each found segment.

music21.serial.findTransposedMultisets(inputStream, searchList, reps='skipConsecutive', includeChords=True)

Finds all instances of given multisets of pitch classes, with transpositions, within a Stream. A multiset is a generalization of a set, as described in findMultisets().

The inputStream is Stream; as in getContiguousSegmentsOfLength(), the inputStream can contain at most one Score and its notes must be contained in measures. The searchList is a list of multisets to be searched for, each multiset being given as a list of pitch classes. Note that the order of pitch classes given in a multiset does not matter. The reps and includeChords settings specify how repeated pitches and chords, respectively, are handled; the possible settings are the same as those in getContiguousSegmentsOfLength().

Returns a list of ContiguousSegmentOfNotes objects for some transposition of the activeSegment, interpreted as a multiset, matches at least one of the elements of the searchList, subject to the settings specified in reps and includeChords.

>>> part = stream.Part()
>>> n1 = note.Note('c4')
>>> n2 = note.Note('c#4')
>>> n3 = note.Note('d4')
>>> n4 = note.Note('e4')
>>> n5 = note.Note('e-4')
>>> n6 = note.Note('e4')
>>> n7 = note.Note('d4')
>>> for n in [n1, n2, n3, n4, n5, n6, n7]:
...    n.quarterLength = 2
...    part.repeatAppend(n, 2)
>>> part = part.makeMeasures()
>>> part.show()
../_images/serial-findTransposedMultisets.png
>>> instanceList = serial.findTransposedMultisets(part, [[-9, -10, -11]], includeChords = False)
>>> for instance in instanceList:
...    (instance.activeSegment, instance.startMeasureNumber, instance.matchedSegment)
([2, 4, 3], 3, [-9, -10, -11])
([3, 4, 2], 5, [-9, -10, -11])
([0, 1, 2], 1, [-9, -10, -11])
music21.serial.findTransposedSegments(inputStream, searchList, reps='skipConsecutive', includeChords=True)

Finds all instances of given contiguous segments of pitch classes, with transpositions, within a Stream.

The inputStream is a Stream; as in getContiguousSegmentsOfLength(), the inputStream can contain at most one Score and its notes must be contained in measures. The searchList is a list of contiguous segments to be searched for, each segment being given as a list of pitch classes. The reps and includeChords settings specify how repeated pitches and chords, respectively, are handled; the possible settings are the same as those in getContiguousSegmentsOfLength().

Returns a list of ContiguousSegmentOfNotes objects for which some transposition of the activeSegment matches at least one of the elements of the searchList, subject to the settings specified in reps and includeChords.

>>> part = stream.Part()
>>> n1 = note.Note('e4')
>>> n1.quarterLength = 6
>>> part.append(n1)
>>> n2 = note.Note('f4')
>>> n2.quarterLength = 1
>>> part.append(n2)
>>> n3 = chord.Chord(['g4', 'b4'])
>>> n3.quarterLength = 1
>>> part.append(n3)
>>> n4 = note.Note('g4')
>>> n4.quarterLength = 1
>>> part.repeatAppend(n4, 2)
>>> n5 = note.Note('a4')
>>> n5.quarterLength = 3
>>> part.repeatAppend(n5, 2)
>>> n6 = note.Note('b4')
>>> n6.quarterLength = 1
>>> part.append(n6)
>>> n7 = note.Note('c5')
>>> n7.quarterLength = 1
>>> part.append(n7)
>>> newpart = part.makeMeasures()
>>> newpart.makeTies()
>>> newpart.show()
../_images/serial-findTransposedSegments.png

First, note that it is impossible, using the ‘ignoreAll’ setting, to find segments, transposed or not, with repeated pitch classes.

>>> serial.findTransposedSegments(newpart, [[0, 0]], 'ignoreAll')
[]

A somewhat more interesting example is below.

>>> halfStepList = serial.findTransposedSegments(newpart, [[0, 1]], 'rowsOnly', includeChords = False)
>>> L = [step.segment for step in halfStepList]
>>> print(L)
[[<music21.note.Note E>, <music21.note.Note F>], [<music21.note.Note B>, <music21.note.Note C>]]
>>> [step.startMeasureNumber for step in halfStepList]
[1, 5]

In addition to calling the startMeasureNumber property to return the measure numbers on which the half steps start, one may also call the measureNumber property of the first Note of each segment.

>>> s = stream.Stream()
>>> s.repeatAppend(newpart, 2) #s has two parts, each of which is a copy of newpart.
>>> wholeStepList = serial.findTransposedSegments(s, [[12, 2]], includeChords = False)
>>> [(step.segment, step.startMeasureNumber, step.partNumber) for step in wholeStepList]
[([<music21.note.Note G>, <music21.note.Note A>], 3, 0), 
([<music21.note.Note A>, <music21.note.Note B>], 3, 0), 
([<music21.note.Note G>, <music21.note.Note A>], 3, 1), 
([<music21.note.Note A>, <music21.note.Note B>], 3, 1)]

Including chords works similarly as in findSegments.

>>> [seg.segment for seg in serial.findTransposedSegments(newpart, [[4, 6, 'A']])]
[[<music21.note.Note F>, <music21.chord.Chord G4 B4>]]
music21.serial.getContiguousSegmentsOfLength(inputStream, length, reps='skipConsecutive', includeChords=True)

Returns a list of ContiguousSegmentOfNotes objects given a Stream where the desired number of notes in the segment is specified.

The inputStream is a ContiguousSegmentOfNotes containing at most one score. Furthermore, all notes must be contained within measures.

The reps argument specifies how repeated pitch classes are dealt with. It may be set to ‘skipConsecutive’ (default), ‘rowsOnly’, ‘includeAll’, or ‘ignoreAll’. These are explained in detail below.

The includeChords argument specifies how chords are dealt with. When set to True (default), the pitches of all chords are read in order from bottom to top, and when set to False, all segments containing chords are ignored.

The main subtleties of this function lie in how each reps setting works in conjunction with chords when includeChords is set to True, and how the lengths of the segments are measured. However, let us first examine what happens when includeChords is set to False, to get an idea of how the function works.

To begin, we create a stream on which we will apply the function.

>>> s = stream.Stream()
>>> n1 = note.Note('e4')
>>> n1.quarterLength = 6
>>> s.append(n1)
>>> n2 = note.Note('f4')
>>> n2.quarterLength = 1
>>> s.append(n2)
>>> n3 = chord.Chord(['g4', 'b4'])
>>> n3.quarterLength = 1
>>> s.append(n3)
>>> n4 = note.Note('g4')
>>> n4.quarterLength = 1
>>> s.repeatAppend(n4, 2)
>>> n5 = note.Note('a4')
>>> n5.quarterLength = 3
>>> s.repeatAppend(n5, 2)
>>> n6 = note.Note('b4')
>>> n6.quarterLength = 1
>>> s.append(n6)
>>> n7 = note.Note('c5')
>>> n7.quarterLength = 1
>>> s.append(n7)

We can now try to apply this function:

>>> contiglist = serial.getContiguousSegmentsOfLength(s, 3, 'skipConsecutive', False)
>>> print(contiglist)
[]

On our first attempt, no contiguous segments of notes were found above because the inputStream has no measures - hence we replace s with s.makeMeasures().

>>> s = s.makeMeasures()
>>> s.makeTies()
>>> s.show()
../_images/serial-findTransposedSegments.png

We now can apply the function, and in doing so we examine in detail each of the reps settings.

‘skipConsecutive’ means that whenever immediate repetitions of notes or chords occur, only the first instance of the note or chord is included in the segment. The durations of the repeated notes, do not have to be the same.

>>> skipConsecutiveList = serial.getContiguousSegmentsOfLength(s, 3, 'skipConsecutive', False)
>>> print(skipConsecutiveList)
[<music21.serial.ContiguousSegmentOfNotes object ...]
>>> [instance.segment for instance in skipConsecutiveList]
[[<music21.note.Note G>, <music21.note.Note A>, <music21.note.Note B>], 
[<music21.note.Note A>, <music21.note.Note B>, <music21.note.Note C>]]

In order to be considered repetition, the spellings of the notes in question must be exactly the same: enharmonic equivalents are not checked and notes with the same pitch in different octaves are considered different. To illustrate this, see the example below, in which all three notes, with pitch class 0, are considered separately.

>>> new = stream.Stream()
>>> N1 = note.Note('c4')
>>> N2 = note.Note('c5')
>>> N3 = note.Note('b#5')
>>> new.append(N1)
>>> new.append(N2)
>>> new.append(N3)
>>> new = new.makeMeasures()
>>> [seg.segment for seg in serial.getContiguousSegmentsOfLength(new, 3, 'skipConsecutive', includeChords = False)]
[[<music21.note.Note C>, <music21.note.Note C>, <music21.note.Note B#>]]

‘rowsOnly’ searches only for tone rows, in which all pitch classes in the segment must be distinct. Below, we are looking for sequences three consecutive notes within the stream s, all of which have different pitch classes. There is only one such set of notes, and by calling the ContiguousSegmentOfNotes we can determine its location (the measure number of its first note).

>>> rowsOnlyList = serial.getContiguousSegmentsOfLength(s, 3, 'rowsOnly', includeChords = False)
>>> [(instance.segment, instance.startMeasureNumber) for instance in rowsOnlyList]
[([<music21.note.Note A>, <music21.note.Note B>, <music21.note.Note C>], 4)]

‘includeAll’ disregards all repetitions, and simply gets all contiguous segments of the specified length (still subject to the includeChords setting).

>>> includeAllList = serial.getContiguousSegmentsOfLength(s, 3, 'includeAll', includeChords = False)
>>> [(instance.segment, instance.startMeasureNumber, instance.startOffset) for instance in includeAllList]
[([<music21.note.Note G>, <music21.note.Note G>, <music21.note.Note A>], 3, 0.0),
([<music21.note.Note G>, <music21.note.Note A>, <music21.note.Note A>], 3, 1.0),
([<music21.note.Note A>, <music21.note.Note A>, <music21.note.Note B>], 3, 2.0),
([<music21.note.Note A>, <music21.note.Note B>, <music21.note.Note C>], 4, 1.0)]

Note that there only two total As appear in these segments, despite there being three Note objects with the A4 as the pitch in the stream s; this is because only the first note of each set of tied notes is considered. This convention applies to this function and all parsing functions below. Also note that so far, neither of the first two notes n1, n2 nor the major third n3 in s have been included in any of the returned contiguous segments. This is because for each of these, any instance of three consecutive notes or chords contains the chord n3. This phenomenon also applies to the next example below.

Finally, when includeChords is set to False, ‘ignoreAll’ finds all contiguous segments containing exactly three distinct pitch classes within it. It is unique in that unlike the previous three reps settings, the segments returned in fact have more than the number of notes specified (3). Rather, they each have 3 distinct pitch classes, and some pitch classes may be repeated.

>>> ignoreAllList = serial.getContiguousSegmentsOfLength(s, 3, 'ignoreAll', includeChords = False)
>>> [instance.segment for instance in ignoreAllList]
[[<music21.note.Note G>, <music21.note.Note G>, <music21.note.Note A>, <music21.note.Note A>, <music21.note.Note B>], 
[<music21.note.Note G>, <music21.note.Note A>, <music21.note.Note A>, <music21.note.Note B>], 
[<music21.note.Note A>, <music21.note.Note A>, <music21.note.Note B>, <music21.note.Note C>], 
[<music21.note.Note A>, <music21.note.Note B>, <music21.note.Note C>]]

Let us now examine what happens in the default chord setting, in which includeChords is set to True.

There are two points to remember when considering chords: the first is that all chords are read as sequences of single notes, from bottom to top. The second is that ‘length’ always applies to the total number of single pitches or pitch classes found in the segment, including within chords, and not to the number of notes or chords. However, as we will see, when we search for contiguous segments of length 4, the returned segments may not have exactly 4 total notes (possibly existing as single notes or within chords), a natural point of confusion.

Below is a new stream s0.

>>> s0 = stream.Stream()
>>> n1 = note.Note('d4')
>>> maj2nd = chord.Chord(['f4', 'g4'])
>>> bmaj1 = chord.Chord(['b4', 'd#5', 'f#5'])
>>> bmaj2 = chord.Chord(['b4', 'd#5', 'f#5'])
>>> n2 = note.Note('f#4')
>>> n3 = note.Note('e4')
>>> n4 = note.Note('a4')
>>> s0.append(n1)
>>> s0.append(maj2nd)
>>> s0.append(bmaj1)
>>> s0.append(bmaj2)
>>> s0.append(n2)
>>> s0.append(n3)
>>> s0.append(n4)
>>> s0 = s0.makeMeasures()
>>> s.show()
../_images/serial-getContiguousSegmentsOfLength2.png
>>> skipConsecutiveWithChords = serial.getContiguousSegmentsOfLength(s0, 4, 'skipConsecutive')
>>> [seg.segment for seg in skipConsecutiveWithChords]
[[<music21.note.Note D>, <music21.chord.Chord F4 G4>, <music21.chord.Chord B4 D#5 F#5>], 
[<music21.chord.Chord F4 G4>, <music21.chord.Chord B4 D#5 F#5>], 
[<music21.chord.Chord B4 D#5 F#5>, <music21.note.Note F#>], 
[<music21.chord.Chord B4 D#5 F#5>, <music21.note.Note F#>, <music21.note.Note E>], 
[<music21.chord.Chord B4 D#5 F#5>, <music21.note.Note F#>, <music21.note.Note E>, <music21.note.Note A>]]

Let us look closely at the found segments. First, because reps was set to ‘skipConsecutive’, the second B major chord (bmaj2) is never considered, as the chord right before it is the same. As was mentioned before, not all of the segments found have exactly 4 notes total. This is because, for each segment, only a subset of the notes contained in the first and last elements are read. Given one of the found segments, it will always be possible to extract exactly four consecutive pitches from the notes and chords, reading in order, so that at least one pitch is taken from each of the first and last chords.

In the first segment, there is one way to extract 4 consecutive pitches: we take the D in the first note, read the F and G (in that order) from the next chord, and finally, reading the last chord from bottom to top, the B from the B major chord. Note that no other reading of the segment is possible because the D from the first note must be used. The second segment in the returned list, on the other hand, can be read as a sequence of 4 consecutive pitches in two ways, both equally valid. We can either take the top note of the first chord, and all three notes, in order, of the second chord, or both notes of the first chord and the bottom two notes of the second chord.

>>> rowsOnlyChords = serial.getContiguousSegmentsOfLength(s0, 4, 'rowsOnly')
>>> [seg.segment for seg in rowsOnlyChords]
[[<music21.note.Note D>, <music21.chord.Chord F4 G4>, <music21.chord.Chord B4 D#5 F#5>], 
[<music21.chord.Chord F4 G4>, <music21.chord.Chord B4 D#5 F#5>]]

When reps is set to ‘rowsOnly’, the segments returned are those such that each may be read as a sequence of 4 pitches, in the same manner as explained above with the ‘skipConsecutive’ setting, such that the sequence of 4 pitches constitutes a four-note tone row. Above, the first segment corresponds to the row [2, 5, 7, 11], and the second may be read as either [5, 7, 11, 3] or [7, 11, 3, 6]. Note that, for example, we could not include both the B-major chord and the F# that comes right after it in the same segment, because there would have to be two consecutive instances of the pitch class 6 (corresponding to F#). Similarly, we could not include both instances of the B-major chord, as, again, we would have a pitch class repeated in any resulting four-note row.

>>> includeAll = serial.getContiguousSegmentsOfLength(s0, 4, 'includeAll')
>>> [seg.segment for seg in includeAll]
[[<music21.note.Note D>, <music21.chord.Chord F4 G4>, <music21.chord.Chord B4 D#5 F#5>], 
[<music21.chord.Chord F4 G4>, <music21.chord.Chord B4 D#5 F#5>], 
[<music21.chord.Chord B4 D#5 F#5>, <music21.chord.Chord B4 D#5 F#5>], 
[<music21.chord.Chord B4 D#5 F#5>, <music21.note.Note F#>], 
[<music21.chord.Chord B4 D#5 F#5>, <music21.note.Note F#>, <music21.note.Note E>], 
[<music21.chord.Chord B4 D#5 F#5>, <music21.note.Note F#>, <music21.note.Note E>, <music21.note.Note A>]]

Here, all segments from which sequences of four consecutive pitches can be extracted, again with at least one pitch coming from each of the first and last elements of the segments, are found.

>>> ignoreAll = serial.getContiguousSegmentsOfLength(s0, 4, 'ignoreAll')
>>> [seg.segment for seg in ignoreAll]
[[<music21.note.Note D>, <music21.chord.Chord F4 G4>, <music21.chord.Chord B4 D#5 F#5>], 
[<music21.chord.Chord F4 G4>, <music21.chord.Chord B4 D#5 F#5>], 
[<music21.chord.Chord F4 G4>, <music21.chord.Chord B4 D#5 F#5>, <music21.chord.Chord B4 D#5 F#5>], 
[<music21.chord.Chord F4 G4>, <music21.chord.Chord B4 D#5 F#5>, <music21.chord.Chord B4 D#5 F#5>, <music21.note.Note F#>], 
[<music21.chord.Chord B4 D#5 F#5>, <music21.chord.Chord B4 D#5 F#5>, <music21.note.Note F#>, <music21.note.Note E>], 
[<music21.chord.Chord B4 D#5 F#5>, <music21.note.Note F#>, <music21.note.Note E>], 
[<music21.chord.Chord B4 D#5 F#5>, <music21.note.Note F#>, <music21.note.Note E>, <music21.note.Note A>]]

When reps is set to ‘ignoreAll’, the pitch classes from each segment are read by taking, in order, the pitch classes in the order in which they first appear, where chords are again read from bottom to top. For example, in the last segment, the first three pitch classes are those in the first chord, from bottom to top: 11, 3, and 6. Then, the next pitch class appearing is 6, which is disregarded because it has already appeared. Finally, the pitch classes 4 and 9 appear in that order. There are thus five pitch classes in this segment, in the order [11, 3, 6, 4, 9].

The segment can be read has having length 4 because four consecutive pitch classes, [3, 6, 4, 9], can be read from this sequence in such a way that the first pitch class of this subsequence is part of the first chord in the segment, and the last pitch class is that of the last note of the segment. More generally, in this setting the found segments are those which contain at least 4 distinct pitch classes, but the top note of the first chord (or note), the bottom note of the last chord (or note), and all pitches of all notes and chords other than the first and last contain at most 4 distinct pitch classes.

music21.serial.getHistoricalRowByName(rowName)

Given the name referring to a twelve-tone row used in the historical literature, returns a HistoricalTwelveToneRow object with attributes describing the row.

The names of the rows with stored attributes are below (each must be passed as a string, in single quotes).

RowSchoenbergOp23No5

RowSchoenbergOp24Mvmt4

RowSchoenbergOp24Mvmt5

RowSchoenbergOp25

RowSchoenbergOp26

RowSchoenbergOp27No1

RowSchoenbergOp27No2

RowSchoenbergOp27No3

RowSchoenbergOp27No4

RowSchoenbergOp28No1

RowSchoenbergOp28No3

RowSchoenbergOp29

RowSchoenbergOp30

RowSchoenbergOp31

RowSchoenbergOp32

RowSchoenbergOp33A

RowSchoenbergOp33B

RowSchoenbergOp34

RowSchoenbergOp35No1

RowSchoenbergOp35No2

RowSchoenbergOp35No3

RowSchoenbergOp35No5

RowSchoenbergOp36

RowSchoenbergOp37

RowSchoenbergFragPianoPhantasia

RowSchoenbergFragOrganSonata

RowSchoenbergFragPiano

RowSchoenbergOp41

RowSchoenbergOp42

RowSchoenbergJakobsleiter

RowSchoenbergOp44

RowSchoenbergOp45

RowSchoenbergOp46

RowSchoenbergOp47

RowSchoenbergOp48No1

RowSchoenbergOp48No2

RowSchoenbergOp48No3

RowSchoenbergIsraelExists

RowSchoenbergOp50A

RowSchoenbergOp50B

RowSchoenbergOp50C

RowSchoenbergMosesAron

RowBergChamberConcerto

RowBergWozzeckPassacaglia

RowBergLyricSuite

RowBergLyricSuitePerm

RowBergDerWein

RowBergLulu

RowBergLuluActIScene20

RowBergLuluActIIScene1

RowBergViolinConcerto

RowWebernOpNo17No1

RowWebernOp17No2

RowWebernOp17No3

RowWebernOp18No1

RowWebernOp18No2

RowWebernOp18No3

RowWebernOp19No1

RowWebernOp19No2

RowWebernOp20

RowWebernOp21

RowWebernOp22

RowWebernOp23

RowWebernOp24

RowWebernOp25

RowWebernOp26

RowWebernOp27

RowWebernOp28

RowWebernOp29

RowWebernOp30

RowWebernOp31

>>> a = serial.getHistoricalRowByName('RowWebernOp29')
>>> a.row
[3, 11, 2, 1, 5, 4, 7, 6, 10, 9, 0, 8]
>>> a.composer
'Webern'
>>> a.opus
'Op. 29'
>>> a.title
'Cantata I'
>>> a.isLinkChord()
False
music21.serial.labelMultisets(inputStream, multisetDict, reps='skipConsecutive', includeChords=True)

Labels all instances of a given collection of multisets of pitch classes in a Stream. A multiset is a generalization of a set, as described in findMultisets().

The multisetDict is a dictionary whose keys are names of the multisets to be searched for, and whose values are the segments of pitch classes. The values will be turned in to a segmentList, as in findMultisets(). All other settings are as in findMultisets() as well.

Returns a deep copy of the inputStream with a Line connecting the first and last notes of each found multiset, and the first note of each found multiset labeled with a Lyric, the label being the key corresponding to the segment of pitch classes. One should make sure not to call this function with too large of a segmentDict, as a note being contained in too many segments will result in some spanners not showing.

At the present time a relatively large number of multisets are found using the ‘ignoreAll’ setting, particularly when there are many repetitions of pitch classes (immediate or otherwise). As a result, it is possible that at points in the stream there will be more than six spanners active simultaneously, which may result in some spanners not showing correctly in XML format, or not at all.

>>> part = stream.Part()
>>> n1 = note.Note('e4')
>>> n1.quarterLength = 4
>>> n2 = note.Note('e4')
>>> n2.quarterLength = 4
>>> n3 = note.Note('f4')
>>> n3.quarterLength = 4
>>> n4 = note.Note('e4')
>>> n4.quarterLength = 4
>>> part.append(n1)
>>> part.append(n2)
>>> part.append(n3)
>>> part.append(n4)
>>> part = part.makeMeasures()
>>> labeledPart = serial.labelMultisets(part, {'EEF':[4, 5, 4]}, reps = 'includeAll', includeChords = False)
>>> labeledPart.show()
../_images/serial-labelMultisets.png

Note: the spanners above were moved manually so that they can be more easily distinguished from one another.

music21.serial.labelSegments(inputStream, segmentDict, reps='skipConsecutive', includeChords=True)

Labels all instances of a given collection of segments of pitch classes in a Stream.

The segmentDict is a dictionary whose keys are names of the segments to be searched for, and whose values are the segments of pitch classes. The values will be turned in to a segmentList, as in findSegments(). All other settings are as in findSegments() as well.

Returns a deep copy of the inputStream with a Line connecting the first and last notes of each found segment, and the first note of each found segment labeled with a Lyric, the label being the key corresponding to the segment of pitch classes. One should make sure not to call this function with too large of a segmentDict, as a note being contained in too many segments will result in some spanners not showing.

>>> part = stream.Part()
>>> sig = meter.TimeSignature('2/4')
>>> part.append(sig)
>>> n1 = note.Note('e4')
>>> n1.quarterLength = 6
>>> part.append(n1)
>>> n2 = note.Note('f4')
>>> n2.quarterLength = 1
>>> part.append(n2)
>>> n3 = chord.Chord(['g4', 'b4'])
>>> n3.quarterLength = 1
>>> part.append(n3)
>>> n4 = note.Note('g4')
>>> n4.quarterLength = 1
>>> part.repeatAppend(n4, 2)
>>> n5 = note.Note('a4')
>>> n5.quarterLength = 3
>>> part.repeatAppend(n5, 2)
>>> n6 = note.Note('b4')
>>> n6.quarterLength = 1
>>> part.append(n6)
>>> n7 = note.Note('c5')
>>> n7.quarterLength = 1
>>> part.append(n7)
>>> newpart = part.makeMeasures()
>>> newpart.makeTies()

We can then label the segment of pitch classes [7, 9, 11], which corresponds to a G, followed by an A, followed by a B. Let us call this segment “GAB”.

>>> labelGAB = serial.labelSegments(newpart, {'GAB':[7, 9, 11]}, includeChords = False)
>>> labelGAB.show()
../_images/serial-labelSegments.png
music21.serial.labelTransformedSegments(inputStream, segmentDict, reps='skipConsecutive', chords='skipChords', convention='original')

Labels all instances of a given collection of segments of pitch classes, with transformations, in a Stream.

The segmentDict is a dictionary whose keys are names of the segments to be searched for, and whose values are the segments of pitch classes. The values will be turned in to a segmentList, as in findTransposedSegments(). The last argument specifies the convention (‘zero’ or ‘original’) used for naming serial transformations, as explained in zeroCenteredTransformation() and originalCenteredTransformation().

All other settings are as in findTransposedSegments() as well.

Returns a deep copy of the inputStream with a Line connecting the first and last notes of each found segment, and the first note of each found segment labeled with a Lyric, the label being the key corresponding to the segment of pitch classes. One should make sure not to call this function with too large of a segmentDict, as a note being contained in too many segments will result in some spanners not showing.

>>> c1 = chord.Chord(['c#4', 'e4'])
>>> c2 = chord.Chord(['d#4', 'f4'])
>>> c3 = chord.Chord(['e4', 'g4'])
>>> chordList = [c1, c2, c3]
>>> part = stream.Part()
>>> for c in chordList:
...    c.quarterLength = 4
...    part.append(c)
>>> part = part.makeMeasures()
>>> labeledPart = serial.labelTransformedSegments(part, {'row':[2, 5, 4]})
>>> labeledPart.show()
../_images/serial-labelTransformedSegments.png

Note: the spanners above were moved manually so that they can be more easily distinguished from one another.

music21.serial.labelTransposedAndInvertedMultisets(inputStream, multisetDict, reps='skipConsecutive', includeChords=True)

Labels all instances of a given collection of multisets, with transpositions and inversions, of pitch classes in a Stream.

A multiset is a generalization of a set, as described in findMultisets().

The multisetDict is a dictionary whose keys are names of the multisets to be searched for, and whose values are the segments of pitch classes. The values will be turned in to a segmentList, as in findMultisets().

All other settings are as in findTransposedMultisets() as well.

Returns a deep copy of the inputStream with a Line connecting the first and last notes of each found multiset, and the first note of each found multiset labeled with a Lyric, the label being the key corresponding to the segment of pitch classes. One should make sure not to call this function with too large of a segmentDict, as a note being contained in too many segments will result in some spanners not showing.

At the present time a relatively large number of multisets are found using the ‘ignoreAll’ setting, particularly when there are many repetitions of pitch classes (immediate or otherwise).

As a result, it is possible that at points in the stream there will be more than six spanners active simultaneously, which may result in some spanners not showing correctly in XML format, or not at all.

>>> s = stream.Stream()
>>> n1 = note.Note('c4')
>>> n2 = note.Note('e-4')
>>> n3 = note.Note('g4')
>>> n4 = note.Note('e4')
>>> n5 = note.Note('c4')
>>> for n in [n1, n2, n3, n4]:
...     n.quarterLength = 1
...     s.append(n)
>>> n5.quarterLength = 4
>>> s.append(n5)
>>> s = s.makeMeasures()
>>> serial.labelTransposedAndInvertedMultisets(s, {'triad':[0, 4, 7]}, includeChords = False).show()
../_images/serial-labelTransposedAndInvertedMultisets.png

Note: the spanners above were moved manually so that they can be more easily distinguished from one another.

music21.serial.labelTransposedMultisets(inputStream, multisetDict, reps='skipConsecutive', includeChords=True)

Labels all instances of a given collection of multisets, with transpositions, of pitch classes in a Stream.

A multiset is a generalization of a set, as described in findMultisets().

The multisetDict is a dictionary whose keys are names of the multisets to be searched for, and whose values are the segments of pitch classes. The values will be turned in to a segmentList, as in findMultisets().

All other settings are as in findTransposedMultisets() as well.

Returns a deep copy of the inputStream with a Line connecting the first and last notes of each found multiset, and the first note of each found multiset labeled with a Lyric, the label being the key corresponding to the segment of pitch classes. One should make sure not to call this function with too large of a segmentDict, as a note being contained in too many segments will result in some spanners not showing.

At the present time a relatively large number of multisets are found using the ‘ignoreAll’ setting, particularly when there are many repetitions of pitch classes (immediate or otherwise). As a result, it is possible that at points in the stream there will be more than six spanners active simultaneously, which may result in some spanners not showing correctly in XML format, or not at all.

As a diversion, instead of using this tool on atonal music, let us do so on Bach.

We can label all instances of three of the same pitch classes occurring in a row in one of the chorales.

We learn the obvious - it appears that the alto section would be the most bored while performing this chorale.

>>> bach = corpus.parse('bach/bwv57.8')
>>> serial.labelTransposedMultisets(bach, {'x3':[0, 0, 0]}, reps = 'includeAll', includeChords = False).show()
../_images/serial-labelTransposedMultisets.png

Note: the spanners above were moved manually so that they can be more easily distinguished from one another.

music21.serial.labelTransposedSegments(inputStream, segmentDict, reps='skipConsecutive', includeChords=True)

Labels all instances of a given collection of segments of pitch classes, with transpositions, in a Stream.

The segmentDict is a dictionary whose keys are names of the segments to be searched for, and whose values are the segments of pitch classes. The values will be turned in to a segmentList, as in findTransposedSegments(). All other settings are as in findTransposedSegments() as well.

Returns a deep copy of the inputStream with a Line connecting the first and last notes of each found segment, and the first note of each found segment labeled with a Lyric, the label being the key corresponding to the segment of pitch classes. One should make sure not to call this function with too large of a segmentDict, as a note being contained in too many segments will result in some spanners not showing.

>>> part = stream.Part()
>>> n1 = note.Note('e4')
>>> n1.quarterLength = 6
>>> part.append(n1)
>>> n2 = note.Note('f4')
>>> n2.quarterLength = 1
>>> part.append(n2)
>>> n3 = chord.Chord(['g4', 'b4'])
>>> n3.quarterLength = 1
>>> part.append(n3)
>>> n4 = note.Note('g4')
>>> n4.quarterLength = 1
>>> part.repeatAppend(n4, 2)
>>> n5 = note.Note('a4')
>>> n5.quarterLength = 3
>>> part.repeatAppend(n5, 2)
>>> n6 = note.Note('b4')
>>> n6.quarterLength = 1
>>> part.append(n6)
>>> n7 = note.Note('c5')
>>> n7.quarterLength = 1
>>> part.append(n7)
>>> newpart = part.makeMeasures()
>>> newpart.makeTies()

We have a soprano line; let us now form a bass line.

>>> bass = stream.Part()
>>> n8 = note.Note('c3')
>>> n8.quarterLength = 4
>>> bass.append(n8)
>>> r1 = note.Rest()
>>> r1.quarterLength = 4
>>> bass.append(r1)
>>> n9 = note.Note('b2')
>>> n9.quarterLength = 4
>>> bass.append(n9)
>>> r2 = note.Rest()
>>> r2.quarterLength = 4
>>> bass.append(r2)
>>> n10 = note.Note('c3')
>>> n10.quarterLength = 4
>>> bass.append(n10)
>>> newbass = bass.makeMeasures()
>>> sc = stream.Score()
>>> import copy
>>> sc.insert(0, copy.deepcopy(newpart))
>>> sc.insert(0, copy.deepcopy(newbass))
>>> labeledsc = serial.labelTransposedSegments(sc, {'half':[0, 1]}, 'rowsOnly')
>>> labeledsc.show()
../_images/serial-labelTransposedSegments.png
music21.serial.pcToToneRow(pcSet)

A convenience function that, given a list of pitch classes represented as integers and turns it in to a ToneRow object.

>>> a = serial.pcToToneRow(range(12))
>>> a.show('text')
{0.0} <music21.note.Note C>
{0.0} <music21.note.Note C#>
{0.0} <music21.note.Note D>
{0.0} <music21.note.Note E->
{0.0} <music21.note.Note E>
{0.0} <music21.note.Note F>
{0.0} <music21.note.Note F#>
{0.0} <music21.note.Note G>
{0.0} <music21.note.Note G#>
{0.0} <music21.note.Note A>
{0.0} <music21.note.Note B->
{0.0} <music21.note.Note B>
>>> matrixObj = a.matrix()
>>> print(matrixObj)
  0  1  2  3  4  5  6  7  8  9  A  B
  B  0  1  2  3  4  5  6  7  8  9  A
...
>>> a = serial.pcToToneRow([4,5,0,6,7,2,'a',8,9,1,'b',3])
>>> matrixObj = a.matrix()
>>> print(matrixObj)
  0  1  8  2  3  A  6  4  5  9  7  B
  B  0  7  1  2  9  5  3  4  8  6  A
...
music21.serial.rowToMatrix(p)

takes a row of numbers of converts it to a 12-tone matrix.

ContiguousSegmentOfNotes

class music21.serial.ContiguousSegmentOfNotes(segment=None, containerStream=None, partNumber=0)

Class whose instantiations represent contiguous segments of notes and chords appearing within a Stream. Generally speaking, these objects are instantiated internally, though it is possible for the user to create them as well.

ContiguousSegmentOfNotes bases

ContiguousSegmentOfNotes read-only properties

ContiguousSegmentOfNotes.originalCenteredTransformationsFromMatched

The list of original-centered transformations taking a segment being searched for to a found segment, for example, in findTransformedSegments(). For an explanation of the zero-centered convention for serial transformations, see music21.serial.ToneRow.originalCenteredTransformation().

ContiguousSegmentOfNotes.startMeasureNumber

The measure number on which the contiguous segment begins.

ContiguousSegmentOfNotes.startOffset

The offset of the beginning of the contiguous segment, with respect to the measure containing the first note.

ContiguousSegmentOfNotes.zeroCenteredTransformationsFromMatched

The list of zero-centered transformations taking a segment being searched for to a found segment, for example, in findTransformedSegments(). For an explanation of the zero-centered convention for serial transformations, see music21.serial.ToneRow.zeroCenteredTransformation().

Read-only properties inherited from Music21Object:

ContiguousSegmentOfNotes read/write properties

Read/write properties inherited from Music21Object:

ContiguousSegmentOfNotes methods

ContiguousSegmentOfNotes.getDistinctPitchClasses()

Returns a list of distinct pitch classes in the segment, in order of appearance, where pitches in a chord are read from bottom to top.

>>> sc = stream.Score()
>>> n1 = note.Note('d4')
>>> n1.quarterLength = 1
>>> c = chord.Chord(['d4', 'e4', 'g4', 'd5'])
>>> c.quarterLength = 1
>>> sc.append(n1)
>>> sc.append(c)
>>> sc = sc.makeMeasures()
>>> allNotes = serial.getContiguousSegmentsOfLength(sc, 5)
>>> allNotes[0].getDistinctPitchClasses()
[2, 4, 7]
ContiguousSegmentOfNotes.readPitchClassesFromBottom()

Returns the list of pitch classes in the segment, reading pitches within chords from bottom to top.

>>> sc = stream.Score()
>>> n1 = note.Note('d4')
>>> n1.quarterLength = 1
>>> Cmaj = chord.Chord(['c4', 'e4', 'g4'])
>>> Cmaj.quarterLength = 1
>>> sc.append(n1)
>>> sc.append(Cmaj)
>>> sc = sc.makeMeasures()
>>> allNotes = serial.getContiguousSegmentsOfLength(sc, 4)
>>> allNotes[0].readPitchClassesFromBottom()
[2, 0, 4, 7]

Methods inherited from Music21Object:

ContiguousSegmentOfNotes instance variables

ContiguousSegmentOfNotes.activeSegment

A list of pitch classes representing the way the contiguous segment of notes is being read as a sequence of single pitches. Set to None unless the container stream is being searched for segments or multisets (for example, using findSegments()), in which case the representation depends on the segments or multisets being searched for. If there are no chords in the segment, this attribute will simply give the pitch classes of the notes in the segment.

ContiguousSegmentOfNotes.containerStream

The stream containing the contiguous segment - all contiguous segments must have a container stream.

ContiguousSegmentOfNotes.matchedSegment

A list of pitch classes representing the segment to which the contiguous segment of notes is matched when segments or multisets are searched for (for example, using findSegments()); otherwise set to None. Note that the contiguous segment will only be matched to one of the segments or multisets being searched for.

ContiguousSegmentOfNotes.partNumber

The part number in which the segment appears, or None (if the container stream has no parts). Note that this attribute is zero-indexed, so the top (e.g. soprano) part is labeled 0.

ContiguousSegmentOfNotes.segment

The list of notes and chords in the contiguous segment.

Instance variables inherited from Music21Object:

HistoricalTwelveToneRow

class music21.serial.HistoricalTwelveToneRow(composer=None, opus=None, title=None, row=None)

Subclass of TwelveToneRow storing additional attributes of a twelve-tone row used in the historical literature.

HistoricalTwelveToneRow bases

HistoricalTwelveToneRow read-only properties

Read-only properties inherited from Stream:

Read-only properties inherited from Music21Object:

HistoricalTwelveToneRow read/write properties

Read/write properties inherited from Stream:

Read/write properties inherited from Music21Object:

HistoricalTwelveToneRow methods

Methods inherited from TwelveToneRow:

Methods inherited from ToneRow:

Methods inherited from Stream:

Methods inherited from Music21Object:

HistoricalTwelveToneRow instance variables

HistoricalTwelveToneRow.composer

The name of the composer.

HistoricalTwelveToneRow.opus

The opus of the work, or None.

HistoricalTwelveToneRow.title

The title of the work.

Instance variables inherited from TwelveToneRow:

  • row

Instance variables inherited from ToneRow:

Instance variables inherited from Stream:

Instance variables inherited from Music21Object:

ToneRow

class music21.serial.ToneRow

A Stream representation of a tone row, or an ordered sequence of pitches; can most importantly be used to deal with serial transformations.

ToneRow bases

ToneRow read-only properties

Read-only properties inherited from Stream:

Read-only properties inherited from Music21Object:

ToneRow read/write properties

Read/write properties inherited from Stream:

Read/write properties inherited from Music21Object:

ToneRow methods

ToneRow.findOriginalCenteredTransformations(otherRow)

Gives the list of original-centered serial transformations taking one ToneRow to another, the second specified in the argument. Each transformation is given as a tuple of the transformation type and index.

See originalCenteredTransformation() for an explanation of this convention.

>>> chromatic = serial.pcToToneRow([2, 3, 4, 5, 6, 7, 8, 9, 'A', 'B', 0, 1])
>>> reversechromatic = serial.pcToToneRow([8, 7, 6, 5, 4, 3, 2, 1, 0, 'B', 'A', 9])
>>> chromatic.findOriginalCenteredTransformations(reversechromatic)
[('I', 6), ('R', 7)]
>>> schoenberg25 = serial.getHistoricalRowByName('RowSchoenbergOp25')
>>> schoenberg26 = serial.getHistoricalRowByName('RowSchoenbergOp26')
>>> schoenberg25.findOriginalCenteredTransformations(schoenberg26)
[]
>>> schoenberg26.findOriginalCenteredTransformations(schoenberg26.originalCenteredTransformation('RI',8))
[('RI', 8)]
ToneRow.findZeroCenteredTransformations(otherRow)

Gives the list of zero-centered serial transformations taking one ToneRow to another, the second specified in the argument. Each transformation is given as a tuple of the transformation type and index.

See zeroCenteredTransformation() for an explanation of this convention.

>>> chromatic = serial.pcToToneRow([2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0, 1])
>>> reversechromatic = serial.pcToToneRow([8, 7, 6, 5, 4, 3, 2, 1, 0, 11, 10, 9])
>>> chromatic.findZeroCenteredTransformations(reversechromatic)
[('I', 8), ('R', 9)]
>>> schoenberg25 = serial.getHistoricalRowByName('RowSchoenbergOp25')
>>> schoenberg26 = serial.pcToToneRow(serial.getHistoricalRowByName('RowSchoenbergOp26').row)
>>> schoenberg25.findZeroCenteredTransformations(schoenberg26)
[]
>>> schoenberg26.findZeroCenteredTransformations(schoenberg26.zeroCenteredTransformation('RI',8))
[('RI', 8)]
ToneRow.getIntervalsAsString()

Returns the string of intervals between consecutive pitch classes of a ToneRow. ‘T’ = 10, ‘E’ = 11.

>>> cRow = serial.pcToToneRow([0])
>>> cRow.getIntervalsAsString()
''
>>> reversechromatic = serial.pcToToneRow([11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0])
>>> reversechromatic.getIntervalsAsString()
'EEEEEEEEEEE'
ToneRow.isSameRow(row)

Convenience function describing if two rows are the same.

>>> row1 = serial.pcToToneRow([6, 7, 8])
>>> row2 = serial.pcToToneRow([-6, 19, 128])
>>> row3 = serial.pcToToneRow([6, 7, -8])
>>> row1.isSameRow(row2)
True
>>> row2.isSameRow(row1)
True
>>> row1.isSameRow(row3)
False
ToneRow.isTwelveToneRow()

Describes whether or not a ToneRow constitutes a twelve-tone row. Note that a TwelveToneRow object might not be a twelve-tone row.

>>> serial.pcToToneRow(range(0,12)).isTwelveToneRow()
True
>>> serial.pcToToneRow(range(0,10)).isTwelveToneRow()
False
>>> serial.pcToToneRow([3,3,3,3,3,3,3,3,3,3,3,3]).isTwelveToneRow()
False
ToneRow.makeTwelveToneRow()

Convenience function returning a TwelveToneRow with the same pitches. Note that a ToneRow may be created without being a true twelve tone row.

>>> a = serial.pcToToneRow(range(0,11))
>>> type(a)
<class 'music21.serial.ToneRow'>
>>> n = note.Note()
>>> n.pitch.pitchClass = 11
>>> a.append(n)
>>> a = a.makeTwelveToneRow()
...
>>> type(a)
<class 'music21.serial.TwelveToneRow'>
ToneRow.noteNames()

Convenience function showing the note names of a ToneRow as a list.

>>> chromatic = serial.pcToToneRow(range(0,12))
>>> chromatic.noteNames()
['C', 'C#', 'D', 'E-', 'E', 'F', 'F#', 'G', 'G#', 'A', 'B-', 'B']
>>> halfStep = serial.pcToToneRow([0,1])
>>> halfStep.noteNames()
['C', 'C#']
ToneRow.originalCenteredTransformation(transformationType, index)

Returns a ToneRow giving a transformation of a tone row. Admissible transformations are ‘T’ (transposition), ‘I’ (inversion), ‘R’ (retrograde), and ‘RI’ (retrograde inversion).

In the “original-centered” convention, which is less common than the “zero-centered” convention, the original row is not initially transposed to start on the pitch class 0. Thus, the transformation Tn transposes the original row up by n semitones, and the transformations In, Rn, and RIn first transform the row appropriately (without transposition), then transpose the resulting row by n semitones.

>>> chromatic = serial.pcToToneRow(range(0,12))
>>> chromatic.pitchClasses()
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]
>>> chromaticP3 = chromatic.originalCenteredTransformation('T',3)
>>> chromaticP3.pitchClasses()
[3, 4, 5, 6, 7, 8, 9, 10, 11, 0, 1, 2]
>>> chromaticI6 = chromatic.originalCenteredTransformation('I',6)
>>> chromaticI6.pitchClasses()
[6, 5, 4, 3, 2, 1, 0, 11, 10, 9, 8, 7]
>>> schoenberg = serial.getHistoricalRowByName('RowSchoenbergOp26')
>>> schoenberg.pitchClasses()
[3, 7, 9, 11, 1, 0, 10, 2, 4, 6, 8, 5]
>>> schoenbergR8 = schoenberg.originalCenteredTransformation('R',8)
>>> schoenbergR8.pitchClasses()
[1, 4, 2, 0, 10, 6, 8, 9, 7, 5, 3, 11]
>>> schoenbergRI9 = schoenberg.originalCenteredTransformation('RI',9)
>>> schoenbergRI9.noteNames()
['B-', 'G', 'A', 'B', 'C#', 'F', 'E-', 'D', 'E', 'F#', 'G#', 'C']
ToneRow.pitchClasses()

Convenience function showing the pitch classes of a ToneRow as a list.

>>> L = [5*i for i in range(0,12)]
>>> quintupleRow = serial.pcToToneRow(L)
>>> quintupleRow.pitchClasses()
[0, 5, 10, 3, 8, 1, 6, 11, 4, 9, 2, 7]
>>> halfStep = serial.pcToToneRow([0, 1])
>>> halfStep.pitchClasses()
[0, 1]
ToneRow.zeroCenteredTransformation(transformationType, index)

Returns a ToneRow giving a transformation of a tone row. Admissible transformationTypes are ‘P’ (prime), ‘I’ (inversion), ‘R’ (retrograde), and ‘RI’ (retrograde inversion).

In the “zero-centered” convention, the transformations Pn and In start on the pitch class n, and the transformations Rn and RIn end on the pitch class n.

>>> chromatic = serial.pcToToneRow(range(0,12))
>>> chromatic.pitchClasses()
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]
>>> chromaticP3 = chromatic.zeroCenteredTransformation('P',3)
>>> chromaticP3.pitchClasses()
[3, 4, 5, 6, 7, 8, 9, 10, 11, 0, 1, 2]
>>> chromaticI6 = chromatic.zeroCenteredTransformation('I',6)
>>> chromaticI6.pitchClasses()
[6, 5, 4, 3, 2, 1, 0, 11, 10, 9, 8, 7]
>>> schoenberg = serial.getHistoricalRowByName('RowSchoenbergOp26')
>>> schoenberg.pitchClasses()
[3, 7, 9, 11, 1, 0, 10, 2, 4, 6, 8, 5]
>>> schoenbergR8 = schoenberg.zeroCenteredTransformation('R',8)
>>> schoenbergR8.pitchClasses()
[10, 1, 11, 9, 7, 3, 5, 6, 4, 2, 0, 8]
>>> schoenbergRI9 = schoenberg.zeroCenteredTransformation('RI',9)
>>> schoenbergRI9.noteNames()
['G', 'E', 'F#', 'G#', 'B-', 'D', 'C', 'B', 'C#', 'E-', 'F', 'A']

Methods inherited from Stream:

Methods inherited from Music21Object:

ToneRow instance variables

ToneRow.row

A list representing the pitch class values of the row.

Instance variables inherited from Stream:

Instance variables inherited from Music21Object:

TwelveToneMatrix

class music21.serial.TwelveToneMatrix(*arguments, **keywords)

An object representation of a 2-dimensional array of 12 pitches. Internal representation is as a Stream, which stores 12 Streams, each Stream a horizontal row of pitches in the matrix.

This object is commonly used by calling the matrix() method of TwelveToneRow() (or a subclass).

TwelveToneMatrix bases

TwelveToneMatrix read-only properties

Read-only properties inherited from Stream:

Read-only properties inherited from Music21Object:

TwelveToneMatrix read/write properties

Read/write properties inherited from Stream:

Read/write properties inherited from Music21Object:

TwelveToneMatrix methods

Methods inherited from Stream:

Methods inherited from Music21Object:

TwelveToneMatrix instance variables

Instance variables inherited from Stream:

Instance variables inherited from Music21Object:

TwelveToneRow

class music21.serial.TwelveToneRow

A Stream representation of a twelve-tone row, capable of producing a 12-tone matrix.

TwelveToneRow bases

TwelveToneRow read-only properties

Read-only properties inherited from Stream:

Read-only properties inherited from Music21Object:

TwelveToneRow read/write properties

Read/write properties inherited from Stream:

Read/write properties inherited from Music21Object:

TwelveToneRow methods

TwelveToneRow.areCombinatorial(transType1, index1, transType2, index2, convention)

Describes whether or not two transformations of a twelve-tone row are combinatorial.

The first and second arguments describe one transformation, while the third and fourth describe another. One of the zero-centered or original-centered conventions for tone row transformations must be specified in the last argument; see zeroCenteredTransformation() and originalCenteredTransformation() explanations of these conventions.

>>> moses = serial.getHistoricalRowByName('RowSchoenbergMosesAron')
>>> moses.pitchClasses()
[9, 10, 4, 2, 3, 1, 7, 5, 6, 8, 11, 0]
>>> moses.areCombinatorial('P', 1, 'I', 4, 'zero')
True
>>> moses.areCombinatorial('R', 5, 'RI', 6, 'original')
False
TwelveToneRow.findHistorical()

Checks if a given music21.serial.TwelveToneRow is the same as any of the historical twelve-tone rows stored by music21: see music21.serial.getHistoricalRowByName(). Returns a list of names of historical rows to which the input row is identical.

>>> row = serial.pcToToneRow([2, 3, 9, 1, 11, 5, 8, 7, 4, 0, 10, 6])
>>> row.findHistorical()
['RowSchoenbergOp32']
>>> chromatic = serial.pcToToneRow(range(0,12))
>>> chromatic.findHistorical()
[]
TwelveToneRow.findTransformedHistorical(convention)

Checks if a given music21.serial.TwelveToneRow is a transformation of any of the historical twelve-tone rows stored by music21: see music21.serial.getHistoricalRowByName(). Returns a list of tuples, the tuple consisting of the name of a historical row, and a list of transformations relating the input row to the historical row.

The convention for serial transformations must also be specified as ‘zero’ or ‘original’, as explained in findZeroCenteredTransformations() and findOriginalCenteredTransformations().

>>> row = serial.pcToToneRow([5, 9, 11, 3, 6, 7, 4, 10, 0, 8, 2, 1])
>>> row.findTransformedHistorical('original')
[('RowSchoenbergOp32', [('R', 11)])]
TwelveToneRow.getLinkClassification()

Gives the classification number of a Link Chord (as given in http://www.johnlinkmusic.com/LinkChords.pdf), that is, is an all-interval twelve-tone row containing a voicing of the all-trichord hexachord: [0, 1, 2, 4, 7, 8]. In addition, gives a list of sets of five contiguous intervals within the row representing a voicing of the all-trichord hexachord. Note that the interval sets may be transformed.

Named for John Link who discovered them.

>>> bergLyric = serial.getHistoricalRowByName('RowBergLyricSuite')
>>> bergLyric.pitchClasses()
[5, 4, 0, 9, 7, 2, 8, 1, 3, 6, 10, 11]
>>> bergLyric.isAllInterval()
True
>>> bergLyric.getLinkClassification()
(None, [])
>>> link = serial.pcToToneRow([0, 3, 8, 2, 10, 11, 9, 4, 1, 5, 7, 6])
>>> link.getLinkClassification()
(62, ['8352E'])
>>> doubleLink = serial.pcToToneRow([0, 1, 8, 5, 7, 10, 4, 3, 11, 9, 2, 6])
>>> doubleLink.getLinkClassification()
(33, ['236E8', '36E8T'])
TwelveToneRow.isAllInterval()

Describes whether or not a TwelveToneRow is an all-interval row.

>>> chromatic = serial.pcToToneRow(range(0,12))
>>> chromatic.pitchClasses()
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]
>>> chromatic.isAllInterval()
False
>>> bergLyric = serial.getHistoricalRowByName('RowBergLyricSuite')
>>> bergLyric.pitchClasses()
[5, 4, 0, 9, 7, 2, 8, 1, 3, 6, 10, 11]
>>> bergLyric.isAllInterval()
True
TwelveToneRow.isLinkChord()

Describes whether or not a TwelveToneRow is a Link Chord.

>>> bergLyric = serial.getHistoricalRowByName('RowBergLyricSuite')
>>> bergLyric.pitchClasses()
[5, 4, 0, 9, 7, 2, 8, 1, 3, 6, 10, 11]
>>> bergLyric.isAllInterval()
True
>>> bergLyric.isLinkChord()
False
>>> link = serial.pcToToneRow([0, 3, 8, 2, 10, 11, 9, 4, 1, 5, 7, 6])
>>> link.isLinkChord()
True
>>> doubleLink = serial.pcToToneRow([0, 1, 8, 5, 7, 10, 4, 3, 11, 9, 2, 6])
>>> doubleLink.isLinkChord()
True
TwelveToneRow.matrix()

Returns a TwelveToneMatrix object for the row. That object can just be printed (or displayed via .show())

>>> src = serial.getHistoricalRowByName('RowSchoenbergOp37')
>>> [p.name for p in src]
['D', 'C#', 'A', 'B-', 'F', 'E-', 'E', 'C', 'G#', 'G', 'F#', 'B']
>>> len(src)
12
>>> s37 = serial.getHistoricalRowByName('RowSchoenbergOp37').matrix()
>>> print(s37)
  0  B  7  8  3  1  2  A  6  5  4  9
  1  0  8  9  4  2  3  B  7  6  5  A
  5  4  0  1  8  6  7  3  B  A  9  2
  4  3  B  0  7  5  6  2  A  9  8  1
...
>>> [str(e.pitch) for e in s37[0]]
['C', 'B', 'G', 'G#', 'E-', 'C#', 'D', 'B-', 'F#', 'F', 'E', 'A']

Methods inherited from ToneRow:

Methods inherited from Stream:

Methods inherited from Music21Object:

TwelveToneRow instance variables

Instance variables inherited from ToneRow:

Instance variables inherited from Stream:

Instance variables inherited from Music21Object: