Пример #1
0
    def barlineListFromBarline(self, barlineElement):
        '''
        Indication that the barline at this point should be something other than normal.
        
        Capella does not indicate measure breaks or barline breaks normally, so the only barlines
        that are indicated are unusual ones.
        
        Returns a LIST of :class:`~music21.bar.Barline` or :class:`~music21.bar.Repeat` objects
        because the `repEndBegin` type requires two `bar.Repeat` objects to encode in `music21`. 
        
        
        >>> ci = capella.fromCapellaXML.CapellaImporter()
        >>> barlineTag = ci.domElementFromText('<barline type="end"/>')
        >>> ci.barlineListFromBarline(barlineTag)    
        [<music21.bar.Barline style=final>]

        >>> repeatTag = ci.domElementFromText('<barline type="repEndBegin"/>')
        >>> ci.barlineListFromBarline(repeatTag)    
        [<music21.bar.Repeat direction=end>, <music21.bar.Repeat direction=start>]

        '''
        barlineList = []
        hasRepeatEnd = False
        if 'type' in barlineElement._attrs:
            barlineType = barlineElement._attrs['type'].value
            if barlineType.startswith('rep'):  # begins with rep
                if barlineType in self.barlineMap:
                    repeatType = self.barlineMap[barlineType]
                    if repeatType.find('end') > -1:
                        barlineList.append(bar.Repeat('end'))
                        hasRepeatEnd = True
                    if repeatType.find('start') > -1:
                        startRep = bar.Repeat('start')
                        if hasRepeatEnd is True:
                            startRep.priority = 1
                        barlineList.append(startRep)
            else:
                if barlineType in self.barlineMap:
                    barlineList.append(
                        bar.Barline(self.barlineMap[barlineType]))

        return barlineList
Пример #2
0
def _addRepeatsFromRepeatEndings(s, repeatEndings):
    '''
    given a Stream and the repeatEndings dict, add repeats to the stream...    
    '''
    from music21 import spanner
    consolidatedRepeats = _consolidateRepeatEndings(repeatEndings)
    for repeatEndingTuple in consolidatedRepeats:
        measureList, endingNumber = repeatEndingTuple[0], repeatEndingTuple[1]
        rb = spanner.RepeatBracket(measureList, number=endingNumber)
        rbOffset = measureList[0].getOffsetBySite(s)
        #Adding repeat bracket to stream at beginning of repeated section.
        #Maybe better at end?
        s.insert(rbOffset, rb)
        if endingNumber == 1:  # should be "if not max(endingNumbers), but we can't tell that for each repeat...
            if measureList[-1].rightBarline is None:
                measureList[-1].rightBarline = bar.Repeat(direction='end')
Пример #3
0
    def testSortorder(self):
        from music21 import stream, bar, clef, note, metadata
        m = stream.Measure()
        b = bar.Repeat()
        m.leftBarline = b
        c = clef.BassClef()
        m.append(c)
        n = note.Note()
        m.append(n)

        # check sort order
        self.assertEqual(m[0], b)
        self.assertEqual(m[1], c)
        self.assertEqual(m[2], n)

        # if we add metadata, it sorts ahead of bar
        md = metadata.Metadata()
        m.insert(0, md)

        self.assertEqual(m[0], md)
        self.assertEqual(m[1], b)
Пример #4
0
    def createBarlines(self, attributes):
        r'''
        Translates bar lines into music21.
        
        
        

        >>> nwt = noteworthy.translate.NoteworthyTranslator()
        >>> nwt.currentPart = stream.Part()
        >>> nwt.currentMeasure = stream.Measure() 
        >>> nwt.createBarlines({"Style":"MasterRepeatOpen"})
        >>> nwt.currentMeasure
        <music21.stream.Measure 0 offset=0.0>        
        >>> nwt.currentMeasure.leftBarline
        <music21.bar.Repeat direction=start> 
        
        '''
        self.activeAccidentals = {}

        if 'Style' not in attributes:
            # pure barline
            self.currentPart.append(self.currentMeasure)
            self.currentMeasure = stream.Measure()
            return
        
        style = attributes['Style']
        
        if style == "MasterRepeatOpen":
            self.currentPart.append(self.currentMeasure)
            self.currentMeasure = stream.Measure()
            self.currentMeasure.leftBarline = bar.Repeat(direction='start')
    
        elif style == "MasterRepeatClose":
            self.currentMeasure.rightBarline = bar.Repeat(direction='end')
            self.currentPart.append(self.currentMeasure)
            self.currentMeasure = stream.Measure()
            
        elif style == "LocalRepeatOpen":
            self.currentPart.append(self.currentMeasure)
            self.currentMeasure = stream.Measure()
            self.currentMeasure.leftBarline = bar.Repeat(direction='start')
            
        elif style == "LocalRepeatClose":
            self.currentMeasure.rightBarline = bar.Repeat(direction='end')
            self.currentPart.append(self.currentMeasure)
            self.currentMeasure = stream.Measure()
            
        elif style == "Double":
            self.currentMeasure.rightBarline = bar.Barline('double')
            self.currentPart.append(self.currentMeasure)
            self.currentMeasure = stream.Measure()    
            
        elif style == "SectionOpen":
            self.currentMeasure.rightBarline = bar.Barline('heavy-light')
            self.currentPart.append(self.currentMeasure)
            self.currentMeasure = stream.Measure()    
        elif style == "SectionClose":
            self.currentMeasure.rightBarline = bar.Barline('final')
            self.currentPart.append(self.currentMeasure)
            self.currentMeasure = stream.Measure()    
        else:
            raise NoteworthyTranslateException('cannot find a style %s in our list' % style)
Пример #5
0
def romanTextToStreamScore(rtHandler, inputM21=None):
    '''The main processing module for single-movement RomanText works.

    Given a romanText handler or string, return or fill a Score Stream.
    '''
    # accept a string directly; mostly for testing
    if common.isStr(rtHandler):
        rtf = rtObjects.RTFile()
        rtHandler = rtf.readstr(rtHandler)  # return handler, processes tokens

    # this could be just a Stream, but b/c we are creating metadata, perhaps better to match presentation of other scores.

    from music21 import metadata
    from music21 import stream
    from music21 import note
    from music21 import meter
    from music21 import key
    from music21 import roman
    from music21 import tie

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

    # metadata can be first
    md = metadata.Metadata()
    s.insert(0, md)

    p = stream.Part()
    # ts indication are found in header, and also found elsewhere
    tsCurrent = meter.TimeSignature('4/4')  # create default 4/4
    tsSet = False  # store if set to a measure
    lastMeasureToken = None
    lastMeasureNumber = 0
    previousRn = None
    keySigCurrent = None
    keySigSet = True  # set a keySignature
    foundAKeySignatureSoFar = False
    kCurrent, unused_prefixLyric = _getKeyAndPrefix(
        'C')  # default if none defined
    prefixLyric = ''

    repeatEndings = {}
    rnKeyCache = {}

    for t in rtHandler.tokens:
        try:

            # environLocal.printDebug(['token', t])
            if t.isTitle():
                md.title = t.data

            elif t.isWork():
                md.alternativeTitle = t.data

            elif t.isPiece():
                md.alternativeTitle = t.data

            elif t.isComposer():
                md.composer = t.data

            elif t.isMovement():
                md.movementNumber = t.data

            elif t.isTimeSignature():
                tsCurrent = meter.TimeSignature(t.data)
                tsSet = False
                # environLocal.printDebug(['tsCurrent:', tsCurrent])

            elif t.isKeySignature():
                if t.data == "":
                    keySigCurrent = key.KeySignature(0)
                elif t.data == "Bb":
                    keySigCurrent = key.KeySignature(-1)
                else:
                    pass
                    # better to print a message
                    # environLocal.printDebug(['still need to write a generic RomanText KeySignature routine.  this is just temporary'])
                    # raise RomanTextTranslateException("still need to write a generic RomanText KeySignature routine.  this is just temporary")
                keySigSet = False
                # environLocal.printDebug(['keySigCurrent:', keySigCurrent])
                foundAKeySignatureSoFar = True

            elif t.isMeasure():
                # environLocal.printDebug(['handling measure token:', t])
                #if t.number[0] % 10 == 0:
                #    print "at number " + str(t.number[0])
                if t.variantNumber is not None:
                    # environLocal.printDebug(['skipping variant: %s' % t])
                    continue
                if t.variantLetter is not None:
                    # environLocal.printDebug(['skipping variant: %s' % t])
                    continue

                # if this measure number is more than 1 greater than the last
                # defined measure number, and the previous chord is not None,
                # then fill with copies of the last-defined measure
                if ((t.number[0] > lastMeasureNumber + 1)
                        and (previousRn is not None)):
                    for i in range(lastMeasureNumber + 1, t.number[0]):
                        mFill = stream.Measure()
                        mFill.number = i
                        newRn = copy.deepcopy(previousRn)
                        newRn.lyric = ""
                        # set to entire bar duration and tie
                        newRn.duration = copy.deepcopy(tsCurrent.barDuration)
                        if previousRn.tie is None:
                            previousRn.tie = tie.Tie('start')
                        else:
                            previousRn.tie.type = 'continue'
                        # set to stop for now; may extend on next iteration
                        newRn.tie = tie.Tie('stop')
                        previousRn = newRn
                        mFill.append(newRn)
                        appendMeasureToRepeatEndingsDict(
                            lastMeasureToken, mFill, repeatEndings, i)
                        p._appendCore(mFill)
                    lastMeasureNumber = t.number[0] - 1
                    lastMeasureToken = t

                # create a new measure or copy a past measure
                if len(t.number) == 1 and t.isCopyDefinition:  # if not a range
                    p.elementsChanged()
                    m, kCurrent = _copySingleMeasure(t, p, kCurrent)
                    p._appendCore(m)
                    lastMeasureNumber = m.number
                    lastMeasureToken = t
                    romans = m.getElementsByClass(roman.RomanNumeral,
                                                  returnStreamSubClass='list')
                    if len(romans) > 0:
                        previousRn = romans[-1]

                elif len(t.number) > 1:
                    p.elementsChanged()
                    measures, kCurrent = _copyMultipleMeasures(t, p, kCurrent)
                    p.append(measures)  # appendCore does not work with list
                    lastMeasureNumber = measures[-1].number
                    lastMeasureToken = t
                    romans = measures[-1].getElementsByClass(
                        roman.RomanNumeral, returnStreamSubClass='list')
                    if len(romans) > 0:
                        previousRn = romans[-1]

                else:
                    m = stream.Measure()
                    m.number = t.number[0]
                    appendMeasureToRepeatEndingsDict(t, m, repeatEndings)
                    lastMeasureNumber = t.number[0]
                    lastMeasureToken = t

                    if not tsSet:
                        m.timeSignature = tsCurrent
                        tsSet = True  # only set when changed
                    if not keySigSet and keySigCurrent is not None:
                        m.insert(0, keySigCurrent)
                        keySigSet = True  # only set when changed

                    o = 0.0  # start offsets at zero
                    previousChordInMeasure = None
                    pivotChordPossible = False
                    numberOfAtoms = len(t.atoms)
                    setKeyChangeToken = False  # first RomanNumeral object after a key change should have this set to True

                    for i, a in enumerate(t.atoms):
                        if isinstance(a, rtObjects.RTKey) or \
                           ((foundAKeySignatureSoFar == False) and \
                            (isinstance(a, rtObjects.RTAnalyticKey))):
                            # found a change of Key+KeySignature or
                            # just found a change of analysis but no keysignature so far

                            # environLocal.printDebug(['handling key token:', a])
                            try:  # this sets the key and the keysignature
                                kCurrent, pl = _getKeyAndPrefix(a)
                                prefixLyric += pl
                            except:
                                raise RomanTextTranslateException(
                                    'cannot get key from %s in line %s' %
                                    (a.src, t.src))
                            # insert at beginning of measure if at beginning -- for things like pickups.
                            if m.number < 2:
                                m._insertCore(0, kCurrent)
                            else:
                                m._insertCore(o, kCurrent)
                            foundAKeySignatureSoFar = True
                            setKeyChangeToken = True

                        elif isinstance(a, rtObjects.RTKeySignature):
                            try:  # this sets the keysignature but not the prefix text
                                thisSig = a.getKeySignature()
                            except:
                                raise RomanTextTranslateException(
                                    'cannot get key from %s in line %s' %
                                    (a.src, t.src))
                            #insert at beginning of measure if at beginning -- for things like pickups.
                            if m.number < 2:
                                m._insertCore(0, thisSig)
                            else:
                                m._insertCore(o, thisSig)
                            foundAKeySignatureSoFar = True

                        elif isinstance(a, rtObjects.RTAnalyticKey):
                            # just a change in analyzed key, not a change in anything else
                            #try: # this sets the key, not the keysignature
                            kCurrent, pl = _getKeyAndPrefix(a)
                            prefixLyric += pl
                            setKeyChangeToken = True

                            #except:
                            #    raise RomanTextTranslateException('cannot get key from %s in line %s' % (a.src, t.src))

                        elif isinstance(a, rtObjects.RTBeat):
                            # set new offset based on beat
                            try:
                                o = a.getOffset(tsCurrent)
                            except ValueError:
                                raise RomanTextTranslateException(
                                    "cannot properly get an offset from beat data %s under timeSignature %s in line %s"
                                    % (a.src, tsCurrent, t.src))
                            if (previousChordInMeasure is None
                                    and previousRn is not None and o > 0):
                                # setting a new beat before giving any chords
                                firstChord = copy.deepcopy(previousRn)
                                firstChord.quarterLength = o
                                firstChord.lyric = ""
                                if previousRn.tie == None:
                                    previousRn.tie = tie.Tie('start')
                                else:
                                    previousRn.tie.type = 'continue'
                                firstChord.tie = tie.Tie('stop')
                                previousRn = firstChord
                                previousChordInMeasure = firstChord
                                m._insertCore(0, firstChord)
                            pivotChordPossible = False

                        elif isinstance(a, rtObjects.RTNoChord):
                            # use source to evaluation roman
                            rn = note.Rest()
                            if pivotChordPossible == False:
                                # probably best to find duration
                                if previousChordInMeasure is None:
                                    pass  # use default duration
                                else:  # update duration of previous chord in Measure
                                    oPrevious = previousChordInMeasure.getOffsetBySite(
                                        m)
                                    newQL = o - oPrevious
                                    if newQL <= 0:
                                        raise RomanTextTranslateException(
                                            'too many notes in this measure: %s'
                                            % t.src)
                                    previousChordInMeasure.quarterLength = newQL
                                prefixLyric = ""
                                m._insertCore(o, rn)
                                previousChordInMeasure = rn
                                previousRn = rn
                                pivotChordPossible = False

                        elif isinstance(a, rtObjects.RTChord):
                            # use source to evaluation roman
                            try:
                                asrc = a.src
                                #                            if kCurrent.mode == 'minor':
                                #                                if asrc.lower().startswith('vi'): #vi or vii w/ or w/o o
                                #                                    if asrc.upper() == a.src: # VI or VII to bVI or bVII
                                #                                        asrc = 'b' + asrc
                                cacheTuple = (asrc,
                                              kCurrent.tonicPitchNameWithCase)
                                if USE_RN_CACHE and cacheTuple in rnKeyCache:
                                    #print "Got a match: " + str(cacheTuple)
                                    # Problems with Caches not picking up pivot chords... Not faster, see below.
                                    rn = copy.deepcopy(rnKeyCache[cacheTuple])
                                else:
                                    #print "No match for: " + str(cacheTuple)
                                    rn = roman.RomanNumeral(
                                        asrc, copy.deepcopy(kCurrent))
                                    rnKeyCache[cacheTuple] = rn
                                # surprisingly, not faster... and more dangerous
                                #rn = roman.RomanNumeral(asrc, kCurrent)
                                ## SLOWEST!!!
                                #rn = roman.RomanNumeral(asrc, kCurrent.tonicPitchNameWithCase)

                                #>>> from timeit import timeit as t
                                #>>> t('roman.RomanNumeral("IV", "c#")', 'from music21 import roman', number=1000)
                                #45.75
                                #>>> t('roman.RomanNumeral("IV", k)', 'from music21 import roman, key; k = key.Key("c#")', number=1000)
                                #16.09
                                #>>> t('roman.RomanNumeral("IV", copy.deepcopy(k))', 'from music21 import roman, key; import copy; k = key.Key("c#")', number=1000)
                                #22.49
                                ## key cache, does not help much...
                                #>>> t('copy.deepcopy(r)', 'from music21 import roman; import copy; r = roman.RomanNumeral("IV", "c#")', number=1000)
                                #19.01

                                if setKeyChangeToken is True:
                                    rn.followsKeyChange = True
                                    setKeyChangeToken = False
                                else:
                                    rn.followsKeyChange = False
                            except (roman.RomanNumeralException,
                                    common.Music21CommonException):
                                #environLocal.printDebug('cannot create RN from: %s' % a.src)
                                rn = note.Note()  # create placeholder

                            if pivotChordPossible == False:
                                # probably best to find duration
                                if previousChordInMeasure is None:
                                    pass  # use default duration
                                else:  # update duration of previous chord in Measure
                                    oPrevious = previousChordInMeasure.getOffsetBySite(
                                        m)
                                    newQL = o - oPrevious
                                    if newQL <= 0:
                                        raise RomanTextTranslateException(
                                            'too many notes in this measure: %s'
                                            % t.src)
                                    previousChordInMeasure.quarterLength = newQL

                                rn.addLyric(prefixLyric + a.src)
                                prefixLyric = ""
                                m._insertCore(o, rn)
                                previousChordInMeasure = rn
                                previousRn = rn
                                pivotChordPossible = True
                            else:
                                previousChordInMeasure.lyric += "//" + prefixLyric + a.src
                                previousChordInMeasure.pivotChord = rn
                                prefixLyric = ""
                                pivotChordPossible = False

                        elif isinstance(a, rtObjects.RTRepeat):
                            if o == 0:
                                if isinstance(a, rtObjects.RTRepeatStart):
                                    m.leftBarline = bar.Repeat(
                                        direction='start')
                                else:
                                    rtt = RomanTextUnprocessedToken(a)
                                    m._insertCore(o, rtt)
                            elif tsCurrent is not None and (
                                    tsCurrent.barDuration.quarterLength == o
                                    or i == numberOfAtoms - 1):
                                if isinstance(a, rtObjects.RTRepeatStop):
                                    m.rightBarline = bar.Repeat(
                                        direction='end')
                                else:
                                    rtt = RomanTextUnprocessedToken(a)
                                    m._insertCore(o, rtt)
                            else:  # mid measure repeat signs
                                rtt = RomanTextUnprocessedToken(a)
                                m._insertCore(o, rtt)

                        else:
                            rtt = RomanTextUnprocessedToken(a)
                            m._insertCore(o, rtt)
                            #environLocal.warn("Got an unknown token: %r" % a)

                    # may need to adjust duration of last chord added
                    if tsCurrent is not None:
                        previousRn.quarterLength = tsCurrent.barDuration.quarterLength - o
                    m.elementsChanged()
                    p._appendCore(m)

        except Exception:
            import traceback
            tracebackMessage = traceback.format_exc()
            raise RomanTextTranslateException(
                "At line %d for token %r, an exception was raised: \n%s" %
                (t.lineNumber, t, tracebackMessage))

    p.elementsChanged()
    fixPickupMeasure(p)
    p.makeBeams(inPlace=True)
    p.makeAccidentals(inPlace=True)
    _addRepeatsFromRepeatEndings(p, repeatEndings)  # 1st and second endings...
    s.insert(0, p)

    return s
Пример #6
0
    def convertM21(self, outVote, arrError, ground):
        errorColor = "#ff0000"
        missingColor = "#00ff00"
        #         sOut=stream.Stream()
        sOut = stream.Score()
        sPart = stream.Part()
        measureIndex = 1
        measure = stream.Measure()
        measure.number = measureIndex
        indexS = 0

        for symbol in outVote:
            mytie = ""
            realDuration = None
            s = symbol
            isError = False
            isMissing = False
            if (len(ground) > indexS):
                sGround = ground[indexS]

            if (indexS in arrError):
                isError = True
                if s == "*":
                    s = sGround
                    isMissing = True

            if isinstance(s, list):
                s = s[0]
            if s.find('TS:') != -1:
                ts = meter.TimeSignature(s[3:])
                if isError:
                    ts.color = errorColor
                if isMissing:
                    ts.color = missingColor
                measure.append(ts)
            if s.find('KS:') != -1:
                k = key.KeySignature(int(s[3:]))
                if isError:
                    k.color = errorColor
                if isMissing:
                    k.color = missingColor
                measure.append(k)
            if s.find('CL:') != -1:
                c = clef.clefFromString(str(s[3:]))
                if isError:
                    c.color = errorColor
                if isMissing:
                    c.color = missingColor
                measure.append(c)
            if s.find('N:') != -1:
                try:
                    if isinstance(symbol, list):
                        realDuration = symbol[1]
                        mytie = symbol[2]

                    sep = s.index("_")
                    duration = s[sep + 1:]
                    #                     if realDuration!=None:
                    #                         duration=realDuration
                    if (float(duration) > 0):
                        n = note.Note(s[2:sep], quarterLength=float(duration))
                        if isError:
                            n.color = errorColor
                        if isMissing:
                            n.color = missingColor
                        if mytie != "":
                            n.tie = tie.Tie(mytie)
                        measure.append(n)
                except:
                    print "error" + s

            if s.find('R:') != -1:
                try:
                    if isinstance(symbol, list):
                        realDuration = symbol[1]
                        mytie = symbol[2]
                    duration = s[2:]
                    #                     if realDuration!=None:
                    #                         duration=realDuration
                    n = note.Rest(quarterLength=float(duration))
                    if isError:
                        n.color = errorColor
                    if isMissing:
                        n.color = missingColor
                    measure.append(n)
                except:
                    print "error" + s

            if s.find('C:') != -1:
                notes = s.split("[:")
                cPitch = []
                for n in notes:
                    if n != 'C:':
                        sep = n.index("_")
                        duration = n[sep + 1:]
                        pitch = n[0:sep]
                        cPitch.append(pitch)
                c = chord.Chord(cPitch)
                c.duration.quarterLength = float(duration)
                if isError:
                    c.color = errorColor
                if isMissing:
                    c.color = missingColor
                measure.append(c)
            if s.find('!') != -1:

                if isinstance(symbol, list):
                    barType = symbol[1]
                    barRepeat = symbol[2]
                    if barType != "":
                        mybartype = bar.styleToMusicXMLBarStyle(barType)
                        myBar = bar.Barline(style=mybartype)
                        measure.rightBarline = myBar

                    if barRepeat != "":
                        myBar = bar.Repeat(direction=barRepeat)
                        if barRepeat == "start":
                            measure.leftBarline = myBar
                        if barRepeat == "end":
                            measure.rightBarline = myBar
                sPart.append(measure)
                measureIndex += 1
                measure = stream.Measure()
                measure.number = measureIndex
            indexS += 1

        sOut.append(sPart)
        return sOut