-
Notifications
You must be signed in to change notification settings - Fork 396
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix #1633 #1636
Open
TimFelixBeyer
wants to merge
4
commits into
cuthbertLab:master
Choose a base branch
from
TimFelixBeyer:TimFelixBeyer-patch-1
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Fix #1633 #1636
Changes from all commits
Commits
Show all changes
4 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -31,6 +31,7 @@ | |
from music21 import duration | ||
from music21 import dynamics | ||
from music21.common.enums import OrnamentDelay | ||
from music21.common.numberTools import opFrac | ||
from music21 import editorial | ||
from music21 import environment | ||
from music21 import exceptions21 | ||
|
@@ -866,6 +867,19 @@ def xmlRootToScore(self, mxScore, inputM21=None): | |
self.spannerBundle.remove(sp) | ||
|
||
s.coreElementsChanged() | ||
# Fill gaps with rests where needed | ||
for m in s[stream.Measure]: | ||
for v in m.voices: | ||
if v: # do not bother with empty voices | ||
# the musicDataMethods use insertCore, thus the voices need to run | ||
# coreElementsChanged | ||
v.coreElementsChanged() | ||
# Fill mid-measure gaps, and find end of measure gaps by ref to measure stream | ||
# https://github.com/cuthbertlab/music21/issues/444 | ||
v.makeRests(refStreamOrTimeRange=m, | ||
fillGaps=True, | ||
inPlace=True, | ||
hideRests=True) | ||
s.definesExplicitSystemBreaks = self.definesExplicitSystemBreaks | ||
s.definesExplicitPageBreaks = self.definesExplicitPageBreaks | ||
for p in s.parts: | ||
|
@@ -1760,32 +1774,8 @@ def parseMeasures(self): | |
for mxMeasure in self.mxPart.iterfind('measure'): | ||
self.xmlMeasureToMeasure(mxMeasure) | ||
|
||
self.removeEndForwardRest() | ||
part.coreElementsChanged() | ||
|
||
def removeEndForwardRest(self): | ||
''' | ||
If the last measure ended with a forward tag, as happens | ||
in some pieces that end with incomplete measures, | ||
and voices are not involved, | ||
remove the rest there (for backwards compatibility, esp. | ||
since bwv66.6 uses it) | ||
|
||
* New in v7. | ||
''' | ||
if self.lastMeasureParser is None: # pragma: no cover | ||
return # should not happen | ||
lmp = self.lastMeasureParser | ||
self.lastMeasureParser = None # clean memory | ||
|
||
if lmp.endedWithForwardTag is None: | ||
return | ||
if lmp.useVoices is True: | ||
return | ||
endedForwardRest = lmp.endedWithForwardTag | ||
if lmp.stream.recurse().notesAndRests.last() is endedForwardRest: | ||
lmp.stream.remove(endedForwardRest, recurse=True) | ||
|
||
def separateOutPartStaves(self) -> list[stream.PartStaff]: | ||
''' | ||
Take a `Part` with multiple staves and make them a set of `PartStaff` objects. | ||
|
@@ -2233,7 +2223,7 @@ def adjustTimeAttributesFromMeasure(self, m: stream.Measure): | |
else: | ||
self.lastMeasureWasShort = False | ||
|
||
self.lastMeasureOffset += mOffsetShift | ||
self.lastMeasureOffset = opFrac(self.lastMeasureOffset + mOffsetShift) | ||
|
||
def applyMultiMeasureRest(self, r: note.Rest): | ||
''' | ||
|
@@ -2390,13 +2380,6 @@ def __init__(self, | |
# what is the offset in the measure of the current note position? | ||
self.offsetMeasureNote: OffsetQL = 0.0 | ||
|
||
# keep track of the last rest that was added with a forward tag. | ||
# there are many pieces that end with incomplete measures that | ||
# older versions of Finale put a forward tag at the end, but this | ||
# disguises the incomplete last measure. The PartParser will | ||
# pick this up from the last measure. | ||
self.endedWithForwardTag: note.Rest | None = None | ||
|
||
@staticmethod | ||
def getStaffNumber(mxObjectOrNumber) -> int: | ||
''' | ||
|
@@ -2553,19 +2536,8 @@ def parse(self): | |
if methName is not None: | ||
meth = getattr(self, methName) | ||
meth(mxObj) | ||
|
||
if self.useVoices is True: | ||
for v in self.stream.iter().voices: | ||
if v: # do not bother with empty voices | ||
# the musicDataMethods use insertCore, thus the voices need to run | ||
# coreElementsChanged | ||
v.coreElementsChanged() | ||
# Fill mid-measure gaps, and find end of measure gaps by ref to measure stream | ||
# https://github.com/cuthbertlab/music21/issues/444 | ||
v.makeRests(refStreamOrTimeRange=self.stream, | ||
fillGaps=True, | ||
inPlace=True, | ||
hideRests=True) | ||
for v in self.stream[stream.Voice]: | ||
v.coreElementsChanged() | ||
self.stream.coreElementsChanged() | ||
|
||
if (self.restAndNoteCount['rest'] == 1 | ||
|
@@ -2588,18 +2560,16 @@ def xmlBackup(self, mxObj: ET.Element): | |
>>> mxBackup = EL('<backup><duration>100</duration></backup>') | ||
>>> MP.xmlBackup(mxBackup) | ||
>>> MP.offsetMeasureNote | ||
0.9979 | ||
Fraction(9979, 10000) | ||
|
||
>>> MP.xmlBackup(mxBackup) | ||
>>> MP.offsetMeasureNote | ||
0.0 | ||
''' | ||
mxDuration = mxObj.find('duration') | ||
if durationText := strippedText(mxDuration): | ||
change = common.numberTools.opFrac( | ||
float(durationText) / self.divisions | ||
) | ||
self.offsetMeasureNote -= change | ||
change = opFrac(float(durationText) / self.divisions) | ||
self.offsetMeasureNote = opFrac(self.offsetMeasureNote - change) | ||
Comment on lines
+2571
to
+2572
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is a useful change that I'd be glad to accept in isolation. |
||
# check for negative offsets produced by | ||
# musicxml durations with float rounding issues | ||
# https://github.com/cuthbertLab/music21/issues/971 | ||
|
@@ -2611,22 +2581,9 @@ def xmlForward(self, mxObj: ET.Element): | |
''' | ||
mxDuration = mxObj.find('duration') | ||
if durationText := strippedText(mxDuration): | ||
change = common.numberTools.opFrac( | ||
float(durationText) / self.divisions | ||
) | ||
|
||
# Create hidden rest (in other words, a spacer) | ||
# old Finale documents close incomplete final measures with <forward> | ||
# this will be removed afterward by removeEndForwardRest() | ||
r = note.Rest(quarterLength=change) | ||
r.style.hideObjectOnPrint = True | ||
self.addToStaffReference(mxObj, r) | ||
self.insertInMeasureOrVoice(mxObj, r) | ||
|
||
change = opFrac(float(durationText) / self.divisions) | ||
# Allow overfilled measures for now -- TODO(someday): warn? | ||
self.offsetMeasureNote += change | ||
# xmlToNote() sets None | ||
self.endedWithForwardTag = r | ||
self.offsetMeasureNote = opFrac(self.offsetMeasureNote + change) | ||
|
||
def xmlPrint(self, mxPrint: ET.Element): | ||
''' | ||
|
@@ -2785,8 +2742,7 @@ def xmlToNote(self, mxNote: ET.Element) -> None: | |
self.nLast = c # update | ||
|
||
# only increment Chords after completion | ||
self.offsetMeasureNote += offsetIncrement | ||
self.endedWithForwardTag = None | ||
self.offsetMeasureNote = opFrac(self.offsetMeasureNote + offsetIncrement) | ||
|
||
def xmlToChord(self, mxNoteList: list[ET.Element]) -> chord.ChordBase: | ||
# noinspection PyShadowingNames | ||
|
@@ -3578,7 +3534,7 @@ def xmlToDuration(self, mxNote, inputM21=None): | |
mxDuration = mxNote.find('duration') | ||
if mxDuration is not None: | ||
noteDivisions = float(mxDuration.text.strip()) | ||
qLen = common.numberTools.opFrac(noteDivisions / divisions) | ||
qLen = opFrac(noteDivisions / divisions) | ||
else: | ||
qLen = 0.0 | ||
|
||
|
@@ -5510,7 +5466,7 @@ def parseAttributesTag(self, mxAttributes): | |
meth(mxSub) | ||
# NOT to be done: directive -- deprecated since v2. | ||
elif tag == 'divisions': | ||
self.divisions = common.opFrac(float(mxSub.text)) | ||
self.divisions = opFrac(float(mxSub.text)) | ||
# TODO: musicxml4: for-part including part-clef | ||
# TODO: instruments -- int if more than one instrument plays most of the time | ||
# TODO: part-symbol | ||
|
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this is too presumptive on the part of the parser. We should be interpolating/inventing as few elements as possible that are not in the document.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree!
I just put the makeRests there because previously the parser also ran
makeRests
(this block is basically just copy pasted from before), but I'd be more than happy to remove it.