def run(
        self,
        inputScore,
        allowableChords=None,
        closedPosition=False,
        forbiddenChords=None,
        maximumNumberOfChords=3,
    ):
        from music21.stream import timespans
        if 'Score' not in inputScore.classes:
            raise ChordReducerException("Must be called on a stream.Score")

        tree = timespans.streamToTimespanTree(inputScore,
                                              flatten=True,
                                              classList=(note.Note,
                                                         chord.Chord))

        if allowableChords is not None:
            assert all(isinstance(x, chord.Chord) for x in allowableChords)
            intervalClassSets = []
            for x in allowableChords:
                intervalClassSet = self._getIntervalClassSet(x.pitches)
                intervalClassSets.append(intervalClassSet)
            allowableChords = frozenset(intervalClassSets)

        if forbiddenChords is not None:
            assert all(isinstance(x, chord.Chord) for x in forbiddenChords)
            intervalClassSets = []
            for x in allowableChords:
                intervalClassSet = self._getIntervalClassSet(x.pitches)
                intervalClassSets.append(intervalClassSet)
            forbiddenChords = frozenset(intervalClassSets)

        self.removeZeroDurationTimespans(tree)
        self.splitByBass(tree)
        self.removeVerticalDissonances(
            tree=tree,
            allowableChords=allowableChords,
            forbiddenChords=forbiddenChords,
        )

        partwiseTrees = tree.toPartwiseTimespanTrees()

        self.fillBassGaps(tree, partwiseTrees)

        self.removeShortTimespans(tree, partwiseTrees, duration=0.5)
        self.fillBassGaps(tree, partwiseTrees)
        self.fillMeasureGaps(tree, partwiseTrees)

        self.removeShortTimespans(tree, partwiseTrees, duration=1.0)
        self.fillBassGaps(tree, partwiseTrees)
        self.fillMeasureGaps(tree, partwiseTrees)

        reduction = stream.Score()
        #partwiseReduction = tree.toPartwiseScore()
        #for part in partwiseReduction:
        #    reduction.append(part)
        chordifiedReduction = timespans.timespansToChordifiedStream(
            tree,
            templateStream=inputScore,
        )
        chordifiedPart = stream.Part()
        for measure in chordifiedReduction:
            reducedMeasure = self.reduceMeasureToNChords(
                measure,
                maximumNumberOfChords=maximumNumberOfChords,
                weightAlgorithm=self.qlbsmpConsonance,
                trimBelow=0.25,
            )
            chordifiedPart.append(reducedMeasure)
        reduction.append(chordifiedPart)

        if closedPosition:
            for x in reduction.flat.getElementsByClass('Chord'):
                x.closedPosition(forceOctave=4, inPlace=True)

        return reduction
Exemple #2
0
    def run(
        self,
        inputScore,
        allowableChords=None,
        closedPosition=False,
        forbiddenChords=None,
        maximumNumberOfChords=3,
        ):
        from music21.stream import timespans
        if 'Score' not in inputScore.classes:
            raise ChordReducerException("Must be called on a stream.Score")

        tree = timespans.streamToTimespanTree(inputScore, flatten=True, classList=(note.Note, chord.Chord))

        if allowableChords is not None:
            assert all(isinstance(x, chord.Chord) for x in allowableChords)
            intervalClassSets = []
            for x in allowableChords:
                intervalClassSet = self._getIntervalClassSet(x.pitches)
                intervalClassSets.append(intervalClassSet)
            allowableChords = frozenset(intervalClassSets)

        if forbiddenChords is not None:
            assert all(isinstance(x, chord.Chord) for x in forbiddenChords)
            intervalClassSets = []
            for x in allowableChords:
                intervalClassSet = self._getIntervalClassSet(x.pitches)
                intervalClassSets.append(intervalClassSet)
            forbiddenChords = frozenset(intervalClassSets)

        self.removeZeroDurationTimespans(tree)
        self.splitByBass(tree)
        self.removeVerticalDissonances(
            tree=tree,
            allowableChords=allowableChords,
            forbiddenChords=forbiddenChords,
            )

        partwiseTrees = tree.toPartwiseTimespanTrees()

        self.fillBassGaps(tree, partwiseTrees)

        self.removeShortTimespans(tree, partwiseTrees, duration=0.5)
        self.fillBassGaps(tree, partwiseTrees)
        self.fillMeasureGaps(tree, partwiseTrees)

        self.removeShortTimespans(tree, partwiseTrees, duration=1.0)
        self.fillBassGaps(tree, partwiseTrees)
        self.fillMeasureGaps(tree, partwiseTrees)

        reduction = stream.Score()
        #partwiseReduction = tree.toPartwiseScore()
        #for part in partwiseReduction:
        #    reduction.append(part)
        chordifiedReduction = timespans.timespansToChordifiedStream(
            tree,
            templateStream=inputScore,
            )
        chordifiedPart = stream.Part()
        for measure in chordifiedReduction:
            reducedMeasure = self.reduceMeasureToNChords(
                measure,
                maximumNumberOfChords=maximumNumberOfChords,
                weightAlgorithm=self.qlbsmpConsonance,
                trimBelow=0.25,
                )
            chordifiedPart.append(reducedMeasure)
        reduction.append(chordifiedPart)

        if closedPosition:
            for x in reduction.flat.getElementsByClass('Chord'):
                x.closedPosition(forceOctave=4, inPlace=True)

        return reduction