def multiPartReduction(self,
                           inStream,
                           maxChords=2,
                           closedPosition=False,
                           forceOctave=False):
        '''
        Return a multipart reduction of a stream.
        '''
        i = 0
        p = stream.Part()
        self._lastPitchedObject = None
        lenMeasures = len(inStream.parts[0].getElementsByClass('Measure'))
        self._lastTs = None
        for i in range(lenMeasures):
            mI = inStream.measure(i, indicesNotNumbers=True)
            if not mI.recurse().notesAndRests:
                if i == 0:
                    pass
                else:
                    break
            else:
                m = self.reduceThisMeasure(mI, i, maxChords, closedPosition,
                                           forceOctave)
                p.coreAppend(m)

            if self.printDebug:
                print(i, " ", end="")
                if i % 20 == 0 and i != 0:
                    print("")
        p.coreElementsChanged()
        p.getElementsByClass('Measure')[0].insert(
            0, clef.bestClef(p, allowTreble8vb=True))
        p.makeNotation(inPlace=True)
        return p
예제 #2
0
    def multiPartReduction(self, inStream, maxChords=2, closedPosition=False, forceOctave=False):
        '''
        Return a multipart reduction of a stream.
        '''
        i = 0
        p = stream.Part()
        self._lastPitchedObject = None
        lenMeasures = len(inStream.parts[0].getElementsByClass('Measure'))
        self._lastTs = None
        for i in range(lenMeasures):
            mI = inStream.measure(i, indicesNotNumbers=True)
            if not mI.recurse().notesAndRests:
                if i == 0:
                    pass
                else:
                    break
            else:
                m = self.reduceThisMeasure(mI, i, maxChords, closedPosition, forceOctave)
                p.coreAppend(m)

            if self.printDebug:
                print(i, " ", end="")
                if i % 20 == 0 and i != 0:
                    print("")
        p.coreElementsChanged()
        p.getElementsByClass('Measure')[0].insert(0, clef.bestClef(p, allowTreble8vb=True))
        p.makeNotation(inPlace=True)
        return p
예제 #3
0
def januaryThankYou():
    names = ['opus132', 'opus133', 'opus18no3', 'opus18no4', 'opus18no5', 'opus74']
    names += ['opus59no1', 'opus59no2', 'opus59no3']

    for workName in names:
        beethovenScore = corpus.parse('beethoven/' + workName, 1)
        for partNum in range(4):
            print(workName, str(partNum))
            thisPart = beethovenScore[partNum]
            display = stream.Stream()
            notes = thisPart.flat.findConsecutiveNotes(skipUnisons=True, skipChords=True,
                       skipOctaves=True, skipRests=True, noNone=True )
            for i in range(len(notes) - 4):
                if notes[i].name == 'E-' and notes[i + 1].name == 'E' and notes[i + 2].name == 'A':
                    measureNumber = 0
                    for site in notes[i].sites.get():
                        if isinstance(site, stream.Measure):
                            measureNumber = site.number
                            display.append(site)
                    notes[i].lyric = workName + " " + str(thisPart.id) + " " + str(measureNumber)
                    m = stream.Measure()
                    m.append(notes[i])
                    m.append(notes[i + 1])
                    m.append(notes[i + 2])
                    m.append(notes[i + 3])
                    m.insert(0, clef.bestClef(m))
                    display.append(m)


            display.show()
예제 #4
0
def januaryThankYou():
    names = ['opus132', 'opus133', 'opus18no3', 'opus18no4', 'opus18no5', 'opus74']
    names += ['opus59no1', 'opus59no2', 'opus59no3']

    for workName in names:
        beethovenScore = corpus.parse('beethoven/' + workName, 1)
        for partNum in range(4):
            print(workName, str(partNum))
            thisPart = beethovenScore[partNum]
            display = stream.Stream()
            notes = thisPart.flat.findConsecutiveNotes(skipUnisons=True, skipChords=True,
                       skipOctaves=True, skipRests=True, noNone=True )
            for i in range(len(notes) - 4):
                if notes[i].name == 'E-' and notes[i + 1].name == 'E' and notes[i + 2].name == 'A':
                    measureNumber = 0
                    for site in notes[i].sites.get():
                        if isinstance(site, stream.Measure):
                            measureNumber = site.number
                            display.append(site)
                    notes[i].lyric = workName + " " + str(thisPart.id) + " " + str(measureNumber)
                    m = stream.Measure()
                    m.append(notes[i])
                    m.append(notes[i + 1])
                    m.append(notes[i + 2])
                    m.append(notes[i + 3])
                    m.insert(0, clef.bestClef(m))
                    display.append(m)


            display.show()
예제 #5
0
def simple3():
    '''
    reduce all measures of Chopin mazurkas to their rhythmic components and give the
    measure numbers (harder: render in notation) of all measures sorted by pattern.
    '''
    def lsort(keyname):
        return len(rhythmicHash[keyname])

    defaultPitch = music21.pitch.Pitch("C3")

    #  semiFlat lets me get all Measures no matter where they reside in the tree structure
    measureStream = converter.parse(
        humdrum.testFiles.mazurka6).semiFlat.getElementsByClass('Measure')
    rhythmicHash = defaultdict(list)

    for thisMeasure in measureStream:
        if thisMeasure.duration.quarterLength != 3.0:
            continue
        notes = thisMeasure.flat.notesAndRests  # n.b. won't work any more because of voices...
        if len(notes) == 0:
            continue
        rhythmicStream = stream.Measure()

        offsetString = ""  ## comma separated string of offsets
        for thisNote in notes:
            rhythmNote = copy.deepcopy(thisNote)
            if rhythmNote.isNote:
                rhythmNote.pitch = copy.deepcopy(defaultPitch)
            elif rhythmNote.isChord:
                rhythmNote = note.Note()
                rhythmNote.pitch = copy.deepcopy(defaultPitch)
                rhythmNote.duration = copy.deepcopy(thisNote.duration)

            if not rhythmNote.isRest:
                offsetString += str(rhythmNote.offset) + ", "

            rhythmicStream.append(rhythmNote)

        #notes[0].lyric = str(thisMeasure.number)
        if len(rhythmicHash[offsetString]) == 0:
            # if it is our first encounter with the rhythm, add the rhythm alone in blue
            for thisNote in rhythmicStream:
                thisNote.style.color = "blue"
            rhythmicHash[offsetString].append(rhythmicStream)
        # thisMeasure.flat.notesAndRests[0].editorial.measureNumber = str(thisMeasure.number)
        rhythmicHash[offsetString].append(thisMeasure)

    s = stream.Part()
    s.insert(0, meter.TimeSignature('3/4'))

    for thisRhythmProfile in sorted(rhythmicHash, key=lsort, reverse=True):
        for thisMeasure in rhythmicHash[thisRhythmProfile]:
            thisMeasure.insert(0, clef.bestClef(thisMeasure))
            s.append(thisMeasure)
    s.show('lily.png')
예제 #6
0
def simple3():
    '''
    reduce all measures of Chopin mazurkas to their rhythmic components and give the
    measure numbers (harder: render in notation) of all measures sorted by pattern.
    '''
    def lsort(keyname):
        return len(rhythmicHash[keyname])

    defaultPitch = music21.pitch.Pitch("C3")

    #  semiFlat lets me get all Measures no matter where they reside in the tree structure
    measureStream = converter.parse(humdrum.testFiles.mazurka6
                                    ).semiFlat.getElementsByClass('Measure')
    rhythmicHash = defaultdict(list)

    for thisMeasure in measureStream:
        if thisMeasure.duration.quarterLength != 3.0:
            continue
        notes = thisMeasure.flat.notesAndRests  # n.b. won't work any more because of voices...
        if len(notes) == 0:
            continue
        rhythmicStream = stream.Measure()

        offsetString = "" ## comma separated string of offsets
        for thisNote in notes:
            rhythmNote = copy.deepcopy(thisNote)
            if rhythmNote.isNote:
                rhythmNote.pitch = copy.deepcopy(defaultPitch)
            elif rhythmNote.isChord:
                rhythmNote          = note.Note()
                rhythmNote.pitch    = copy.deepcopy(defaultPitch)
                rhythmNote.duration = copy.deepcopy(thisNote.duration)

            if not rhythmNote.isRest:
                offsetString += str(rhythmNote.offset) + ", "

            rhythmicStream.append(rhythmNote)

        #notes[0].lyric = str(thisMeasure.number)
        if len(rhythmicHash[offsetString]) == 0:
            # if it is our first encounter with the rhythm, add the rhythm alone in blue
            for thisNote in rhythmicStream:
                thisNote.style.color = "blue"
            rhythmicHash[offsetString].append(rhythmicStream)
        # thisMeasure.flat.notesAndRests[0].editorial.measureNumber = str(thisMeasure.number)
        rhythmicHash[offsetString].append(thisMeasure)

    s = stream.Part()
    s.insert(0, meter.TimeSignature('3/4'))

    for thisRhythmProfile in sorted(rhythmicHash, key=lsort, reverse=True):
        for thisMeasure in rhythmicHash[thisRhythmProfile]:
            thisMeasure.insert(0, clef.bestClef(thisMeasure))
            s.append(thisMeasure)
    s.show('lily.png')
예제 #7
0
    def testStreams01(self):
        '''
        Basic stream issues
        '''
        #from music21 import note, stream, clef, metadata, spanner

        #==== "fig-df02"
        # Storing, Ordering, and Timing Elements

        n1 = note.Note('g3', type='half')
        n2 = note.Note('d4', type='half')
        cf1 = clef.AltoClef()

        m1 = stream.Measure(number=1)
        m1.append([n1, n2])
        m1.insert(0, cf1)

        # the measure has three elements
        assert len(m1) == 3
        # the offset returned is the most-recently set
        assert n2.offset == 2.0
        # automatic sorting positions Clef first
        assert m1[0] == cf1
        # list-like indices follow sort order
        assert m1.index(n2) == 2
        # can find an element based on a given offset
        assert m1.getElementAtOrBefore(3) == n2

        n3 = note.Note('g#3', quarterLength=0.5)
        n4 = note.Note('d-4', quarterLength=3.5)

        m2 = stream.Measure(number=2)
        m2.append([n3, n4])

        # appended position is after n3
        assert n4.offset == .5
        assert m2.highestOffset == .5
        # can access objects on elements
        assert m2[1].duration.quarterLength == 3.5
        # the Stream duration is the highest offset + duration
        assert m2.duration.quarterLength == 4

        p1 = stream.Part()
        p1.append([m1, m2])

        # the part has 2 components
        assert len(p1) == 2
        # the Stream duration is the highest offset + durations
        assert p1.duration.quarterLength == 8
        # can access Notes from Part using multiple indices
        assert p1[1][0].pitch.nameWithOctave == 'G#3'

        s1 = stream.Score()
        s1.append(p1)
        md1 = metadata.Metadata(title='The music21 Stream')
        s1.insert(0, md1)
        # calling show by default renders musicxml output
        #s1.show()

        #==== "fig-df02" end

        #==== "fig-df03"
        # Positioning the Same Element in Multiple Containers
        # show positioning the same element in multiple containers
        # do not yet use a flat representation
        s2 = stream.Stream()
        s3 = stream.Stream()
        s2.insert(10, n2)
        s3.insert(40, n2)

        # the offset attribute returns the last assigned
        assert n2.offset == 40
        # we can provide a site to finde a location-specific offset
        assert n2.getOffsetBySite(m1) == 2.0
        assert n2.getOffsetBySite(s2) == 10
        # the None site provides a default offset
        assert set(n2.sites.get()) == set([None, m1, s2, s3])
        # the same instance is found in all Streams
        assert m1.hasElement(n2) == True
        assert s2.hasElement(n2) == True
        assert s3.hasElement(n2) == True

        # only offset is independent to each location
        n2.pitch.transpose('-M2', inPlace=True)
        assert s2[s2.index(n2)].nameWithOctave == 'C4'
        assert s3[s3.index(n2)].nameWithOctave == 'C4'
        assert m1[m1.index(n2)].nameWithOctave == 'C4'

        # the transposition is maintained in the original context
        #s1.show()

        #==== "fig-df03" end

        #==== "fig-df04"
        # Simultaneous Access to Hierarchical and Flat Representations
        #s1.flat.show('t')

        # lengths show the number of elements; indices are sequential
        s1Flat = s1.flat
        assert len(s1) == 2
        assert len(s1Flat) == 6
        assert s1Flat[4] == n3
        assert s1Flat[5] == n4

        # adding another Part to the Score results in a different flat representation
        n5 = note.Note('a#1', quarterLength=2.5)
        n6 = note.Note('b2', quarterLength=1.5)
        m4 = stream.Measure(number=2)
        m4.append([n5, n6])

        r1 = note.Rest(type='whole')
        cf2 = clef.bestClef(m4)  # = BassClef
        m3 = stream.Measure(number=1)
        m3.append([cf2, r1])

        p2 = stream.Part()
        p2.append([m3, m4])
        s1.insert(0, p2)

        assert 'BassClef' in cf2.classes

        # objects are sorted by offset
        s1Flat = s1.flat
        assert len(s1) == 3
        assert len(s1.flat) == 10
        assert s1Flat[6] == n3
        assert s1Flat[7] == n5
        assert s1Flat[8] == n4
        assert s1Flat[9] == n6

        # the F-sharp in m. 2 now as offsets for both flat non-flat sites
        assert n3.getOffsetBySite(m2) == 0
        assert n3.getOffsetBySite(s1Flat) == 4
        # the B in m. 2 now as offsets for both flat non-flat sites
        assert n6.getOffsetBySite(m4) == 2.5
        assert n6.getOffsetBySite(s1Flat) == 6.5

        #s1.show()

        #==== "fig-df04" end

        #==== "fig-df05"
        # Iterating and Filtering Elements by Class

        # get the Clef object, and report its sign, from Measure 1
        assert m1.getElementsByClass('Clef').stream()[0].sign == 'C'
        # collect into a list the sign of all clefs in the flat Score
        assert [cf.sign
                for cf in s1.flat.getElementsByClass('Clef')] == ['C', 'F']

        # collect the offsets Measures in the first part
        assert [e.offset for e in p1.elements] == [0.0, 4.0]
        # collect the offsets of Note in the first part flattened
        assert [e.offset
                for e in p1.flat.notesAndRests] == [0.0, 2.0, 4.0, 4.5]
        # collect the offsets of Notes in all parts flattened
        assert [e.offset for e in s1.flat.notesAndRests
                ] == [0.0, 0.0, 2.0, 4.0, 4.0, 4.5, 6.5]

        # get all pitch names
        match = []
        for e in s1.flat.getElementsByClass('Note').stream():
            match.append(e.pitch.nameWithOctave)
        assert match == ['G3', 'C4', 'G#3', 'A#1', 'D-4', 'B2']

        # collect all Notes and transpose up a perfect fifth
        for n in s1.flat.getElementsByClass('Note').stream():
            n.transpose('P5', inPlace=True)

        # check that all pitches are correctly transposed
        match = []
        for e in s1.flat.getElementsByClass('Note').stream():
            match.append(e.pitch.nameWithOctave)
        assert match == ['D4', 'G4', 'D#4', 'E#2', 'A-4', 'F#3']

        #s1.show()

        #==== "fig-df05" end

        #==== "fig-df06"
        # Searching by Locations and Contexts

        # a Note can always find a Clef
        self.assertIs(n4.getContextByClass('Clef'), cf1)
        # must search oldest sites first
        assert n6.getContextByClass('Clef',
                                    sortByCreationTime='reverse') == cf2

        #        # a Note can find their Measure number from a flat Part
        #        match = []
        #        for e in p1.flat.getElementsByClass('Note'):
        #            match.append(e.getContextByClass('Measure').number)
        #        assert match == [1, 1, 2, 2]

        # all Notes can find their Measure number from a flat Score
        match = []
        for e in s1.flat.notesAndRests:
            match.append([e.name, e.getContextByClass('Measure').number])
        assert match == [['D', 1], ['rest', 1], ['G', 1], ['D#', 2], ['E#', 2],
                         ['A-', 2], ['F#', 2]]
        #==== "fig-df06" end

        #==== "fig-df06"
        # Non-Hierarchical Object Associations
        #oldIds = []
        #for idKey in n1.sites.siteDict:
        #    print (idKey, n1.sites.siteDict[idKey].isDead)
        #    oldIds.append(idKey)
        #print("-------")

        # Spanners can be positioned in Parts or Measures
        sp1 = spanner.Slur([n1, n4])
        p1.append(sp1)
        sp2 = spanner.Slur([n5, n6])
        m4.insert(0, sp2)

        #print(id(sp1), id(sp1.spannerStorage), n1.sites.siteDict[id(sp1.spannerStorage)].isDead)
        #if id(sp1.spannerStorage) in oldIds:
        #    print ("******!!!!!!!!!*******")

        # Elements can report on what Spanner they belong to
        ss1 = n1.getSpannerSites()
        self.assertTrue(sp1 in ss1, (ss1, sp1))

        ss6 = n6.getSpannerSites()
        assert sp2 in ss6

        #         p1Flat = p1.flat
        #         assert sp1.getDurationSpanBySite(p1Flat) == [0.0, 8.0]
        #
        #         p2Flat = p2.flat
        #         assert sp2.getDurationSpanBySite(p2Flat) == [4.0, 8.0]

        #s1.show()
        #==== "fig-df06" end

        # additional tests
        self.assertEqual(m1.clef, cf1)
예제 #8
0
def abcToStreamPart(abcHandler, inputM21=None, spannerBundle=None):
    '''
    Handler conversion of a single Part of a multi-part score.
    Results are added into the provided inputM21 object
    or a newly created Part object

    The part object is then returned.
    '''
    from music21 import abcFormat

    if inputM21 is None:
        p = stream.Part()
    else:
        p = inputM21

    if spannerBundle is None:
        #environLocal.printDebug(['mxToMeasure()', 'creating SpannerBundle'])
        spannerBundle = spanner.SpannerBundle()

    # need to call on entire handlers, as looks for special criterial,
    # like that at least 2 regular bars are used, not just double bars
    if abcHandler.definesMeasures():
        # first, split into a list of Measures; if there is only metadata and
        # one measure, that means that no measures are defined
        barHandlers = abcHandler.splitByMeasure()
        #environLocal.printDebug(['barHandlers', len(barHandlers)])
        # merge loading meta data with each bar that preceedes it
        mergedHandlers = abcFormat.mergeLeadingMetaData(barHandlers)
        #environLocal.printDebug(['mergedHandlers', len(mergedHandlers)])
    else:  # simply stick in a single list
        mergedHandlers = [abcHandler]

    # if only one merged handler, do not create measures
    if len(mergedHandlers) <= 1:
        useMeasures = False
    else:
        useMeasures = True

    # each unit in merged handlers defines possible a Measure (w/ or w/o metadata),
    # trailing meta data, or a single collection of metadata and note data

    barCount = 0
    measureNumber = 1
    # merged handler are ABCHandlerBar objects, defining attributes for barlines

    for mh in mergedHandlers:
        # if use measures and the handler has notes; otherwise add to part
        #environLocal.printDebug(['abcToStreamPart', 'handler', 'left:', mh.leftBarToken,
        #    'right:', mh.rightBarToken, 'len(mh)', len(mh)])

        if useMeasures and mh.hasNotes():
            #environLocal.printDebug(['abcToStreamPart', 'useMeasures',
            #    useMeasures, 'mh.hasNotes()', mh.hasNotes()])
            dst = stream.Measure()
            # bar tokens are already extracted form token list and are available
            # as attributes on the handler object
            # may return None for a regular barline

            if mh.leftBarToken is not None:
                # this may be Repeat Bar subclass
                bLeft = mh.leftBarToken.getBarObject()
                if bLeft is not None:
                    dst.leftBarline = bLeft
                if mh.leftBarToken.isRepeatBracket():
                    # get any open spanners of RepeatBracket type
                    rbSpanners = spannerBundle.getByClass(
                        'RepeatBracket').getByCompleteStatus(False)
                    # this indication is most likely an opening, as ABC does
                    # not encode second ending ending boundaries
                    # we can still check thought:
                    if not rbSpanners:
                        # add this measure as a componnt
                        rb = spanner.RepeatBracket(dst)
                        # set number, returned here
                        rb.number = mh.leftBarToken.isRepeatBracket()
                        # only append if created; otherwise, already stored
                        spannerBundle.append(rb)
                    else:  # close it here
                        rb = rbSpanners[0]  # get RepeatBracket
                        rb.addSpannedElements(dst)
                        rb.completeStatus = True
                        # this returns 1 or 2 depending on the repeat
                    # in ABC, second repeats close immediately; that is
                    # they never span more than one measure
                    if mh.leftBarToken.isRepeatBracket() == 2:
                        rb.completeStatus = True

            if mh.rightBarToken is not None:
                bRight = mh.rightBarToken.getBarObject()
                if bRight is not None:
                    dst.rightBarline = bRight
                # above returns bars and repeats; we need to look if we just
                # have repeats
                if mh.rightBarToken.isRepeat():
                    # if we have a right bar repeat, and a spanner repeat
                    # bracket is open (even if just assigned above) we need
                    # to close it now.
                    # presently, now r bar conditions start a repeat bracket
                    rbSpanners = spannerBundle.getByClass(
                        'RepeatBracket').getByCompleteStatus(False)
                    if any(rbSpanners):
                        rb = rbSpanners[0]  # get RepeatBracket
                        rb.addSpannedElements(dst)
                        rb.completeStatus = True
                        # this returns 1 or 2 depending on the repeat
                        # do not need to append; already in bundle
            barCount += 1
        else:
            dst = p  # store directly in a part instance

        #environLocal.printDebug([mh, 'dst', dst])
        #ql = 0 # might not be zero if there is a pickup

        postTransposition, clefSet = parseTokens(mh, dst, p, useMeasures)

        # append measure to part; in the case of trailing meta data
        # dst may be part, even though useMeasures is True
        if useMeasures and 'Measure' in dst.classes:
            # check for incomplete bars
            # must have a time signature in this bar, or defined recently
            # could use getTimeSignatures() on Stream

            if barCount == 1 and dst.timeSignature is not None:  # easy case
                # can only do this b/c ts is defined
                if dst.barDurationProportion() < 1.0:
                    dst.padAsAnacrusis()
                    dst.number = 0
                    #environLocal.printDebug([
                    #    'incompletely filled Measure found on abc import; ',
                    #    'interpreting as a anacrusis:', 'padingLeft:', dst.paddingLeft])
            else:
                dst.number = measureNumber
                measureNumber += 1
            p.coreAppend(dst)

    try:
        reBar(p, inPlace=True)
    except (ABCTranslateException, meter.MeterException, ZeroDivisionError):
        pass
    # clefs are not typically defined, but if so, are set to the first measure
    # following the meta data, or in the open stream
    if not clefSet and not p.recurse().getElementsByClass('Clef'):
        if useMeasures:  # assume at start of measures
            p.getElementsByClass('Measure')[0].clef = clef.bestClef(
                p, recurse=True)
        else:
            p.coreInsert(0, clef.bestClef(p, recurse=True))

    if postTransposition != 0:
        p.transpose(postTransposition, inPlace=True)

    if useMeasures and p.recurse().getElementsByClass('TimeSignature'):
        # call make beams for now; later, import beams
        #environLocal.printDebug(['abcToStreamPart: calling makeBeams'])
        try:
            p.makeBeams(inPlace=True)
        except (meter.MeterException, stream.StreamException) as e:
            environLocal.warn("Error in beaming...ignoring: %s" % str(e))

    # copy spanners into topmost container; here, a part
    rm = []
    for sp in spannerBundle.getByCompleteStatus(True):
        p.coreInsert(0, sp)
        rm.append(sp)
    # remove from original spanner bundle
    for sp in rm:
        spannerBundle.remove(sp)
    p.coreElementsChanged()
    return p
예제 #9
0
파일: realizer.py 프로젝트: tisttsf/music21
    def generateRealizationFromPossibilityProgression(self,
                                                      possibilityProgression):
        '''
        Generates a realization as a :class:`~music21.stream.Score` given a possibility progression.
        '''
        sol = stream.Score()

        bassLine = stream.Part()
        bassLine.append(
            [copy.deepcopy(self._keySig),
             copy.deepcopy(self._inTime)])
        r = None
        if self._paddingLeft != 0.0:
            r = note.Rest(quarterLength=self._paddingLeft)
            bassLine.append(copy.deepcopy(r))

        if self.keyboardStyleOutput:
            rightHand = stream.Part()
            sol.insert(0.0, rightHand)
            rightHand.append(
                [copy.deepcopy(self._keySig),
                 copy.deepcopy(self._inTime)])
            if r is not None:
                rightHand.append(copy.deepcopy(r))

            for segmentIndex in range(len(self._segmentList)):
                possibA = possibilityProgression[segmentIndex]
                bassNote = self._segmentList[segmentIndex].bassNote
                bassLine.append(copy.deepcopy(bassNote))
                rhPitches = possibA[0:-1]
                rhChord = chord.Chord(rhPitches)
                rhChord.quarterLength = self._segmentList[
                    segmentIndex].quarterLength
                rightHand.append(rhChord)
            rightHand.insert(0.0, clef.TrebleClef())

            rightHand.makeNotation(inPlace=True,
                                   cautionaryNotImmediateRepeat=False)
            if r is not None:
                rightHand[0].pop(3)
                rightHand[0].padAsAnacrusis()

        else:  # Chorale-style output
            upperParts = []
            for partNumber in range(len(possibilityProgression[0]) - 1):
                fbPart = stream.Part()
                sol.insert(0.0, fbPart)
                fbPart.append(
                    [copy.deepcopy(self._keySig),
                     copy.deepcopy(self._inTime)])
                if r is not None:
                    fbPart.append(copy.deepcopy(r))
                upperParts.append(fbPart)

            for segmentIndex in range(len(self._segmentList)):
                possibA = possibilityProgression[segmentIndex]
                bassNote = self._segmentList[segmentIndex].bassNote
                bassLine.append(copy.deepcopy(bassNote))

                for partNumber in range(len(possibA) - 1):
                    n1 = note.Note(possibA[partNumber])
                    n1.quarterLength = self._segmentList[
                        segmentIndex].quarterLength
                    upperParts[partNumber].append(n1)

            for upperPart in upperParts:
                c = clef.bestClef(upperPart, allowTreble8vb=True, recurse=True)
                upperPart.insert(0.0, c)
                upperPart.makeNotation(inPlace=True,
                                       cautionaryNotImmediateRepeat=False)
                if r is not None:
                    upperPart[0].pop(3)
                    upperPart[0].padAsAnacrusis()

        bassLine.insert(0.0, clef.BassClef())
        bassLine.makeNotation(inPlace=True, cautionaryNotImmediateRepeat=False)
        if r is not None:
            bassLine[0].pop(3)
            bassLine[0].padAsAnacrusis()
        sol.insert(0.0, bassLine)
        return sol
예제 #10
0
def musedataPartToStreamPart(museDataPart, inputM21=None):
    '''Translate a musedata part to a :class:`~music21.stream.Part`.
    '''
    from music21 import stream
    from music21 import note
    from music21 import tempo

    if inputM21 is None:
        s = stream.Score()
    else:
        s = inputM21

    p = stream.Part()
    p.id = museDataPart.getPartName()
    p.partName = p.id

    # create and store objects
    mdmObjs = museDataPart.getMeasures()

    # environLocal.printDebug(['first measure parent', mdmObjs[0].parent])

    barCount = 0
    # get each measure
    # store last Note/Chord/Rest for tie comparisons; span measures
    eLast = None
    for mIndex, mdm in enumerate(mdmObjs):
        # environLocal.printDebug(['processing:', mdm.src])
        if not mdm.hasNotes():
            continue

        if mdm.hasVoices():
            hasVoices = True
            vActive = stream.Voice()
        else:
            hasVoices = False
            vActive = None

        #m = stream.Measure()
        # get a measure object with a left configured bar line
        if mIndex <= len(mdmObjs) - 2:
            mdmNext = mdmObjs[mIndex + 1]
        else:
            mdmNext = None

        m = mdm.getMeasureObject()

        # conditions for a final measure definition defining the last bar
        if mdmNext is not None and not mdmNext.hasNotes():
            # environLocal.printDebug(['got mdmNext not none and not has notes'])
            # get bar from next measure definition
            m.rightBarline = mdmNext.getBarObject()

        if barCount == 0:  # only for when no bars are defined
            # the parent of the measure is the part
            c = mdm.parent.getClefObject()
            if c is not None:
                m.clef = mdm.parent.getClefObject()
            m.timeSignature = mdm.parent.getTimeSignatureObject()
            m.keySignature = mdm.parent.getKeySignature()
            # look for a tempo indication
            directive = mdm.parent.getDirective()
            if directive is not None:
                tt = tempo.TempoText(directive)
                # if this appears to be a tempo indication, than get metro
                if tt.isCommonTempoText():
                    mm = tt.getMetronomeMark()
                    m.insert(0, mm)

        # get all records; may be notes or note components
        mdrObjs = mdm.getRecords()
        # store pairs of pitches and durations for making chords after a
        # new note has been found
        pendingRecords = []

        # get notes in each record
        for i in range(len(mdrObjs)):
            mdr = mdrObjs[i]
            # environLocal.printDebug(['processing:', mdr.src])

            if mdr.isBack():
                # the current use of back assumes tt back assumes tt we always
                # return to the start of the measure; this may not be the case
                if pendingRecords != []:
                    eLast = _processPending(hasVoices, pendingRecords, eLast,
                                            m, vActive)
                    pendingRecords = []

                # every time we encounter a back, we need to store
                # our existing voice and create a new one
                m.insert(0, vActive)
                vActive = stream.Voice()

            if mdr.isRest():
                # environLocal.printDebug(['got mdr rest, parent:', mdr.parent])
                # check for pending records first
                if pendingRecords != []:
                    eLast = _processPending(hasVoices, pendingRecords, eLast,
                                            m, vActive)
                    pendingRecords = []
                # create rest after clearing pending records
                r = note.Rest()
                r.quarterLength = mdr.getQuarterLength()
                if hasVoices:
                    vActive.coreAppend(r)
                else:
                    m.coreAppend(r)
                eLast = r
                continue
            # a note is note as chord, but may have chord tones
            # attached to it that follow
            elif mdr.isChord():
                # simply append if a chord; do not clear or change pending
                pendingRecords.append(mdr)

            elif mdr.isNote():
                # either this is a note alone, or this is the first
                # note found that is not a chord; if first not a chord
                # need to append immediately
                if pendingRecords != []:
                    # this could be a Chord or Note
                    eLast = _processPending(hasVoices, pendingRecords, eLast,
                                            m, vActive)
                    pendingRecords = []
                # need to append this record for the current note
                pendingRecords.append(mdr)

        # check for any remaining single notes (if last) or chords
        if pendingRecords != []:
            eLast = _processPending(hasVoices, pendingRecords, eLast, m,
                                    vActive)

        # may be bending elements in a voice to append to a measure
        if vActive is not None and vActive:
            vActive.coreElementsChanged()
            m.coreInsert(0, vActive)

        m.coreElementsChanged()

        if barCount == 0 and m.timeSignature is not None:  # easy case
            # can only do this b/c ts is defined
            if m.barDurationProportion() < 1.0:
                m.padAsAnacrusis()
                # environLocal.printDebug(['incompletely filled Measure found on musedata import; ',
                #   'interpreting as a anacrusis:', 'paddingLeft:', m.paddingLeft])
        p.coreAppend(m)
        barCount += 1

    p.coreElementsChanged()
    # for now, make all imports a c-score on import;
    tInterval = museDataPart.getTranspositionIntervalObject()
    # environLocal.printDebug(['got transposition interval', p.id, tInterval])
    if tInterval is not None:
        p.flat.transpose(tInterval,
                         classFilterList=['Note', 'Chord', 'KeySignature'],
                         inPlace=True)
        # need to call make accidentals to correct new issues
        p.makeAccidentals()

    if museDataPart.stage == 1:
        # cannot yet get stage 1 clef data
        p.getElementsByClass('Measure')[0].clef = clef.bestClef(p,
                                                                recurse=True)
        p.makeBeams(inPlace=True)
        # will call overridden method on Part
        p.makeAccidentals()
    # assume that beams and clefs are defined in all stage 2

    s.insert(0, p)
    return s
예제 #11
0
def musedataPartToStreamPart(museDataPart, inputM21=None):
    '''Translate a musedata part to a :class:`~music21.stream.Part`.
    '''
    from music21 import stream
    from music21 import note
    from music21 import tempo

    if inputM21 is None:
        s = stream.Score()
    else:
        s = inputM21

    p = stream.Part()
    p.id = museDataPart.getPartName()
    p.partName = p.id

    # create and store objects
    mdmObjs = museDataPart.getMeasures()

    # environLocal.printDebug(['first measure parent', mdmObjs[0].parent])

    barCount = 0
    # get each measure
    # store last Note/Chord/Rest for tie comparisons; span measures
    eLast = None
    for mIndex, mdm in enumerate(mdmObjs):
        # environLocal.printDebug(['processing:', mdm.src])
        if not mdm.hasNotes():
            continue

        if mdm.hasVoices():
            hasVoices = True
            vActive = stream.Voice()
        else:
            hasVoices = False
            vActive = None

        #m = stream.Measure()
        # get a measure object with a left configured bar line
        if mIndex <= len(mdmObjs) - 2:
            mdmNext = mdmObjs[mIndex + 1]
        else:
            mdmNext = None

        m = mdm.getMeasureObject()

        # conditions for a final measure definition defining the last bar
        if mdmNext is not None and not mdmNext.hasNotes():
            # environLocal.printDebug(['got mdmNext not none and not has notes'])
            # get bar from next measure definition
            m.rightBarline = mdmNext.getBarObject()

        if barCount == 0: # only for when no bars are defined
            # the parent of the measure is the part
            c = mdm.parent.getClefObject()
            if c is not None:
                m.clef = mdm.parent.getClefObject()
            m.timeSignature = mdm.parent.getTimeSignatureObject()
            m.keySignature = mdm.parent.getKeySignature()
            # look for a tempo indication
            directive = mdm.parent.getDirective()
            if directive is not None:
                tt = tempo.TempoText(directive)
                # if this appears to be a tempo indication, than get metro
                if tt.isCommonTempoText():
                    mm = tt.getMetronomeMark()
                    m.insert(0, mm)

        # get all records; may be notes or note components
        mdrObjs = mdm.getRecords()
        # store pairs of pitches and durations for chording after a
        # new note has been found
        pendingRecords = []

        # get notes in each record
        for i in range(len(mdrObjs)):
            mdr = mdrObjs[i]
            # environLocal.printDebug(['processing:', mdr.src])

            if mdr.isBack():
                # the current use of back assumes tt back assumes tt we always
                # return to the start of the measure; this may not be the case
                if pendingRecords != []:
                    eLast = _processPending(hasVoices, pendingRecords, eLast, m, vActive)
                    pendingRecords = []

                # every time we encounter a back, we need to store
                # our existing voice and create a new one
                m.insert(0, vActive)
                vActive = stream.Voice()

            if mdr.isRest():
                # environLocal.printDebug(['got mdr rest, parent:', mdr.parent])
                # check for pending records first
                if pendingRecords != []:
                    eLast = _processPending(hasVoices, pendingRecords, eLast, m, vActive)
                    pendingRecords = []
                # create rest after clearing pending records
                r = note.Rest()
                r.quarterLength = mdr.getQuarterLength()
                if hasVoices:
                    vActive.coreAppend(r)
                else:
                    m.coreAppend(r)
                eLast = r
                continue
            # a note is note as chord, but may have chord tones
            # attached to it that follow
            elif mdr.isChord():
                # simply append if a chord; do not clear or change pending
                pendingRecords.append(mdr)

            elif mdr.isNote():
                # either this is a note alone, or this is the first
                # note found that is not a chord; if first not a chord
                # need to append immediately
                if pendingRecords != []:
                    # this could be a Chord or Note
                    eLast = _processPending(hasVoices, pendingRecords, eLast, m, vActive)
                    pendingRecords = []
                # need to append this record for the current note
                pendingRecords.append(mdr)

        # check for any remaining single notes (if last) or chords
        if pendingRecords != []:
            eLast = _processPending(hasVoices, pendingRecords, eLast, m, vActive)

        # may be bending elements in a voice to append to a measure
        if vActive is not None and vActive:
            vActive.coreElementsChanged()
            m.coreInsert(0, vActive)

        m.coreElementsChanged()

        if barCount == 0 and m.timeSignature is not None: # easy case
            # can only do this b/c ts is defined
            if m.barDurationProportion() < 1.0:
                m.padAsAnacrusis()
                # environLocal.printDebug(['incompletely filled Measure found on musedata import; ',
                #   'interpreting as a anacrusis:', 'padingLeft:', m.paddingLeft])
        p.coreAppend(m)
        barCount += 1

    p.coreElementsChanged()
    # for now, make all imports a c-score on import;
    tInterval = museDataPart.getTranspositionIntervalObject()
    # environLocal.printDebug(['got transposition interval', p.id, tInterval])
    if tInterval is not None:
        p.flat.transpose(tInterval,
                        classFilterList=['Note', 'Chord', 'KeySignature'],
                        inPlace=True)
        # need to call make accidentals to correct new issues
        p.makeAccidentals()

    if museDataPart.stage == 1:
        # cannot yet get stage 1 clef data
        p.getElementsByClass('Measure')[0].clef = clef.bestClef(p, recurse=True)
        p.makeBeams(inPlace=True)
        # will call overridden method on Part
        p.makeAccidentals()
    # assume that beams and clefs are defined in all stage 2

    s.insert(0, p)
    return s
예제 #12
0
    def generateRealizationFromPossibilityProgression(self, possibilityProgression):
        '''
        Generates a realization as a :class:`~music21.stream.Score` given a possibility progression.
        '''
        sol = stream.Score()

        bassLine = stream.Part()
        bassLine.append([copy.deepcopy(self._keySig), copy.deepcopy(self._inTime)])
        r = None
        if self._paddingLeft != 0.0:
            r = note.Rest(quarterLength=self._paddingLeft)
            bassLine.append(copy.deepcopy(r))

        if self.keyboardStyleOutput:
            rightHand = stream.Part()
            sol.insert(0.0, rightHand)
            rightHand.append([copy.deepcopy(self._keySig), copy.deepcopy(self._inTime)])
            if r is not None:
                rightHand.append(copy.deepcopy(r))

            for segmentIndex in range(len(self._segmentList)):
                possibA = possibilityProgression[segmentIndex]
                bassNote = self._segmentList[segmentIndex].bassNote
                bassLine.append(copy.deepcopy(bassNote))
                rhPitches = possibA[0:-1]
                rhChord = chord.Chord(rhPitches)
                rhChord.quarterLength = self._segmentList[segmentIndex].quarterLength
                rightHand.append(rhChord)
            rightHand.insert(0.0, clef.TrebleClef())

            rightHand.makeNotation(inPlace=True, cautionaryNotImmediateRepeat=False)
            if r is not None:
                rightHand[0].pop(3)
                rightHand[0].padAsAnacrusis()

        else: # Chorale-style output
            upperParts = []
            for partNumber in range(len(possibilityProgression[0]) - 1):
                fbPart = stream.Part()
                sol.insert(0.0, fbPart)
                fbPart.append([copy.deepcopy(self._keySig), copy.deepcopy(self._inTime)])
                if r is not None:
                    fbPart.append(copy.deepcopy(r))
                upperParts.append(fbPart)

            for segmentIndex in range(len(self._segmentList)):
                possibA = possibilityProgression[segmentIndex]
                bassNote = self._segmentList[segmentIndex].bassNote
                bassLine.append(copy.deepcopy(bassNote))

                for partNumber in range(len(possibA) - 1):
                    n1 = note.Note(possibA[partNumber])
                    n1.quarterLength = self._segmentList[segmentIndex].quarterLength
                    upperParts[partNumber].append(n1)

            for upperPart in upperParts:
                c = clef.bestClef(upperPart, allowTreble8vb=True, recurse=True)
                upperPart.insert(0.0, c)
                upperPart.makeNotation(inPlace=True, cautionaryNotImmediateRepeat=False)
                if r is not None:
                    upperPart[0].pop(3)
                    upperPart[0].padAsAnacrusis()


        bassLine.insert(0.0, clef.BassClef())
        bassLine.makeNotation(inPlace=True, cautionaryNotImmediateRepeat=False)
        if r is not None:
            bassLine[0].pop(3)
            bassLine[0].padAsAnacrusis()
        sol.insert(0.0, bassLine)
        return sol
예제 #13
0
def abcToStreamPart(abcHandler, inputM21=None, spannerBundle=None):
    '''
    Handler conversion of a single Part of a multi-part score.
    Results are added into the provided inputM21 object
    or a newly created Part object

    The part object is then returned.
    '''
    from music21 import abcFormat

    if inputM21 is None:
        p = stream.Part()
    else:
        p = inputM21

    if spannerBundle is None:
        # environLocal.printDebug(['mxToMeasure()', 'creating SpannerBundle'])
        spannerBundle = spanner.SpannerBundle()


    # need to call on entire handlers, as looks for special criterial,
    # like that at least 2 regular bars are used, not just double bars
    if abcHandler.definesMeasures():
        # first, split into a list of Measures; if there is only metadata and
        # one measure, that means that no measures are defined
        barHandlers = abcHandler.splitByMeasure()
        # environLocal.printDebug(['barHandlers', len(barHandlers)])
        # merge loading meta data with each bar that preceedes it
        mergedHandlers = abcFormat.mergeLeadingMetaData(barHandlers)
        # environLocal.printDebug(['mergedHandlers', len(mergedHandlers)])
    else: # simply stick in a single list
        mergedHandlers = [abcHandler]

    # if only one merged handler, do not create measures
    if len(mergedHandlers) <= 1:
        useMeasures = False
    else:
        useMeasures = True

    # each unit in merged handlers defines possible a Measure (w/ or w/o metadata),
    # trailing meta data, or a single collection of metadata and note data

    barCount = 0
    measureNumber = 1
    # merged handler are ABCHandlerBar objects, defining attributes for barlines

    for mh in mergedHandlers:
        # if use measures and the handler has notes; otherwise add to part
        # environLocal.printDebug(['abcToStreamPart', 'handler', 'left:', mh.leftBarToken,
        #    'right:', mh.rightBarToken, 'len(mh)', len(mh)])

        if useMeasures and mh.hasNotes():
            # environLocal.printDebug(['abcToStreamPart', 'useMeasures',
            #    useMeasures, 'mh.hasNotes()', mh.hasNotes()])
            dst = stream.Measure()
            # bar tokens are already extracted form token list and are available
            # as attributes on the handler object
            # may return None for a regular barline

            if mh.leftBarToken is not None:
                # this may be Repeat Bar subclass
                bLeft = mh.leftBarToken.getBarObject()
                if bLeft is not None:
                    dst.leftBarline = bLeft
                if mh.leftBarToken.isRepeatBracket():
                    # get any open spanners of RepeatBracket type
                    rbSpanners = spannerBundle.getByClass('RepeatBracket'
                                        ).getByCompleteStatus(False)
                    # this indication is most likely an opening, as ABC does
                    # not encode second ending ending boundaries
                    # we can still check thought:
                    if not rbSpanners:
                        # add this measure as a componnt
                        rb = spanner.RepeatBracket(dst)
                        # set number, returned here
                        rb.number = mh.leftBarToken.isRepeatBracket()
                        # only append if created; otherwise, already stored
                        spannerBundle.append(rb)
                    else: # close it here
                        rb = rbSpanners[0] # get RepeatBracket
                        rb.addSpannedElements(dst)
                        rb.completeStatus = True
                        # this returns 1 or 2 depending on the repeat
                    # in ABC, second repeats close immediately; that is
                    # they never span more than one measure
                    if mh.leftBarToken.isRepeatBracket() == 2:
                        rb.completeStatus = True

            if mh.rightBarToken is not None:
                bRight = mh.rightBarToken.getBarObject()
                if bRight is not None:
                    dst.rightBarline = bRight
                # above returns bars and repeats; we need to look if we just
                # have repeats
                if mh.rightBarToken.isRepeat():
                    # if we have a right bar repeat, and a spanner repeat
                    # bracket is open (even if just assigned above) we need
                    # to close it now.
                    # presently, now r bar conditions start a repeat bracket
                    rbSpanners = spannerBundle.getByClass(
                                        'RepeatBracket').getByCompleteStatus(False)
                    if any(rbSpanners):
                        rb = rbSpanners[0] # get RepeatBracket
                        rb.addSpannedElements(dst)
                        rb.completeStatus = True
                        # this returns 1 or 2 depending on the repeat
                        # do not need to append; already in bundle
            barCount += 1
        else:
            dst = p # store directly in a part instance

        # environLocal.printDebug([mh, 'dst', dst])
        #ql = 0 # might not be zero if there is a pickup

        postTransposition, clefSet = parseTokens(mh, dst, p, useMeasures)

        # append measure to part; in the case of trailing meta data
        # dst may be part, even though useMeasures is True
        if useMeasures and 'Measure' in dst.classes:
            # check for incomplete bars
            # must have a time signature in this bar, or defined recently
            # could use getTimeSignatures() on Stream

            if barCount == 1 and dst.timeSignature is not None: # easy case
                # can only do this b/c ts is defined
                if dst.barDurationProportion() < 1.0:
                    dst.padAsAnacrusis()
                    dst.number = 0
                    # environLocal.printDebug([
                    #    'incompletely filled Measure found on abc import; ',
                    #    'interpreting as a anacrusis:', 'padingLeft:', dst.paddingLeft])
            else:
                dst.number = measureNumber
                measureNumber += 1
            p.coreAppend(dst)

    try:
        reBar(p, inPlace=True)
    except (ABCTranslateException, meter.MeterException, ZeroDivisionError):
        pass
    # clefs are not typically defined, but if so, are set to the first measure
    # following the meta data, or in the open stream
    if not clefSet and not p.recurse().getElementsByClass('Clef'):
        if useMeasures:  # assume at start of measures
            p.getElementsByClass('Measure')[0].clef = clef.bestClef(p, recurse=True)
        else:
            p.coreInsert(0, clef.bestClef(p, recurse=True))

    if postTransposition != 0:
        p.transpose(postTransposition, inPlace=True)

    if useMeasures and p.recurse().getElementsByClass('TimeSignature'):
        # call make beams for now; later, import beams
        # environLocal.printDebug(['abcToStreamPart: calling makeBeams'])
        try:
            p.makeBeams(inPlace=True)
        except (meter.MeterException, stream.StreamException) as e:
            environLocal.warn("Error in beaming...ignoring: %s" % str(e))

    # copy spanners into topmost container; here, a part
    rm = []
    for sp in spannerBundle.getByCompleteStatus(True):
        p.coreInsert(0, sp)
        rm.append(sp)
    # remove from original spanner bundle
    for sp in rm:
        spannerBundle.remove(sp)
    p.coreElementsChanged()
    return p