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 with ScoreVariant #385

Open
leleogere opened this issue Oct 4, 2024 · 1 comment
Open

Issue with ScoreVariant #385

leleogere opened this issue Oct 4, 2024 · 1 comment
Assignees

Comments

@leleogere
Copy link

leleogere commented Oct 4, 2024

Following #380, @sildater suggested opening an issue for that, even if the ScoreVariant class does not seem public looking at its doc.

I was trying to manually split a score into multiple chunks of a few measures, which was in good progress, but I was suggested the object ScoreVariant that would do exactly what I wanted to do.

However, while it does work for some measures, some others seem to cause issues, like the measure 9 of a Rachmaninoff piece:

Manual extraction of measure 9 (working):
Manual extraction of measure 9

Automatic extraction of measure 9 using ScoreVariant (bugged):
Automatic extraction of measure 9

After some investigations, I managed to track down what the issue was. When creating the new part with this score, it seems that the ScoreVariant objects creates it with part._quarter_durations set to [1] by default, while the original part has it set to [120]. Setting it manually using the part.quarter_duration_map method seems to fix the problem.

It's weird that the ScoreVariant does not take care of this by itself, as it seems that its create_variant_part method does play with the quarter durations (although I did not investigate further).

You can generate both versions with the following script:

from pathlib import Path

import partitura as pt
import partitura.score

SCORE_PATH = Path('/home/user/nasap-dataset/Rachmaninoff/Preludes_op_32/5/xml_score.musicxml')
START_MEASURE = 8
END_MEASURE = 10
OUT_DIR = Path("/tmp") / SCORE_PATH.name

score = pt.load_musicxml(SCORE_PATH)
assert len(score.parts) == 1
part = score.parts[0]

OUT_DIR.mkdir(exist_ok=True)

# Get the asked measures
start_measure: pt.score.Measure = part.measures[START_MEASURE - 1]
end_measure: pt.score.Measure = part.measures[END_MEASURE - 1]
print(f"Start measure: {start_measure}")
print(f"End measure: {end_measure}")

# Create a new ScoreVariant
sv = pt.score.ScoreVariant(part)
sv.add_segment(start_measure.start, end_measure.end)
new_part = sv.create_variant_part()

# See the difference between the quarter durations of the original and new part
print(f"{part._quarter_durations = }")
print(f"{new_part._quarter_durations = }")

# Save the new part without adapting the quarter durations
pt.save_musicxml(new_part, OUT_DIR / f"M{START_MEASURE}-{END_MEASURE}_naive.musicxml")

# Manually fix the quarter durations and save the new version
new_part.set_quarter_duration(0, part.quarter_duration_map(start_measure.start.t))
pt.save_musicxml(new_part, OUT_DIR / f"M{START_MEASURE}-{END_MEASURE}_fixed.musicxml")

EDIT: You can find another example of this issue in measure 26 of Bach/Fugue/bwv_857 in the ASAP dataset.

@sildater sildater self-assigned this Oct 4, 2024
@sildater
Copy link
Member

sildater commented Oct 4, 2024

Thanks for submitting this issue and the detailed tests! I'll look into this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants