Пример #1
0
    def recurseGetTreeByClass(inputStream,
                              currentParentage,
                              initialOffset,
                              outputTree=None):
        lastParentage = currentParentage[-1]

        if outputTree is None:
            outputTree = treeClass(source=lastParentage)

        # do this to avoid munging activeSites
        inputStreamElements = inputStream._elements[:] + inputStream._endElements
        parentEndTime = initialOffset + lastParentage.duration.quarterLength

        for element in inputStreamElements:
            flatOffset = common.opFrac(
                lastParentage.elementOffset(element) + initialOffset)

            if element.isStream and flatten is not False:  # True or "semiFlat"
                localParentage = currentParentage + (element, )
                recurseGetTreeByClass(
                    element,  # put the elements into the current tree...
                    currentParentage=localParentage,
                    initialOffset=flatOffset,
                    outputTree=outputTree)
                if flatten != 'semiFlat':
                    continue  # do not insert the stream itself unless we are doing semiflat

            if classList and not element.isClassOrSubclass(classList):
                continue

            endTime = flatOffset + element.duration.quarterLength

            if useTimespans:
                pitchedTimespan = spans.PitchedTimespan(
                    element=element,
                    parentage=tuple(reversed(currentParentage)),
                    parentOffset=initialOffset,
                    parentEndTime=parentEndTime,
                    offset=flatOffset,
                    endTime=endTime)
                outputTree.insert(pitchedTimespan)
            elif groupOffsets is False:
                # for sortTuples
                position = element.sortTuple(lastParentage)
                flatPosition = position.modify(offset=flatOffset)
                outputTree.insert(flatPosition, element)
            else:
                outputTree.insert(flatOffset, element)

        return outputTree
Пример #2
0
def listOfTreesByClass(inputStream,
                       currentParentage=None,
                       initialOffset=0.0,
                       flatten=False,
                       classLists=None,
                       useTimespans=False):
    r'''
    Recurses through `inputStream`, and constructs TimespanTrees for each
    encountered substream and PitchedTimespan 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 = tree.makeExampleScore()
    
    Get everything in the score
    
    >>> treeList = tree.fromStream.listOfTreesByClass(score, useTimespans=True)
    >>> treeList
    [<TimespanTree {2} (-inf to inf) <music21.stream.Score ...>>]    
    >>> tl0 = treeList[0]
    >>> for t in tl0:
    ...     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 TimespanTrees
    
    >>> classLists = ['Note', ('Clef', 'TimeSignature')]
    >>> treeList = tree.fromStream.listOfTreesByClass(score, useTimespans=True,
    ...                                            classLists=classLists, flatten=True)
    >>> treeList
    [<TimespanTree {12} (0.0 to 8.0) <music21.stream.Score ...>>, 
     <TimespanTree {4} (0.0 to 0.0) <music21.stream.Score ...>>]
    '''
    if currentParentage is None:
        currentParentage = (inputStream,)
        ## fix non-tuple classLists -- first call only...
        if classLists:
            for i, cl in enumerate(classLists):
                if not common.isIterable(cl):
                    classLists[i] = (cl,)

            
    lastParentage = currentParentage[-1]
    
    if useTimespans:
        treeClass = timespanTree.TimespanTree
    else:
        treeClass = trees.OffsetTree
    
    if classLists is None or not classLists:
        outputTrees = [treeClass(source=lastParentage)]
        classLists = []
    else:
        outputTrees = [treeClass(source=lastParentage) for _ in classLists]
    # do this to avoid munging activeSites
    inputStreamElements = inputStream._elements[:] + inputStream._endElements
    for element in inputStreamElements:
        offset = lastParentage.elementOffset(element) + initialOffset
        wasStream = False
        
        if element.isStream:
            localParentage = currentParentage + (element,)
            containedTrees = listOfTreesByClass(element,
                                                currentParentage=localParentage,
                                                initialOffset=offset,
                                                flatten=flatten,
                                                classLists=classLists,
                                                useTimespans=useTimespans)
            for outputTree, subTree in zip(outputTrees, containedTrees):
                if flatten is not False: # True or semiFlat
                    outputTree.insert(subTree[:])
                else:
                    outputTree.insert(subTree.lowestPosition(), subTree)
            wasStream = True
            
        if not wasStream or flatten == 'semiFlat':
            parentOffset = initialOffset
            parentEndTime = initialOffset + lastParentage.duration.quarterLength
            endTime = offset + element.duration.quarterLength
            
            for classBasedTree, classList in zip(outputTrees, classLists):
                if classList and not element.isClassOrSubclass(classList):
                    continue
                if useTimespans:
                    pitchedTimespan = spans.PitchedTimespan(element=element,
                                                        parentage=tuple(reversed(currentParentage)),
                                                        parentOffset=parentOffset,
                                                        parentEndTime=parentEndTime,
                                                        offset=offset,
                                                        endTime=endTime)
                    classBasedTree.insert(pitchedTimespan)
                else:
                    classBasedTree.insert(offset, element)

    return outputTrees
Пример #3
0
    def recurseGetTreeByClass(inputStream,
                              currentParentage,
                              initialOffset,
                              outputTree=None):
        lastParentage = currentParentage[-1]

        newOutputTree = False
        if outputTree is None:
            outputTree = treeClass(source=lastParentage)
            newOutputTree = True

        # do this to avoid munging activeSites
        inputStreamElements = inputStream._elements[:] + inputStream._endElements
        parentEndTime = initialOffset + lastParentage.duration.quarterLength

        if (newOutputTree and inputStream.isSorted and usePositions
                and  # currently we can't populate for an OffsetTree
            (inputStream.isFlat or flatten is False)):
            # Can use tree.populateFromSortedList and speed up by an order of magnitude
            if classList is None:
                elementTupleList = [(e.sortTuple(inputStream), e)
                                    for e in inputStreamElements]
            else:
                elementTupleList = [(e.sortTuple(inputStream), e)
                                    for e in inputStreamElements
                                    if e.isClassOrSubclass(classList)]
            outputTree.populateFromSortedList(elementTupleList)
            return outputTree

        for element in inputStreamElements:
            offset = lastParentage.elementOffset(element) + initialOffset

            # for sortTuples
            position = element.sortTuple(lastParentage)
            flatPosition = position.modify(offset=position.offset +
                                           initialOffset)

            wasStream = False

            if element.isStream:
                localParentage = currentParentage + (element, )
                if flatten is not False:  # True or semiFlat
                    recurseGetTreeByClass(
                        element,  # put the elements into the current tree...
                        currentParentage=localParentage,
                        initialOffset=offset,
                        outputTree=outputTree)
                    wasStream = True
                else:
                    pass  # do nothing special for streams if not flattening...

            if not wasStream or flatten == 'semiFlat':
                endTime = offset + element.duration.quarterLength

                if classList and not element.isClassOrSubclass(classList):
                    continue
                if useTimespans:
                    pitchedTimespan = spans.PitchedTimespan(
                        element=element,
                        parentage=tuple(reversed(currentParentage)),
                        parentOffset=initialOffset,
                        parentEndTime=parentEndTime,
                        offset=offset,
                        endTime=endTime)
                    outputTree.insert(pitchedTimespan)
                elif usePositions:
                    outputTree.insert(flatPosition, element)
                else:
                    outputTree.insert(offset, element)

        return outputTree