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.Note('C4', type='quarter')) >>> sSrc.append(note.Note('D4', type='quarter')) >>> sSrc.append(note.Note('E4', type='quarter')) >>> 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. >>> sSrc = stream.Part() >>> n = note.Note('E-4') >>> n.quarterLength = 1 >>> sSrc.repeatAppend(n, 10) 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: >>> 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 [] >>> allNotes[1].articulations [] >>> allNotes[2].articulations [<music21.articulations.Staccato>] >>> [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) #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 #clefList = srcObj.getClefs(searchActiveSite=True, # searchContext=searchContext, # returnDefault=True) #clefObj = clefList[0] #del clefList clefObj = srcObj.clef or srcObj.getContextByClass('Clef') if clefObj is None: clefList = list( srcObj.iter.getElementsByClass('Clef').getElementsByOffset(0)) # only return clefs that have offset = 0.0 if len(clefList) == 0: clefObj = srcObj.bestClef() else: clefObj = clefList[0] #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: e, start, end, voiceIndex = ob #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 'Spanner' in e.classes: 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 = post.elementOffset(m) 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(post.elementOffset(e), e)
def abcToStreamPart(abcHandler, inputM21=None, spannerBundle=None): ''' Handler conversion of a single Part of a multi-part score. Results are added into the provided inputM21 object or a newly created Part object The part object is then returned. ''' from music21 import abcFormat if inputM21 is None: p = stream.Part() else: p = inputM21 if spannerBundle is None: #environLocal.printDebug(['mxToMeasure()', 'creating SpannerBundle']) spannerBundle = spanner.SpannerBundle() # need to call on entire handlers, as looks for special criterial, # like that at least 2 regular bars are used, not just double bars if abcHandler.definesMeasures(): # first, split into a list of Measures; if there is only metadata and # one measure, that means that no measures are defined barHandlers = abcHandler.splitByMeasure() #environLocal.printDebug(['barHandlers', len(barHandlers)]) # merge loading meta data with each bar that preceedes it mergedHandlers = abcFormat.mergeLeadingMetaData(barHandlers) #environLocal.printDebug(['mergedHandlers', len(mergedHandlers)]) else: # simply stick in a single list mergedHandlers = [abcHandler] # if only one merged handler, do not create measures if len(mergedHandlers) <= 1: useMeasures = False else: useMeasures = True # each unit in merged handlers defines possible a Measure (w/ or w/o metadata), # trailing meta data, or a single collection of metadata and note data barCount = 0 measureNumber = 1 # merged handler are ABCHandlerBar objects, defining attributes for barlines for mh in mergedHandlers: # if use measures and the handler has notes; otherwise add to part #environLocal.printDebug(['abcToStreamPart', 'handler', 'left:', mh.leftBarToken, # 'right:', mh.rightBarToken, 'len(mh)', len(mh)]) if useMeasures and mh.hasNotes(): #environLocal.printDebug(['abcToStreamPart', 'useMeasures', # useMeasures, 'mh.hasNotes()', mh.hasNotes()]) dst = stream.Measure() # bar tokens are already extracted form token list and are available # as attributes on the handler object # may return None for a regular barline if mh.leftBarToken is not None: # this may be Repeat Bar subclass bLeft = mh.leftBarToken.getBarObject() if bLeft is not None: dst.leftBarline = bLeft if mh.leftBarToken.isRepeatBracket(): # get any open spanners of RepeatBracket type rbSpanners = spannerBundle.getByClass( 'RepeatBracket').getByCompleteStatus(False) # this indication is most likely an opening, as ABC does # not encode second ending ending boundaries # we can still check thought: if not rbSpanners: # add this measure as a componnt rb = spanner.RepeatBracket(dst) # set number, returned here rb.number = mh.leftBarToken.isRepeatBracket() # only append if created; otherwise, already stored spannerBundle.append(rb) else: # close it here rb = rbSpanners[0] # get RepeatBracket rb.addSpannedElements(dst) rb.completeStatus = True # this returns 1 or 2 depending on the repeat # in ABC, second repeats close immediately; that is # they never span more than one measure if mh.leftBarToken.isRepeatBracket() == 2: rb.completeStatus = True if mh.rightBarToken is not None: bRight = mh.rightBarToken.getBarObject() if bRight is not None: dst.rightBarline = bRight # above returns bars and repeats; we need to look if we just # have repeats if mh.rightBarToken.isRepeat(): # if we have a right bar repeat, and a spanner repeat # bracket is open (even if just assigned above) we need # to close it now. # presently, now r bar conditions start a repeat bracket rbSpanners = spannerBundle.getByClass( 'RepeatBracket').getByCompleteStatus(False) if any(rbSpanners): rb = rbSpanners[0] # get RepeatBracket rb.addSpannedElements(dst) rb.completeStatus = True # this returns 1 or 2 depending on the repeat # do not need to append; already in bundle barCount += 1 else: dst = p # store directly in a part instance #environLocal.printDebug([mh, 'dst', dst]) #ql = 0 # might not be zero if there is a pickup postTransposition, clefSet = parseTokens(mh, dst, p, useMeasures) # append measure to part; in the case of trailing meta data # dst may be part, even though useMeasures is True if useMeasures and 'Measure' in dst.classes: # check for incomplete bars # must have a time signature in this bar, or defined recently # could use getTimeSignatures() on Stream if barCount == 1 and dst.timeSignature is not None: # easy case # can only do this b/c ts is defined if dst.barDurationProportion() < 1.0: dst.padAsAnacrusis() dst.number = 0 #environLocal.printDebug([ # 'incompletely filled Measure found on abc import; ', # 'interpreting as a anacrusis:', 'padingLeft:', dst.paddingLeft]) else: dst.number = measureNumber measureNumber += 1 p.coreAppend(dst) try: reBar(p, inPlace=True) except (ABCTranslateException, meter.MeterException, ZeroDivisionError): pass # clefs are not typically defined, but if so, are set to the first measure # following the meta data, or in the open stream if not clefSet and not p.recurse().getElementsByClass('Clef'): if useMeasures: # assume at start of measures p.getElementsByClass('Measure')[0].clef = clef.bestClef( p, recurse=True) else: p.coreInsert(0, clef.bestClef(p, recurse=True)) if postTransposition != 0: p.transpose(postTransposition, inPlace=True) if useMeasures and p.recurse().getElementsByClass('TimeSignature'): # call make beams for now; later, import beams #environLocal.printDebug(['abcToStreamPart: calling makeBeams']) try: p.makeBeams(inPlace=True) except (meter.MeterException, stream.StreamException) as e: environLocal.warn("Error in beaming...ignoring: %s" % str(e)) # copy spanners into topmost container; here, a part rm = [] for sp in spannerBundle.getByCompleteStatus(True): p.coreInsert(0, sp) rm.append(sp) # remove from original spanner bundle for sp in rm: spannerBundle.remove(sp) p.coreElementsChanged() return p
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.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, abcFormat.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, abcFormat.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, abcFormat.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, abcFormat.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, abcFormat.ABCSlurStart): p._appendCore(t.slurObj) elif isinstance(t, abcFormat.ABCCrescStart): p._appendCore(t.crescObj) elif isinstance(t, abcFormat.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