Exemplo n.º 1
0
def fromDiatonicScale(diatonicScaleObject):
    '''
    Return a complete musicxml of the DiatonicScale

    Overrides the general scale behavior to highlight
    the tonic and dominant.
    '''
    m = stream.Measure()
    for i in range(1, diatonicScaleObject._abstract.getDegreeMaxUnique() + 1):
        p = diatonicScaleObject.pitchFromDegree(i)
        n = note.Note()
        n.pitch = p
        if i == 1:
            n.addLyric(diatonicScaleObject.name)

        if p.name == diatonicScaleObject.getTonic().name:
            n.quarterLength = 4  # set longer
        elif p.name == diatonicScaleObject.getDominant().name:
            n.quarterLength = 2  # set longer
        else:
            n.quarterLength = 1
        m.append(n)
    m.timeSignature = m.bestTimeSignature()
    return fromMeasure(m)
Exemplo n.º 2
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()
Exemplo n.º 3
0
def song():
    """
    Simple helper function that returns "Wlazł kotek na płotek" music stream
    """
    s = stream.Stream()
    ts1 = meter.TimeSignature("3/4")

    p1 = stream.Part(number=1)
    p1.insert(0, ts1)
    p1.insert(0, key.KeySignature(0))
    p1.insert(0, clef.TrebleClef())
    m1 = stream.Measure(number=1)
    m1.append(note.Note("G"))
    m1.append(note.Note("E"))
    m1.append(note.Note("E", type="quarter"))
    m2 = stream.Measure(number=2)
    m2.append(note.Note("F"))
    m2.append(note.Note("D"))
    m2.append(note.Note("D"))
    m3 = stream.Measure(number=3)
    m3.append(note.Note("C", type="eighth"))
    m3.append(note.Note("E", type="eighth"))
    m3.append(note.Note("G", type="half"))
    p1.append(m1)
    p1.append(m2)
    p1.append(m3)
    m4 = stream.Measure(number=4)
    m4.append(note.Note("G"))
    m4.append(note.Note("E"))
    m4.append(note.Note("E", type="quarter"))
    m5 = stream.Measure(number=5)
    m5.append(note.Note("F"))
    m5.append(note.Note("D"))
    m5.append(note.Note("D"))
    m6 = stream.Measure(number=6)
    m6.append(note.Note("C4", type="eighth"))
    m6.append(note.Note("E4", type="eighth"))
    m6.append(note.Note("C4", type="half"))
    p1.append(m4)
    p1.append(m5)
    p1.append(m6)
    s.insert(0, p1)
    return s
Exemplo n.º 4
0
 def testMultipleInstruments(self):
     '''
     This is a score for two woodwind players both doubling on
     flute and oboe. They both switch to flute and then back to oboe.
     There are six m21 instruments to represent this, but the
     <score-instrument> tags need just four, since no
     musicXML <part> needs two oboes in it, etc., unless
     there is a patch change/MIDI instrument change.
     '''
     p1 = stream.Part([
         stream.Measure([instrument.Oboe(),
                         note.Note(type='whole')]),
         stream.Measure([instrument.Flute(),
                         note.Note(type='whole')]),
         stream.Measure([instrument.Oboe(),
                         note.Note(type='whole')]),
     ])
     p2 = stream.Part([
         stream.Measure([instrument.Oboe(),
                         note.Note(type='whole')]),
         stream.Measure([instrument.Flute(),
                         note.Note(type='whole')]),
         stream.Measure([instrument.Oboe(),
                         note.Note(type='whole')]),
     ])
     s = stream.Score([p1, p2])
     scEx = ScoreExporter(s)
     tree = scEx.parse()
     self.assertEqual(len(tree.findall('.//score-instrument')), 4)
     self.assertEqual(len(tree.findall('.//measure/note/instrument')), 6)
     self.assertEqual(
         tree.find('.//score-instrument').get('id'),
         tree.find('.//measure/note/instrument').get('id'))
     self.assertNotEqual(
         tree.find('.//score-instrument').get('id'),
         tree.findall('.//measure/note/instrument')[-1].get('id'))
Exemplo n.º 5
0
    def multiPartReduction(self, inStream, maxChords = 2, closedPosition = False, forceOctave = False):
        '''
        Return a multipart reduction of a stream.
        '''
        i = 0
        p = stream.Part()
        lastPitchedObject = None
        gobcM = inStream.parts[0].getElementsByClass('Measure')
        lenMeasures = len(gobcM)
        lastTs = None
        while i <= lenMeasures:
            mI = inStream.measure(i, ignoreNumbers=True)
            if len(mI.flat.notesAndRests) == 0:
                if i == 0:
                    pass
                else:
                    break
            else:
                m = stream.Measure()
                m.number = i

                mIchord = mI.chordify()
                newPart = self.reduceMeasureToNChords(mIchord, maxChords, weightAlgorithm=self.qlbsmpConsonance, trimBelow = 0.3)
                #newPart.show('text')
                cLast = None
                cLastEnd = 0.0
                for cEl in newPart:
                    cElCopy = copy.deepcopy(cEl)
                    if 'Chord' in cEl.classes:
                        if closedPosition is not False:
                            if forceOctave is not False:
                                cElCopy.closedPosition(forceOctave = forceOctave, inPlace = True)
                            else:
                                cElCopy.closedPosition(inPlace=True)
                            cElCopy.removeRedundantPitches(inPlace=True)
                    newOffset = cEl.getOffsetBySite(newPart)
                    
                    # extend over gaps
                    if cLast is not None:
                        if round(newOffset - cLastEnd, 6) != 0.0:
                            cLast.quarterLength += newOffset - cLastEnd
                    cLast = cElCopy
                    cLastEnd = newOffset + cElCopy.quarterLength
                    m._insertCore(newOffset, cElCopy)
                
                tsContext = mI.parts[0].getContextByClass('TimeSignature')
                if tsContext is not None:
                    if round(tsContext.barDuration.quarterLength - cLastEnd, 6) != 0.0:
                        cLast.quarterLength += tsContext.barDuration.quarterLength - cLastEnd
                
                
                m._elementsChanged()

                # add ties
                if lastPitchedObject is not None:
                    firstPitched = m[0]
                    if lastPitchedObject.isNote and firstPitched.isNote:
                        if lastPitchedObject.pitch == firstPitched.pitch:
                            lastPitchedObject.tie = tie.Tie("start")
                    elif lastPitchedObject.isChord and firstPitched.isChord:
                        if len(lastPitchedObject) == len(firstPitched):
                            allSame = True
                            for pitchI in range(len(lastPitchedObject)):
                                if lastPitchedObject.pitches[pitchI] != firstPitched.pitches[pitchI]:
                                    allSame = False
                            if allSame is True:
                                lastPitchedObject.tie = tie.Tie('start')
                lastPitchedObject = m[-1]

                sourceMeasureTs = mI.parts[0].getElementsByClass('Measure')[0].timeSignature
                if sourceMeasureTs != lastTs:
                    m.timeSignature = copy.deepcopy(sourceMeasureTs)
                    lastTs = sourceMeasureTs

                p._appendCore(m)
            if self.printDebug == True:
                print i, " ",
                if i % 20 == 0 and i != 0:
                    print ""
            i += 1
        p._elementsChanged()
        p.getElementsByClass('Measure')[0].insert(0, p.bestClef(allowTreble8vb=True))
        p.makeNotation(inPlace=True)
        return p
Exemplo n.º 6
0
    def reduceThisMeasure(self, mI, measureIndex, maxChords, closedPosition,
                          forceOctave):
        m = stream.Measure()
        m.number = measureIndex

        mIchord = mI.chordify()
        newPart = self.reduceMeasureToNChords(
            mIchord,
            maxChords,
            weightAlgorithm=self.qlbsmpConsonance,
            trimBelow=0.3)
        #newPart.show('text')
        cLast = None
        cLastEnd = 0.0
        for cEl in newPart:
            cElCopy = copy.deepcopy(cEl)
            if 'Chord' in cEl.classes and closedPosition is not False:
                if forceOctave is not False:
                    cElCopy.closedPosition(forceOctave=forceOctave,
                                           inPlace=True)
                else:
                    cElCopy.closedPosition(inPlace=True)
                cElCopy.removeRedundantPitches(inPlace=True)
            newOffset = cEl.getOffsetBySite(newPart)

            # extend over gaps
            if cLast is not None:
                if round(newOffset - cLastEnd, 6) != 0.0:
                    cLast.quarterLength += newOffset - cLastEnd
            cLast = cElCopy
            cLastEnd = newOffset + cElCopy.quarterLength
            m._insertCore(newOffset, cElCopy)

        tsContext = mI.parts[0].getContextByClass('TimeSignature')
        if tsContext is not None:
            if round(tsContext.barDuration.quarterLength - cLastEnd, 6) != 0.0:
                cLast.quarterLength += tsContext.barDuration.quarterLength - cLastEnd

        m.elementsChanged()

        # add ties
        if self._lastPitchedObject is not None:
            firstPitched = m[0]
            if self._lastPitchedObject.isNote and firstPitched.isNote:
                if self._lastPitchedObject.pitch == firstPitched.pitch:
                    self._lastPitchedObject.tie = tie.Tie("start")
            elif self._lastPitchedObject.isChord and firstPitched.isChord:
                if len(self._lastPitchedObject) == len(firstPitched):
                    allSame = True
                    for pitchI in range(len(self._lastPitchedObject)):
                        if (self._lastPitchedObject.pitches[pitchI] !=
                                firstPitched.pitches[pitchI]):
                            allSame = False
                    if allSame is True:
                        self._lastPitchedObject.tie = tie.Tie('start')
        self._lastPitchedObject = m[-1]

        sourceMeasureTs = mI.parts[0].getElementsByClass(
            'Measure')[0].timeSignature
        if sourceMeasureTs != self._lastTs:
            m.timeSignature = copy.deepcopy(sourceMeasureTs)
            self._lastTs = sourceMeasureTs

        return m
Exemplo n.º 7
0
def makeTies(
    s,
    meterStream=None,
    inPlace=True,
    displayTiedAccidentals=False,
    ):
    '''
    Given a stream containing measures, examine each element in the
    Stream. If the elements duration extends beyond the measure's boundary,
    create a tied entity, placing the split Note in the next Measure.

    Note that this method assumes that there is appropriate space in the
    next Measure: this will not shift Note objects, but instead allocate
    them evenly over barlines. Generally, makeMeasures is called prior to
    calling this method.

    If `inPlace` is True, this is done in-place;
    if `inPlace` is False, this returns a modified deep copy.

    ::

        >>> from music21 import stream

    ::

        >>> d = stream.Stream()
        >>> n = note.Note()
        >>> n.quarterLength = 12
        >>> d.repeatAppend(n, 10)
        >>> d.repeatInsert(n, [x+.5 for x in range(10)])
        >>> x = d.makeMeasures()
        >>> x = x.makeTies()

    OMIT_FROM_DOCS
    TODO: inPlace should be False
    TODO: inPlace = True should return None
    TODO: take a list of clases to act as filter on what elements are tied.

    configure ".previous" and ".next" attributes
    '''
    from music21 import stream

    #environLocal.printDebug(['calling Stream.makeTies()'])

    if not inPlace:  # make a copy
        returnObj = copy.deepcopy(s)
    else:
        returnObj = s
    if len(returnObj) == 0:
        raise stream.StreamException('cannot process an empty stream')

    # get measures from this stream
    measureStream = returnObj.getElementsByClass('Measure')
    if len(measureStream) == 0:
        raise stream.StreamException(
            'cannot process a stream without measures')

    #environLocal.printDebug([
    #    'makeTies() processing measureStream, length', measureStream,
    #    len(measureStream)])

    # may need to look in activeSite if no time signatures are found
    # presently searchContext is False to save time
    if meterStream is None:
        meterStream = returnObj.getTimeSignatures(sortByCreationTime=True,
                        searchContext=False)

    mCount = 0
    lastTimeSignature = None
    while True:
        # update measureStream on each iteration,
        # as new measure may have been added to the returnObj stream
        measureStream = returnObj.getElementsByClass('Measure')
        if mCount >= len(measureStream):
            break  # reached the end of all measures available or added
        # get the current measure to look for notes that need ties
        m = measureStream[mCount]
        if m.timeSignature is not None:
            lastTimeSignature = m.timeSignature

        # get next measure; we may not need it, but have it ready
        if mCount + 1 < len(measureStream):
            mNext = measureStream[mCount + 1]
            mNextAdd = False  # already present; do not append
        else:  # create a new measure
            mNext = stream.Measure()
            # set offset to last offset plus total length
            moffset = m.getOffsetBySite(measureStream)
            if lastTimeSignature is not None:
                mNext.offset = (moffset +
                                lastTimeSignature.barDuration.quarterLength)
            else:
                mNext.offset = moffset
            if len(meterStream) == 0:  # in case no meters are defined
                ts = meter.TimeSignature()
                ts.load('%s/%s' % (defaults.meterNumerator,
                    defaults.meterDenominatorBeatType))
            else:  # get the last encountered meter
                ts = meterStream.getElementAtOrBefore(mNext.offset)
            # only copy and assign if not the same as the last
            if lastTimeSignature is not None \
                and not lastTimeSignature.ratioEqual(ts):
                mNext.timeSignature = copy.deepcopy(ts)
            # increment measure number
            mNext.number = m.number + 1
            mNextAdd = True  # new measure, needs to be appended

        if mNext.hasVoices():
            mNextHasVoices = True
        else:
            mNextHasVoices = False

        #environLocal.printDebug([
        #    'makeTies() dealing with measure', m, 'mNextAdd', mNextAdd])
        # for each measure, go through each element and see if its
        # duraton fits in the bar that contains it

        # if there are voices, we must look at voice id values to only
        # connect ties to components in the same voice, assuming there
        # are voices in the next measure
        try:
            mEnd = lastTimeSignature.barDuration.quarterLength
        except AttributeError:
            ts = m.getContextByClass('TimeSignature')
            if ts is not None:
                lastTimeSignature = ts
                mEnd = lastTimeSignature.barDuration.quarterLength
            else:
                mEnd = 4.0  # Default
        if m.hasVoices():
            bundle = m.voices
            mHasVoices = True
        else:
            bundle = [m]
            mHasVoices = False
        # bundle components may be voices, or just a measure
        for v in bundle:
            for e in v:
                #environLocal.printDebug([
                #    'Stream.makeTies() iterating over elements in measure',
                #    m, e])
                #if hasattr(e, 'duration') and e.duration is not None:
                if e.duration is not None:
                    # check to see if duration is within Measure
                    eOffset = e.getOffsetBySite(v)
                    eEnd = eOffset + e.duration.quarterLength
                    # assume end can be at boundary of end of measure
                    overshot = eEnd - mEnd
                    # only process if overshot is greater than a minimum
                    # 1/64 is 0.015625
                    if overshot > .001:
                        if eOffset >= mEnd:
                            raise stream.StreamException(
                                'element (%s) has offset %s within a measure '
                                'that ends at offset %s' % (e, eOffset, mEnd))

                        qLenBegin = mEnd - eOffset
                        e, eRemain = e.splitAtQuarterLength(qLenBegin,
                            retainOrigin=True,
                            displayTiedAccidentals=displayTiedAccidentals)

                        # manage bridging voices
                        if mNextHasVoices:
                            if mHasVoices:  # try to match voice id
                                dst = mNext.voices[v.id]
                            # src does not have voice, but dst does
                            else:  # place in top-most voice
                                dst = mNext.voices[0]
                        else:
                            # mNext has no voices but this one does
                            if mHasVoices:
                                # internalize all components in a voice
                                mNext.internalize(container=stream.Voice)
                                # place in first voice
                                dst = mNext.voices[0]
                            else:  # no voices in either
                                dst = mNext

                        #eRemain.activeSite = mNext
                        # manually set activeSite
                        # cannot use _insertCore here
                        dst.insert(0, eRemain)

                        # we are not sure that this element fits
                        # completely in the next measure, thus, need to
                        # continue processing each measure
                        if mNextAdd:
                            #environLocal.printDebug([
                            #    'makeTies() inserting mNext into returnObj',
                            #    mNext])
                            returnObj.insert(mNext.offset, mNext)
                    elif overshot > 0:
                        environLocal.printDebug([
                            'makeTies() found and skipping extremely small '
                            'overshot into next measure', overshot])
        mCount += 1
    del measureStream  # clean up unused streams
    # changes elements
    returnObj._elementsChanged()
    if not inPlace:
        return returnObj
    else:
        return None
Exemplo n.º 8
0
    def frontPadLine(self, thisStream):
        '''Pads a line with a bunch of rests at the
        front to make it the same length as the longest line
        
        
        >>> ts = meter.TimeSignature('1/4')
        >>> s1 = stream.Part([ts])
        >>> s1.repeatAppend(note.QuarterNote(), 4)
        >>> s2 = stream.Part([ts])
        >>> s2.repeatAppend(note.QuarterNote(), 2)
        >>> s3 = stream.Part([ts])
        >>> s3.repeatAppend(note.QuarterNote(), 1)
        >>> fiveExcelRows = [s1, s2, s3, '', '1/4']
        >>> ps = trecento.polyphonicSnippet.FrontPaddedSnippet(fiveExcelRows)
        >>> ps.frontPadLine(s2)
        >>> s2.show('text')
        {0.0} <music21.stream.Measure 1 offset=0.0>
            {0.0} <music21.clef.TrebleClef>
            {0.0} <music21.meter.TimeSignature 1/4>
            {0.0} <music21.note.Rest rest>
        {1.0} <music21.stream.Measure 2 offset=1.0>
            {0.0} <music21.note.Rest rest>
        {2.0} <music21.stream.Measure 3 offset=2.0>
            {0.0} <music21.note.Note C>
        {3.0} <music21.stream.Measure 4 offset=3.0>
            {0.0} <music21.note.Note C>
            {1.0} <music21.bar.Barline style=final>
            
        '''
        shortMeasures = int(self.measuresShort(thisStream))

        if (shortMeasures > 0):
            shortDuration = self.timeSig.barDuration
            offsetShift = shortDuration.quarterLength * shortMeasures
            hasMeasures = thisStream.hasMeasures()

            if hasMeasures:
                allM = thisStream.getElementsByClass('Measure')
                oldFirstM = allM[0]
                for m in allM:
                    m.number += shortMeasures
                    m.setOffsetBySite(
                        thisStream,
                        m.getOffsetBySite(thisStream) + offsetShift)
            else:
                for thisNote in thisStream.notesAndRests:
                    thisNote.setOffsetBySite(
                        thisStream,
                        thisNote.getOffsetBySite(thisStream) + offsetShift)

            for i in range(0, shortMeasures):
                newRest = note.Rest()
                newRest.duration = copy.deepcopy(shortDuration)
                newRest.transparent = True
                if hasMeasures:
                    m = stream.Measure()
                    m.number = 1 + i
                    m.append(newRest)
                    thisStream.insert(shortDuration.quarterLength * i, m)
                else:
                    thisStream.insert(shortDuration.quarterLength * i, newRest)
                if i == 0:
                    newRest.startTransparency = True
                elif i == (shortMeasures - 1):
                    newRest.stopTransparency = True

            if hasMeasures:
                newFirstM = thisStream.getElementsByClass('Measure')[0]
                oldFirstMEls = copy.copy(oldFirstM.elements)
                for n in oldFirstMEls:
                    if isinstance(n, note.GeneralNote):
                        pass
                    else:
                        nOffset = n.offset
                        oldFirstM.remove(n)
                        newFirstM.insert(nOffset, n)
Exemplo n.º 9
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 != 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 len(rbSpanners) == 0:
                        # 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 != 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 != 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._appendCore(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:
        if useMeasures:  # assume at start of measures
            p.getElementsByClass('Measure')[0].clef = p.flat.bestClef()
        else:
            p._insertCore(0, p.bestClef())

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

    if useMeasures and len(
            p.flat.getTimeSignatures(searchContext=False,
                                     returnDefault=False)) > 0:
        # call make beams for now; later, import beams
        #environLocal.printDebug(['abcToStreamPart: calling makeBeams'])
        try:
            p.makeBeams(inPlace=True)
        except meter.MeterException 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._insertCore(0, sp)
        rm.append(sp)
    # remove from original spanner bundle
    for sp in rm:
        spannerBundle.remove(sp)
    p.elementsChanged()
    return p
Exemplo n.º 10
0
    def testShowAllTypes(self):
        '''
        show all known types to display
        
        tests fromMusic21Object()
        '''
        from music21 import scale
        from music21 import chord
        from music21 import duration
        from music21 import dynamics
        from music21 import meter
        from music21 import pitch

        m = stream.Measure()
        n = note.Note("D#6")
        m.repeatAppend(n, 6)
        m.show()

        s = stream.Stream()
        s.repeatAppend(n, 6)
        s.show()

        s = stream.Score()
        s.repeatAppend(n, 6)
        s.show()

        s = stream.Score()
        p = stream.Part()
        p.repeatAppend(n, 6)
        p2 = stream.Part()
        p2.repeatAppend(n, 6)
        s.insert(0, p)
        s.insert(0, p2)
        s.show()
        #emptyStream
        s = stream.Stream()
        s.show()
        p2.show()

        n.show()

        c = chord.Chord(['C3', 'D4', 'E5'])
        c.show()

        r = note.Rest()
        r.show()

        p = pitch.Pitch()
        p.show()

        d = duration.Duration(2.0)
        d.show()

        #empty duration! shows blank 4/4 measure, maybe with default rest.
        d = duration.Duration()
        d.show()

        mf = dynamics.Dynamic('mf')
        mf.show()

        cm = scale.MajorScale('C')
        cm.show()

        o = scale.OctatonicScale("C#4")
        o.show()

        ts = meter.TimeSignature('3/4')
        ts.show()
Exemplo n.º 11
0
# -*- coding: utf-8 -*-
from music21 import stream, note, clef

if __name__ == '__main__':
    p = stream.Part()
    p2 = stream.Part()
    m1 = stream.Measure()
    m2 = stream.Measure()
    m1.insert(0, note.Note("C5", type="whole"))
    m2.insert(0, note.Note("D3", type="whole"))
    m1.insert(0, clef.TrebleClef())
    m2.insert(0, clef.BassClef())
    p.insert(0, m1)
    p2.insert(0, m2)
    s = stream.Score()
    s.insert(0, p)
    s.insert(0, p2)
    s.show('vexflow')
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
#--------------------------------------------------------------------------------------------------

from music21 import stream, note, meter, key, clef

# Everything in the Measure should be invisible... we have only one Rest and one
# TimeSignature
invisibility_1 = stream.Measure()
invisibility_1.append(meter.TimeSignature('4/4'))
invisibility_1.append(note.Rest(quarterLength=4.0))
invisibility_1.lily_invisible = True

# Everything in the Measure should be invisible... we have a Rest, a
# TimeSignature, and a KeySignature
invisibility_2 = stream.Measure()
invisibility_2.append(meter.TimeSignature('4/4'))
invisibility_2.append(key.KeySignature(5))
invisibility_2.append(note.Rest(quarterLength=4.0))
invisibility_2.lily_invisible = True

# Everything in the Measure should be invisible... we have a Rest, a
# TimeSignature, a KeySignature, and a Clef
invisibility_3 = stream.Measure()
Exemplo n.º 13
0
#
Logging.basicConfig(level=Logging.INFO)
Logging.warning('Watch out!')

aPart0 = drumsPart()
aPart0.metadata = metadata.Metadata()
aPart0.metadata.title = 'music21drumsnotes'
aPart0.metadata.composer = '*****@*****.**'

# add a dummy Instrument to avoid musecore warn
aInstrument = instrument.Instrument()
# aInstrument.midiChannel = 9, 10, whatever
aPart0.insert(aInstrument)
#

aMeasure0 = stream.Measure()
aMeasure0.append(Chord([Crash(), Kick()]))
aMeasure0.append(HiHat())
aMeasure0.append(Chord([HiHat(), Snare()]))
aMeasure0.append(HiHat())
aMeasure0.append(Chord([Ride(), Kick()]))
aMeasure0.append(HiHat())
aMeasure0.append(Chord([HiHat(), Snare()]))
aMeasure0.append(Chord([HiHat(), Kick()]))
aPart0.append(aMeasure0)

aMeasure0 = stream.Measure()
aMeasure0.append(Chord([HiHat(), Kick()]))
aMeasure0.append(HiHat())
aMeasure0.append(Chord([HiHat(), Snare()]))
aMeasure0.append(Chord([HiHat(), Kick()]))
Exemplo n.º 14
0
    def test_getBeams_offset(self):
        '''
        Test getting Beams from a Measure that has an anacrusis that makes the
        first note not beamed.
        '''
        m = stream.Measure()
        m.repeatAppend(note.Note(type='eighth'), 5)
        ts = TimeSignature('2/2')

        beams = ts.getBeams(m, measureStartOffset=1.5)
        self.assertIsNone(beams[0])
        for b in beams[1:]:
            self.assertIsNotNone(b)
        match = '''[None,
        <music21.beam.Beams <music21.beam.Beam 1/start>>,
        <music21.beam.Beams <music21.beam.Beam 1/continue>>,
        <music21.beam.Beams <music21.beam.Beam 1/continue>>,
        <music21.beam.Beams <music21.beam.Beam 1/stop>>]'''
        self.assertTrue(common.whitespaceEqual(str(beams), match))

        m.append(note.Note(type='eighth'))
        beams = ts.getBeams(m, measureStartOffset=1.0)
        match = '''[<music21.beam.Beams <music21.beam.Beam 1/start>>,
        <music21.beam.Beams <music21.beam.Beam 1/stop>>,
        <music21.beam.Beams <music21.beam.Beam 1/start>>,
        <music21.beam.Beams <music21.beam.Beam 1/continue>>,
        <music21.beam.Beams <music21.beam.Beam 1/continue>>,
        <music21.beam.Beams <music21.beam.Beam 1/stop>>]'''
        self.assertTrue(common.whitespaceEqual(str(beams), match), str(beams))

        m = stream.Measure()
        m.repeatAppend(note.Note(type='eighth'), 5)
        ts = TimeSignature('3/2')

        beams = ts.getBeams(m, measureStartOffset=3.5)
        match = '''[None,
        <music21.beam.Beams <music21.beam.Beam 1/start>>,
        <music21.beam.Beams <music21.beam.Beam 1/continue>>,
        <music21.beam.Beams <music21.beam.Beam 1/continue>>,
        <music21.beam.Beams <music21.beam.Beam 1/stop>>]'''
        self.assertTrue(common.whitespaceEqual(str(beams), match))


        m = stream.Measure()
        m.repeatAppend(note.Note(type='eighth'), 4)
        ts = TimeSignature('6/8')
        beams = ts.getBeams(m, measureStartOffset=1.0)
        match = '''[None,
        <music21.beam.Beams <music21.beam.Beam 1/start>>,
        <music21.beam.Beams <music21.beam.Beam 1/continue>>,
        <music21.beam.Beams <music21.beam.Beam 1/stop>>]'''
        self.assertTrue(common.whitespaceEqual(str(beams), match))

        m.append(note.Note(type='eighth'))
        beams = ts.getBeams(m, measureStartOffset=0.5)
        match = '''[<music21.beam.Beams <music21.beam.Beam 1/start>>,
        <music21.beam.Beams <music21.beam.Beam 1/stop>>,
        <music21.beam.Beams <music21.beam.Beam 1/start>>,
        <music21.beam.Beams <music21.beam.Beam 1/continue>>,
        <music21.beam.Beams <music21.beam.Beam 1/stop>>]'''
        self.assertTrue(common.whitespaceEqual(str(beams), match), str(beams))
Exemplo n.º 15
0
 def _buildOutputMeasure(self,
     closedPosition,
     forceOctave,
     i,
     inputMeasure,
     inputMeasureReduction,
     lastPitchedObject,
     lastTimeSignature,
     ):
     outputMeasure = stream.Measure()
     outputMeasure.number = i
     #inputMeasureReduction.show('text')
     cLast = None
     cLastEnd = 0.0
     for cEl in inputMeasureReduction:
         cElCopy = copy.deepcopy(cEl)
         if 'Chord' in cEl.classes:
             if closedPosition is not False:
                 if forceOctave is not False:
                     cElCopy.closedPosition(
                         forceOctave=forceOctave,
                         inPlace=True,
                         )
                 else:
                     cElCopy.closedPosition(inPlace=True)
                 cElCopy.removeRedundantPitches(inPlace=True)
         newOffset = cEl.getOffsetBySite(inputMeasureReduction)
         # extend over gaps
         if cLast is not None:
             if round(newOffset - cLastEnd, 6) != 0.0:
                 cLast.quarterLength += newOffset - cLastEnd
         cLast = cElCopy
         cLastEnd = newOffset + cElCopy.quarterLength
         outputMeasure._insertCore(newOffset, cElCopy)
     tsContext = inputMeasure.getContextByClass('TimeSignature')
     #tsContext = inputMeasure.parts[0].getContextByClass('TimeSignature')
     if tsContext is not None:
         if round(tsContext.barDuration.quarterLength - cLastEnd, 6) != 0.0:
             cLast.quarterLength += tsContext.barDuration.quarterLength - cLastEnd
     outputMeasure._elementsChanged()
     # add ties
     if lastPitchedObject is not None:
         firstPitched = outputMeasure[0]
         if lastPitchedObject.isNote and firstPitched.isNote:
             if lastPitchedObject.pitch == firstPitched.pitch:
                 lastPitchedObject.tie = tie.Tie("start")
         elif lastPitchedObject.isChord and firstPitched.isChord:
             if len(lastPitchedObject) == len(firstPitched):
                 allSame = True
                 for pitchI in range(len(lastPitchedObject)):
                     if lastPitchedObject.pitches[pitchI] != firstPitched.pitches[pitchI]:
                         allSame = False
                 if allSame is True:
                     lastPitchedObject.tie = tie.Tie('start')
     lastPitchedObject = outputMeasure[-1]
     #sourceMeasureTs = inputMeasure.parts[0].getElementsByClass('Measure')[0].timeSignature
     sourceMeasureTs = tsContext
     if sourceMeasureTs != lastTimeSignature:
         outputMeasure.timeSignature = copy.deepcopy(sourceMeasureTs)
         lastTimeSignature = sourceMeasureTs
     return lastPitchedObject, lastTimeSignature, outputMeasure
Exemplo n.º 16
0
        #s = corpus.parse('beethoven/opus18no1', 2).parts[0].measures(4,10)

        vfp = VexflowPickler()
        vfp.defaults[
            'm21URI'] = 'file:///Users/Cuthbert/git/music21j/src/music21'
        vfp.defaults[
            'requireURI'] = 'file:///Users/Cuthbert/git/music21j/ext/require/require.js'
        data = vfp.fromObject(s)
        fp = environLocal.getTempFile('.html')
        with open(fp, 'w') as f:
            f.write(data)
        environLocal.launch('vexflow', fp)


if __name__ == "__main__":
    import music21
    music21.mainTest(Test)

    from music21 import note, clef, meter
    s = stream.Measure()
    s.insert(0, clef.TrebleClef())
    s.insert(0, meter.TimeSignature('1/4'))
    n = note.Note()
    n.duration.quarterLength = 1 / 3.
    s.repeatAppend(n, 3)
    p = stream.Part()
    p.repeatAppend(s, 2)
    p.show('vexflow', local=True)

    #s.show('vexflow')
Exemplo n.º 17
0
        def createDoubleTrillMeasure():
            '''
            Returns a dictionary with the following keys

            returnDict = {
                "name": string,
                "midi": measure stream,
                "omr": measure stream,
                "expected": measure stream,
            }
            '''
            noteDuration = duration.Duration('quarter')

            # GAGA Trill
            trill1NoteDuration = duration.Duration(.25)
            n0 = note.Note("G")
            n0.duration = noteDuration
            n1 = note.Note("G")
            n1.duration = trill1NoteDuration
            n2 = note.Note("A")
            n2.duration = trill1NoteDuration
            trill1 = [n1, n2, deepcopy(n1), deepcopy(n2)]  # GAGA

            # CBCB Trill
            trill2NoteDuration = duration.Duration(.0625)
            n3 = note.Note("B3")  # omr
            n3.duration = noteDuration
            n4 = note.Note("B3")
            n4.duration = trill2NoteDuration
            n5 = note.Note("C")
            n5.duration = trill2NoteDuration
            trill2 = [n5, n4, deepcopy(n5), deepcopy(n4),
                      deepcopy(n5), deepcopy(n4), deepcopy(n5), deepcopy(n4)]

            midiMeasure = stream.Measure()
            midiMeasure.append(trill1)
            midiMeasure.append(trill2)

            omrMeasure = stream.Measure()
            omrMeasure.append([n0, n3])

            expectedFixedOmrMeasure = stream.Measure()
            n0WithTrill = deepcopy(n0)
            n0Trill = expressions.Trill()
            n0Trill.size = interval.Interval('m-2')
            n0Trill.quarterLength = trill1NoteDuration.quarterLength
            n0WithTrill.expressions.append(n0Trill)
            n1WithTrill = deepcopy(n3)
            n1Trill = expressions.Trill()
            n1Trill.size = interval.Interval('M2')
            n1Trill.quarterLength = trill2NoteDuration.quarterLength
            n1WithTrill.expressions.append(n0Trill)
            expectedFixedOmrMeasure.append([n0WithTrill, n1WithTrill])

            returnDict = {
                "name": "Double Trill Measure",
                "midi": midiMeasure,
                "omr": omrMeasure,
                "expected": expectedFixedOmrMeasure,
            }
            return returnDict
Exemplo n.º 18
0
    def prepStream(self):
        '''
        Prepares a music21 stream for the harmonic analysis to go into.
        Specifically: creates the score, part, and measure streams,
        as well as some (the available) metadata based on the original TSV data.
        Works like the .template() method,
        except that we don't have a score to base the template on as such.
        '''

        s = stream.Score()
        p = stream.Part()

        s.insert(0, metadata.Metadata())

        firstEntry = self.chordList[0]  # Any entry will do
        s.metadata.opusNumber = firstEntry.op
        s.metadata.number = firstEntry.no
        s.metadata.movementNumber = firstEntry.mov
        s.metadata.title = 'Op' + firstEntry.op + '_No' + firstEntry.no + '_Mov' + firstEntry.mov

        startingKeySig = str(self.chordList[0].global_key)
        ks = key.Key(startingKeySig)
        p.insert(0, ks)

        currentTimeSig = str(self.chordList[0].timesig)
        ts = meter.TimeSignature(currentTimeSig)
        p.insert(0, ts)

        currentMeasureLength = ts.barDuration.quarterLength

        currentOffset = 0

        previousMeasure = self.chordList[0].measure - 1  # Covers pickups
        for entry in self.chordList:
            if entry.measure == previousMeasure:
                continue
            elif entry.measure != previousMeasure + 1:  # Not every measure has a chord change.
                for mNo in range(previousMeasure + 1, entry.measure):
                    m = stream.Measure(number=mNo)
                    m.offset = currentOffset + currentMeasureLength
                    p.insert(m)

                    currentOffset = m.offset
                    previousMeasure = mNo
            else:  # entry.measure = previousMeasure + 1
                m = stream.Measure(number=entry.measure)
                m.offset = entry.totbeat
                p.insert(m)
                if entry.timesig != currentTimeSig:
                    newTS = meter.TimeSignature(entry.timesig)
                    m.insert(entry.beat - 1, newTS)

                    currentTimeSig = entry.timesig
                    currentMeasureLength = newTS.barDuration.quarterLength

                previousMeasure = entry.measure
                currentOffset = entry.totbeat

        s.append(p)

        self.preparedStream = s

        return s
Exemplo n.º 19
0
def makeTies(
    s,
    meterStream=None,
    inPlace=True,
    displayTiedAccidentals=False,
):
    '''
    Given a stream containing measures, examine each element in the
    Stream. If the elements duration extends beyond the measure's boundary,
    create a tied entity, placing the split Note in the next Measure.

    Note that this method assumes that there is appropriate space in the
    next Measure: this will not shift Note objects, but instead allocate
    them evenly over barlines. Generally, makeMeasures is called prior to
    calling this method.

    If `inPlace` is True, this is done in-place;
    if `inPlace` is False, this returns a modified deep copy.

    Put a 12-quarter-note-long note into a Stream w/ 4/4 as the duration.

    >>> d = stream.Stream()
    >>> d.insert(0, meter.TimeSignature('4/4'))
    >>> n = note.Note('C4')
    >>> n.quarterLength = 12
    >>> d.insert(0, n)
    >>> d.show('text')
    {0.0} <music21.meter.TimeSignature 4/4>
    {0.0} <music21.note.Note C>

    After running makeMeasures, we get nice measures, a clef, but only one
    way-too-long note in Measure 1:
    
    >>> x = d.makeMeasures()
    >>> x.show('text')
    {0.0} <music21.stream.Measure 1 offset=0.0>
        {0.0} <music21.clef.TrebleClef>
        {0.0} <music21.meter.TimeSignature 4/4>
        {0.0} <music21.note.Note C>
    {4.0} <music21.stream.Measure 2 offset=4.0>
    <BLANKLINE>
    {8.0} <music21.stream.Measure 3 offset=8.0>
        {0.0} <music21.bar.Barline style=final>
    >>> n2 = x.measure(1).notes[0]
    >>> n2.duration.quarterLength
    12.0    
    >>> n2 is n
    False
    
    But after running makeTies, all is good:
    
    >>> x.makeTies(inPlace=True)
    >>> x.show('text')
    {0.0} <music21.stream.Measure 1 offset=0.0>
        {0.0} <music21.clef.TrebleClef>
        {0.0} <music21.meter.TimeSignature 4/4>
        {0.0} <music21.note.Note C>
    {4.0} <music21.stream.Measure 2 offset=4.0>
        {0.0} <music21.note.Note C>
    {8.0} <music21.stream.Measure 3 offset=8.0>
        {0.0} <music21.note.Note C>
        {4.0} <music21.bar.Barline style=final>
    >>> m = x.measure(1).notes[0]
    >>> m.duration.quarterLength
    4.0
    >>> m is n
    False
    >>> m.tie
    <music21.tie.Tie start>
    >>> x.measure(2).notes[0].tie
    <music21.tie.Tie continue>
    >>> x.measure(3).notes[0].tie
    <music21.tie.Tie stop>
        
    Same experiment, but with rests:
    
    >>> d = stream.Stream()
    >>> d.insert(0, meter.TimeSignature('4/4'))
    >>> r = note.Rest()
    >>> r.quarterLength = 12
    >>> d.insert(0, r)
    >>> x = d.makeMeasures()
    >>> x.makeTies(inPlace = True)
    >>> x.show('text')
    {0.0} <music21.stream.Measure 1 offset=0.0>
        {0.0} <music21.clef.TrebleClef>
        {0.0} <music21.meter.TimeSignature 4/4>
        {0.0} <music21.note.Rest rest>
    {4.0} <music21.stream.Measure 2 offset=4.0>
        {0.0} <music21.note.Rest rest>
    {8.0} <music21.stream.Measure 3 offset=8.0>
        {0.0} <music21.note.Rest rest>
        {4.0} <music21.bar.Barline style=final>        

    Notes: uses base.Music21Object.splitAtQuarterLength() once it has figured out
    what to split.

    OMIT_FROM_DOCS
    TODO: inPlace should be False
    TODO: take a list of clases to act as filter on what elements are tied.

    configure ".previous" and ".next" attributes
    '''
    from music21 import stream

    #environLocal.printDebug(['calling Stream.makeTies()'])

    if not inPlace:  # make a copy
        returnObj = copy.deepcopy(s)
    else:
        returnObj = s
    if len(returnObj) == 0:
        raise stream.StreamException('cannot process an empty stream')

    # get measures from this stream
    measureStream = returnObj.getElementsByClass('Measure')
    if len(measureStream) == 0:
        raise stream.StreamException(
            'cannot process a stream without measures')

    #environLocal.printDebug([
    #    'makeTies() processing measureStream, length', measureStream,
    #    len(measureStream)])

    # may need to look in activeSite if no time signatures are found
    # presently searchContext is False to save time
    if meterStream is None:
        meterStream = returnObj.getTimeSignatures(sortByCreationTime=True,
                                                  searchContext=False)

    mCount = 0
    lastTimeSignature = None

    while True:  # TODO: find a way to avoid "while True"
        # update measureStream on each iteration,
        # as new measure may have been added to the returnObj stream
        measureStream = returnObj.getElementsByClass('Measure').stream()
        if mCount >= len(measureStream):
            break  # reached the end of all measures available or added
        # get the current measure to look for notes that need ties
        m = measureStream[mCount]
        if m.timeSignature is not None:
            lastTimeSignature = m.timeSignature

        # get next measure; we may not need it, but have it ready
        if mCount + 1 < len(measureStream):
            mNext = measureStream[mCount + 1]
            mNextAdd = False  # already present; do not append
        else:  # create a new measure
            mNext = stream.Measure()
            # set offset to last offset plus total length
            moffset = measureStream.elementOffset(m)
            if lastTimeSignature is not None:
                mNext.offset = (moffset +
                                lastTimeSignature.barDuration.quarterLength)
            else:
                mNext.offset = moffset
            if len(meterStream) == 0:  # in case no meters are defined
                ts = meter.TimeSignature()
                ts.load('%s/%s' % (defaults.meterNumerator,
                                   defaults.meterDenominatorBeatType))
            else:  # get the last encountered meter
                ts = meterStream.getElementAtOrBefore(mNext.offset)
            # only copy and assign if not the same as the last
            if (lastTimeSignature is not None
                    and not lastTimeSignature.ratioEqual(ts)):
                mNext.timeSignature = copy.deepcopy(ts)
            # increment measure number
            mNext.number = m.number + 1
            mNextAdd = True  # new measure, needs to be appended

        if mNext.hasVoices():
            mNextHasVoices = True
        else:
            mNextHasVoices = False

        #environLocal.printDebug([
        #    'makeTies() dealing with measure', m, 'mNextAdd', mNextAdd])
        # for each measure, go through each element and see if its
        # duraton fits in the bar that contains it

        # if there are voices, we must look at voice id values to only
        # connect ties to components in the same voice, assuming there
        # are voices in the next measure
        try:
            mEnd = lastTimeSignature.barDuration.quarterLength
        except AttributeError:
            ts = m.getContextByClass('TimeSignature')
            if ts is not None:
                lastTimeSignature = ts
                mEnd = lastTimeSignature.barDuration.quarterLength
            else:
                mEnd = 4.0  # Default
        if m.hasVoices():
            bundle = m.voices
            mHasVoices = True
        else:
            bundle = [m]
            mHasVoices = False
        # bundle components may be voices, or just a measure
        for v in bundle:
            for e in v:
                #environLocal.printDebug([
                #    'Stream.makeTies() iterating over elements in measure',
                #    m, e])
                #if hasattr(e, 'duration') and e.duration is not None:
                if e.duration is not None:
                    # check to see if duration is within Measure
                    eOffset = v.elementOffset(e)
                    eEnd = opFrac(eOffset + e.duration.quarterLength)
                    # assume end can be at boundary of end of measure
                    overshot = eEnd - mEnd

                    if overshot > 0:
                        if eOffset >= mEnd:
                            continue  # skip elements that extend past measure boundary.


#                             raise stream.StreamException(
#                                 'element (%s) has offset %s within a measure '
#                                 'that ends at offset %s' % (e, eOffset, mEnd))

                        qLenBegin = mEnd - eOffset
                        e, eRemain = e.splitAtQuarterLength(
                            qLenBegin,
                            retainOrigin=True,
                            displayTiedAccidentals=displayTiedAccidentals)

                        # manage bridging voices
                        if mNextHasVoices:
                            if mHasVoices:  # try to match voice id
                                dst = mNext.voices[v.id]
                            # src does not have voice, but dst does
                            else:  # place in top-most voice
                                dst = mNext.voices[0]
                        else:
                            # mNext has no voices but this one does
                            if mHasVoices:
                                # internalize all components in a voice
                                mNext.internalize(container=stream.Voice)
                                # place in first voice
                                dst = mNext.voices[0]
                            else:  # no voices in either
                                dst = mNext

                        #eRemain.activeSite = mNext
                        # manually set activeSite
                        # cannot use _insertCore here
                        dst.insert(0, eRemain)

                        # we are not sure that this element fits
                        # completely in the next measure, thus, need to
                        # continue processing each measure
                        if mNextAdd:
                            #environLocal.printDebug([
                            #    'makeTies() inserting mNext into returnObj',
                            #    mNext])
                            returnObj.insert(mNext.offset, mNext)
                    elif overshot > 0:
                        environLocal.printDebug([
                            'makeTies() found and skipping extremely small '
                            'overshot into next measure', overshot
                        ])
        mCount += 1
    del measureStream  # clean up unused streams

    # changes elements
    returnObj.elementsChanged()
    if not inPlace:
        return returnObj
    else:
        return None
Exemplo n.º 20
0
from music21 import stream, instrument
from music21.note import Note

n = Note("A2", type='quarter')

drumPart = stream.Part()
drumPart.insert(0, instrument.Woodblock())

drumMeasure = stream.Measure()
drumMeasure.append(n)
drumPart.append(drumMeasure)

# This line actually generate the midi on my mac but there is no relevant software to read it and the opening fail
drumPart.show('midi')
Exemplo n.º 21
0
    def backPadLine(self, thisStream):
        '''
        Pads a Stream with a bunch of rests at the
        end to make it the same length as the longest line

        
        >>> ts = meter.TimeSignature('1/4')
        >>> s1 = stream.Part([ts])
        >>> s1.repeatAppend(note.QuarterNote(), 4)
        >>> s2 = stream.Part([ts])
        >>> s2.repeatAppend(note.QuarterNote(), 2)
        >>> s3 = stream.Part([ts])
        >>> s3.repeatAppend(note.QuarterNote(), 1)
        >>> fiveExcelRows = [s1, s2, s3, '', '1/4']
        >>> ps = trecento.polyphonicSnippet.Incipit(fiveExcelRows)
        >>> ps.backPadLine(s2)
        >>> s2.show('text')
        {0.0} <music21.stream.Measure 1 offset=0.0>
            {0.0} <music21.clef.TrebleClef>
            {0.0} <music21.meter.TimeSignature 1/4>
            {0.0} <music21.note.Note C>
        {1.0} <music21.stream.Measure 2 offset=1.0>
            {0.0} <music21.note.Note C>
        {2.0} <music21.stream.Measure 3 offset=2.0>
            {0.0} <music21.note.Rest rest>
        {3.0} <music21.stream.Measure 4 offset=3.0>
            {0.0} <music21.note.Rest rest>
            {1.0} <music21.bar.Barline style=final>
            
        '''
        shortMeasures = int(self.measuresShort(thisStream))

        if (shortMeasures > 0):
            shortDuration = self.timeSig.barDuration
            hasMeasures = thisStream.hasMeasures()
            if hasMeasures:
                lastMeasure = thisStream.getElementsByClass('Measure')[-1]
                maxMeasures = lastMeasure.number
                oldRightBarline = lastMeasure.rightBarline
                lastMeasure.rightBarline = None

            for i in range(0, shortMeasures):
                newRest = note.Rest()
                newRest.duration = copy.deepcopy(shortDuration)
                newRest.transparent = 1
                if hasMeasures:
                    m = stream.Measure()
                    m.number = maxMeasures + 1 + i
                    m.append(newRest)
                    thisStream.append(m)
                else:
                    thisStream.append(newRest)

                if i == 0:
                    newRest.startTransparency = 1
                elif i == (shortMeasures - 1):
                    newRest.stopTransparency = 1

            if hasMeasures:
                lastMeasure = thisStream.getElementsByClass('Measure')[-1]
                lastMeasure.rightBarline = oldRightBarline
Exemplo n.º 22
0
def objectToBraille(music21Obj: base.Music21Object,
                    *,
                    inPlace=False,
                    debug=False,
                    cancelOutgoingKeySig=True,
                    descendingChords=None,
                    dummyRestLength=None,
                    maxLineLength=40,
                    segmentBreaks=None,
                    showClefSigns=False,
                    showFirstMeasureNumber=True,
                    showHand=None,
                    showHeading=True,
                    showLongSlursAndTiesTogether: t.Optional[bool] = None,
                    showShortSlursAndTiesTogether=False,
                    slurLongPhraseWithBrackets=True,
                    suppressOctaveMarks=False,
                    upperFirstInNoteFingering=True,
                    ):
    '''
    Translates an arbitrary object to braille.

    >>> from music21.braille import translate
    >>> samplePart = converter.parse('tinynotation: 3/4 C4 D16 E F G# r4 e2.')
    >>> #_DOCS_SHOW samplePart.show()


        .. image:: images/objectToBraille.*
            :width: 700


    >>> print(translate.objectToBraille(samplePart))
    ⠀⠀⠀⠀⠀⠀⠀⠼⠉⠲⠀⠀⠀⠀⠀⠀⠀
    ⠼⠁⠀⠸⠹⠵⠋⠛⠩⠓⠧⠀⠐⠏⠄⠣⠅


    For normal users, you'll just call this, which starts a text editor:


    >>> #_DOCS_SHOW samplePart.show('braille')
    ⠀⠀⠀⠀⠀⠀⠀⠼⠉⠲⠀⠀⠀⠀⠀⠀⠀
    ⠼⠁⠀⠸⠹⠵⠋⠛⠩⠓⠧⠀⠐⠏⠄⠣⠅


    Other examples:


    >>> sampleNote = note.Note('C3')
    >>> print(translate.objectToBraille(sampleNote))
    ⠸⠹

    >>> sampleDynamic = dynamics.Dynamic('fff')
    >>> print(translate.objectToBraille(sampleDynamic))
    ⠜⠋⠋⠋

    >>> sample_voice = stream.Voice([note.Note()])
    >>> sample_measure = stream.Measure([sample_voice])
    >>> print(translate.objectToBraille(sample_measure))
    ⠀⠼⠁⠲⠀
    ⠼⠚⠀⠐⠹

    >>> empty_measure = stream.Measure()
    >>> print(translate.objectToBraille(empty_measure))
    ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠼⠙⠲⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
    ⠼⠚

    Not currently supported: generic `stream.Stream` objects or `stream.Voice` objects:

    >>> sample_generic_stream = stream.Stream([note.Note()])
    >>> translate.objectToBraille(sample_generic_stream)
    Traceback (most recent call last):
    music21.braille.translate.BrailleTranslateException: Stream cannot be translated to Braille.
    '''
    if isinstance(music21Obj, (stream.Opus, stream.Score, stream.Part, stream.Measure)):
        return streamToBraille(music21Obj,
                               inPlace=inPlace,
                               debug=debug,
                               cancelOutgoingKeySig=cancelOutgoingKeySig,
                               descendingChords=descendingChords,
                               dummyRestLength=dummyRestLength,
                               maxLineLength=maxLineLength,
                               segmentBreaks=segmentBreaks,
                               showClefSigns=showClefSigns,
                               showFirstMeasureNumber=showFirstMeasureNumber,
                               showHand=showHand,
                               showHeading=showHeading,
                               showLongSlursAndTiesTogether=showLongSlursAndTiesTogether,
                               showShortSlursAndTiesTogether=showShortSlursAndTiesTogether,
                               slurLongPhraseWithBrackets=slurLongPhraseWithBrackets,
                               suppressOctaveMarks=suppressOctaveMarks,
                               upperFirstInNoteFingering=upperFirstInNoteFingering,
                               )
    elif isinstance(music21Obj, stream.Stream):
        raise BrailleTranslateException('Stream cannot be translated to Braille.')
    else:
        music21Measure = stream.Measure()
        music21Measure.append(music21Obj)
        return measureToBraille(music21Measure,
                                inPlace=True,  # observe True!
                                debug=debug,
                                cancelOutgoingKeySig=cancelOutgoingKeySig,
                                descendingChords=descendingChords,
                                dummyRestLength=dummyRestLength,
                                maxLineLength=maxLineLength,
                                segmentBreaks=segmentBreaks,
                                showClefSigns=showClefSigns,
                                showFirstMeasureNumber=False,  # observe False!
                                showHand=showHand,
                                showHeading=False,  # observe False!
                                showLongSlursAndTiesTogether=showLongSlursAndTiesTogether,
                                showShortSlursAndTiesTogether=showShortSlursAndTiesTogether,
                                slurLongPhraseWithBrackets=slurLongPhraseWithBrackets,
                                suppressOctaveMarks=suppressOctaveMarks,
                                upperFirstInNoteFingering=upperFirstInNoteFingering,
                                )
Exemplo n.º 23
0
def makeMeasures(
    s,
    meterStream=None,
    refStreamOrTimeRange=None,
    searchContext=False,
    innerBarline=None,
    finalBarline='final',
    bestClef=False,
    inPlace=False,
    ):
    '''
    Takes a stream and places all of its elements into
    measures (:class:`~music21.stream.Measure` objects)
    based on the :class:`~music21.meter.TimeSignature` objects
    placed within
    the stream. If no TimeSignatures are found in the
    stream, a default of 4/4 is used.

    If `inPlace` is True, the original Stream is modified and lost
    if `inPlace` is False, this returns a modified deep copy.

    Many advanced features are available:

    (1) If a `meterStream` is given, the TimeSignatures in this
    stream are used instead of any found in the Stream.
    Alternatively, a single TimeSignature object
    can be provided in lieu of the stream. This feature lets you
    test out how a group of notes might be interpreted as measures
    in a number of different metrical schemes.

    (2) If `refStreamOrTimeRange` is provided, this Stream or List
    is used to give the span that you want to make measures for
    necessary to fill empty rests at the ends or beginnings of
    Streams, etc.  Say for instance you'd like to make a complete
    score from a short ossia section, then you might use another
    Part from the Score as a `refStreamOrTimeRange` to make sure
    that the appropriate measures of rests are added at either side.

    (3) If `innerBarline` is not None, the specified Barline object
    or string-specification of Barline style will be used to create
    Barline objects between every created Measure. The default is None.

    (4) If `finalBarline` is not None, the specified Barline object or
    string-specification of Barline style will be used to create a Barline
    objects at the end of the last Measure. The default is 'final'.

    The `searchContext` parameter determines whether or not context
    searches are used to find Clef and other notation objects.

    Here is a simple example of makeMeasures:

    A single measure of 4/4 is created by from a Stream
    containing only three quarter notes:

    ::

        >>> from music21 import articulations
        >>> from music21 import clef
        >>> from music21 import meter
        >>> from music21 import note
        >>> from music21 import stream

    ::

        >>> sSrc = stream.Stream()
        >>> sSrc.append(note.QuarterNote('C4'))
        >>> sSrc.append(note.QuarterNote('D4'))
        >>> sSrc.append(note.QuarterNote('E4'))
        >>> sMeasures = sSrc.makeMeasures()
        >>> sMeasures.show('text')
        {0.0} <music21.stream.Measure 1 offset=0.0>
            {0.0} <music21.clef.TrebleClef>
            {0.0} <music21.meter.TimeSignature 4/4>
            {0.0} <music21.note.Note C>
            {1.0} <music21.note.Note D>
            {2.0} <music21.note.Note E>
            {3.0} <music21.bar.Barline style=final>

    Notice that the last measure is incomplete -- makeMeasures
    does not fill up incomplete measures.

    We can also check that the measure created has
    the correct TimeSignature:

    ::

        >>> sMeasures[0].timeSignature
        <music21.meter.TimeSignature 4/4>

    Now let's redo this work in 2/4 by putting a TimeSignature
    of 2/4 at the beginning of the stream and rerunning
    makeMeasures. Now we will have two measures, each with
    correct measure numbers:

    ::

        >>> sSrc.insert(0.0, meter.TimeSignature('2/4'))
        >>> sMeasuresTwoFour = sSrc.makeMeasures()
        >>> sMeasuresTwoFour.show('text')
        {0.0} <music21.stream.Measure 1 offset=0.0>
            {0.0} <music21.clef.TrebleClef>
            {0.0} <music21.meter.TimeSignature 2/4>
            {0.0} <music21.note.Note C>
            {1.0} <music21.note.Note D>
        {2.0} <music21.stream.Measure 2 offset=2.0>
            {0.0} <music21.note.Note E>
            {1.0} <music21.bar.Barline style=final>

    Let us put 10 quarter notes in a Part.

    After we run makeMeasures, we will have
    3 measures of 4/4 in a new Part object. This experiment
    demonstrates that running makeMeasures does not
    change the type of Stream you are using:

    ::

        >>> sSrc = stream.Part()
        >>> n = note.Note('E-4')
        >>> n.quarterLength = 1
        >>> sSrc.repeatAppend(n, 10)
        >>> sMeasures = sSrc.makeMeasures()
        >>> len(sMeasures.getElementsByClass('Measure'))
        3
        >>> sMeasures.__class__.__name__
        'Part'

    Demonstrate what makeMeasures will do with inPlace is True:

    ::

        >>> sScr = stream.Stream()
        >>> sScr.insert(0, clef.TrebleClef())
        >>> sScr.insert(0, meter.TimeSignature('3/4'))
        >>> sScr.append(note.Note('C4', quarterLength = 3.0))
        >>> sScr.append(note.Note('D4', quarterLength = 3.0))
        >>> sScr.makeMeasures(inPlace = True)
        >>> sScr.show('text')
        {0.0} <music21.stream.Measure 1 offset=0.0>
            {0.0} <music21.clef.TrebleClef>
            {0.0} <music21.meter.TimeSignature 3/4>
            {0.0} <music21.note.Note C>
        {3.0} <music21.stream.Measure 2 offset=3.0>
            {0.0} <music21.note.Note D>
            {3.0} <music21.bar.Barline style=final>

    If after running makeMeasures you run makeTies, it will also split
    long notes into smaller notes with ties.  Lyrics and articulations
    are attached to the first note.  Expressions (fermatas,
    etc.) will soon be attached to the last note but this is not yet done:

    ::

        >>> p1 = stream.Part()
        >>> p1.append(meter.TimeSignature('3/4'))
        >>> longNote = note.Note("D#4")
        >>> longNote.quarterLength = 7.5
        >>> longNote.articulations = [articulations.Staccato()]
        >>> longNote.lyric = "hi"
        >>> p1.append(longNote)
        >>> partWithMeasures = p1.makeMeasures()
        >>> dummy = partWithMeasures.makeTies(inPlace = True)
        >>> partWithMeasures.show('text')
        {0.0} <music21.stream.Measure 1 offset=0.0>
            {0.0} <music21.clef.TrebleClef>
            {0.0} <music21.meter.TimeSignature 3/4>
            {0.0} <music21.note.Note D#>
        {3.0} <music21.stream.Measure 2 offset=3.0>
            {0.0} <music21.note.Note D#>
        {6.0} <music21.stream.Measure 3 offset=6.0>
            {0.0} <music21.note.Note D#>
            {1.5} <music21.bar.Barline style=final>

    ::

        >>> allNotes = partWithMeasures.flat.notes
        >>> allNotes[0].articulations
        [<music21.articulations.Staccato>]

    ::

        >>> allNotes[1].articulations
        []

    ::

        >>> allNotes[2].articulations
        []

    ::

        >>> [allNotes[0].lyric, allNotes[1].lyric, allNotes[2].lyric]
        ['hi', None, None]

    '''
    from music21 import spanner
    from music21 import stream

    #environLocal.printDebug(['calling Stream.makeMeasures()'])

    # the srcObj shold not be modified or chagned
    # removed element copying below and now making a deepcopy of entire stream
    # must take a flat representation, as we need to be able to
    # position components, and sub-streams might hide elements that
    # should be contained

    if s.hasVoices():
        #environLocal.printDebug(['make measures found voices'])
        # cannot make flat here, as this would destroy stream partitions
        srcObj = copy.deepcopy(s.sorted)
        voiceCount = len(srcObj.voices)
    else:
        #environLocal.printDebug(['make measures found no voices'])
        # take flat and sorted version
        srcObj = copy.deepcopy(s.flat.sorted)
        voiceCount = 0

    #environLocal.printDebug([
    #    'Stream.makeMeasures(): passed in meterStream', meterStream,
    #    meterStream[0]])

    # may need to look in activeSite if no time signatures are found
    if meterStream is None:
        # get from this Stream, or search the contexts
        meterStream = srcObj.flat.getTimeSignatures(returnDefault=True,
                        searchContext=False,
                        sortByCreationTime=False)
        #environLocal.printDebug([
        #    'Stream.makeMeasures(): found meterStream', meterStream[0]])
    # if meterStream is a TimeSignature, use it
    elif isinstance(meterStream, meter.TimeSignature):
        ts = meterStream
        meterStream = stream.Stream()
        meterStream.insert(0, ts)

    #assert len(meterStream), 1

    #environLocal.printDebug([
    #    'makeMeasures(): meterStream', 'meterStream[0]', meterStream[0],
    #    'meterStream[0].offset',  meterStream[0].offset,
    #    'meterStream.elements[0].activeSite',
    #    meterStream.elements[0].activeSite])

    # need a SpannerBundle to store any found spanners and place
    # at the part level
    spannerBundleAccum = spanner.SpannerBundle()

    # get a clef for the entire stream; this will use bestClef
    # presently, this only gets the first clef
    # may need to store a clefStream and access changes in clefs
    # as is done with meterStream
    #clefStream = srcObj.getClefs(searchActiveSite=True,
    #                searchContext=searchContext,
    #                returnDefault=True)
    #clefObj = clefStream[0]
    #del clefStream
    clefObj = srcObj.getContextByClass('Clef') 
    if clefObj is None:
        clefObj = srcObj.bestClef()

    #environLocal.printDebug([
    #    'makeMeasures(): first clef found after copying and flattening',
    #    clefObj])

    # for each element in stream, need to find max and min offset
    # assume that flat/sorted options will be set before procesing
    # list of start, start+dur, element
    offsetMap = srcObj.offsetMap
    #environLocal.printDebug(['makeMeasures(): offset map', offsetMap])
    #offsetMap.sort() not necessary; just get min and max
    if len(offsetMap) > 0:
        oMax = max([x['endTime'] for x in offsetMap])
    else:
        oMax = 0

    # if a ref stream is provided, get highest time from there
    # only if it is greater thant the highest time yet encountered
    if refStreamOrTimeRange is not None:
        if isinstance(refStreamOrTimeRange, stream.Stream):
            refStreamHighestTime = refStreamOrTimeRange.highestTime
        else:  # assume its a list
            refStreamHighestTime = max(refStreamOrTimeRange)
        if refStreamHighestTime > oMax:
            oMax = refStreamHighestTime

    # create a stream of measures to contain the offsets range defined
    # create as many measures as needed to fit in oMax
    post = s.__class__()
    post.derivation.origin = s
    post.derivation.method = 'makeMeasures'

    o = 0.0  # initial position of first measure is assumed to be zero
    measureCount = 0
    lastTimeSignature = None
    while True:
        m = stream.Measure()
        m.number = measureCount + 1
        #environLocal.printDebug([
        #    'handling measure', m, m.number, 'current offset value', o,
        #    meterStream._reprTextLine()])
        # get active time signature at this offset
        # make a copy and it to the meter
        thisTimeSignature = meterStream.getElementAtOrBefore(o)
        #environLocal.printDebug([
        #    'm.number', m.number, 'meterStream.getElementAtOrBefore(o)',
        #    meterStream.getElementAtOrBefore(o), 'lastTimeSignature',
        #    lastTimeSignature, 'thisTimeSignature', thisTimeSignature ])

        if thisTimeSignature is None and lastTimeSignature is None:
            raise stream.StreamException(
                'failed to find TimeSignature in meterStream; '
                'cannot process Measures')
        if thisTimeSignature is not lastTimeSignature \
            and thisTimeSignature is not None:
            lastTimeSignature = thisTimeSignature
            # this seems redundant
            #lastTimeSignature = meterStream.getElementAtOrBefore(o)
            m.timeSignature = copy.deepcopy(thisTimeSignature)
            #environLocal.printDebug(['assigned time sig', m.timeSignature])

        # only add a clef for the first measure when automatically
        # creating Measures; this clef is from getClefs, called above
        if measureCount == 0:
            m.clef = clefObj
            #environLocal.printDebug(
            #    ['assigned clef to measure', measureCount, m.clef])

        # add voices if necessary (voiceCount > 0)
        for voiceIndex in range(voiceCount):
            v = stream.Voice()
            v.id = voiceIndex  # id is voice index, starting at 0
            m._insertCore(0, v)

        # avoid an infinite loop
        if thisTimeSignature.barDuration.quarterLength == 0:
            raise stream.StreamException(
                'time signature {0!r} has no duration'.format(
                    thisTimeSignature))
        post._insertCore(o, m)  # insert measure
        # increment by meter length
        o += thisTimeSignature.barDuration.quarterLength
        if o >= oMax:  # may be zero
            break  # if length of this measure exceedes last offset
        else:
            measureCount += 1

    # populate measures with elements
    for ob in offsetMap:
        start, end, e, voiceIndex = (
            ob['offset'],
            ob['endTime'],
            ob['element'],
            ob['voiceIndex'],
            )

        #environLocal.printDebug(['makeMeasures()', start, end, e, voiceIndex])
        # iterate through all measures, finding a measure that
        # can contain this element

        # collect all spanners and move to outer Stream
        if e.isSpanner:
            spannerBundleAccum.append(e)
            continue

        match = False
        lastTimeSignature = None
        for i in range(len(post)):
            m = post[i]
            if m.timeSignature is not None:
                lastTimeSignature = m.timeSignature
            # get start and end offsets for each measure
            # seems like should be able to use m.duration.quarterLengths
            mStart = m.getOffsetBySite(post)
            mEnd = mStart + lastTimeSignature.barDuration.quarterLength
            # if elements start fits within this measure, break and use
            # offset cannot start on end
            if start >= mStart and start < mEnd:
                match = True
                #environLocal.printDebug([
                #    'found measure match', i, mStart, mEnd, start, end, e])
                break
        if not match:
            raise stream.StreamException(
                'cannot place element %s with start/end %s/%s '
                'within any measures' % (e, start, end))

        # find offset in the temporal context of this measure
        # i is the index of the measure that this element starts at
        # mStart, mEnd are correct
        oNew = start - mStart  # remove measure offset from element offset

        # insert element at this offset in the measure
        # not copying elements here!

        # in the case of a Clef, and possibly other measure attributes,
        # the element may have already been placed in this measure
        # we need to only exclude elements that are placed in the special
        # first position
        if m.clef is e:
            continue
        # do not accept another time signature at the zero position: this
        # is handled above
        if oNew == 0 and 'TimeSignature' in e.classes:
            continue

        #environLocal.printDebug(['makeMeasures()', 'inserting', oNew, e])
        # NOTE: cannot use _insertCore here for some reason
        if voiceIndex is None:
            m.insert(oNew, e)
        else:  # insert into voice specified by the voice index
            m.voices[voiceIndex].insert(oNew, e)

    # add found spanners to higher-level; could insert at zero
    for sp in spannerBundleAccum:
        post.append(sp)

    post._elementsChanged()

    # clean up temporary streams to avoid extra site accumulation
    del srcObj

    # set barlines if necessary
    lastIndex = len(post.getElementsByClass('Measure')) - 1
    for i, m in enumerate(post.getElementsByClass('Measure')):
        if i != lastIndex:
            if innerBarline not in ['regular', None]:
                m.rightBarline = innerBarline
        else:
            if finalBarline not in ['regular', None]:
                m.rightBarline = finalBarline
        if bestClef:
            m.clef = m.bestClef()  # may need flat for voices

    if not inPlace:
        return post  # returns a new stream populated w/ new measure streams
    else:  # clear the stored elements list of this Stream and repopulate
        # with Measures created above
        s._elements = []
        s._endElements = []
        s._elementsChanged()
        for e in post.sorted:
            # may need to handle spanners; already have s as site
            s.insert(e.getOffsetBySite(post), e)
Exemplo n.º 24
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
Exemplo n.º 25
0
    def expand(self, ts=None, ks=None):
        '''
        The meat of it all -- expand one rule completely and return a list of Measure objects.
        '''
        if ts is None:
            ts = meter.TimeSignature('4/4')
        if ks is None:
            ks = key.Key('C')
        measures = []

        lastRegularAtom = None
        lastChord = None

        for content, sep, numReps in self._measureGroups():
            lastChordIsInSameMeasure = False
            if sep == "$":
                if content not in self.parent.rules:
                    raise CTRuleException(
                        "Cannot expand rule {0} in {2}".format(content, self))
                rule = self.parent.rules[content]
                for i in range(numReps):
                    returnedMeasures = rule.expand(ts, ks)
                    self.insertKsTs(returnedMeasures[0], ts, ks)
                    for m in returnedMeasures:
                        tsEs = m.iter.getElementsByClass('TimeSignature')
                        for returnedTs in tsEs:
                            if returnedTs is not ts:
                                # the TS changed mid-rule; create a new one for return.
                                ts = copy.deepcopy(ts)

                    measures.extend(returnedMeasures)
            elif sep == "|":
                m = stream.Measure()
                atoms = content.split()
                # key/timeSig pass...
                regularAtoms = []
                for atom in atoms:
                    if atom.startswith('['):
                        atomContent = atom[1:-1]
                        if atomContent == '0':
                            ts = meter.TimeSignature('4/4')
                            # irregular meter.  Cannot fully represent;
                            #TODO: replace w/ senza misura when possible.

                        elif '/' in atomContent:  # only one key / ts per measure.
                            ts = meter.TimeSignature(atomContent)
                        else:
                            ks = key.Key(
                                key.convertKeyStringToMusic21KeyString(
                                    atomContent))

                    elif atom == '.':
                        if lastRegularAtom is None:
                            raise CTRuleException(" . w/o previous atom: %s" %
                                                  self)
                        regularAtoms.append(lastRegularAtom)
                    elif atom in ("", None):
                        pass
                    else:
                        regularAtoms.append(atom)
                        lastRegularAtom = atom
                numAtoms = len(regularAtoms)
                if numAtoms == 0:
                    continue  # maybe just ts and ks setting

                self.insertKsTs(m, ts, ks)

                atomLength = common.opFrac(ts.barDuration.quarterLength /
                                           numAtoms)
                for atom in regularAtoms:
                    if atom == 'R':
                        rest = note.Rest(quarterLength=atomLength)
                        lastChord = None
                        lastChordIsInSameMeasure = False
                        m.append(rest)
                    else:
                        atom = self.fixupChordAtom(atom)
                        rn = roman.RomanNumeral(atom, ks)
                        if self.isSame(rn,
                                       lastChord) and lastChordIsInSameMeasure:
                            lastChord.duration.quarterLength += atomLength
                            m.elementsChanged()
                        else:
                            rn.duration.quarterLength = atomLength
                            self.addOptionalTieAndLyrics(rn, lastChord)
                            lastChord = rn
                            lastChordIsInSameMeasure = True
                            m.append(rn)
                measures.append(m)
                for i in range(1, numReps):
                    measures.append(copy.deepcopy(m))
            else:
                environLocal.warn(
                    "Rule found without | or $, ignoring: '{0}','{1}': in {2}".
                    format(content, sep, self.text))
                #pass
        if len(measures) > 0:
            for m in measures:
                noteIter = m.recurse().notes
                if (noteIter
                        and (self.parent is None
                             or self.parent.labelSubsectionsOnScore is True)
                        and self.LHS != 'S'):
                    rn = noteIter[0]
                    lyricNum = len(rn.lyrics) + 1
                    rn.lyrics.append(note.Lyric(self.LHS, number=lyricNum))
                    break

        return measures
Exemplo n.º 26
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.
    '''
    if inputM21 == 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 = abcModule.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 != None:
                    dst.leftBarline = bLeft
                if mh.leftBarToken.isRepeatBracket():
                    # get any open spanners of RepeatBracket type
                    rbSpanners = spannerBundle.getByClassComplete(
                        'RepeatBracket', False)
                    # this indication is most likely an opening, as ABC does
                    # not encode second ending ending boundaries
                    # we can still check thought:
                    if len(rbSpanners) == 0:
                        # 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 != 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.getByClassComplete(
                        'RepeatBracket', False)
                    if len(rbSpanners) > 0:
                        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
        # in case need to transpose due to clef indication
        postTransposition = 0
        clefSet = False
        for t in mh.tokens:
            if isinstance(t, abcModule.ABCMetadata):
                if t.isMeter():
                    ts = t.getTimeSignatureObject()
                    if ts != None:  # can be None
                        # should append at the right position
                        if useMeasures:  # assume at start of measures
                            dst.timeSignature = ts
                        else:
                            dst._appendCore(ts)
                elif t.isKey():
                    ks = t.getKeySignatureObject()
                    if useMeasures:  # assume at start of measures
                        dst.keySignature = ks
                    else:
                        dst._appendCore(ks)
                    # check for clef information sometimes stored in key
                    clefObj, transposition = t.getClefObject()
                    if clefObj != None:
                        clefSet = False
                        #environLocal.printDebug(['found clef in key token:', t, clefObj, transposition])
                        if useMeasures:  # assume at start of measures
                            dst.clef = clefObj
                        else:
                            dst._appendCore(clefObj)
                        postTransposition = transposition
                elif t.isTempo():
                    mmObj = t.getMetronomeMarkObject()
                    dst._appendCore(mmObj)

            # as ABCChord is subclass of ABCNote, handle first
            elif isinstance(t, abcModule.ABCChord):
                # may have more than notes?
                pitchNameList = []
                accStatusList = []  # accidental display status list
                for tSub in t.subTokens:
                    # notes are contained as subtokens are already parsed
                    if isinstance(tSub, abcModule.ABCNote):
                        pitchNameList.append(tSub.pitchName)
                        accStatusList.append(tSub.accidentalDisplayStatus)
                c = chord.Chord(pitchNameList)
                c.quarterLength = t.quarterLength
                # adjust accidental display for each contained pitch
                for pIndex in range(len(c.pitches)):
                    if c.pitches[pIndex].accidental == None:
                        continue
                    c.pitches[pIndex].accidental.displayStatus = accStatusList[
                        pIndex]
                dst._appendCore(c)

                #ql += t.quarterLength

            elif isinstance(t, abcModule.ABCNote):
                if t.isRest:
                    n = note.Rest()
                else:
                    n = note.Note(t.pitchName)
                    if n.accidental != None:
                        n.accidental.displayStatus = t.accidentalDisplayStatus

                n.quarterLength = t.quarterLength

                # start or end a tie at note n
                if t.tie is not None:
                    if t.tie == "start":
                        n.tie = tie.Tie(t.tie)
                        n.tie.style = "normal"
                    elif t.tie == "stop":
                        n.tie = tie.Tie(t.tie)
                ### Was: Extremely Slow for large Opus files... why?
                ### Answer: some pieces didn't close all their spanners, so
                ###         everything was in a Slur/Diminuendo, etc.
                for span in t.applicableSpanners:
                    span.addSpannedElements(n)

                if t.inGrace:
                    n = n.getGrace()

                n.articulations = []
                while len(t.artic) > 0:
                    tmp = t.artic.pop()
                    if tmp == "staccato":
                        n.articulations.append(articulations.Staccato())
                    if tmp == "upbow":
                        n.articulations.append(articulations.UpBow())
                    if tmp == "downbow":
                        n.articulations.append(articulations.DownBow())
                    if tmp == "accent":
                        n.articulations.append(articulations.Accent())
                    if tmp == "strongaccent":
                        n.articulations.append(articulations.StrongAccent())
                    if tmp == "tenuto":
                        n.articulations.append(articulations.Tenuto())

                dst._appendCore(n)
            elif isinstance(t, abcModule.ABCSlurStart):
                p._appendCore(t.slurObj)
            elif isinstance(t, abcModule.ABCCrescStart):
                p._appendCore(t.crescObj)
            elif isinstance(t, abcModule.ABCDimStart):
                p._appendCore(t.dimObj)
        dst._elementsChanged()

        # 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 != 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._appendCore(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:
        if useMeasures:  # assume at start of measures
            p.getElementsByClass('Measure')[0].clef = p.flat.bestClef()
        else:
            p._insertCore(0, p.bestClef())

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

    if useMeasures and len(
            p.flat.getTimeSignatures(searchContext=False,
                                     returnDefault=False)) > 0:
        # call make beams for now; later, import beams
        #environLocal.printDebug(['abcToStreamPart: calling makeBeams'])
        try:
            p.makeBeams(inPlace=True)
        except meter.MeterException 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._insertCore(0, sp)
        rm.append(sp)
    # remove from original spanner bundle
    for sp in rm:
        spannerBundle.remove(sp)
    p._elementsChanged()
    return p
Exemplo n.º 27
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)
Exemplo n.º 28
0
    def testGetNotesWithinDuration(self):
        n1 = note.Note('C')
        n1.duration = duration.Duration('quarter')
        m1 = stream.Stream()
        m1.append(n1)

        result = getNotesWithinDuration(n1, duration.Duration('quarter'))
        self.assertIsInstance(result, stream.Stream)
        self.assertListEqual([n1], list(result.notes),
                             "starting note occupies full duration")

        result = getNotesWithinDuration(n1, duration.Duration('half'))
        self.assertListEqual([n1], list(result.notes),
                             "starting note occupies partial duration")

        result = getNotesWithinDuration(n1, duration.Duration('eighth'))
        self.assertListEqual([], list(result.notes), "starting note too long")

        m2 = stream.Measure()
        n2 = note.Note('D')
        n2.duration = duration.Duration('eighth')
        n3 = note.Note('E')
        n3.duration = duration.Duration('eighth')
        m2.append([n1, n2, n3])

        result = getNotesWithinDuration(n1, duration.Duration('quarter'))
        self.assertListEqual([n1], list(result.notes),
                             "starting note occupies full duration")

        result = getNotesWithinDuration(n1, duration.Duration('half'))
        self.assertListEqual([n1, n2, n3], list(result.notes),
                             "all notes fill up full duration")

        result = getNotesWithinDuration(n1, duration.Duration('whole'))
        self.assertListEqual([n1, n2, n3], list(result.notes),
                             "all notes fill up partial duration")

        result = getNotesWithinDuration(n1, duration.Duration(1.5))
        self.assertListEqual([n1, n2], list(result.notes),
                             "some notes fill up full duration")

        result = getNotesWithinDuration(n1, duration.Duration(1.75))
        self.assertListEqual([n1, n2], list(result.notes),
                             "some notes fill up partial duration")

        # set active site from m2 to m1 (which runs out of notes to fill up)
        result = getNotesWithinDuration(n1,
                                        duration.Duration('half'),
                                        referenceStream=m1)
        self.assertListEqual([n1], list(result.notes),
                             "partial fill up from reference stream m1")

        m3 = stream.Measure()
        m3.id = "m3"
        r1 = note.Rest()
        r1.duration = duration.Duration('quarter')
        m3.append([n1, r1])  # n1 active site now with m2
        result = getNotesWithinDuration(n1, duration.Duration('half'))
        msg = "note and rest fill up full duration"
        self.assertListEqual([n1, r1], list(result.notesAndRests), msg)

        # set active site from m3 to m2
        result = getNotesWithinDuration(n1,
                                        duration.Duration('half'),
                                        referenceStream=m2)
        self.assertListEqual([n1, n2, n3], list(result.notes),
                             "fill up from reference stream m2")
Exemplo n.º 29
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)
Exemplo n.º 30
0
def toPart(volpianoText, *, breaksToLayout=False):
    # noinspection PyShadowingNames
    '''
    Returns a music21 Part from volpiano text.

    >>> veniSancti = volpiano.toPart('1---c--d---f--d---ed--c--d---f'
    ...                              + '---g--h--j---hgf--g--h---')
    >>> veniSancti.show('text')
    {0.0} <music21.stream.Measure 0 offset=0.0>
        {0.0} <music21.clef.TrebleClef>
        {0.0} <music21.note.Note C>
        {1.0} <music21.note.Note D>
        {2.0} <music21.note.Note F>
        {3.0} <music21.note.Note D>
        {4.0} <music21.note.Note E>
        {5.0} <music21.note.Note D>
        {6.0} <music21.volpiano.Neume <music21.note.Note E><music21.note.Note D>>
        {6.0} <music21.note.Note C>
        {7.0} <music21.note.Note D>
        {8.0} <music21.note.Note F>
        {9.0} <music21.note.Note G>
        {10.0} <music21.note.Note A>
        {11.0} <music21.note.Note B>
        {12.0} <music21.note.Note A>
        {13.0} <music21.note.Note G>
        {14.0} <music21.note.Note F>
        {15.0} <music21.volpiano.Neume <music21.note.Note A><music21.note.Note G>>
        {15.0} <music21.note.Note G>
        {16.0} <music21.note.Note A>

    Clefs!

    >>> clefTest = volpiano.toPart('1---c--2---c')
    >>> clefTest.show('text')
    {0.0} <music21.stream.Measure 0 offset=0.0>
        {0.0} <music21.clef.TrebleClef>
        {0.0} <music21.note.Note C>
        {1.0} <music21.clef.BassClef>
        {1.0} <music21.note.Note E>
    >>> for n in clefTest.recurse().notes:
    ...     n.nameWithOctave
    'C4'
    'E2'

    Flats and Naturals:

    >>> accTest = volpiano.toPart('1---e--we--e--We--e')
    >>> [n.name for n in accTest.recurse().notes]
    ['E', 'E-', 'E-', 'E', 'E']

    Breaks and barlines

    >>> breakTest = volpiano.toPart('1---e-7-e-77-e-777-e-3-e-4')
    >>> breakTest.show('text')
    {0.0} <music21.stream.Measure 0 offset=0.0>
        {0.0} <music21.clef.TrebleClef>
        {0.0} <music21.note.Note E>
        {1.0} <music21.volpiano.LineBreak object at 0x105250fd0>
        {1.0} <music21.note.Note E>
        {2.0} <music21.volpiano.PageBreak object at 0x105262128>
        {2.0} <music21.note.Note E>
        {3.0} <music21.volpiano.ColumnBreak object at 0x105262240>
        {3.0} <music21.note.Note E>
        {4.0} <music21.bar.Barline type=regular>
    {4.0} <music21.stream.Measure 0 offset=4.0>
        {0.0} <music21.note.Note E>
        {1.0} <music21.bar.Barline type=double>


    As layout objects using breaksToLayout=True

    >>> breakTest = volpiano.toPart('1---e-7-e-77-e-777-e-3-e-4', breaksToLayout=True)
    >>> breakTest.show('text')
    {0.0} <music21.stream.Measure 0 offset=0.0>
        {0.0} <music21.clef.TrebleClef>
        {0.0} <music21.note.Note E>
        {1.0} <music21.layout.SystemLayout>
        {1.0} <music21.note.Note E>
        {2.0} <music21.layout.PageLayout>
        {2.0} <music21.note.Note E>
        {3.0} <music21.volpiano.ColumnBreak object at 0x105262240>
        {3.0} <music21.note.Note E>
        {4.0} <music21.bar.Barline type=regular>
    {4.0} <music21.stream.Measure 0 offset=4.0>
        {0.0} <music21.note.Note E>
        {1.0} <music21.bar.Barline type=double>


    Liquescence test:

    >>> breakTest = volpiano.toPart('1---e-E-')
    >>> breakTest.recurse().notes[0].editorial.liquescence
    False
    >>> breakTest.recurse().notes[0].notehead
    'normal'
    >>> breakTest.recurse().notes[1].editorial.liquescence
    True
    >>> breakTest.recurse().notes[1].notehead
    'x'

    Changed in v5.7 -- corrected spelling of liquescence.
    '''
    p = stream.Part()
    m = stream.Measure()

    currentMeasure = m
    currentNeumeSpanner = None
    noteThatWouldGoInSpanner = None
    lastClef = clef.TrebleClef()
    continuousNumberOfBreakTokens = 0

    bIsFlat = False
    eIsFlat = False

    for token in volpianoText:
        if token == '7':
            continuousNumberOfBreakTokens += 1
            continue
        elif continuousNumberOfBreakTokens > 0:
            if not breaksToLayout:  # default
                breakClass = classByNumBreakTokens[
                    continuousNumberOfBreakTokens]
                breakToken = breakClass()  # pylint: disable=not-callable
            else:
                breakClass = classByNumBreakTokensLayout[
                    continuousNumberOfBreakTokens]
                if continuousNumberOfBreakTokens < 3:
                    breakToken = breakClass(isNew=True)  # pylint: disable=not-callable
                else:
                    breakToken = breakClass()  # pylint: disable=not-callable

            currentMeasure.append(breakToken)

        continuousNumberOfBreakTokens = 0

        if token == '-':
            noteThatWouldGoInSpanner = None
            if currentNeumeSpanner:
                currentMeasure.append(currentNeumeSpanner)
                currentNeumeSpanner = None
            continue

        if token in '1234':
            noteThatWouldGoInSpanner = None
            currentNeumeSpanner = None

        if token in '12':
            if token == '1':
                c = clef.TrebleClef()
            else:
                c = clef.BassClef()

            lastClef = c
            m.append(c)

        elif token in '34':
            bl = bar.Barline()
            if token == '4':
                bl.type = 'double'
            m.rightBarline = bl
            p.append(m)
            m = stream.Measure()

        elif token in normalPitches or token in liquescentPitches:
            n = note.Note()
            n.stemDirection = 'noStem'

            if token in normalPitches:
                distanceFromLowestLine = normalPitches.index(token) - 5
                n.editorial.liquescence = False
            else:
                distanceFromLowestLine = liquescentPitches.index(token) - 5
                n.notehead = 'x'
                n.editorial.liquescence = True

            clefLowestLine = lastClef.lowestLine
            diatonicNoteNum = clefLowestLine + distanceFromLowestLine

            n.pitch.diatonicNoteNum = diatonicNoteNum
            if n.pitch.step == 'B' and bIsFlat:
                n.pitch.accidental = pitch.Accidental('flat')
            elif n.pitch.step == 'E' and eIsFlat:
                n.pitch.accidental = pitch.Accidental('flat')

            m.append(n)

            if noteThatWouldGoInSpanner is not None:
                currentNeumeSpanner = Neume([noteThatWouldGoInSpanner, n])
                noteThatWouldGoInSpanner = None
            else:
                noteThatWouldGoInSpanner = n

        elif token in accidentalTokens:
            if token.lower() in eflatTokens and token in naturalTokens:
                eIsFlat = False
            elif token.lower() in bflatTokens and token in naturalTokens:
                bIsFlat = False
            elif token.lower() in eflatTokens and token in flatTokens:
                eIsFlat = True
            elif token.lower() in bflatTokens and token in flatTokens:
                bIsFlat = True
            else:  # pragma: no cover
                raise VolpianoException('Unknown accidental: ' + token +
                                        ': Should not happen')

    if continuousNumberOfBreakTokens > 0:
        breakClass = classByNumBreakTokens[continuousNumberOfBreakTokens]
        breakToken = breakClass()  # pylint: disable=not-callable
        currentMeasure.append(breakToken)

    if m:
        p.append(m)

    return p