Tools for grouping notes and chords into a searchable tree organized by start and stop offsets.
This is a lower-level tool that for now at least normal music21 users won’t need to worry about.
Recurses through inputStream, and constructs TimespanTrees for each encountered substream and ElementTimespans for each encountered non-stream element.
classLists should be a sequence of valid inputs for isClassOrSubclass(). One TimespanTree will be constructed for each element in classLists, in a single optimized pass through the inputStream.
This is used internally by streamToTimespanTree.
>>> score = timespans.makeExampleScore()
Get everything in the score
>>> trees = timespans.listOfTimespanTreesByClass(score)
>>> trees
[<TimespanTree {2} (-inf to inf) <music21.stream.Score ...>>]
>>> for t in trees[0]:
... print(t)
<TimespanTree {4} (-inf to inf) <music21.stream.Part ...>>
<TimespanTree {0} (-inf to inf) <music21.stream.Measure 1 offset=0.0>>
<TimespanTree {0} (-inf to inf) <music21.stream.Measure 2 offset=2.0>>
<TimespanTree {0} (-inf to inf) <music21.stream.Measure 3 offset=4.0>>
<TimespanTree {0} (-inf to inf) <music21.stream.Measure 4 offset=6.0>>
<TimespanTree {4} (-inf to inf) <music21.stream.Part ...>>
<TimespanTree {0} (-inf to inf) <music21.stream.Measure 1 offset=0.0>>
<TimespanTree {0} (-inf to inf) <music21.stream.Measure 2 offset=2.0>>
<TimespanTree {0} (-inf to inf) <music21.stream.Measure 3 offset=4.0>>
<TimespanTree {0} (-inf to inf) <music21.stream.Measure 4 offset=6.0>>
Now filter the Notes and the Clefs & TimeSignatures of the score (flattened) into a list of two timespans
>>> classLists = ['Note', ('Clef', 'TimeSignature')]
>>> trees = timespans.listOfTimespanTreesByClass(score, classLists=classLists, flatten=True)
>>> trees
[<TimespanTree {12} (0.0 to 8.0) <music21.stream.Score ...>>,
<TimespanTree {4} (0.0 to 0.0) <music21.stream.Score ...>>]
Makes example score for use in stream-to-timespan conversion docs.
>>> score = timespans.makeExampleScore()
>>> score.show('text')
{0.0} <music21.stream.Part ...>
{0.0} <music21.instrument.Instrument PartA: : >
{0.0} <music21.stream.Measure 1 offset=0.0>
{0.0} <music21.clef.BassClef>
{0.0} <music21.meter.TimeSignature 2/4>
{0.0} <music21.note.Note C>
{1.0} <music21.note.Note D>
{2.0} <music21.stream.Measure 2 offset=2.0>
{0.0} <music21.note.Note E>
{1.0} <music21.note.Note F>
{4.0} <music21.stream.Measure 3 offset=4.0>
{0.0} <music21.note.Note G>
{1.0} <music21.note.Note A>
{6.0} <music21.stream.Measure 4 offset=6.0>
{0.0} <music21.note.Note B>
{1.0} <music21.note.Note C>
{2.0} <music21.bar.Barline style=final>
{0.0} <music21.stream.Part ...>
{0.0} <music21.instrument.Instrument PartB: : >
{0.0} <music21.stream.Measure 1 offset=0.0>
{0.0} <music21.clef.BassClef>
{0.0} <music21.meter.TimeSignature 2/4>
{0.0} <music21.note.Note C>
{2.0} <music21.stream.Measure 2 offset=2.0>
{0.0} <music21.note.Note G>
{4.0} <music21.stream.Measure 3 offset=4.0>
{0.0} <music21.note.Note E>
{6.0} <music21.stream.Measure 4 offset=6.0>
{0.0} <music21.note.Note D>
{2.0} <music21.bar.Barline style=final>
Recurses through a score and constructs a TimespanTree. Use Stream.asTimespans() generally since that caches the TimespanTree.
>>> score = corpus.parse('bwv66.6')
>>> tree = timespans.streamToTimespanTree(score, flatten=True, classList=(note.Note, chord.Chord))
>>> tree
<TimespanTree {165} (0.0 to 36.0) <music21.stream.Score ...>>
>>> for x in tree[:5]:
... x
...
<ElementTimespan (0.0 to 0.5) <music21.note.Note C#>>
<ElementTimespan (0.0 to 1.0) <music21.note.Note E>>
<ElementTimespan (0.0 to 0.5) <music21.note.Note A>>
<ElementTimespan (0.0 to 0.5) <music21.note.Note A>>
<ElementTimespan (0.5 to 1.0) <music21.note.Note B>>
>>> tree = timespans.streamToTimespanTree(
... score,
... flatten=False,
... classList=(),
... )
Each of these has 11 elements – mainly the Measures
TODO: Fix – why is StaffGroup between Soprano and Alto?
>>> for x in tree:
... x
...
<ElementTimespan (0.0 to 0.0) <music21.metadata.Metadata object at 0x...>>
<TimespanTree {11} (0.0 to 36.0) <music21.stream.Part Soprano>>
<TimespanTree {11} (0.0 to 36.0) <music21.stream.Part Alto>>
<TimespanTree {11} (0.0 to 36.0) <music21.stream.Part Tenor>>
<TimespanTree {11} (0.0 to 36.0) <music21.stream.Part Bass>>
<ElementTimespan (0.0 to 0.0) <music21.layout.StaffGroup <music21.stream.Part Soprano><music21.stream.Part Alto><music21.stream.Part Tenor><music21.stream.Part Bass>>>
>>> tenorElements = tree[3]
>>> tenorElements
<TimespanTree {11} (0.0 to 36.0) <music21.stream.Part Tenor>>
>>> tenorElements.source
<music21.stream.Part Tenor>
>>> tenorElements.source is score[3]
True
Creates a score from the ElementTimespan objects stored in this offset-tree.
A “template” score may be used to provide measure and time-signature information.
>>> score = corpus.parse('bwv66.6')
>>> tree = score.asTimespans()
>>> chordifiedScore = timespans.timespansToChordifiedStream(
... tree, templateStream=score)
>>> chordifiedScore.show('text')
{0.0} <music21.stream.Measure 0 offset=0.0>
{0.0} <music21.clef.TrebleClef>
{0.0} <music21.key.KeySignature of 3 sharps, mode minor>
{0.0} <music21.meter.TimeSignature 4/4>
{0.0} <music21.chord.Chord A3 E4 C#5>
{0.5} <music21.chord.Chord G#3 B3 E4 B4>
{1.0} <music21.stream.Measure 1 offset=1.0>
{0.0} <music21.chord.Chord F#3 C#4 F#4 A4>
{1.0} <music21.chord.Chord G#3 B3 E4 B4>
{2.0} <music21.chord.Chord A3 E4 C#5>
{3.0} <music21.chord.Chord G#3 B3 E4 E5>
{5.0} <music21.stream.Measure 2 offset=5.0>
{0.0} <music21.chord.Chord A3 E4 C#5>
{0.5} <music21.chord.Chord C#3 E4 A4 C#5>
{1.0} <music21.chord.Chord E3 E4 G#4 B4>
{1.5} <music21.chord.Chord E3 D4 G#4 B4>
{2.0} <music21.chord.Chord A2 C#4 E4 A4>
{3.0} <music21.chord.Chord E#3 C#4 G#4 C#5>
{9.0} <music21.stream.Measure 3 offset=9.0>
{0.0} <music21.layout.SystemLayout>
{0.0} <music21.chord.Chord F#3 C#4 F#4 A4>
{0.5} <music21.chord.Chord B2 D4 G#4 B4>
{1.0} <music21.chord.Chord C#3 C#4 E#4 G#4>
{1.5} <music21.chord.Chord C#3 B3 E#4 G#4>
{2.0} <music21.chord.Chord F#2 A3 C#4 F#4>
{3.0} <music21.chord.Chord F#3 C#4 F#4 A4>
...
todo docs