Skip to content
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

Issue in MusicXML export #390

Open
leleogere opened this issue Oct 16, 2024 · 3 comments · Fixed by #391
Open

Issue in MusicXML export #390

leleogere opened this issue Oct 16, 2024 · 3 comments · Fixed by #391
Assignees
Labels
invalid This doesn't seem right

Comments

@leleogere
Copy link

leleogere commented Oct 16, 2024

I'm not sure if it is related to Partitura or MuseScore, but I'm facing weird behavior when I try to extract a part of a score:

Here is the MusicXML rendered by MuseScore:
MusicXML rendered by MuseScore

Here is the list of elements in the partitura Part object:

0--48 Note id=n264 voice=1 staff=1 type=half articulations=(accent) pitch=Eb5
0--48 Note id=n265 voice=1 staff=1 type=half pitch=Eb6
0--6 Note id=n280 voice=5 staff=2 type=16th pitch=C2
0--24 Beam
0--96 Slur start=n280 end=n295
0--96 Measure number=11 name=11
0-- TimeSignature 4/4                    <<< The time signature does start at 0 here <<<
0--42 IncreasingLoudnessDirection "crescendo" wedge
6--12 Note id=n281 voice=5 staff=2 type=16th pitch=G2
12--18 Note id=n282 voice=5 staff=2 type=16th pitch=C3
18--24 Note id=n283 voice=5 staff=2 type=16th pitch=D3
24--30 Note id=n284 voice=5 staff=2 type=16th pitch=Eb3
24--48 Beam
30--36 Note id=n285 voice=5 staff=2 type=16th pitch=G3
36--42 Note id=n286 voice=5 staff=2 type=16th pitch=C4
42--48 Note id=n287 voice=5 staff=2 type=16th pitch=D4
48--54 Note id=n288 voice=5 staff=2 type=16th pitch=Eb4
48--60 Rest id=n266 voice=1 staff=1 type=eighth
48--72 Beam
48--90 DecreasingLoudnessDirection "diminuendo" wedge
54--60 Note id=n289 voice=5 staff=2 type=16th pitch=D4
60--66 Note id=n290 voice=5 staff=2 type=16th pitch=C4
60--66 Rest id=n267 voice=1 staff=1 type=16th
60--156 ConstantLoudnessDirection "p"
66--72 Note id=n268 voice=1 staff=1 type=16th pitch=G4
66--72 Note id=n269 voice=1 staff=1 type=16th pitch=C5
66--72 Note id=n270 voice=1 staff=1 type=16th pitch=Eb5
66--72 Note id=n271 voice=1 staff=1 type=16th pitch=G5
66--72 Note id=n291 voice=5 staff=2 type=16th pitch=G3
66--90 IncreasingLoudnessDirection "crescendo" wedge
72--90 Note id=n272 voice=1 staff=1 type=eighth. pitch=G4
72--90 Note id=n273 voice=1 staff=1 type=eighth. pitch=C5
72--90 Note id=n274 voice=1 staff=1 type=eighth. pitch=Eb5
72--90 Note id=n275 voice=1 staff=1 type=eighth. pitch=G5
72--78 Note id=n292 voice=5 staff=2 type=16th pitch=Eb3
72--90 Beam
72--96 Beam
78--84 Note id=n293 voice=5 staff=2 type=16th pitch=D3
84--90 Note id=n294 voice=5 staff=2 type=16th pitch=C3
90--96 Note id=n276 voice=1 staff=1 type=16th pitch=G4
90--96 Note id=n277 voice=1 staff=1 type=16th pitch=C5
90--96 Note id=n278 voice=1 staff=1 type=16th pitch=Eb5
90--96 Note id=n279 voice=1 staff=1 type=16th pitch=G5
90--96 Note id=n295 voice=5 staff=2 type=16th pitch=G2

The TimeSignature object does start at 0, but when I open the MusicXML file in MuseScore, I get it in the middle of the measure, resulting in the two hands not being in sync and the measure containing apparently 8 beats.

Interestingly, it does not fail for every measure, for example, the measure 11 of this piece fails, but the 10 works as expected.

You can find the problematic MusicXML here.

Here is the code to reproduce the issue (the measure in question is the measure 11 from Chopin's Etude op10 no12):

import copy
from pathlib import Path

import partitura as pt
import partitura.score


score_path = Path("/home/user/nasap-dataset/Chopin/Etudes_op_10/12/xml_score.musicxml")

score = pt.load_musicxml(score_path).parts[0]

measure_idx = 11
measure = score.measures[measure_idx - 1]
extracted_measure = pt.score.Part(id="measure")

for obj in score.iter_all(start=measure.start, end=measure.end):
    print(obj)

    # Shift start and end to measure start
    start = None if obj.start is None else obj.start.t - measure.start.t
    end = None if obj.end is None else obj.end.t - measure.start.t

    # Add object to extracted_measure
    extracted_measure.add(copy.copy(obj), start=start, end=end)

# Add 4/4 time signature
extracted_measure.add(pt.score.TimeSignature(4, 4), start=0)

print("#" * 80)
for obj in extracted_measure.iter_all():
    print(obj)

pt.save_musicxml(extracted_measure, Path("/tmp/test.musicxml"))
@manoskary manoskary assigned manoskary and sildater and unassigned manoskary Oct 17, 2024
@sildater sildater added the invalid This doesn't seem right label Oct 17, 2024
@sildater
Copy link
Member

Hi @leleogere Thanks for the issue and code to reproduce it! I can get it to work using a small change in your code and a patch to the export function:

  • in your code, be sure to instantiate the new part with the same number of quarter divisions as the old one, like so extracted_measure = pt.score.Part(id="measure", quarter_duration = score._quarter_durations[0])
  • in the export, I disable cost-based merging of attributes, so the time signature and other info are now in the beginning of the exported musicxml measure. This seems to work with musescore, but I don't know whether it'll have any negative consequences in the future. It's just a patch, we might roll it back at some point when we spend some time on export_musicxml.

@sildater sildater linked a pull request Oct 17, 2024 that will close this issue
@sildater
Copy link
Member

image

@leleogere
Copy link
Author

Thank you for your help! I'll use this patch for now as it fix the issue, and let you know if I can spot any abnormal behavior.

The fact that it does not happen on all measures is quite bizarre.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
invalid This doesn't seem right
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants