Previous topic

music21.figuredBass.segment

Next topic

music21.graph

Table Of Contents

Table Of Contents

This Page

music21.freezeThaw

This module contains objects for storing complete Music21Objects, especially Stream and Score objects on disk. Freezing (or “pickling”) refers to writing the object to a file on disk (or to a string). Thawing (or “unpickling”) refers to reading in a string or file and returning a Music21 object.

This module offers alternatives to writing a Score to MusicXML with s.write(‘musicxml’). FreezeThaw has some advantages over using .write(): virtually every aspect of a music21 object is retained when Freezing. So objects like medRen.Ligature, which aren’t supported by most formats, can be stored with FreezeThaw and then read back again. Freezing is also much faster than most conversion methods. But there’s a big downside: only music21 and Python can use the Thaw side to get back Music21Objects (though more information can be brought out of the JSONFreeze format through any .json reader). In fact, there’s not even a guarantee that future versions of music21 will be able to read a frozen version of a Stream. So the advantages and disadvantages of this model definitely need to be kept in mind.

There are two formats that freezeThaw can produce: “Pickle” or JSON (for JavaScript Object Notation – essentially a string representation of the JavaScript equivalent of a Python dictionary).

Pickle is a Python-specific idea for storing objects. The pickle module stores objects as a text file that can’t be easily read by non-Python applications; it also isn’t guaranteed to work across Python versions or even computers. However, it works well, is fast, and is a standard part of python.

JSON was originally created to pass JavaScript objects from a web server to a web browser, but its utility (combining the power of XML with the ease of use of objects) has made it a growing standard for other languages. (see http://docs.python.org/library/json.html). Music21 has two implementations of JSON (confusing, no?) because we weren’t sure and are still not sure which will be best in the long-run: the first approach uses explicit lists of attributes that need to be stored and just saves those. This uses a homemade set of methods that are specifically tailored for music21; but it misses some things that may be important to you. The second approach uses the the freely distributable jsonpickle module found in music21.ext.jsonpickle (See that folder’s “license.txt” for copyright information). This approach probably stores more data than someone not using music21 or python is likely to want, but can be used to get back an entire music21 Stream with no conversion.

Both JSON and Pickle files can be huge, but freezeThaw can compress them with gzip or ZipFile and thus they’re not that large at all.

Streams need to be run through .setupSerializationScaffold and .teardownSerializationScaffold before and after either Pickle or jsonpickle in order to restore all the weakrefs that we use.

The name freezeThaw comes from Perl’s implementation of similar methods – I like the idea of thawing something that’s frozen; “unpickling” just doesn’t seem possible. In any event, I needed a name that wouldn’t already exist in the Python namespace.

JSONFreezeThawBase

class music21.freezeThaw.JSONFreezeThawBase(storedObject=None)

Shared functionality for JSONFreeze and JSONThaw

JSONFreezeThawBase methods

JSONFreezeThawBase.fullyQualifiedClassFromObject(obj)

return a fullyQualified class name from an object.

for Music21Objects you can just do: obj.fullyQualifiedClasses[0], but this works on any object (such as Durations which aren’t Music21Objects)

>>> d = duration.DurationUnit()
>>> jsbase = freezeThaw.JSONFreezeThawBase()
>>> jsbase.fullyQualifiedClassFromObject(d)
'music21.duration.DurationUnit'

Works on class objects as well:

>>> dclass = duration.DurationUnit
>>> jsbase.fullyQualifiedClassFromObject(dclass)
'music21.duration.DurationUnit'
JSONFreezeThawBase.music21ObjectFromString(idStr)

Given a stored string during JSON serialization, return an object. This method effectively converts a string class specification into a vanilla instance ready for specialization via stored data attributes.

A subclass that overrides this method will have access to all modules necessary to create whatever objects necessary.

>>> jss = freezeThaw.JSONFreezer()
>>> n = jss.music21ObjectFromString('note.Note')
>>> n
<music21.note.Note C>

One can begin with “music21.” if you’d like:

>>> d = jss.music21ObjectFromString('music21.duration.Duration')
>>> d
<music21.duration.Duration 0.0>

Undefined classes give a JSONFreezerException

>>> jss.music21ObjectFromString('blah.NotAClass')
Traceback (most recent call last):
JSONFreezerException: Cannot generate a new object from blah.NotAClass

JSONFreezer

class music21.freezeThaw.JSONFreezer(storedObject=None)

Class that provides JSON output from an object (whether Music21Object or other).

>>> n = note.Note("C#4")
>>> jsonF = freezeThaw.JSONFreezer(n)
>>> jsonF.storedObject
<music21.note.Note C#>
>>> jsonF.className
'music21.note.Note'

JSONFreezer bases

JSONFreezer read-only properties

JSONFreezer.json

Get string JSON data for this object.

This method is only available if a JSONFreezer subclass object has been customized and configured by overriding the following methods: jsonAttributes(), music21ObjectFromString().

Return the dictionary returned by self.getJSONDict() as a JSON string.

JSONFreezer.prettyJson

JSONFreezer methods

JSONFreezer.autoGatherAttributes()

Gather just the instance data members that are proceeded by an underscore.

Returns a list of those data members

>>> n = note.Note()
>>> jss = freezeThaw.JSONFreezer(n)
>>> for attr in jss.autoGatherAttributes():
...     attr
...
'_activeSite'
'_activeSiteId'
'_duration'
'_editorial'
'_idLastDeepCopyOf'
'_notehead'
'_noteheadFill'
'_noteheadParenthesis'
'_priority'
'_stemDirection'
'_volume'
JSONFreezer.canBeFrozen(possiblyFreezeable)

Returns True or False if this attribute can be frozen in a way that is stronger than just storing the repr of it.

>>> jsf = freezeThaw.JSONFreezer()
>>> jsf.canBeFrozen(note.Note())
True
>>> jsf.canBeFrozen(345)
False
>>> jsf.canBeFrozen(None)
False

Lists and Tuples and Dicts return False, but they are not just stored as __repr__, don’t worry...

>>> jsf.canBeFrozen([7,8])
False
JSONFreezer.getJSONDict(includeVersion=False)

Return a dictionary representation for JSON processing. All component objects are similarly encoded as dictionaries. This method is recursively called as needed to store dictionaries of component objects that are JSONFreezer subclasses.

>>> t = metadata.Text('my text')
>>> t.language = 'en'
>>> jsf = freezeThaw.JSONFreezer(t)
>>> jsdict = jsf.getJSONDict()
>>> jsdict['__class__']
'music21.metadata.primitives.Text'
>>> jsdict['__attr__']['_language']
'en'
JSONFreezer.jsonAttributes(autoGather=True)

Define all attributes of this object that should be JSON serialized for storage and re-instantiation. Attributes that name basic Python objects or JSONFreezer subclasses, or dictionaries or lists that contain Python objects or JSONFreezer subclasses, can be provided.

Should be overridden in subclasses.

For an object which does not define this, just returns all the _underscore attributes:

>>> ed = editorial.NoteEditorial()
>>> jsf = freezeThaw.JSONFreezer(ed)
>>> jsf.jsonAttributes()
['color', 'misc', 'comment']
>>> l = note.Lyric()
>>> jsf = freezeThaw.JSONFreezer(l)
>>> jsf.jsonAttributes()
['text', 'syllabic', 'number', 'identifier']

Has autoGatherAttributes and others:

>>> gn = note.GeneralNote()
>>> jsf = freezeThaw.JSONFreezer(gn)
>>> jsf.jsonAttributes()
['_duration', '_priority', 'offset', '_editorial', 'lyrics', 'expressions', 'articulations', 'tie']
JSONFreezer.jsonPrint()

Prints out the json output for a given object:

>>> n = note.Note('D#5')
>>> jsf = freezeThaw.JSONFreezer(n)
>>> jsf.jsonPrint()
{
  "__attr__": {
    "_duration": {
      "__attr__": {
        "_cachedIsLinked": true, 
        "_components": [
          {
            "__attr__": {
              "_componentsNeedUpdating": false, 
              "_dots": [
                0
              ], 
              "_link": true, 
              "_qtrLength": 1.0, 
              "_quarterLengthNeedsUpdating": false, 
              "_tuplets": [], 
              "_type": "quarter", 
              "_typeNeedsUpdating": false
            }, 
            "__class__": "music21.duration.DurationUnit"
          }
        ], 
        "_componentsNeedUpdating": false, 
        "_qtrLength": 1.0, 
        "_quarterLengthNeedsUpdating": false, 
        "_typeNeedsUpdating": false
      }, 
      "__class__": "music21.duration.Duration"
    }, 
    "_notehead": "normal", 
    "_noteheadFill": "default", 
    "_noteheadParenthesis": false, 
    "_priority": 0, 
    "_stemDirection": "unspecified", 
    "articulations": [], 
    "beams": {
      "__attr__": {
        "beamsList": [], 
        "feathered": false
      }, 
      "__class__": "music21.beam.Beams"
    }, 
    "expressions": [], 
    "lyrics": [], 
    "offset": 0.0, 
    "pitch": {
      "__attr__": {
        "_accidental": {
          "__attr__": {
            "_alter": 1.0, 
            "_displayType": "normal", 
            "_modifier": "#", 
            "_name": "sharp" 
          }, 
          "__class__": "music21.pitch.Accidental"
        }, 
        "_microtone": {
          "__attr__": {
            "_centShift": 0, 
            "_harmonicShift": 1
          }, 
          "__class__": "music21.pitch.Microtone"
        }, 
        "_octave": 5, 
        "_step": "D"
      }, 
      "__class__": "music21.pitch.Pitch"
    }
  }, 
  "__class__": "music21.note.Note", 
  "__version__": [
    2, 
    0, 
    0
  ]
}
JSONFreezer.jsonWrite(fp, formatOutput=True)

Given a file path, write JSON to a file for this object.

File extension should be .json. File is opened and closed within this method call.

Methods inherited from JSONFreezeThawBase:

JSONThawer

class music21.freezeThaw.JSONThawer(storedObject=None)

Class that takes JSON input and makes a Music21Object.

JSONThawer bases

JSONThawer read/write properties

JSONThawer.json

Take string JSON data from json() and produce an object and store it in self.storedObject.`.

JSONThawer methods

JSONThawer.jsonRead(fp)

Given a file path, read JSON from a file to this object. Default file extension should be .json. File is opened and closed within this method call.

returns the stored object

Methods inherited from JSONFreezeThawBase:

StreamFreezeThawBase

class music21.freezeThaw.StreamFreezeThawBase

Contains a few methods that are used for both StreamFreezer and StreamThawer

StreamFreezeThawBase methods

StreamFreezeThawBase.findAllM21Objects(streamObj)

find all M21 Objects in _elements and _endElements and in nested streams.

StreamFreezeThawBase.getJsonFp(directory)
StreamFreezeThawBase.getPickleFp(directory)

StreamFreezer

class music21.freezeThaw.StreamFreezer(streamObj=None, fastButUnsafe=False, topLevel=True, streamIds=None)

This class is used to freeze a Stream, preparing it for serialization and providing conversion routines.

In general, use freeze() for serializing to a file.

Use the unfreeze() to read from a serialized file

>>> from music21 import freezeThaw
>>> s = stream.Stream()
>>> s.repeatAppend(note.Note('C4'), 8)
>>> temp = [s[n].transpose(n, inPlace=True) for n in range(len(s))]
>>> sf = freezeThaw.StreamFreezer(s) # provide a Stream at init
>>> data = sf.writeStr(fmt='pickle') # pickle is default format
>>> st = freezeThaw.StreamThawer()
>>> st.openStr(data)
>>> s = st.stream
>>> s.show('t')
{0.0} <music21.note.Note C>
{1.0} <music21.note.Note D->
{2.0} <music21.note.Note D>
{3.0} <music21.note.Note E->
{4.0} <music21.note.Note E>
{5.0} <music21.note.Note F>
{6.0} <music21.note.Note G->
{7.0} <music21.note.Note G>
>>> sf2 = freezeThaw.StreamFreezer(s) # do not reuse StreamFreezers
>>> data2 = sf2.writeStr(fmt='jsonpickle')
>>> st2 = freezeThaw.StreamThawer()
>>> st2.openStr(data2)
>>> s2 = st2.stream
>>> s2.show('t')
{0.0} <music21.note.Note C>
{1.0} <music21.note.Note D->
{2.0} <music21.note.Note D>
{3.0} <music21.note.Note E->
{4.0} <music21.note.Note E>
{5.0} <music21.note.Note F>
{6.0} <music21.note.Note G->
{7.0} <music21.note.Note G>
>>> c = corpus.parse('luca/gloria')
>>> sf = freezeThaw.StreamFreezer(c)
>>> data = sf.writeStr(fmt='pickle')
>>> st = freezeThaw.StreamThawer()
>>> st.openStr(data)
>>> s2 = st.stream
>>> len(s2.parts[0].measure(7).notes) == 6
True
>>> sf2 = freezeThaw.StreamFreezer(c) # do not reuse StreamFreezers
>>> data2 = sf2.writeStr(fmt='jsonpickle')
>>> st2 = freezeThaw.StreamThawer()
>>> st2.openStr(data2)
>>> s3 = st.stream
>>> len(s3.parts[0].measure(7).notes) == 6
True

StreamFreezer bases

StreamFreezer methods

StreamFreezer.findActiveStreamIdsInHierarchy(hierarchyObject=None, getSpanners=True, getVariants=True)

Return a list of all Stream ids anywhere in the hierarchy.

Stores them in .streamIds.

if hierarchyObject is None, uses self.stream.

>>> sc = stream.Score()
>>> p1 = stream.Part()
>>> p2 = stream.Part()
>>> m1 = stream.Measure()
>>> v1 = stream.Voice()
>>> m1.insert(0, v1)
>>> p2.insert(0, m1)
>>> sc.insert(0, p1)
>>> sc.insert(0, p2)
>>> shouldFindIds = [id(sc), id(p1), id(p2), id(m1), id(v1)]

fastButUnsafe is needed because it does not make a deepcopy and thus lets you compare ids before and after.

>>> sf = freezeThaw.StreamFreezer(sc, fastButUnsafe=True)
>>> foundIds = sf.findActiveStreamIdsInHierarchy()
>>> for thisId in shouldFindIds:
...     if thisId not in foundIds:
...         raise Exception("Missing Id")
>>> for thisId in foundIds:
...     if thisId not in shouldFindIds:
...         raise Exception("Additional Id Found")

Spanners are included unless getSpanners is False

>>> staffGroup = layout.StaffGroup([p1, p2])
>>> sc.insert(0, staffGroup)

StaffGroup is a spanner, so it should be found

>>> sf2 = freezeThaw.StreamFreezer(sc, fastButUnsafe=True)
>>> foundIds = sf2.findActiveStreamIdsInHierarchy()

But you won’t find the id of the spanner itself in the foundIds:

>>> id(staffGroup) in foundIds
False

instead it’s the id of the storage object:

>>> staffGroup.getSpannerStorageId() in foundIds
True

Variants are treated similarly:

>>> s = stream.Stream()
>>> m = stream.Measure()
>>> m.append(note.Note(type="whole"))
>>> s.append(m)
>>> s2 = stream.Stream()
>>> m2 = stream.Measure()
>>> n2 = note.Note("D#4")
>>> n2.duration.type = "whole"
>>> m2.append(n2)
>>> s2.append(m2)
>>> v = variant.Variant(s2)
>>> s.insert(0, v)
>>> sf = freezeThaw.StreamFreezer(s, fastButUnsafe=True)
>>> allIds = sf.findActiveStreamIdsInHierarchy()
>>> len(allIds)
4
>>> for streamElement in [s, m, m2, v._stream]:
...    if id(streamElement) not in allIds:
...        print("this should not happen...", allIds, id(streamElement))

N.B. with variants:

>>> id(s2) == id(v._stream)
False

The method also sets self.streamIds to the returned list:

>>> sf.streamIds is allIds
True
StreamFreezer.packStream(streamObj=None)

Prepare the passed in Stream in place, return storage dictionary format.

>>> s = stream.Stream()
>>> n = note.Note('D#4')
>>> s.append(n)
>>> sf = freezeThaw.StreamFreezer(s)
>>> sf.packStream()
{'m21Version': (1, 9, 3), 'stream': <music21.stream.Stream 4391393680>}
StreamFreezer.parseWriteFmt(fmt)

Parse a passed-in write format

>>> from music21 import freezeThaw
>>> sf = freezeThaw.StreamFreezer()
>>> sf.parseWriteFmt(None)
'pickle'
>>> sf.parseWriteFmt('JSON')
'jsonpickle'
StreamFreezer.recursiveClearSites(startObj)

recursively clear all sites, including activeSites, taking into account that spanners and variants behave differently.

Called by setupSerializationScaffold.

To be run after setupStoredElementOffsetTuples() has been run

>>> n = note.Note('D#4')
>>> len(n.sites)
1
>>> s = stream.Stream()
>>> s.id = 'stream s'
>>> s.insert(10, n)
>>> len(n.sites)
2
>>> t = stream.Stream()
>>> t.insert(20, n)
>>> t.id = 'stream t'
>>> len(n.sites)
3
>>> n.getOffsetBySite(s)
10.0
>>> n.getOffsetBySite(t)
20.0
>>> sf = freezeThaw.StreamFreezer()

This will remove n from s but leave the rest of the sites intact...

>>> sf.setupStoredElementOffsetTuples(s)
>>> len(n.sites)
2
>>> n.getOffsetBySite(s)
Traceback (most recent call last):
SitesException: The object <music21.note.Note D#> is not in site <music21.stream.Stream stream s>.
>>> n.getOffsetBySite(t)
20.0

After recursiveClearSites n will be not know its location anywhere...

>>> sf.recursiveClearSites(s)
>>> len(n.sites)
0
>>> n.getOffsetBySite(t)
Traceback (most recent call last):
SitesException: The object <music21.note.Note D#> is not in site <music21.stream.Stream stream t>.

This leaves n and t in strange positions, because n is in t.elements still....

>>> n in t.elements
True

This predicament is why when the standard freezeThaw call is made, what is frozen is a deepcopy of the Stream so that nothing is left in an unusable position

StreamFreezer.removeStreamStatusClient(streamObj)

if s is a stream then

s.streamStatus._client is s

this can be hard to pickle, so this method removes the streamStatus._client from the streamObj (not recursive). Called by setupSerializationScaffold.

StreamFreezer.setupSerializationScaffold(streamObj=None)

Prepare this stream and all of its contents for pickle/pickling, that is, serializing and storing an object representation on file or as a string.

The topLevel and streamIdsFound arguments are used to keep track of recursive calls.

Note that this is a destructive process: elements contained within this Stream will have their sites cleared of all contents not in the hierarchy of the Streams. Thus, when doing a normal .write(‘pickle’) the Stream is deepcopied before this method is called. The attribute fastButUnsafe = True setting of StreamFreezer ignores the destructive effects of these processes and skips the deepcopy.

>>> from music21 import freezeThaw
>>> a = stream.Stream()
>>> n = note.Note()
>>> n.duration.type = "whole"
>>> a.repeatAppend(n, 10)
>>> sf = freezeThaw.StreamFreezer(a)
>>> sf.setupSerializationScaffold()
StreamFreezer.setupStoredElementOffsetTuples(streamObj)

move all elements from ._elements and ._endElements to a new attribute ._storedElementOffsetTuples which contains a list of tuples of the form (el, offset or ‘end’).

Called by setupSerializationScaffold.

>>> s = stream.Measure()
>>> n1 = note.Note("C#")
>>> n2 = note.Note("E-")
>>> bl1 = bar.Barline()
>>> s.insert(0.0, n1)
>>> s.insert(1.0, n2)
>>> s.storeAtEnd(bl1)
>>> sfreeze = freezeThaw.StreamFreezer()
>>> sfreeze.setupStoredElementOffsetTuples(s)
>>> s._elements, s._endElements
([], [])
>>> s._storedElementOffsetTuples
[(<music21.note.Note C#>, 0.0), (<music21.note.Note E->, 1.0), (<music21.bar.Barline style=regular>, 'end')]
>>> n1.getOffsetBySite(s)
Traceback (most recent call last):
SitesException: The object <music21.note.Note C#> is not in site <music21.stream.Measure 0 offset=0.0>.

Trying it again, but now with substreams:

>>> s2 = stream.Measure()
>>> n1 = note.Note("C#")
>>> n2 = note.Note("E-")
>>> bl1 = bar.Barline()
>>> v1 = stream.Voice()
>>> n3 = note.Note("F#")
>>> v1.insert(2.0, n3)
>>> s2.insert(0.0, n1)
>>> s2.insert(1.0, n2)
>>> s2.storeAtEnd(bl1)
>>> s2.insert(2.0, v1)
>>> sfreeze.setupStoredElementOffsetTuples(s2)
>>> v1._storedElementOffsetTuples
[(<music21.note.Note F#>, 2.0)]
>>> s2._storedElementOffsetTuples
[(<music21.note.Note C#>, 0.0), (<music21.note.Note E->, 1.0), (<music21.stream.Voice ...>, 2.0), (<music21.bar.Barline style=regular>, 'end')]
>>> s2._storedElementOffsetTuples[2][0] is v1
True
StreamFreezer.write(fmt='pickle', fp=None, zipType=None, **keywords)

For a supplied Stream, write a serialized version to disk in either ‘pickle’ or ‘jsonpickle’ format and return the filepath to the file.

jsonpickle is the better format for transporting from one computer to another, but slower and may have some bugs.

If zipType == ‘zlib’ then zlib compression is done after serializing. No other compression types are currently supported.

StreamFreezer.writeStr(fmt=None, **keywords)

Convert the object to a pickled/jsonpickled string and return the string

Methods inherited from StreamFreezeThawBase:

StreamThawer

class music21.freezeThaw.StreamThawer

This class is used to thaw a data string into a Stream

In general user parse() to read from a serialized file.

>>> from music21 import freezeThaw
>>> s = stream.Stream()
>>> s.repeatAppend(note.Note('C4'), 8)
>>> temp = [s[n].transpose(n, inPlace=True) for n in range(len(s))]
>>> sf = freezeThaw.StreamFreezer(s) # provide a Stream at init
>>> data = sf.writeStr(fmt='pickle') # pickle is default format
>>> sfOut = freezeThaw.StreamThawer()
>>> sfOut.openStr(data)
>>> s = sfOut.stream
>>> s.show('t')
{0.0} <music21.note.Note C>
{1.0} <music21.note.Note D->
{2.0} <music21.note.Note D>
{3.0} <music21.note.Note E->
{4.0} <music21.note.Note E>
{5.0} <music21.note.Note F>
{6.0} <music21.note.Note G->
{7.0} <music21.note.Note G>

# >>> c = corpus.parse(‘luca/gloria’) # >>> sf = freezeThaw.StreamFreezer(c) # >>> data = sf.writeStr(fmt=’jsonpickle’) # # >>> sfOut = freezeThaw.StreamThawer() # >>> sfOut.openStr(data) # >>> s = sfOut.stream # >>> #s.show(‘t’)

StreamThawer bases

StreamThawer methods

StreamThawer.open(fp, zipType=None)

For a supplied file path to a pickled stream, unpickle

StreamThawer.openStr(fileData, pickleFormat=None)

Take a string representing a Frozen(pickled/jsonpickled) Stream and convert it to a normal Stream.

if format is None then the format is automatically determined from the string contents.

StreamThawer.parseOpenFmt(storage)

Look at the file and determine the format

StreamThawer.restoreElementsFromTuples(streamObj)

Take a Stream with elements and offsets stored in a list of tuples (element, offset or ‘end’) at _storedElementOffsetTuples and restore it to the ._elements and ._endElements lists in the proper locations:

>>> s = stream.Measure()
>>> s._elements, s._endElements
([], [])
>>> n1 = note.Note("C#")
>>> n2 = note.Note("E-")
>>> bl1 = bar.Barline()
>>> tupleList = [(n1, 0.0), (n2, 1.0), (bl1, 'end')]
>>> s._storedElementOffsetTuples = tupleList
>>> sthaw = freezeThaw.StreamThawer()
>>> sthaw.restoreElementsFromTuples(s)
>>> s.show('text')
{0.0} <music21.note.Note C#>
{1.0} <music21.note.Note E->
{2.0} <music21.bar.Barline style=regular>
>>> s._endElements
[<music21.bar.Barline style=regular>]
>>> s[1].getOffsetBySite(s)
1.0

Trying it again, but now with substreams:

>>> s2 = stream.Measure()
>>> v1 = stream.Voice()
>>> n3 = note.Note("F#")
>>> v1._storedElementOffsetTuples = [(n3, 2.0)]
>>> tupleList = [(n1, 0.0), (n2, 1.0), (bl1, 'end'), (v1, 2.0)]
>>> s2._storedElementOffsetTuples = tupleList
>>> sthaw.restoreElementsFromTuples(s2)
>>> s2.show('text')
{0.0} <music21.note.Note C#>
{1.0} <music21.note.Note E->
{2.0} <music21.stream.Voice ...>
    {2.0} <music21.note.Note F#>
{5.0} <music21.bar.Barline style=regular>
StreamThawer.restoreStreamStatusClient(streamObj)
StreamThawer.teardownSerializationScaffold(streamObj=None)

After rebuilding this Stream from pickled storage, prepare this as a normal Stream.

If streamObj is None, runs it on the embedded stream

>>> from music21 import freezeThaw
>>> a = stream.Stream()
>>> n = note.Note()
>>> n.duration.type = "whole"
>>> a.repeatAppend(n, 10)
>>> sf = freezeThaw.StreamFreezer(a)
>>> sf.setupSerializationScaffold()
>>> st = freezeThaw.StreamThawer()
>>> st.teardownSerializationScaffold(a)
StreamThawer.unpackStream(storage)

Convert from storage dictionary to Stream.

Methods inherited from StreamFreezeThawBase: