music21.stream.core¶
the Stream Core Mixin handles the core attributes of streams that should be thought of almost as private values and not used except by advanced programmers who need the highest speed in programming.
Nothing here promises to be stable. The music21 team can make any changes here for efficiency reasons while being considered backwards compatible so long as the public methods that call this remain stable.
All attributes here will eventually begin with .core.
StreamCoreMixin¶
-
class
music21.stream.core.
StreamCoreMixin
¶
StreamCoreMixin
read-only properties
-
StreamCoreMixin.
spannerBundle
¶ A low-level object for Spanner management. This is a read-only property.
StreamCoreMixin
methods
-
StreamCoreMixin.
asTimespans
(classList=None, flatten=True)¶ Convert stream to a
TimespanTree
instance, a highly optimized data structure for searching through elements and offsets.TODO: these should not all be PitchedTimespans...
>>> score = tree.makeExampleScore() >>> scoreTree = score.asTimespans() >>> print(scoreTree) <TimespanTree {20} (0.0 to 8.0) <music21.stream.Score exampleScore>> <PitchedTimespan (0.0 to 0.0) <music21.clef.BassClef>> <PitchedTimespan (0.0 to 0.0) <music21.meter.TimeSignature 2/4>> <PitchedTimespan (0.0 to 0.0) <music21.instrument.Instrument PartA: : >> <PitchedTimespan (0.0 to 0.0) <music21.clef.BassClef>> <PitchedTimespan (0.0 to 0.0) <music21.meter.TimeSignature 2/4>> <PitchedTimespan (0.0 to 0.0) <music21.instrument.Instrument PartB: : >> <PitchedTimespan (0.0 to 1.0) <music21.note.Note C>> <PitchedTimespan (0.0 to 2.0) <music21.note.Note C#>> <PitchedTimespan (1.0 to 2.0) <music21.note.Note D>> <PitchedTimespan (2.0 to 3.0) <music21.note.Note E>> <PitchedTimespan (2.0 to 4.0) <music21.note.Note G#>> <PitchedTimespan (3.0 to 4.0) <music21.note.Note F>> <PitchedTimespan (4.0 to 5.0) <music21.note.Note G>> <PitchedTimespan (4.0 to 6.0) <music21.note.Note E#>> <PitchedTimespan (5.0 to 6.0) <music21.note.Note A>> <PitchedTimespan (6.0 to 7.0) <music21.note.Note B>> <PitchedTimespan (6.0 to 8.0) <music21.note.Note D#>> <PitchedTimespan (7.0 to 8.0) <music21.note.Note C>> <PitchedTimespan (8.0 to 8.0) <music21.bar.Barline style=final>> <PitchedTimespan (8.0 to 8.0) <music21.bar.Barline style=final>>
-
StreamCoreMixin.
asTree
(flatten=False, classList=None, useTimespans=False, groupOffsets=False)¶ Returns an elementTree of the score, using exact positioning.
See tree.fromStream.asTree() for more details.
>>> score = tree.makeExampleScore() >>> scoreTree = score.asTree(flatten=True) >>> scoreTree <ElementTree {20} (0.0 <0.-25...> to 8.0) <music21.stream.Score exampleScore>>
-
StreamCoreMixin.
coreGatherMissingSpanners
(recurse=True, requireAllPresent=True, insert=True)¶ find all spanners that are referenced by elements in the (recursed if recurse=True) stream and either inserts them in the Stream (if insert is True) or returns them if insert is False.
If requireAllPresent is True (default) then only those spanners whose complete spanned elements are in the Stream are returned.
Because spanners are stored weakly in .sites this is only guaranteed to find the spanners in cases where the spanner is in another stream that is still active.
Here’s a little helper function since we’ll make the same Stream several times:
>>> def getStream(): ... s = stream.Stream() ... n = note.Note('C') ... m = note.Note('D') ... sl = spanner.Slur(n, m) ... n.bogusAttributeNotWeakref = sl # prevent garbage collecting sl ... s.append([n, m]) ... return s
>>> s = getStream() >>> s.show('text') {0.0} <music21.note.Note C> {1.0} <music21.note.Note D> >>> s.coreGatherMissingSpanners() >>> s.show('text') {0.0} <music21.note.Note C> {0.0} <music21.spanner.Slur <music21.note.Note C><music21.note.Note D>> {1.0} <music21.note.Note D>
Insert is False:
>>> s = getStream() >>> spList = s.coreGatherMissingSpanners(insert=False) >>> spList [<music21.spanner.Slur <music21.note.Note C><music21.note.Note D>>] >>> s.show('text') {0.0} <music21.note.Note C> {1.0} <music21.note.Note D>
Not all elements are present:
>>> s = getStream() >>> s.remove(s[-1]) >>> s.show('text') {0.0} <music21.note.Note C> >>> s.coreGatherMissingSpanners() >>> s.show('text') {0.0} <music21.note.Note C> >>> s.coreGatherMissingSpanners(requireAllPresent=False) >>> s.show('text') {0.0} <music21.note.Note C> {0.0} <music21.spanner.Slur <music21.note.Note C><music21.note.Note D>>
Test recursion:
>>> t = stream.Part() >>> s = getStream() >>> t.insert(0, s) >>> t.coreGatherMissingSpanners(recurse=False) >>> t.show('text') {0.0} <music21.stream.Stream 0x104935b00> {0.0} <music21.note.Note C> {1.0} <music21.note.Note D>
Default: with recursion:
>>> t.coreGatherMissingSpanners() >>> t.show('text') {0.0} <music21.stream.Stream 0x104935b00> {0.0} <music21.note.Note C> {1.0} <music21.note.Note D> {0.0} <music21.spanner.Slur <music21.note.Note C><music21.note.Note D>>
Make sure that spanners already in the stream are not put there twice:
>>> s = getStream() >>> sl = s[0].getSpannerSites()[0] >>> s.insert(0, sl) >>> s.coreGatherMissingSpanners() >>> s.show('text') {0.0} <music21.note.Note C> {0.0} <music21.spanner.Slur <music21.note.Note C><music21.note.Note D>> {1.0} <music21.note.Note D>
And with recursion?
>>> t = stream.Part() >>> s = getStream() >>> sl = s[0].getSpannerSites()[0] >>> s.insert(0, sl) >>> t.insert(0, s) >>> t.coreGatherMissingSpanners() >>> t.show('text') {0.0} <music21.stream.Stream 0x104935b00> {0.0} <music21.note.Note C> {0.0} <music21.spanner.Slur <music21.note.Note C><music21.note.Note D>> {1.0} <music21.note.Note D>
-
StreamCoreMixin.
elementsChanged
(updateIsFlat=True, clearIsSorted=True, memo=None, keepIndex=False)¶ An advanced stream method that is not necessary for most users.
This method is called automatically any time the elements in the Stream are changed. However, it may be called manually in case sites or other advanced features of an element have been modified. It was previously a private method and for most users should still be treated as such.
The various arguments permit optimizing the clearing of cached data in situations when completely dropping all cached data is excessive.
>>> a = stream.Stream() >>> a.isFlat True
Here we manipulate the private ._elements storage (which generally shouldn’t be done) and thus need to call .elementsChanged directly.
>>> a._elements.append(stream.Stream()) >>> a.isFlat # this is wrong. True
>>> a.elementsChanged() >>> a.isFlat False